UNPKG

the-world-engine

Version:

three.js based, unity like game engine for browser

192 lines (170 loc) 5.46 kB
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; }