UNPKG

the-world-engine

Version:

three.js based, unity like game engine for browser

172 lines (162 loc) 5.6 kB
import { b2_polygonRadius } from "../common/b2_settings.js"; import { b2Vec2, b2Transform } from "../common/b2_math.js"; import { b2Shape, b2ShapeType } from "./b2_shape.js"; import { b2EdgeShape } from "./b2_edge_shape.js"; export class b2ChainShape extends b2Shape { constructor() { super(b2ShapeType.e_chainShape, b2_polygonRadius); this.m_vertices = []; this.m_count = 0; this.m_prevVertex = new b2Vec2; this.m_nextVertex = new b2Vec2; } CreateLoop(...t) { if (typeof t[0][0] === "number") { const e = t[0]; if (e.length % 2 !== 0) { throw new Error; } return this._CreateLoop((t => ({ x: e[t * 2], y: e[t * 2 + 1] })), e.length / 2); } else { const e = t[0]; return this._CreateLoop((t => e[t]), e.length); } } _CreateLoop(t, e) { if (e < 3) { return this; } this.m_count = e + 1; this.m_vertices = b2Vec2.MakeArray(this.m_count); for (let s = 0; s < e; ++s) { this.m_vertices[s].Copy(t(s)); } this.m_vertices[e].Copy(this.m_vertices[0]); this.m_prevVertex.Copy(this.m_vertices[this.m_count - 2]); this.m_nextVertex.Copy(this.m_vertices[1]); return this; } CreateChain(...t) { if (typeof t[0][0] === "number") { const e = t[0]; const s = t[1]; const h = t[2]; if (e.length % 2 !== 0) { throw new Error; } return this._CreateChain((t => ({ x: e[t * 2], y: e[t * 2 + 1] })), e.length / 2, s, h); } else { const e = t[0]; const s = t[1]; const h = t[2]; return this._CreateChain((t => e[t]), e.length, s, h); } } _CreateChain(t, e, s, h) { this.m_count = e; this.m_vertices = b2Vec2.MakeArray(e); for (let s = 0; s < e; ++s) { this.m_vertices[s].Copy(t(s)); } this.m_prevVertex.Copy(s); this.m_nextVertex.Copy(h); return this; } Clone() { return (new b2ChainShape).Copy(this); } Copy(t) { super.Copy(t); this._CreateChain((e => t.m_vertices[e]), t.m_count, t.m_prevVertex, t.m_nextVertex); this.m_prevVertex.Copy(t.m_prevVertex); this.m_nextVertex.Copy(t.m_nextVertex); return this; } GetChildCount() { return this.m_count - 1; } GetChildEdge(t, e) { t.m_radius = this.m_radius; t.m_vertex1.Copy(this.m_vertices[e]); t.m_vertex2.Copy(this.m_vertices[e + 1]); t.m_oneSided = true; if (e > 0) { t.m_vertex0.Copy(this.m_vertices[e - 1]); } else { t.m_vertex0.Copy(this.m_prevVertex); } if (e < this.m_count - 2) { t.m_vertex3.Copy(this.m_vertices[e + 2]); } else { t.m_vertex3.Copy(this.m_nextVertex); } } TestPoint(t, e) { return false; } ComputeDistance(t, e, s, h) { const i = b2ChainShape.ComputeDistance_s_edgeShape; this.GetChildEdge(i, h); return i.ComputeDistance(t, e, s, 0); } RayCast(t, e, s, h) { const i = b2ChainShape.RayCast_s_edgeShape; i.m_vertex1.Copy(this.m_vertices[h]); i.m_vertex2.Copy(this.m_vertices[(h + 1) % this.m_count]); return i.RayCast(t, e, s, 0); } ComputeAABB(t, e, s) { const h = this.m_vertices[s]; const i = this.m_vertices[(s + 1) % this.m_count]; const n = b2Transform.MulXV(e, h, b2ChainShape.ComputeAABB_s_v1); const r = b2Transform.MulXV(e, i, b2ChainShape.ComputeAABB_s_v2); const a = b2Vec2.MinV(n, r, b2ChainShape.ComputeAABB_s_lower); const o = b2Vec2.MaxV(n, r, b2ChainShape.ComputeAABB_s_upper); t.lowerBound.x = a.x - this.m_radius; t.lowerBound.y = a.y - this.m_radius; t.upperBound.x = o.x + this.m_radius; t.upperBound.y = o.y + this.m_radius; } ComputeMass(t, e) { t.mass = 0; t.center.SetZero(); t.I = 0; } SetupDistanceProxy(t, e) { t.m_vertices = t.m_buffer; t.m_vertices[0].Copy(this.m_vertices[e]); if (e + 1 < this.m_count) { t.m_vertices[1].Copy(this.m_vertices[e + 1]); } else { t.m_vertices[1].Copy(this.m_vertices[0]); } t.m_count = 2; t.m_radius = this.m_radius; } ComputeSubmergedArea(t, e, s, h) { h.SetZero(); return 0; } Dump(t) { t(" const shape: b2ChainShape = new b2ChainShape();\n"); t(" const vs: b2Vec2[] = [];\n"); for (let e = 0; e < this.m_count; ++e) { t(" vs[%d] = new bVec2(%.15f, %.15f);\n", e, this.m_vertices[e].x, this.m_vertices[e].y); } t(" shape.CreateChain(vs, %d);\n", this.m_count); t(" shape.m_prevVertex.Set(%.15f, %.15f);\n", this.m_prevVertex.x, this.m_prevVertex.y); t(" shape.m_nextVertex.Set(%.15f, %.15f);\n", this.m_nextVertex.x, this.m_nextVertex.y); } } b2ChainShape.ComputeDistance_s_edgeShape = new b2EdgeShape; b2ChainShape.RayCast_s_edgeShape = new b2EdgeShape; b2ChainShape.ComputeAABB_s_v1 = new b2Vec2; b2ChainShape.ComputeAABB_s_v2 = new b2Vec2; b2ChainShape.ComputeAABB_s_lower = new b2Vec2; b2ChainShape.ComputeAABB_s_upper = new b2Vec2;