the-world-engine
Version:
three.js based, unity like game engine for browser
172 lines (162 loc) • 5.6 kB
JavaScript
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;