From 509c4f0cd7ca0c4f7c7aa86219fa8a5d4c09f4ca Mon Sep 17 00:00:00 2001 From: Oliver Zell Date: Sat, 5 Aug 2023 11:23:31 +0200 Subject: [PATCH 1/3] docs: extend some docs --- src/common/Sweep.ts | 10 +++++----- src/dynamics/World.ts | 8 +++++--- src/dynamics/joint/DistanceJoint.ts | 2 ++ 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/src/common/Sweep.ts b/src/common/Sweep.ts index 249eee17..c978b5a8 100644 --- a/src/common/Sweep.ts +++ b/src/common/Sweep.ts @@ -84,15 +84,15 @@ export class Sweep { /** * Get the interpolated transform at a specific time. * - * @param xf + * @param transform the output transform * @param beta A factor in [0,1], where 0 indicates alpha0 */ - getTransform(xf: TransformValue, beta: number = 0): void { - matrix.setRotAngle(xf.q, (1.0 - beta) * this.a0 + beta * this.a); - matrix.combineVec2(xf.p, (1.0 - beta), this.c0, beta, this.c); + getTransform(transform: TransformValue, beta: number = 0): void { + matrix.setRotAngle(transform.q, (1.0 - beta) * this.a0 + beta * this.a); + matrix.combineVec2(transform.p, (1.0 - beta), this.c0, beta, this.c); // shift to origin - matrix.subVec2(xf.p, matrix.rotVec2(temp, xf.q, this.localCenter)); + matrix.subVec2(transform.p, matrix.rotVec2(temp, transform.q, this.localCenter)); } /** diff --git a/src/dynamics/World.ts b/src/dynamics/World.ts index 9e3f3170..40d02232 100644 --- a/src/dynamics/World.ts +++ b/src/dynamics/World.ts @@ -74,14 +74,16 @@ const WorldDefDefault: WorldDef = { * Callback function for ray casts, see {@link World.rayCast}. * * Called for each fixture found in the query. You control how the ray cast - * proceeds by returning a float: return -1: ignore this fixture and continue - * return 0: terminate the ray cast return fraction: clip the ray to this point + * proceeds by returning a float: + * return -1: ignore this fixture and continue + * return 0: terminate the ray cast + * return fraction: clip the ray to this point * return 1: don't clip the ray and continue * * @param fixture The fixture hit by the ray * @param point The point of initial intersection * @param normal The normal vector at the point of intersection - * @param fraction + * @param fraction The fraction along the ray at the point of intersection * * @return -1 to filter, 0 to terminate, fraction to clip the ray for closest hit, 1 to continue */ diff --git a/src/dynamics/joint/DistanceJoint.ts b/src/dynamics/joint/DistanceJoint.ts index d593186c..f65fc7fa 100644 --- a/src/dynamics/joint/DistanceJoint.ts +++ b/src/dynamics/joint/DistanceJoint.ts @@ -349,6 +349,8 @@ export class DistanceJoint extends Joint { // magic formulas const h = step.dt; + + // gamma = 1 / (h * (d + h * k)), the extra factor of h in the denominator is since the lambda is an impulse, not a force this.m_gamma = h * (d + h * k); this.m_gamma = this.m_gamma != 0.0 ? 1.0 / this.m_gamma : 0.0; this.m_bias = C * h * k * this.m_gamma; From 71204d266ffbf228aec464007b9957bdc0f9d7fd Mon Sep 17 00:00:00 2001 From: Oliver Zell Date: Sat, 5 Aug 2023 12:12:21 +0200 Subject: [PATCH 2/3] feat!: rename body active property to enabled and set newContacts --- example/PolyShapes.js | 2 +- src/dynamics/Body.ts | 55 ++++++++++++++++++++++-------------------- src/dynamics/Joint.ts | 6 ++--- src/dynamics/Solver.ts | 6 ++--- src/dynamics/World.ts | 8 +++--- 5 files changed, 40 insertions(+), 37 deletions(-) diff --git a/example/PolyShapes.js b/example/PolyShapes.js index afc884d8..c722d94e 100644 --- a/example/PolyShapes.js +++ b/example/PolyShapes.js @@ -124,7 +124,7 @@ testbed.keydown = function(code, char) { case 'Z': for (var i = 0; i < bodies.length; i += 2) { var body = bodies[i]; - body.setActive(!body.isActive()); + body.setEnabled(!body.isEnabled()); } break; diff --git a/src/dynamics/Body.ts b/src/dynamics/Body.ts index c1ba7818..9d89e359 100644 --- a/src/dynamics/Body.ts +++ b/src/dynamics/Body.ts @@ -108,9 +108,9 @@ export interface BodyDef { */ awake?: boolean; /** - * Does this body start out active? + * Does this body start out enabled? */ - active?: boolean; + enabled?: boolean; userData?: any; } @@ -131,7 +131,7 @@ const BodyDefDefault: BodyDef = { allowSleep : true, awake : true, - active : true, + enabled : true, userData : null }; @@ -185,7 +185,7 @@ export class Body { /** @internal */ m_autoSleepFlag: boolean; /** @internal */ m_bulletFlag: boolean; /** @internal */ m_fixedRotationFlag: boolean; - /** @internal */ m_activeFlag: boolean; + /** @internal */ m_enabledFlag: boolean; /** @internal */ m_islandFlag: boolean; /** @internal */ m_toiFlag: boolean; /** @internal */ m_userData: unknown; @@ -234,7 +234,7 @@ export class Body { this.m_autoSleepFlag = def.allowSleep; this.m_bulletFlag = def.bullet; this.m_fixedRotationFlag = def.fixedRotation; - this.m_activeFlag = def.active; + this.m_enabledFlag = def.enabled; this.m_islandFlag = false; this.m_toiFlag = false; @@ -486,39 +486,42 @@ export class Body { } } - isActive(): boolean { - return this.m_activeFlag; + isEnabled(): boolean { + return this.m_enabledFlag; } /** - * Set the active state of the body. An inactive body is not simulated and - * cannot be collided with or woken up. If you pass a flag of true, all fixtures - * will be added to the broad-phase. If you pass a flag of false, all fixtures - * will be removed from the broad-phase and all contacts will be destroyed. - * Fixtures and joints are otherwise unaffected. - * - * You may continue to create/destroy fixtures and joints on inactive bodies. - * Fixtures on an inactive body are implicitly inactive and will not participate - * in collisions, ray-casts, or queries. Joints connected to an inactive body - * are implicitly inactive. An inactive body is still owned by a World object - * and remains + * Allow a body to be disabled. A disabled body is not simulated and cannot be + * collided with or woken up. + * If you pass a flag of true, all fixtures will be added to the broad-phase. + * If you pass a flag of false, all fixtures will be removed from the + * broad-phase and all contacts will be destroyed. + * + * Fixtures and joints are otherwise unaffected. You may continue to + * create/destroy fixtures and joints on disabled bodies. + * Fixtures on a disabled body are implicitly disabled and will not + * participate in collisions, ray-casts, or queries. + * Joints connected to a disabled body are implicitly disabled. + * An diabled body is still owned by a b2World object and remains in the body + * list. */ - setActive(flag: boolean): void { + setEnabled(flag: boolean): void { _ASSERT && console.assert(this.isWorldLocked() == false); - if (flag == this.m_activeFlag) { + if (flag == this.m_enabledFlag) { return; } - this.m_activeFlag = !!flag; + this.m_enabledFlag = !!flag; - if (this.m_activeFlag) { + if (this.m_enabledFlag) { // Create all proxies. const broadPhase = this.m_world.m_broadPhase; for (let f = this.m_fixtureList; f; f = f.m_next) { f.createProxies(broadPhase, this.m_xf); } - // Contacts are created the next time step. + // Contacts are created at the beginning of the next time step. + this.m_world.m_newContacts = true; } else { // Destroy all proxies. @@ -1021,7 +1024,7 @@ export class Body { return null; } - if (this.m_activeFlag) { + if (this.m_enabledFlag) { const broadPhase = this.m_world.m_broadPhase; fixture.createProxies(broadPhase, this.m_xf); } @@ -1036,7 +1039,7 @@ export class Body { // Let the world know we have a new fixture. This will cause new contacts // to be created at the beginning of the next time step. - this.m_world.m_newFixture = true; + this.m_world.m_newContacts = true; return fixture; } @@ -1124,7 +1127,7 @@ export class Body { } } - if (this.m_activeFlag) { + if (this.m_enabledFlag) { const broadPhase = this.m_world.m_broadPhase; fixture.destroyProxies(broadPhase); } diff --git a/src/dynamics/Joint.ts b/src/dynamics/Joint.ts index 1a1bc72f..4324bd5a 100644 --- a/src/dynamics/Joint.ts +++ b/src/dynamics/Joint.ts @@ -126,10 +126,10 @@ export abstract class Joint { } /** - * Short-cut function to determine if either body is inactive. + * Short-cut function to determine if either body is enabled. */ - isActive(): boolean { - return this.m_bodyA.isActive() && this.m_bodyB.isActive(); + isEnabled(): boolean { + return this.m_bodyA.isEnabled() && this.m_bodyB.isEnabled(); } /** diff --git a/src/dynamics/Solver.ts b/src/dynamics/Solver.ts index 91235b05..fa892c92 100644 --- a/src/dynamics/Solver.ts +++ b/src/dynamics/Solver.ts @@ -185,7 +185,7 @@ export class Solver { continue; } - if (seed.isAwake() == false || seed.isActive() == false) { + if (seed.isAwake() == false || seed.isEnabled() == false) { continue; } @@ -205,7 +205,7 @@ export class Solver { while (stack.length > 0) { // Grab the next body off the stack and add it to the island. const b = stack.pop(); - _ASSERT && console.assert(b.isActive() == true); + _ASSERT && console.assert(b.isEnabled() == true); this.addBody(b); // Make sure the body is awake (without resetting sleep timer). @@ -262,7 +262,7 @@ export class Solver { const other = je.other; // Don't simulate joints connected to inactive bodies. - if (other.isActive() == false) { + if (other.isEnabled() == false) { continue; } diff --git a/src/dynamics/World.ts b/src/dynamics/World.ts index 40d02232..d97fa8ad 100644 --- a/src/dynamics/World.ts +++ b/src/dynamics/World.ts @@ -107,7 +107,7 @@ export class World { /** @internal */ m_allowSleep: boolean; /** @internal */ m_gravity: Vec2; /** @internal */ m_clearForces: boolean; - /** @internal */ m_newFixture: boolean; + /** @internal */ m_newContacts: boolean; /** @internal */ m_locked: boolean; /** @internal */ m_warmStarting: boolean; /** @internal */ m_continuousPhysics: boolean; @@ -158,7 +158,7 @@ export class World { this.m_gravity = Vec2.clone(def.gravity); this.m_clearForces = true; - this.m_newFixture = false; + this.m_newContacts = false; this.m_locked = false; // These are for debugging the solver. @@ -794,9 +794,9 @@ export class World { positionIterations = positionIterations || this.m_positionIterations; // If new fixtures were added, we need to find the new contacts. - if (this.m_newFixture) { + if (this.m_newContacts) { this.findNewContacts(); - this.m_newFixture = false; + this.m_newContacts = false; } this.m_locked = true; From 48d4cd44f46956eae603f7a8e7e31b4f3456ea1c Mon Sep 17 00:00:00 2001 From: Oliver Zell Date: Sat, 5 Aug 2023 12:15:29 +0200 Subject: [PATCH 3/3] refactor: fix baumgarte typo --- src/Settings.ts | 6 +++--- src/dynamics/Contact.ts | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Settings.ts b/src/Settings.ts index 093ffdc6..ed27ab03 100644 --- a/src/Settings.ts +++ b/src/Settings.ts @@ -137,7 +137,7 @@ export class Settings { * to 1 often lead to overshoot. */ static baumgarte: number = 0.2; - static toiBaugarte: number = 0.75; + static toiBaumgarte: number = 0.75; // Sleep @@ -219,8 +219,8 @@ export class SettingsInternal { static get baumgarte() { return Settings.baumgarte; } - static get toiBaugarte() { - return Settings.toiBaugarte; + static get toiBaumgarte() { + return Settings.toiBaumgarte; } static get timeToSleep() { return Settings.timeToSleep; diff --git a/src/dynamics/Contact.ts b/src/dynamics/Contact.ts index 661c85a7..9f71f334 100644 --- a/src/dynamics/Contact.ts +++ b/src/dynamics/Contact.ts @@ -732,7 +732,7 @@ export class Contact { // Track max constraint error. minSeparation = Math.min(minSeparation, separation); - const baumgarte = toi ? Settings.toiBaugarte : Settings.baumgarte; + const baumgarte = toi ? Settings.toiBaumgarte : Settings.baumgarte; const linearSlop = Settings.linearSlop; const maxLinearCorrection = Settings.maxLinearCorrection;