the-world-engine
Version:
three.js based, unity like game engine for browser
192 lines (170 loc) • 5.46 kB
JavaScript
import { b2_linearSlop, b2_maxFloat, b2_maxManifoldPoints } from "../common/b2_settings.js";
import { b2Vec2, b2Transform, b2Rot } from "../common/b2_math.js";
import { b2ClipVertex, b2ContactFeatureType, b2ManifoldType, b2ClipSegmentToLine } from "./b2_collision.js";
const b2FindMaxSeparation_s_xf = new b2Transform;
const b2FindMaxSeparation_s_n = new b2Vec2;
const b2FindMaxSeparation_s_v1 = new b2Vec2;
function b2FindMaxSeparation(o, n, e, t, s) {
const l = n.m_count;
const c = t.m_count;
const b = n.m_normals;
const i = n.m_vertices;
const a = t.m_vertices;
const _ = b2Transform.MulTXX(s, e, b2FindMaxSeparation_s_xf);
let r = 0;
let d = -b2_maxFloat;
for (let o = 0; o < l; ++o) {
const n = b2Rot.MulRV(_.q, b[o], b2FindMaxSeparation_s_n);
const e = b2Transform.MulXV(_, i[o], b2FindMaxSeparation_s_v1);
let t = b2_maxFloat;
for (let o = 0; o < c; ++o) {
const s = b2Vec2.DotVV(n, b2Vec2.SubVV(a[o], e, b2Vec2.s_t0));
if (s < t) {
t = s;
}
}
if (t > d) {
d = t;
r = o;
}
}
o[0] = r;
return d;
}
const b2FindIncidentEdge_s_normal1 = new b2Vec2;
function b2FindIncidentEdge(o, n, e, t, s, l) {
const c = n.m_normals;
const b = s.m_count;
const i = s.m_vertices;
const a = s.m_normals;
const _ = b2Rot.MulTRV(l.q, b2Rot.MulRV(e.q, c[t], b2Vec2.s_t0), b2FindIncidentEdge_s_normal1);
let r = 0;
let d = b2_maxFloat;
for (let o = 0; o < b; ++o) {
const n = b2Vec2.DotVV(_, a[o]);
if (n < d) {
d = n;
r = o;
}
}
const g = r;
const C = g + 1 < b ? g + 1 : 0;
const p = o[0];
b2Transform.MulXV(l, i[g], p.v);
const f = p.id.cf;
f.indexA = t;
f.indexB = g;
f.typeA = b2ContactFeatureType.e_face;
f.typeB = b2ContactFeatureType.e_vertex;
const m = o[1];
b2Transform.MulXV(l, i[C], m.v);
const y = m.id.cf;
y.indexA = t;
y.indexB = C;
y.typeA = b2ContactFeatureType.e_face;
y.typeB = b2ContactFeatureType.e_vertex;
}
const b2CollidePolygons_s_incidentEdge = [ new b2ClipVertex, new b2ClipVertex ];
const b2CollidePolygons_s_clipPoints1 = [ new b2ClipVertex, new b2ClipVertex ];
const b2CollidePolygons_s_clipPoints2 = [ new b2ClipVertex, new b2ClipVertex ];
const b2CollidePolygons_s_edgeA = [ 0 ];
const b2CollidePolygons_s_edgeB = [ 0 ];
const b2CollidePolygons_s_localTangent = new b2Vec2;
const b2CollidePolygons_s_localNormal = new b2Vec2;
const b2CollidePolygons_s_planePoint = new b2Vec2;
const b2CollidePolygons_s_normal = new b2Vec2;
const b2CollidePolygons_s_tangent = new b2Vec2;
const b2CollidePolygons_s_ntangent = new b2Vec2;
const b2CollidePolygons_s_v11 = new b2Vec2;
const b2CollidePolygons_s_v12 = new b2Vec2;
export function b2CollidePolygons(o, n, e, t, s) {
o.pointCount = 0;
const l = n.m_radius + t.m_radius;
const c = b2CollidePolygons_s_edgeA;
c[0] = 0;
const b = b2FindMaxSeparation(c, n, e, t, s);
if (b > l) {
return;
}
const i = b2CollidePolygons_s_edgeB;
i[0] = 0;
const a = b2FindMaxSeparation(i, t, s, n, e);
if (a > l) {
return;
}
let _;
let r;
let d, g;
let C = 0;
let p = 0;
const f = .1 * b2_linearSlop;
if (a > b + f) {
_ = t;
r = n;
d = s;
g = e;
C = i[0];
o.type = b2ManifoldType.e_faceB;
p = 1;
} else {
_ = n;
r = t;
d = e;
g = s;
C = c[0];
o.type = b2ManifoldType.e_faceA;
p = 0;
}
const m = b2CollidePolygons_s_incidentEdge;
b2FindIncidentEdge(m, _, d, C, r, g);
const y = _.m_count;
const P = _.m_vertices;
const V = C;
const x = C + 1 < y ? C + 1 : 0;
const F = P[V];
const T = P[x];
const w = b2Vec2.SubVV(T, F, b2CollidePolygons_s_localTangent);
w.Normalize();
const M = b2Vec2.CrossVOne(w, b2CollidePolygons_s_localNormal);
const S = b2Vec2.MidVV(F, T, b2CollidePolygons_s_planePoint);
const u = b2Rot.MulRV(d.q, w, b2CollidePolygons_s_tangent);
const v = b2Vec2.CrossVOne(u, b2CollidePolygons_s_normal);
const E = b2Transform.MulXV(d, F, b2CollidePolygons_s_v11);
const R = b2Transform.MulXV(d, T, b2CollidePolygons_s_v12);
const I = b2Vec2.DotVV(v, E);
const j = -b2Vec2.DotVV(u, E) + l;
const L = b2Vec2.DotVV(u, R) + l;
const A = b2CollidePolygons_s_clipPoints1;
const B = b2CollidePolygons_s_clipPoints2;
let N;
const h = b2Vec2.NegV(u, b2CollidePolygons_s_ntangent);
N = b2ClipSegmentToLine(A, m, h, j, V);
if (N < 2) {
return;
}
N = b2ClipSegmentToLine(B, A, u, L, x);
if (N < 2) {
return;
}
o.localNormal.Copy(M);
o.localPoint.Copy(S);
let k = 0;
for (let n = 0; n < b2_maxManifoldPoints; ++n) {
const e = B[n];
const t = b2Vec2.DotVV(v, e.v) - I;
if (t <= l) {
const n = o.points[k];
b2Transform.MulTXV(g, e.v, n.localPoint);
n.id.Copy(e.id);
if (p) {
const o = n.id.cf;
n.id.cf.indexA = o.indexB;
n.id.cf.indexB = o.indexA;
n.id.cf.typeA = o.typeB;
n.id.cf.typeB = o.typeA;
}
++k;
}
}
o.pointCount = k;
}