the-world-engine
Version:
three.js based, unity like game engine for browser
102 lines (93 loc) • 3.24 kB
JavaScript
import { b2_maxFloat, b2_epsilon } from "../common/b2_settings.js";
import { b2Vec2, b2Transform } from "../common/b2_math.js";
import { b2ManifoldType } from "./b2_collision.js";
const b2CollideCircles_s_pA = new b2Vec2;
const b2CollideCircles_s_pB = new b2Vec2;
export function b2CollideCircles(e, o, c, n, l) {
e.pointCount = 0;
const b = b2Transform.MulXV(c, o.m_p, b2CollideCircles_s_pA);
const s = b2Transform.MulXV(l, n.m_p, b2CollideCircles_s_pB);
const i = b2Vec2.DistanceSquaredVV(b, s);
const t = o.m_radius + n.m_radius;
if (i > t * t) {
return;
}
e.type = b2ManifoldType.e_circles;
e.localPoint.Copy(o.m_p);
e.localNormal.SetZero();
e.pointCount = 1;
e.points[0].localPoint.Copy(n.m_p);
e.points[0].id.key = 0;
}
const b2CollidePolygonAndCircle_s_c = new b2Vec2;
const b2CollidePolygonAndCircle_s_cLocal = new b2Vec2;
const b2CollidePolygonAndCircle_s_faceCenter = new b2Vec2;
export function b2CollidePolygonAndCircle(e, o, c, n, l) {
e.pointCount = 0;
const b = b2Transform.MulXV(l, n.m_p, b2CollidePolygonAndCircle_s_c);
const s = b2Transform.MulTXV(c, b, b2CollidePolygonAndCircle_s_cLocal);
let i = 0;
let t = -b2_maxFloat;
const r = o.m_radius + n.m_radius;
const V = o.m_count;
const f = o.m_vertices;
const _ = o.m_normals;
for (let e = 0; e < V; ++e) {
const o = b2Vec2.DotVV(_[e], b2Vec2.SubVV(s, f[e], b2Vec2.s_t0));
if (o > r) {
return;
}
if (o > t) {
t = o;
i = e;
}
}
const C = i;
const d = (C + 1) % V;
const a = f[C];
const m = f[d];
if (t < b2_epsilon) {
e.pointCount = 1;
e.type = b2ManifoldType.e_faceA;
e.localNormal.Copy(_[i]);
b2Vec2.MidVV(a, m, e.localPoint);
e.points[0].localPoint.Copy(n.m_p);
e.points[0].id.key = 0;
return;
}
const p = b2Vec2.DotVV(b2Vec2.SubVV(s, a, b2Vec2.s_t0), b2Vec2.SubVV(m, a, b2Vec2.s_t1));
const y = b2Vec2.DotVV(b2Vec2.SubVV(s, m, b2Vec2.s_t0), b2Vec2.SubVV(a, m, b2Vec2.s_t1));
if (p <= 0) {
if (b2Vec2.DistanceSquaredVV(s, a) > r * r) {
return;
}
e.pointCount = 1;
e.type = b2ManifoldType.e_faceA;
b2Vec2.SubVV(s, a, e.localNormal).SelfNormalize();
e.localPoint.Copy(a);
e.points[0].localPoint.Copy(n.m_p);
e.points[0].id.key = 0;
} else if (y <= 0) {
if (b2Vec2.DistanceSquaredVV(s, m) > r * r) {
return;
}
e.pointCount = 1;
e.type = b2ManifoldType.e_faceA;
b2Vec2.SubVV(s, m, e.localNormal).SelfNormalize();
e.localPoint.Copy(m);
e.points[0].localPoint.Copy(n.m_p);
e.points[0].id.key = 0;
} else {
const o = b2Vec2.MidVV(a, m, b2CollidePolygonAndCircle_s_faceCenter);
const c = b2Vec2.DotVV(b2Vec2.SubVV(s, o, b2Vec2.s_t1), _[C]);
if (c > r) {
return;
}
e.pointCount = 1;
e.type = b2ManifoldType.e_faceA;
e.localNormal.Copy(_[C]).SelfNormalize();
e.localPoint.Copy(o);
e.points[0].localPoint.Copy(n.m_p);
e.points[0].id.key = 0;
}
}