the-world-engine
Version:
three.js based, unity like game engine for browser
1,126 lines (1,080 loc) • 25.4 kB
JavaScript
import { b2_pi, b2_epsilon, b2MakeArray } from "./b2_settings.js";
export const b2_pi_over_180 = b2_pi / 180;
export const b2_180_over_pi = 180 / b2_pi;
export const b2_two_pi = 2 * b2_pi;
export const b2Abs = Math.abs;
export function b2Min(t, s) {
return t < s ? t : s;
}
export function b2Max(t, s) {
return t > s ? t : s;
}
export function b2Clamp(t, s, i) {
return t < s ? s : t > i ? i : t;
}
export function b2Swap(t, s) {
const i = t[0];
t[0] = s[0];
s[0] = i;
}
export const b2IsValid = isFinite;
export function b2Sq(t) {
return t * t;
}
export function b2InvSqrt(t) {
return 1 / Math.sqrt(t);
}
export const b2Sqrt = Math.sqrt;
export const b2Pow = Math.pow;
export function b2DegToRad(t) {
return t * b2_pi_over_180;
}
export function b2RadToDeg(t) {
return t * b2_180_over_pi;
}
export const b2Cos = Math.cos;
export const b2Sin = Math.sin;
export const b2Acos = Math.acos;
export const b2Asin = Math.asin;
export const b2Atan2 = Math.atan2;
export function b2NextPowerOfTwo(t) {
t |= t >> 1 & 2147483647;
t |= t >> 2 & 1073741823;
t |= t >> 4 & 268435455;
t |= t >> 8 & 16777215;
t |= t >> 16 & 65535;
return t + 1;
}
export function b2IsPowerOfTwo(t) {
return t > 0 && (t & t - 1) === 0;
}
export function b2Random() {
return Math.random() * 2 - 1;
}
export function b2RandomRange(t, s) {
return (s - t) * Math.random() + t;
}
export class b2Vec2 {
constructor(t = 0, s = 0) {
this.x = t;
this.y = s;
}
Clone() {
return new b2Vec2(this.x, this.y);
}
SetZero() {
this.x = 0;
this.y = 0;
return this;
}
Set(t, s) {
this.x = t;
this.y = s;
return this;
}
Copy(t) {
this.x = t.x;
this.y = t.y;
return this;
}
SelfAdd(t) {
this.x += t.x;
this.y += t.y;
return this;
}
SelfAddXY(t, s) {
this.x += t;
this.y += s;
return this;
}
SelfSub(t) {
this.x -= t.x;
this.y -= t.y;
return this;
}
SelfSubXY(t, s) {
this.x -= t;
this.y -= s;
return this;
}
SelfMul(t) {
this.x *= t;
this.y *= t;
return this;
}
SelfMulAdd(t, s) {
this.x += t * s.x;
this.y += t * s.y;
return this;
}
SelfMulSub(t, s) {
this.x -= t * s.x;
this.y -= t * s.y;
return this;
}
Dot(t) {
return this.x * t.x + this.y * t.y;
}
Cross(t) {
return this.x * t.y - this.y * t.x;
}
Length() {
const t = this.x, s = this.y;
return Math.sqrt(t * t + s * s);
}
LengthSquared() {
const t = this.x, s = this.y;
return t * t + s * s;
}
Normalize() {
const t = this.Length();
if (t >= b2_epsilon) {
const s = 1 / t;
this.x *= s;
this.y *= s;
}
return t;
}
SelfNormalize() {
const t = this.Length();
if (t >= b2_epsilon) {
const s = 1 / t;
this.x *= s;
this.y *= s;
}
return this;
}
SelfRotate(t) {
const s = Math.cos(t);
const i = Math.sin(t);
const e = this.x;
this.x = s * e - i * this.y;
this.y = i * e + s * this.y;
return this;
}
SelfRotateCosSin(t, s) {
const i = this.x;
this.x = t * i - s * this.y;
this.y = s * i + t * this.y;
return this;
}
IsValid() {
return isFinite(this.x) && isFinite(this.y);
}
SelfCrossVS(t) {
const s = this.x;
this.x = t * this.y;
this.y = -t * s;
return this;
}
SelfCrossSV(t) {
const s = this.x;
this.x = -t * this.y;
this.y = t * s;
return this;
}
SelfMinV(t) {
this.x = b2Min(this.x, t.x);
this.y = b2Min(this.y, t.y);
return this;
}
SelfMaxV(t) {
this.x = b2Max(this.x, t.x);
this.y = b2Max(this.y, t.y);
return this;
}
SelfAbs() {
this.x = b2Abs(this.x);
this.y = b2Abs(this.y);
return this;
}
SelfNeg() {
this.x = -this.x;
this.y = -this.y;
return this;
}
SelfSkew() {
const t = this.x;
this.x = -this.y;
this.y = t;
return this;
}
static MakeArray(t) {
return b2MakeArray(t, (t => new b2Vec2));
}
static AbsV(t, s) {
s.x = b2Abs(t.x);
s.y = b2Abs(t.y);
return s;
}
static MinV(t, s, i) {
i.x = b2Min(t.x, s.x);
i.y = b2Min(t.y, s.y);
return i;
}
static MaxV(t, s, i) {
i.x = b2Max(t.x, s.x);
i.y = b2Max(t.y, s.y);
return i;
}
static ClampV(t, s, i, e) {
e.x = b2Clamp(t.x, s.x, i.x);
e.y = b2Clamp(t.y, s.y, i.y);
return e;
}
static RotateV(t, s, i) {
const e = t.x, r = t.y;
const h = Math.cos(s);
const n = Math.sin(s);
i.x = h * e - n * r;
i.y = n * e + h * r;
return i;
}
static DotVV(t, s) {
return t.x * s.x + t.y * s.y;
}
static CrossVV(t, s) {
return t.x * s.y - t.y * s.x;
}
static CrossVS(t, s, i) {
const e = t.x;
i.x = s * t.y;
i.y = -s * e;
return i;
}
static CrossVOne(t, s) {
const i = t.x;
s.x = t.y;
s.y = -i;
return s;
}
static CrossSV(t, s, i) {
const e = s.x;
i.x = -t * s.y;
i.y = t * e;
return i;
}
static CrossOneV(t, s) {
const i = t.x;
s.x = -t.y;
s.y = i;
return s;
}
static AddVV(t, s, i) {
i.x = t.x + s.x;
i.y = t.y + s.y;
return i;
}
static SubVV(t, s, i) {
i.x = t.x - s.x;
i.y = t.y - s.y;
return i;
}
static MulSV(t, s, i) {
i.x = s.x * t;
i.y = s.y * t;
return i;
}
static MulVS(t, s, i) {
i.x = t.x * s;
i.y = t.y * s;
return i;
}
static AddVMulSV(t, s, i, e) {
e.x = t.x + s * i.x;
e.y = t.y + s * i.y;
return e;
}
static SubVMulSV(t, s, i, e) {
e.x = t.x - s * i.x;
e.y = t.y - s * i.y;
return e;
}
static AddVCrossSV(t, s, i, e) {
const r = i.x;
e.x = t.x - s * i.y;
e.y = t.y + s * r;
return e;
}
static MidVV(t, s, i) {
i.x = (t.x + s.x) * .5;
i.y = (t.y + s.y) * .5;
return i;
}
static ExtVV(t, s, i) {
i.x = (s.x - t.x) * .5;
i.y = (s.y - t.y) * .5;
return i;
}
static IsEqualToV(t, s) {
return t.x === s.x && t.y === s.y;
}
static DistanceVV(t, s) {
const i = t.x - s.x;
const e = t.y - s.y;
return Math.sqrt(i * i + e * e);
}
static DistanceSquaredVV(t, s) {
const i = t.x - s.x;
const e = t.y - s.y;
return i * i + e * e;
}
static NegV(t, s) {
s.x = -t.x;
s.y = -t.y;
return s;
}
}
b2Vec2.ZERO = new b2Vec2(0, 0);
b2Vec2.UNITX = new b2Vec2(1, 0);
b2Vec2.UNITY = new b2Vec2(0, 1);
b2Vec2.s_t0 = new b2Vec2;
b2Vec2.s_t1 = new b2Vec2;
b2Vec2.s_t2 = new b2Vec2;
b2Vec2.s_t3 = new b2Vec2;
export const b2Vec2_zero = new b2Vec2(0, 0);
export class b2TypedVec2 {
constructor(...t) {
if (t[0] instanceof Float32Array) {
if (t[0].length !== 2) {
throw new Error;
}
this.data = t[0];
} else {
const s = typeof t[0] === "number" ? t[0] : 0;
const i = typeof t[1] === "number" ? t[1] : 0;
this.data = new Float32Array([ s, i ]);
}
}
get x() {
return this.data[0];
}
set x(t) {
this.data[0] = t;
}
get y() {
return this.data[1];
}
set y(t) {
this.data[1] = t;
}
Clone() {
return new b2TypedVec2(new Float32Array(this.data));
}
SetZero() {
this.x = 0;
this.y = 0;
return this;
}
Set(t, s) {
this.x = t;
this.y = s;
return this;
}
Copy(t) {
if (t instanceof b2TypedVec2) {
this.data.set(t.data);
} else {
this.x = t.x;
this.y = t.y;
}
return this;
}
SelfAdd(t) {
this.x += t.x;
this.y += t.y;
return this;
}
SelfAddXY(t, s) {
this.x += t;
this.y += s;
return this;
}
SelfSub(t) {
this.x -= t.x;
this.y -= t.y;
return this;
}
SelfSubXY(t, s) {
this.x -= t;
this.y -= s;
return this;
}
SelfMul(t) {
this.x *= t;
this.y *= t;
return this;
}
SelfMulAdd(t, s) {
this.x += t * s.x;
this.y += t * s.y;
return this;
}
SelfMulSub(t, s) {
this.x -= t * s.x;
this.y -= t * s.y;
return this;
}
Dot(t) {
return this.x * t.x + this.y * t.y;
}
Cross(t) {
return this.x * t.y - this.y * t.x;
}
Length() {
const t = this.x, s = this.y;
return Math.sqrt(t * t + s * s);
}
LengthSquared() {
const t = this.x, s = this.y;
return t * t + s * s;
}
Normalize() {
const t = this.Length();
if (t >= b2_epsilon) {
const s = 1 / t;
this.x *= s;
this.y *= s;
}
return t;
}
SelfNormalize() {
const t = this.Length();
if (t >= b2_epsilon) {
const s = 1 / t;
this.x *= s;
this.y *= s;
}
return this;
}
SelfRotate(t) {
const s = Math.cos(t);
const i = Math.sin(t);
const e = this.x;
this.x = s * e - i * this.y;
this.y = i * e + s * this.y;
return this;
}
SelfRotateCosSin(t, s) {
const i = this.x;
this.x = t * i - s * this.y;
this.y = s * i + t * this.y;
return this;
}
IsValid() {
return isFinite(this.x) && isFinite(this.y);
}
SelfCrossVS(t) {
const s = this.x;
this.x = t * this.y;
this.y = -t * s;
return this;
}
SelfCrossSV(t) {
const s = this.x;
this.x = -t * this.y;
this.y = t * s;
return this;
}
SelfMinV(t) {
this.x = b2Min(this.x, t.x);
this.y = b2Min(this.y, t.y);
return this;
}
SelfMaxV(t) {
this.x = b2Max(this.x, t.x);
this.y = b2Max(this.y, t.y);
return this;
}
SelfAbs() {
this.x = b2Abs(this.x);
this.y = b2Abs(this.y);
return this;
}
SelfNeg() {
this.x = -this.x;
this.y = -this.y;
return this;
}
SelfSkew() {
const t = this.x;
this.x = -this.y;
this.y = t;
return this;
}
}
export class b2Vec3 {
constructor(...t) {
if (t[0] instanceof Float32Array) {
if (t[0].length !== 3) {
throw new Error;
}
this.data = t[0];
} else {
const s = typeof t[0] === "number" ? t[0] : 0;
const i = typeof t[1] === "number" ? t[1] : 0;
const e = typeof t[2] === "number" ? t[2] : 0;
this.data = new Float32Array([ s, i, e ]);
}
}
get x() {
return this.data[0];
}
set x(t) {
this.data[0] = t;
}
get y() {
return this.data[1];
}
set y(t) {
this.data[1] = t;
}
get z() {
return this.data[2];
}
set z(t) {
this.data[2] = t;
}
Clone() {
return new b2Vec3(this.x, this.y, this.z);
}
SetZero() {
this.x = 0;
this.y = 0;
this.z = 0;
return this;
}
SetXYZ(t, s, i) {
this.x = t;
this.y = s;
this.z = i;
return this;
}
Copy(t) {
this.x = t.x;
this.y = t.y;
this.z = t.z;
return this;
}
SelfNeg() {
this.x = -this.x;
this.y = -this.y;
this.z = -this.z;
return this;
}
SelfAdd(t) {
this.x += t.x;
this.y += t.y;
this.z += t.z;
return this;
}
SelfAddXYZ(t, s, i) {
this.x += t;
this.y += s;
this.z += i;
return this;
}
SelfSub(t) {
this.x -= t.x;
this.y -= t.y;
this.z -= t.z;
return this;
}
SelfSubXYZ(t, s, i) {
this.x -= t;
this.y -= s;
this.z -= i;
return this;
}
SelfMul(t) {
this.x *= t;
this.y *= t;
this.z *= t;
return this;
}
static DotV3V3(t, s) {
return t.x * s.x + t.y * s.y + t.z * s.z;
}
static CrossV3V3(t, s, i) {
const e = t.x, r = t.y, h = t.z;
const n = s.x, o = s.y, c = s.z;
i.x = r * c - h * o;
i.y = h * n - e * c;
i.z = e * o - r * n;
return i;
}
}
b2Vec3.ZERO = new b2Vec3(0, 0, 0);
b2Vec3.s_t0 = new b2Vec3;
export class b2Mat22 {
constructor() {
this.ex = new b2Vec2(1, 0);
this.ey = new b2Vec2(0, 1);
}
Clone() {
return (new b2Mat22).Copy(this);
}
static FromVV(t, s) {
return (new b2Mat22).SetVV(t, s);
}
static FromSSSS(t, s, i, e) {
return (new b2Mat22).SetSSSS(t, s, i, e);
}
static FromAngle(t) {
return (new b2Mat22).SetAngle(t);
}
SetSSSS(t, s, i, e) {
this.ex.Set(t, i);
this.ey.Set(s, e);
return this;
}
SetVV(t, s) {
this.ex.Copy(t);
this.ey.Copy(s);
return this;
}
SetAngle(t) {
const s = Math.cos(t);
const i = Math.sin(t);
this.ex.Set(s, i);
this.ey.Set(-i, s);
return this;
}
Copy(t) {
this.ex.Copy(t.ex);
this.ey.Copy(t.ey);
return this;
}
SetIdentity() {
this.ex.Set(1, 0);
this.ey.Set(0, 1);
return this;
}
SetZero() {
this.ex.SetZero();
this.ey.SetZero();
return this;
}
GetAngle() {
return Math.atan2(this.ex.y, this.ex.x);
}
GetInverse(t) {
const s = this.ex.x;
const i = this.ey.x;
const e = this.ex.y;
const r = this.ey.y;
let h = s * r - i * e;
if (h !== 0) {
h = 1 / h;
}
t.ex.x = h * r;
t.ey.x = -h * i;
t.ex.y = -h * e;
t.ey.y = h * s;
return t;
}
Solve(t, s, i) {
const e = this.ex.x, r = this.ey.x;
const h = this.ex.y, n = this.ey.y;
let o = e * n - r * h;
if (o !== 0) {
o = 1 / o;
}
i.x = o * (n * t - r * s);
i.y = o * (e * s - h * t);
return i;
}
SelfAbs() {
this.ex.SelfAbs();
this.ey.SelfAbs();
return this;
}
SelfInv() {
this.GetInverse(this);
return this;
}
SelfAddM(t) {
this.ex.SelfAdd(t.ex);
this.ey.SelfAdd(t.ey);
return this;
}
SelfSubM(t) {
this.ex.SelfSub(t.ex);
this.ey.SelfSub(t.ey);
return this;
}
static AbsM(t, s) {
const i = t.ex, e = t.ey;
s.ex.x = b2Abs(i.x);
s.ex.y = b2Abs(i.y);
s.ey.x = b2Abs(e.x);
s.ey.y = b2Abs(e.y);
return s;
}
static MulMV(t, s, i) {
const e = t.ex, r = t.ey;
const h = s.x, n = s.y;
i.x = e.x * h + r.x * n;
i.y = e.y * h + r.y * n;
return i;
}
static MulTMV(t, s, i) {
const e = t.ex, r = t.ey;
const h = s.x, n = s.y;
i.x = e.x * h + e.y * n;
i.y = r.x * h + r.y * n;
return i;
}
static AddMM(t, s, i) {
const e = t.ex, r = t.ey;
const h = s.ex, n = s.ey;
i.ex.x = e.x + h.x;
i.ex.y = e.y + h.y;
i.ey.x = r.x + n.x;
i.ey.y = r.y + n.y;
return i;
}
static MulMM(t, s, i) {
const e = t.ex.x, r = t.ex.y;
const h = t.ey.x, n = t.ey.y;
const o = s.ex.x, c = s.ex.y;
const u = s.ey.x, a = s.ey.y;
i.ex.x = e * o + h * c;
i.ex.y = r * o + n * c;
i.ey.x = e * u + h * a;
i.ey.y = r * u + n * a;
return i;
}
static MulTMM(t, s, i) {
const e = t.ex.x, r = t.ex.y;
const h = t.ey.x, n = t.ey.y;
const o = s.ex.x, c = s.ex.y;
const u = s.ey.x, a = s.ey.y;
i.ex.x = e * o + r * c;
i.ex.y = h * o + n * c;
i.ey.x = e * u + r * a;
i.ey.y = h * u + n * a;
return i;
}
}
b2Mat22.IDENTITY = new b2Mat22;
export class b2Mat33 {
constructor() {
this.data = new Float32Array([ 1, 0, 0, 0, 1, 0, 0, 0, 1 ]);
this.ex = new b2Vec3(this.data.subarray(0, 3));
this.ey = new b2Vec3(this.data.subarray(3, 6));
this.ez = new b2Vec3(this.data.subarray(6, 9));
}
Clone() {
return (new b2Mat33).Copy(this);
}
SetVVV(t, s, i) {
this.ex.Copy(t);
this.ey.Copy(s);
this.ez.Copy(i);
return this;
}
Copy(t) {
this.ex.Copy(t.ex);
this.ey.Copy(t.ey);
this.ez.Copy(t.ez);
return this;
}
SetIdentity() {
this.ex.SetXYZ(1, 0, 0);
this.ey.SetXYZ(0, 1, 0);
this.ez.SetXYZ(0, 0, 1);
return this;
}
SetZero() {
this.ex.SetZero();
this.ey.SetZero();
this.ez.SetZero();
return this;
}
SelfAddM(t) {
this.ex.SelfAdd(t.ex);
this.ey.SelfAdd(t.ey);
this.ez.SelfAdd(t.ez);
return this;
}
Solve33(t, s, i, e) {
const r = this.ex.x, h = this.ex.y, n = this.ex.z;
const o = this.ey.x, c = this.ey.y, u = this.ey.z;
const a = this.ez.x, b = this.ez.y, l = this.ez.z;
let S = r * (c * l - u * b) + h * (u * a - o * l) + n * (o * b - c * a);
if (S !== 0) {
S = 1 / S;
}
e.x = S * (t * (c * l - u * b) + s * (u * a - o * l) + i * (o * b - c * a));
e.y = S * (r * (s * l - i * b) + h * (i * a - t * l) + n * (t * b - s * a));
e.z = S * (r * (c * i - u * s) + h * (u * t - o * i) + n * (o * s - c * t));
return e;
}
Solve22(t, s, i) {
const e = this.ex.x, r = this.ey.x;
const h = this.ex.y, n = this.ey.y;
let o = e * n - r * h;
if (o !== 0) {
o = 1 / o;
}
i.x = o * (n * t - r * s);
i.y = o * (e * s - h * t);
return i;
}
GetInverse22(t) {
const s = this.ex.x, i = this.ey.x, e = this.ex.y, r = this.ey.y;
let h = s * r - i * e;
if (h !== 0) {
h = 1 / h;
}
t.ex.x = h * r;
t.ey.x = -h * i;
t.ex.z = 0;
t.ex.y = -h * e;
t.ey.y = h * s;
t.ey.z = 0;
t.ez.x = 0;
t.ez.y = 0;
t.ez.z = 0;
}
GetSymInverse33(t) {
let s = b2Vec3.DotV3V3(this.ex, b2Vec3.CrossV3V3(this.ey, this.ez, b2Vec3.s_t0));
if (s !== 0) {
s = 1 / s;
}
const i = this.ex.x, e = this.ey.x, r = this.ez.x;
const h = this.ey.y, n = this.ez.y;
const o = this.ez.z;
t.ex.x = s * (h * o - n * n);
t.ex.y = s * (r * n - e * o);
t.ex.z = s * (e * n - r * h);
t.ey.x = t.ex.y;
t.ey.y = s * (i * o - r * r);
t.ey.z = s * (r * e - i * n);
t.ez.x = t.ex.z;
t.ez.y = t.ey.z;
t.ez.z = s * (i * h - e * e);
}
static MulM33V3(t, s, i) {
const e = s.x, r = s.y, h = s.z;
i.x = t.ex.x * e + t.ey.x * r + t.ez.x * h;
i.y = t.ex.y * e + t.ey.y * r + t.ez.y * h;
i.z = t.ex.z * e + t.ey.z * r + t.ez.z * h;
return i;
}
static MulM33XYZ(t, s, i, e, r) {
r.x = t.ex.x * s + t.ey.x * i + t.ez.x * e;
r.y = t.ex.y * s + t.ey.y * i + t.ez.y * e;
r.z = t.ex.z * s + t.ey.z * i + t.ez.z * e;
return r;
}
static MulM33V2(t, s, i) {
const e = s.x, r = s.y;
i.x = t.ex.x * e + t.ey.x * r;
i.y = t.ex.y * e + t.ey.y * r;
return i;
}
static MulM33XY(t, s, i, e) {
e.x = t.ex.x * s + t.ey.x * i;
e.y = t.ex.y * s + t.ey.y * i;
return e;
}
}
b2Mat33.IDENTITY = new b2Mat33;
export class b2Rot {
constructor(t = 0) {
this.s = 0;
this.c = 1;
if (t) {
this.s = Math.sin(t);
this.c = Math.cos(t);
}
}
Clone() {
return (new b2Rot).Copy(this);
}
Copy(t) {
this.s = t.s;
this.c = t.c;
return this;
}
SetAngle(t) {
this.s = Math.sin(t);
this.c = Math.cos(t);
return this;
}
SetIdentity() {
this.s = 0;
this.c = 1;
return this;
}
GetAngle() {
return Math.atan2(this.s, this.c);
}
GetXAxis(t) {
t.x = this.c;
t.y = this.s;
return t;
}
GetYAxis(t) {
t.x = -this.s;
t.y = this.c;
return t;
}
static MulRR(t, s, i) {
const e = t.c, r = t.s;
const h = s.c, n = s.s;
i.s = r * h + e * n;
i.c = e * h - r * n;
return i;
}
static MulTRR(t, s, i) {
const e = t.c, r = t.s;
const h = s.c, n = s.s;
i.s = e * n - r * h;
i.c = e * h + r * n;
return i;
}
static MulRV(t, s, i) {
const e = t.c, r = t.s;
const h = s.x, n = s.y;
i.x = e * h - r * n;
i.y = r * h + e * n;
return i;
}
static MulTRV(t, s, i) {
const e = t.c, r = t.s;
const h = s.x, n = s.y;
i.x = e * h + r * n;
i.y = -r * h + e * n;
return i;
}
}
b2Rot.IDENTITY = new b2Rot;
export class b2Transform {
constructor() {
this.p = new b2Vec2;
this.q = new b2Rot;
}
Clone() {
return (new b2Transform).Copy(this);
}
Copy(t) {
this.p.Copy(t.p);
this.q.Copy(t.q);
return this;
}
SetIdentity() {
this.p.SetZero();
this.q.SetIdentity();
return this;
}
SetPositionRotation(t, s) {
this.p.Copy(t);
this.q.Copy(s);
return this;
}
SetPositionAngle(t, s) {
this.p.Copy(t);
this.q.SetAngle(s);
return this;
}
SetPosition(t) {
this.p.Copy(t);
return this;
}
SetPositionXY(t, s) {
this.p.Set(t, s);
return this;
}
SetRotation(t) {
this.q.Copy(t);
return this;
}
SetRotationAngle(t) {
this.q.SetAngle(t);
return this;
}
GetPosition() {
return this.p;
}
GetRotation() {
return this.q;
}
GetRotationAngle() {
return this.q.GetAngle();
}
GetAngle() {
return this.q.GetAngle();
}
static MulXV(t, s, i) {
const e = t.q.c, r = t.q.s;
const h = s.x, n = s.y;
i.x = e * h - r * n + t.p.x;
i.y = r * h + e * n + t.p.y;
return i;
}
static MulTXV(t, s, i) {
const e = t.q.c, r = t.q.s;
const h = s.x - t.p.x;
const n = s.y - t.p.y;
i.x = e * h + r * n;
i.y = -r * h + e * n;
return i;
}
static MulXX(t, s, i) {
b2Rot.MulRR(t.q, s.q, i.q);
b2Vec2.AddVV(b2Rot.MulRV(t.q, s.p, i.p), t.p, i.p);
return i;
}
static MulTXX(t, s, i) {
b2Rot.MulTRR(t.q, s.q, i.q);
b2Rot.MulTRV(t.q, b2Vec2.SubVV(s.p, t.p, i.p), i.p);
return i;
}
}
b2Transform.IDENTITY = new b2Transform;
export class b2Sweep {
constructor() {
this.localCenter = new b2Vec2;
this.c0 = new b2Vec2;
this.c = new b2Vec2;
this.a0 = 0;
this.a = 0;
this.alpha0 = 0;
}
Clone() {
return (new b2Sweep).Copy(this);
}
Copy(t) {
this.localCenter.Copy(t.localCenter);
this.c0.Copy(t.c0);
this.c.Copy(t.c);
this.a0 = t.a0;
this.a = t.a;
this.alpha0 = t.alpha0;
return this;
}
GetTransform(t, s) {
t.p.x = (1 - s) * this.c0.x + s * this.c.x;
t.p.y = (1 - s) * this.c0.y + s * this.c.y;
const i = (1 - s) * this.a0 + s * this.a;
t.q.SetAngle(i);
t.p.SelfSub(b2Rot.MulRV(t.q, this.localCenter, b2Vec2.s_t0));
return t;
}
Advance(t) {
const s = (t - this.alpha0) / (1 - this.alpha0);
const i = 1 - s;
this.c0.x = i * this.c0.x + s * this.c.x;
this.c0.y = i * this.c0.y + s * this.c.y;
this.a0 = i * this.a0 + s * this.a;
this.alpha0 = t;
}
Normalize() {
const t = b2_two_pi * Math.floor(this.a0 / b2_two_pi);
this.a0 -= t;
this.a -= t;
}
}