blaze-2d
Version:
A fast and simple WebGL 2 2D game engine written in TypeScript
81 lines • 3.23 kB
JavaScript
import { vec2 } from "gl-matrix";
import CollisionObject from "../collisionObject";
import Constraint from "./constraint";
/**
* Represents a damped spring joint between two {@link CollisionObject}s or
* a {@link CollisionObject} and a point.
*/
export default class SpringConstraint extends Constraint {
constructor(a, b, length, stiffness, damping = 0) {
if (a instanceof CollisionObject && b instanceof CollisionObject) {
// constraint between two bodies
super(a, b);
this.length = length;
this.stiffness = stiffness;
this.damping = damping;
}
else if (a instanceof CollisionObject) {
// constraint between body and point
super(a, b);
this.length = length;
this.stiffness = stiffness;
this.damping = damping;
}
else {
// constraint from options
super(a);
this.length = a.length;
this.stiffness = a.stiffness;
this.damping = a.damping;
}
}
/**
* Updates the constraints anchors and prepares for solving.
*
* @param dt The time since the last update
*/
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);
const length = vec2.len(delta);
this.nDelta = vec2.normalize(vec2.create(), delta);
const k = this.kScalar(this.nDelta);
this.nMass = 1 / k;
this.targetVrn = 0;
this.vCoef = 1 - Math.exp(-this.damping * dt * k);
// apply spring force
const fSpring = this.calcForce(length);
const jSpring = (this.jAcc = fSpring * dt);
this.applyImpulses(jSpring, this.nDelta);
}
/**
* Applies the spring forces to the attached bodies.
*
* @see [Chipmunk2D Damped Spring](https://github.com/slembcke/Chipmunk2D/blob/master/src/cpDampedSpring.c)
* @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);
const vrn = vec2.dot(relVel, this.nDelta);
// compute velocity loss from drag
const vDamp = (this.targetVrn - vrn) * this.vCoef;
this.targetVrn = vrn + vDamp;
const jDamp = vDamp * this.nMass;
this.jAcc += jDamp;
this.applyImpulses(jDamp, this.nDelta);
}
postSolve() { }
calcForce(length) {
return (this.length - length) * this.stiffness;
}
}
//# sourceMappingURL=spring.js.map