the-world-engine
Version:
three.js based, unity like game engine for browser
351 lines (337 loc) • 15.2 kB
JavaScript
import { b2_linearSlop, b2Maybe } from "../common/b2_settings.js";
import { b2Vec2, b2Rot } from "../common/b2_math.js";
import { b2Joint, b2JointDef, b2JointType } from "./b2_joint.js";
export class b2GearJointDef extends b2JointDef {
constructor() {
super(b2JointType.e_gearJoint);
this.ratio = 1;
}
}
export class b2GearJoint extends b2Joint {
constructor(t) {
super(t);
this.m_typeA = b2JointType.e_unknownJoint;
this.m_typeB = b2JointType.e_unknownJoint;
this.m_localAnchorA = new b2Vec2;
this.m_localAnchorB = new b2Vec2;
this.m_localAnchorC = new b2Vec2;
this.m_localAnchorD = new b2Vec2;
this.m_localAxisC = new b2Vec2;
this.m_localAxisD = new b2Vec2;
this.m_referenceAngleA = 0;
this.m_referenceAngleB = 0;
this.m_constant = 0;
this.m_ratio = 0;
this.m_impulse = 0;
this.m_indexA = 0;
this.m_indexB = 0;
this.m_indexC = 0;
this.m_indexD = 0;
this.m_lcA = new b2Vec2;
this.m_lcB = new b2Vec2;
this.m_lcC = new b2Vec2;
this.m_lcD = new b2Vec2;
this.m_mA = 0;
this.m_mB = 0;
this.m_mC = 0;
this.m_mD = 0;
this.m_iA = 0;
this.m_iB = 0;
this.m_iC = 0;
this.m_iD = 0;
this.m_JvAC = new b2Vec2;
this.m_JvBD = new b2Vec2;
this.m_JwA = 0;
this.m_JwB = 0;
this.m_JwC = 0;
this.m_JwD = 0;
this.m_mass = 0;
this.m_qA = new b2Rot;
this.m_qB = new b2Rot;
this.m_qC = new b2Rot;
this.m_qD = new b2Rot;
this.m_lalcA = new b2Vec2;
this.m_lalcB = new b2Vec2;
this.m_lalcC = new b2Vec2;
this.m_lalcD = new b2Vec2;
this.m_joint1 = t.joint1;
this.m_joint2 = t.joint2;
this.m_typeA = this.m_joint1.GetType();
this.m_typeB = this.m_joint2.GetType();
let s, i;
this.m_bodyC = this.m_joint1.GetBodyA();
this.m_bodyA = this.m_joint1.GetBodyB();
const h = this.m_bodyA.m_xf;
const e = this.m_bodyA.m_sweep.a;
const n = this.m_bodyC.m_xf;
const o = this.m_bodyC.m_sweep.a;
if (this.m_typeA === b2JointType.e_revoluteJoint) {
const i = t.joint1;
this.m_localAnchorC.Copy(i.m_localAnchorA);
this.m_localAnchorA.Copy(i.m_localAnchorB);
this.m_referenceAngleA = i.m_referenceAngle;
this.m_localAxisC.SetZero();
s = e - o - this.m_referenceAngleA;
} else {
const i = t.joint1;
this.m_localAnchorC.Copy(i.m_localAnchorA);
this.m_localAnchorA.Copy(i.m_localAnchorB);
this.m_referenceAngleA = i.m_referenceAngle;
this.m_localAxisC.Copy(i.m_localXAxisA);
const e = this.m_localAnchorC;
const o = b2Rot.MulTRV(n.q, b2Vec2.AddVV(b2Rot.MulRV(h.q, this.m_localAnchorA, b2Vec2.s_t0), b2Vec2.SubVV(h.p, n.p, b2Vec2.s_t1), b2Vec2.s_t0), b2Vec2.s_t0);
s = b2Vec2.DotVV(b2Vec2.SubVV(o, e, b2Vec2.s_t0), this.m_localAxisC);
}
this.m_bodyD = this.m_joint2.GetBodyA();
this.m_bodyB = this.m_joint2.GetBodyB();
const b = this.m_bodyB.m_xf;
const c = this.m_bodyB.m_sweep.a;
const V = this.m_bodyD.m_xf;
const r = this.m_bodyD.m_sweep.a;
if (this.m_typeB === b2JointType.e_revoluteJoint) {
const s = t.joint2;
this.m_localAnchorD.Copy(s.m_localAnchorA);
this.m_localAnchorB.Copy(s.m_localAnchorB);
this.m_referenceAngleB = s.m_referenceAngle;
this.m_localAxisD.SetZero();
i = c - r - this.m_referenceAngleB;
} else {
const s = t.joint2;
this.m_localAnchorD.Copy(s.m_localAnchorA);
this.m_localAnchorB.Copy(s.m_localAnchorB);
this.m_referenceAngleB = s.m_referenceAngle;
this.m_localAxisD.Copy(s.m_localXAxisA);
const h = this.m_localAnchorD;
const e = b2Rot.MulTRV(V.q, b2Vec2.AddVV(b2Rot.MulRV(b.q, this.m_localAnchorB, b2Vec2.s_t0), b2Vec2.SubVV(b.p, V.p, b2Vec2.s_t1), b2Vec2.s_t0), b2Vec2.s_t0);
i = b2Vec2.DotVV(b2Vec2.SubVV(e, h, b2Vec2.s_t0), this.m_localAxisD);
}
this.m_ratio = b2Maybe(t.ratio, 1);
this.m_constant = s + this.m_ratio * i;
this.m_impulse = 0;
}
InitVelocityConstraints(t) {
this.m_indexA = this.m_bodyA.m_islandIndex;
this.m_indexB = this.m_bodyB.m_islandIndex;
this.m_indexC = this.m_bodyC.m_islandIndex;
this.m_indexD = this.m_bodyD.m_islandIndex;
this.m_lcA.Copy(this.m_bodyA.m_sweep.localCenter);
this.m_lcB.Copy(this.m_bodyB.m_sweep.localCenter);
this.m_lcC.Copy(this.m_bodyC.m_sweep.localCenter);
this.m_lcD.Copy(this.m_bodyD.m_sweep.localCenter);
this.m_mA = this.m_bodyA.m_invMass;
this.m_mB = this.m_bodyB.m_invMass;
this.m_mC = this.m_bodyC.m_invMass;
this.m_mD = this.m_bodyD.m_invMass;
this.m_iA = this.m_bodyA.m_invI;
this.m_iB = this.m_bodyB.m_invI;
this.m_iC = this.m_bodyC.m_invI;
this.m_iD = this.m_bodyD.m_invI;
const s = t.positions[this.m_indexA].a;
const i = t.velocities[this.m_indexA].v;
let h = t.velocities[this.m_indexA].w;
const e = t.positions[this.m_indexB].a;
const n = t.velocities[this.m_indexB].v;
let o = t.velocities[this.m_indexB].w;
const b = t.positions[this.m_indexC].a;
const c = t.velocities[this.m_indexC].v;
let V = t.velocities[this.m_indexC].w;
const r = t.positions[this.m_indexD].a;
const a = t.velocities[this.m_indexD].v;
let J = t.velocities[this.m_indexD].w;
const l = this.m_qA.SetAngle(s), G = this.m_qB.SetAngle(e), w = this.m_qC.SetAngle(b), R = this.m_qD.SetAngle(r);
this.m_mass = 0;
if (this.m_typeA === b2JointType.e_revoluteJoint) {
this.m_JvAC.SetZero();
this.m_JwA = 1;
this.m_JwC = 1;
this.m_mass += this.m_iA + this.m_iC;
} else {
const t = b2Rot.MulRV(w, this.m_localAxisC, b2GearJoint.InitVelocityConstraints_s_u);
b2Vec2.SubVV(this.m_localAnchorC, this.m_lcC, this.m_lalcC);
const s = b2Rot.MulRV(w, this.m_lalcC, b2GearJoint.InitVelocityConstraints_s_rC);
b2Vec2.SubVV(this.m_localAnchorA, this.m_lcA, this.m_lalcA);
const i = b2Rot.MulRV(l, this.m_lalcA, b2GearJoint.InitVelocityConstraints_s_rA);
this.m_JvAC.Copy(t);
this.m_JwC = b2Vec2.CrossVV(s, t);
this.m_JwA = b2Vec2.CrossVV(i, t);
this.m_mass += this.m_mC + this.m_mA + this.m_iC * this.m_JwC * this.m_JwC + this.m_iA * this.m_JwA * this.m_JwA;
}
if (this.m_typeB === b2JointType.e_revoluteJoint) {
this.m_JvBD.SetZero();
this.m_JwB = this.m_ratio;
this.m_JwD = this.m_ratio;
this.m_mass += this.m_ratio * this.m_ratio * (this.m_iB + this.m_iD);
} else {
const t = b2Rot.MulRV(R, this.m_localAxisD, b2GearJoint.InitVelocityConstraints_s_u);
b2Vec2.SubVV(this.m_localAnchorD, this.m_lcD, this.m_lalcD);
const s = b2Rot.MulRV(R, this.m_lalcD, b2GearJoint.InitVelocityConstraints_s_rD);
b2Vec2.SubVV(this.m_localAnchorB, this.m_lcB, this.m_lalcB);
const i = b2Rot.MulRV(G, this.m_lalcB, b2GearJoint.InitVelocityConstraints_s_rB);
b2Vec2.MulSV(this.m_ratio, t, this.m_JvBD);
this.m_JwD = this.m_ratio * b2Vec2.CrossVV(s, t);
this.m_JwB = this.m_ratio * b2Vec2.CrossVV(i, t);
this.m_mass += this.m_ratio * this.m_ratio * (this.m_mD + this.m_mB) + this.m_iD * this.m_JwD * this.m_JwD + this.m_iB * this.m_JwB * this.m_JwB;
}
this.m_mass = this.m_mass > 0 ? 1 / this.m_mass : 0;
if (t.step.warmStarting) {
i.SelfMulAdd(this.m_mA * this.m_impulse, this.m_JvAC);
h += this.m_iA * this.m_impulse * this.m_JwA;
n.SelfMulAdd(this.m_mB * this.m_impulse, this.m_JvBD);
o += this.m_iB * this.m_impulse * this.m_JwB;
c.SelfMulSub(this.m_mC * this.m_impulse, this.m_JvAC);
V -= this.m_iC * this.m_impulse * this.m_JwC;
a.SelfMulSub(this.m_mD * this.m_impulse, this.m_JvBD);
J -= this.m_iD * this.m_impulse * this.m_JwD;
} else {
this.m_impulse = 0;
}
t.velocities[this.m_indexA].w = h;
t.velocities[this.m_indexB].w = o;
t.velocities[this.m_indexC].w = V;
t.velocities[this.m_indexD].w = J;
}
SolveVelocityConstraints(t) {
const s = t.velocities[this.m_indexA].v;
let i = t.velocities[this.m_indexA].w;
const h = t.velocities[this.m_indexB].v;
let e = t.velocities[this.m_indexB].w;
const n = t.velocities[this.m_indexC].v;
let o = t.velocities[this.m_indexC].w;
const b = t.velocities[this.m_indexD].v;
let c = t.velocities[this.m_indexD].w;
let V = b2Vec2.DotVV(this.m_JvAC, b2Vec2.SubVV(s, n, b2Vec2.s_t0)) + b2Vec2.DotVV(this.m_JvBD, b2Vec2.SubVV(h, b, b2Vec2.s_t0));
V += this.m_JwA * i - this.m_JwC * o + (this.m_JwB * e - this.m_JwD * c);
const r = -this.m_mass * V;
this.m_impulse += r;
s.SelfMulAdd(this.m_mA * r, this.m_JvAC);
i += this.m_iA * r * this.m_JwA;
h.SelfMulAdd(this.m_mB * r, this.m_JvBD);
e += this.m_iB * r * this.m_JwB;
n.SelfMulSub(this.m_mC * r, this.m_JvAC);
o -= this.m_iC * r * this.m_JwC;
b.SelfMulSub(this.m_mD * r, this.m_JvBD);
c -= this.m_iD * r * this.m_JwD;
t.velocities[this.m_indexA].w = i;
t.velocities[this.m_indexB].w = e;
t.velocities[this.m_indexC].w = o;
t.velocities[this.m_indexD].w = c;
}
SolvePositionConstraints(t) {
const s = t.positions[this.m_indexA].c;
let i = t.positions[this.m_indexA].a;
const h = t.positions[this.m_indexB].c;
let e = t.positions[this.m_indexB].a;
const n = t.positions[this.m_indexC].c;
let o = t.positions[this.m_indexC].a;
const b = t.positions[this.m_indexD].c;
let c = t.positions[this.m_indexD].a;
const V = this.m_qA.SetAngle(i), r = this.m_qB.SetAngle(e), a = this.m_qC.SetAngle(o), J = this.m_qD.SetAngle(c);
const l = 0;
let G, w;
const R = this.m_JvAC, d = this.m_JvBD;
let p, f, j, y;
let u = 0;
if (this.m_typeA === b2JointType.e_revoluteJoint) {
R.SetZero();
p = 1;
j = 1;
u += this.m_iA + this.m_iC;
G = i - o - this.m_referenceAngleA;
} else {
const t = b2Rot.MulRV(a, this.m_localAxisC, b2GearJoint.SolvePositionConstraints_s_u);
const i = b2Rot.MulRV(a, this.m_lalcC, b2GearJoint.SolvePositionConstraints_s_rC);
const h = b2Rot.MulRV(V, this.m_lalcA, b2GearJoint.SolvePositionConstraints_s_rA);
R.Copy(t);
j = b2Vec2.CrossVV(i, t);
p = b2Vec2.CrossVV(h, t);
u += this.m_mC + this.m_mA + this.m_iC * j * j + this.m_iA * p * p;
const e = this.m_lalcC;
const o = b2Rot.MulTRV(a, b2Vec2.AddVV(h, b2Vec2.SubVV(s, n, b2Vec2.s_t0), b2Vec2.s_t0), b2Vec2.s_t0);
G = b2Vec2.DotVV(b2Vec2.SubVV(o, e, b2Vec2.s_t0), this.m_localAxisC);
}
if (this.m_typeB === b2JointType.e_revoluteJoint) {
d.SetZero();
f = this.m_ratio;
y = this.m_ratio;
u += this.m_ratio * this.m_ratio * (this.m_iB + this.m_iD);
w = e - c - this.m_referenceAngleB;
} else {
const t = b2Rot.MulRV(J, this.m_localAxisD, b2GearJoint.SolvePositionConstraints_s_u);
const s = b2Rot.MulRV(J, this.m_lalcD, b2GearJoint.SolvePositionConstraints_s_rD);
const i = b2Rot.MulRV(r, this.m_lalcB, b2GearJoint.SolvePositionConstraints_s_rB);
b2Vec2.MulSV(this.m_ratio, t, d);
y = this.m_ratio * b2Vec2.CrossVV(s, t);
f = this.m_ratio * b2Vec2.CrossVV(i, t);
u += this.m_ratio * this.m_ratio * (this.m_mD + this.m_mB) + this.m_iD * y * y + this.m_iB * f * f;
const e = this.m_lalcD;
const n = b2Rot.MulTRV(J, b2Vec2.AddVV(i, b2Vec2.SubVV(h, b, b2Vec2.s_t0), b2Vec2.s_t0), b2Vec2.s_t0);
w = b2Vec2.DotVV(b2Vec2.SubVV(n, e, b2Vec2.s_t0), this.m_localAxisD);
}
const m = G + this.m_ratio * w - this.m_constant;
let T = 0;
if (u > 0) {
T = -m / u;
}
s.SelfMulAdd(this.m_mA * T, R);
i += this.m_iA * T * p;
h.SelfMulAdd(this.m_mB * T, d);
e += this.m_iB * T * f;
n.SelfMulSub(this.m_mC * T, R);
o -= this.m_iC * T * j;
b.SelfMulSub(this.m_mD * T, d);
c -= this.m_iD * T * y;
t.positions[this.m_indexA].a = i;
t.positions[this.m_indexB].a = e;
t.positions[this.m_indexC].a = o;
t.positions[this.m_indexD].a = c;
return l < b2_linearSlop;
}
GetAnchorA(t) {
return this.m_bodyA.GetWorldPoint(this.m_localAnchorA, t);
}
GetAnchorB(t) {
return this.m_bodyB.GetWorldPoint(this.m_localAnchorB, t);
}
GetReactionForce(t, s) {
return b2Vec2.MulSV(t * this.m_impulse, this.m_JvAC, s);
}
GetReactionTorque(t) {
return t * this.m_impulse * this.m_JwA;
}
GetJoint1() {
return this.m_joint1;
}
GetJoint2() {
return this.m_joint2;
}
GetRatio() {
return this.m_ratio;
}
SetRatio(t) {
this.m_ratio = t;
}
Dump(t) {
const s = this.m_bodyA.m_islandIndex;
const i = this.m_bodyB.m_islandIndex;
const h = this.m_joint1.m_index;
const e = this.m_joint2.m_index;
t(" const jd: b2GearJointDef = new b2GearJointDef();\n");
t(" jd.bodyA = bodies[%d];\n", s);
t(" jd.bodyB = bodies[%d];\n", i);
t(" jd.collideConnected = %s;\n", this.m_collideConnected ? "true" : "false");
t(" jd.joint1 = joints[%d];\n", h);
t(" jd.joint2 = joints[%d];\n", e);
t(" jd.ratio = %.15f;\n", this.m_ratio);
t(" joints[%d] = this.m_world.CreateJoint(jd);\n", this.m_index);
}
}
b2GearJoint.InitVelocityConstraints_s_u = new b2Vec2;
b2GearJoint.InitVelocityConstraints_s_rA = new b2Vec2;
b2GearJoint.InitVelocityConstraints_s_rB = new b2Vec2;
b2GearJoint.InitVelocityConstraints_s_rC = new b2Vec2;
b2GearJoint.InitVelocityConstraints_s_rD = new b2Vec2;
b2GearJoint.SolvePositionConstraints_s_u = new b2Vec2;
b2GearJoint.SolvePositionConstraints_s_rA = new b2Vec2;
b2GearJoint.SolvePositionConstraints_s_rB = new b2Vec2;
b2GearJoint.SolvePositionConstraints_s_rC = new b2Vec2;
b2GearJoint.SolvePositionConstraints_s_rD = new b2Vec2;