Skip to content

Commit

Permalink
Improve collision handlers: add separated before and after collision …
Browse files Browse the repository at this point in the history
…handlers
  • Loading branch information
DrA1ex committed Oct 6, 2023
1 parent f0fecf4 commit 4fde7c6
Show file tree
Hide file tree
Showing 6 changed files with 41 additions and 12 deletions.
11 changes: 6 additions & 5 deletions examples/common/bootstrap.js
Original file line number Diff line number Diff line change
Expand Up @@ -398,11 +398,6 @@ export class Bootstrap extends EventEmitter {
const t = performance.now();
if (this.state !== State.pause) {
this.#physicsStep(this.#stats.elapsed / 1000);

for (const collision of this.#solver.stepInfo.collisions) {
collision.aBody.collider.onCollide(collision, collision.bBody);
collision.bBody.collider.onCollide(collision, collision.aBody);
}
}

if (this.state === State.step) {
Expand All @@ -416,6 +411,12 @@ export class Bootstrap extends EventEmitter {
this.#stats.collisionCount = this.#solver.stepInfo.collisionCount;
this.#stats.checkCount = this.#solver.stepInfo.checkCount;

for (const body of this.rigidBodies) {
if (body.destroyed) {
this.#destroyBodyImpl(body);
}
}

requestAnimationFrame(timestamp => {
this.#stats.elapsed = timestamp - this.#stats.lastStepTime;
this.#stats.lastStepTime = timestamp;
Expand Down
2 changes: 1 addition & 1 deletion examples/particles/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ class SmokeCollider extends CircleCollider {
return !(body2.collider instanceof SmokeCollider);
}

onCollide(collision, body2) {
afterCollision(collision, body2) {
if (body2.tag === Tags.world) {
this.particle.setState(SmokeState.destroy);
}
Expand Down
6 changes: 3 additions & 3 deletions examples/snow/objects/misc.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ export class SnowdriftCollider extends PolygonCollider {
this.#onCollideHandler = onCollideFn;
}

onCollide(collision, body2) {
afterCollision(collision, body2) {
this.#onCollideHandler(collision, this.body, body2);
}
}
Expand All @@ -49,7 +49,7 @@ export class WorldBorderCollider extends Collider {
this.#engine = engine;
}

onCollide(collision, body2) {
afterCollision(collision, body2) {
if (body2.tag === Tags.snowflake) {
this.#engine.destroyBody(body2);
}
Expand Down Expand Up @@ -116,7 +116,7 @@ export class SmokeCollider extends CircleCollider {
return SmokeCollider.#NoCollideTags.indexOf(body2.tag) === -1;
}

onCollide(collision, body2) {
afterCollision(collision, body2) {
if (body2.tag === Tags.worldBorder && !this.#particle.destroyed) {
this.#particle.setState(SmokeState.destroy);
}
Expand Down
12 changes: 10 additions & 2 deletions lib/physics/body/base.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export class Body {
collider;
_active = true;
_static = false;
_destroyed = false;

_id = 0;
_mass = 0;
Expand Down Expand Up @@ -134,6 +135,7 @@ export class Body {
get tag() {return this._tag;}
get active() {return this._static ? false : this._active;}
get static() {return this._static;}
get destroyed() {return this._destroyed;}

get mass() {return this.active ? this._mass : 1e12;}
set mass(value) {this.setMass(value);}
Expand Down Expand Up @@ -193,6 +195,8 @@ export class Body {
* @param {Vector2} point
*/
applyImpulse(impulse, point) {
if (this.destroyed) return;

this.velocity.add(impulse.scaled(this.invertedMass));
this.angularVelocity += point.delta(this.position).cross(impulse) * this.invertedInertia;
}
Expand All @@ -202,7 +206,7 @@ export class Body {
* @param {Vector2} point
*/
applyPseudoImpulse(impulse, point) {
if (!this.active) return;
if (!this.active || this.destroyed) return;

this.position.add(impulse);
this.angle += point.delta(this.position).cross(impulse) * this.invertedInertia;
Expand All @@ -213,7 +217,7 @@ export class Body {
* @param {number} rotation
*/
applyVelocity(velocity, rotation) {
if (!this.active) return;
if (!this.active || this.destroyed) return;

this.position.add(velocity);
this.angle += rotation;
Expand All @@ -223,4 +227,8 @@ export class Body {
this.angle = this.angle - 2 * Math.PI * scale;
}
}

destroy() {
this._destroyed = true;
}
}
9 changes: 8 additions & 1 deletion lib/physics/collider/base.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,11 +50,18 @@ export class Collider {
return Collider.detectBoundaryCollision(this.body.boundary, body2.boundary);
}


/**
* @param {Collision} collision
* @param {Body} body2
*/
beforeCollision(collision, body2) {}

/**
* @param {Collision} collision
* @param {Body} body2
*/
onCollide(collision, body2) {}
afterCollision(collision, body2) {}

/**
* @param {Body} body2
Expand Down
13 changes: 13 additions & 0 deletions lib/physics/solver.js
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,11 @@ export class ImpulseBasedSolver {
}
}

for (const collision of this.stepInfo.collisions) {
collision.aBody.collider.afterCollision(collision, collision.bBody);
collision.bBody.collider.afterCollision(collision, collision.aBody);
}

if (this.debug) {
for (const info of this.#collisionInfos) {
if (this.debug.showNormalVector) {
Expand Down Expand Up @@ -182,8 +187,16 @@ export class ImpulseBasedSolver {
this.#processTreeLeaf(this.stepInfo.tree.root);

for (const collision of this.stepInfo.collisions) {
collision.aBody.collider.beforeCollision(collision, collision.bBody);
collision.bBody.collider.beforeCollision(collision, collision.aBody);
}

for (const collision of this.stepInfo.collisions) {
if (collision.aBody.destroyed || collision.bBody.destroyed) continue;

this.#collisionInfos.push(this.#prepareCollisionInfo(collision));
}

this.stepInfo.collisionCount = this.stepInfo.collisions.length;
this.stepInfo.collisionTime = performance.now() - t;
}
Expand Down

0 comments on commit 4fde7c6

Please sign in to comment.