blaze-2d
Version:
A fast and simple WebGL 2 2D game engine written in TypeScript
74 lines • 3.25 kB
JavaScript
import { vec2 } from "gl-matrix";
import CollisionObject from "../collisionObject";
import Constraint from "./constraint";
/**
* Represents a pivot joint between two {@link CollisionObject}s or
* a {@link CollisionObject} and a point.
*
* This constraint will keep the object's joined together by their anchor points at the given point.
*/
export default class PivotConstraint extends Constraint {
constructor(a, b, point) {
if (a instanceof CollisionObject && b instanceof CollisionObject) {
// constraint between two bodies
super(a, b);
this.point = point;
}
else if (a instanceof CollisionObject) {
// constraint between body and point
super(a, b);
}
else {
// constraint from options
super(a);
this.point = a.point;
}
this.jAcc = vec2.create();
}
preSolve(dt) {
this.updateAnchors();
const anchorA = this.anchorA;
const anchorB = this.isBodyToPoint() ? this.point : this.anchorB;
const anchorAWorld = vec2.add(vec2.create(), this.a.getPosition(), anchorA);
const anchorBWorld = this.isBodyToPoint() ? anchorB : vec2.add(vec2.create(), this.b.getPosition(), anchorB);
const delta = vec2.sub(vec2.create(), anchorBWorld, anchorAWorld);
this.k = this.kTensor();
// calculate bias velocity
const bias = vec2.scale(vec2.create(), delta, -this.biasCoef(dt) / dt);
vec2.min(bias, bias, vec2.fromValues(this.maxBias, this.maxBias));
vec2.max(bias, bias, vec2.fromValues(-this.maxBias, -this.maxBias));
this.bias = bias;
}
/**
* Computes and applies the impulse to keep the bodies at the joint's length.
*
* @see [Chipmunk2D Pin Joint](https://github.com/slembcke/Chipmunk2D/blob/master/src/cpPinJoint.c)
* @see [MatterJS Constraint](https://github.com/liabru/matter-js/blob/master/src/constraint/Constraint.js)
* @see [Dyn4j Distance Constraint](https://dyn4j.org/2010/09/distance-constraint/)
* @see [Constraints and Solvers](https://research.ncl.ac.uk/game/mastersdegree/gametechnologies/physicstutorials/8constraintsandsolvers/Physics%20-%20Constraints%20and%20Solvers.pdf)
*
* @param dt The time since the last update
*/
solve(dt) {
const anchorA = this.anchorA;
const anchorB = this.isBodyToPoint() ? this.point : this.anchorB;
// compute relative velocity
const relVel = this.calculateRelativeVelocity(anchorA, anchorB);
// compute normal impulse
const j = vec2.transformMat2(vec2.create(), vec2.sub(vec2.create(), this.bias, relVel), this.k);
const jOld = vec2.clone(this.jAcc);
const maxForce = this.maxForce * dt;
vec2.add(this.jAcc, this.jAcc, j);
vec2.min(this.jAcc, this.jAcc, vec2.fromValues(maxForce, maxForce));
vec2.max(this.jAcc, this.jAcc, vec2.fromValues(-maxForce, -maxForce));
vec2.sub(j, this.jAcc, jOld);
this.applyImpulses(j);
}
/**
* Applies the cached impulse.
*/
postSolve() {
// this.applyImpulses(this.jnAcc * 0.0001, this.nDelta);
}
}
//# sourceMappingURL=pivot.js.map