UNPKG

the-world-engine

Version:

three.js based, unity like game engine for browser

162 lines (155 loc) 5.61 kB
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;