UNPKG

blaze-2d

Version:

A fast and simple WebGL 2 2D game engine written in TypeScript

74 lines 3.25 kB
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