the-world-engine
Version:
three.js based, unity like game engine for browser
162 lines (155 loc) • 5.61 kB
JavaScript
import { b2_pi, b2Maybe } from "../common/b2_settings.js";
import { b2Vec2, b2Mat22, b2Rot, b2Transform } from "../common/b2_math.js";
import { b2Joint, b2JointDef, b2JointType } from "./b2_joint.js";
export class b2MouseJointDef extends b2JointDef {
constructor() {
super(b2JointType.e_mouseJoint);
this.target = new b2Vec2;
this.maxForce = 0;
this.stiffness = 5;
this.damping = .7;
}
}
export class b2MouseJoint extends b2Joint {
constructor(t) {
super(t);
this.m_localAnchorB = new b2Vec2;
this.m_targetA = new b2Vec2;
this.m_stiffness = 0;
this.m_damping = 0;
this.m_beta = 0;
this.m_impulse = new b2Vec2;
this.m_maxForce = 0;
this.m_gamma = 0;
this.m_indexA = 0;
this.m_indexB = 0;
this.m_rB = new b2Vec2;
this.m_localCenterB = new b2Vec2;
this.m_invMassB = 0;
this.m_invIB = 0;
this.m_mass = new b2Mat22;
this.m_C = new b2Vec2;
this.m_qB = new b2Rot;
this.m_lalcB = new b2Vec2;
this.m_K = new b2Mat22;
this.m_targetA.Copy(b2Maybe(t.target, b2Vec2.ZERO));
b2Transform.MulTXV(this.m_bodyB.GetTransform(), this.m_targetA, this.m_localAnchorB);
this.m_maxForce = b2Maybe(t.maxForce, 0);
this.m_impulse.SetZero();
this.m_stiffness = b2Maybe(t.stiffness, 0);
this.m_damping = b2Maybe(t.damping, 0);
this.m_beta = 0;
this.m_gamma = 0;
}
SetTarget(t) {
if (!this.m_bodyB.IsAwake()) {
this.m_bodyB.SetAwake(true);
}
this.m_targetA.Copy(t);
}
GetTarget() {
return this.m_targetA;
}
SetMaxForce(t) {
this.m_maxForce = t;
}
GetMaxForce() {
return this.m_maxForce;
}
SetStiffness(t) {
this.m_stiffness = t;
}
GetStiffness() {
return this.m_stiffness;
}
SetDamping(t) {
this.m_damping = t;
}
GetDamping() {
return this.m_damping;
}
InitVelocityConstraints(t) {
this.m_indexB = this.m_bodyB.m_islandIndex;
this.m_localCenterB.Copy(this.m_bodyB.m_sweep.localCenter);
this.m_invMassB = this.m_bodyB.m_invMass;
this.m_invIB = this.m_bodyB.m_invI;
const s = t.positions[this.m_indexB].c;
const i = t.positions[this.m_indexB].a;
const h = t.velocities[this.m_indexB].v;
let e = t.velocities[this.m_indexB].w;
const n = this.m_qB.SetAngle(i);
const o = this.m_bodyB.GetMass();
const b = 2 * b2_pi * this.m_stiffness;
const c = 2 * o * this.m_damping * b;
const r = o * (b * b);
const u = t.step.dt;
this.m_gamma = u * (c + u * r);
if (this.m_gamma !== 0) {
this.m_gamma = 1 / this.m_gamma;
}
this.m_beta = u * r * this.m_gamma;
b2Vec2.SubVV(this.m_localAnchorB, this.m_localCenterB, this.m_lalcB);
b2Rot.MulRV(n, this.m_lalcB, this.m_rB);
const V = this.m_K;
V.ex.x = this.m_invMassB + this.m_invIB * this.m_rB.y * this.m_rB.y + this.m_gamma;
V.ex.y = -this.m_invIB * this.m_rB.x * this.m_rB.y;
V.ey.x = V.ex.y;
V.ey.y = this.m_invMassB + this.m_invIB * this.m_rB.x * this.m_rB.x + this.m_gamma;
V.GetInverse(this.m_mass);
this.m_C.x = s.x + this.m_rB.x - this.m_targetA.x;
this.m_C.y = s.y + this.m_rB.y - this.m_targetA.y;
this.m_C.SelfMul(this.m_beta);
e *= .98;
if (t.step.warmStarting) {
this.m_impulse.SelfMul(t.step.dtRatio);
h.x += this.m_invMassB * this.m_impulse.x;
h.y += this.m_invMassB * this.m_impulse.y;
e += this.m_invIB * b2Vec2.CrossVV(this.m_rB, this.m_impulse);
} else {
this.m_impulse.SetZero();
}
t.velocities[this.m_indexB].w = e;
}
SolveVelocityConstraints(t) {
const s = t.velocities[this.m_indexB].v;
let i = t.velocities[this.m_indexB].w;
const h = b2Vec2.AddVCrossSV(s, i, this.m_rB, b2MouseJoint.SolveVelocityConstraints_s_Cdot);
const e = b2Mat22.MulMV(this.m_mass, b2Vec2.AddVV(h, b2Vec2.AddVV(this.m_C, b2Vec2.MulSV(this.m_gamma, this.m_impulse, b2Vec2.s_t0), b2Vec2.s_t0), b2Vec2.s_t0).SelfNeg(), b2MouseJoint.SolveVelocityConstraints_s_impulse);
const n = b2MouseJoint.SolveVelocityConstraints_s_oldImpulse.Copy(this.m_impulse);
this.m_impulse.SelfAdd(e);
const o = t.step.dt * this.m_maxForce;
if (this.m_impulse.LengthSquared() > o * o) {
this.m_impulse.SelfMul(o / this.m_impulse.Length());
}
b2Vec2.SubVV(this.m_impulse, n, e);
s.SelfMulAdd(this.m_invMassB, e);
i += this.m_invIB * b2Vec2.CrossVV(this.m_rB, e);
t.velocities[this.m_indexB].w = i;
}
SolvePositionConstraints(t) {
return true;
}
GetAnchorA(t) {
t.x = this.m_targetA.x;
t.y = this.m_targetA.y;
return t;
}
GetAnchorB(t) {
return this.m_bodyB.GetWorldPoint(this.m_localAnchorB, t);
}
GetReactionForce(t, s) {
return b2Vec2.MulSV(t, this.m_impulse, s);
}
GetReactionTorque(t) {
return 0;
}
Dump(t) {
t("Mouse joint dumping is not supported.\n");
}
ShiftOrigin(t) {
this.m_targetA.SelfSub(t);
}
}
b2MouseJoint.SolveVelocityConstraints_s_Cdot = new b2Vec2;
b2MouseJoint.SolveVelocityConstraints_s_impulse = new b2Vec2;
b2MouseJoint.SolveVelocityConstraints_s_oldImpulse = new b2Vec2;