the-world-engine
Version:
three.js based, unity like game engine for browser
112 lines (102 loc) • 3.68 kB
JavaScript
import { b2_pi, b2_epsilon } from "../common/b2_settings.js";
import { b2Sq, b2Sqrt, b2Asin, b2Pow, b2Vec2, b2Transform } from "../common/b2_math.js";
import { b2Shape, b2ShapeType } from "./b2_shape.js";
export class b2CircleShape extends b2Shape {
constructor(e = 0) {
super(b2ShapeType.e_circleShape, e);
this.m_p = new b2Vec2;
}
Set(e, t = this.m_radius) {
this.m_p.Copy(e);
this.m_radius = t;
return this;
}
Clone() {
return (new b2CircleShape).Copy(this);
}
Copy(e) {
super.Copy(e);
this.m_p.Copy(e.m_p);
return this;
}
GetChildCount() {
return 1;
}
TestPoint(e, t) {
const s = b2Transform.MulXV(e, this.m_p, b2CircleShape.TestPoint_s_center);
const i = b2Vec2.SubVV(t, s, b2CircleShape.TestPoint_s_d);
return b2Vec2.DotVV(i, i) <= b2Sq(this.m_radius);
}
ComputeDistance(e, t, s, i) {
const r = b2Transform.MulXV(e, this.m_p, b2CircleShape.ComputeDistance_s_center);
b2Vec2.SubVV(t, r, s);
return s.Normalize() - this.m_radius;
}
RayCast(e, t, s, i) {
const r = b2Transform.MulXV(s, this.m_p, b2CircleShape.RayCast_s_position);
const b = b2Vec2.SubVV(t.p1, r, b2CircleShape.RayCast_s_s);
const n = b2Vec2.DotVV(b, b) - b2Sq(this.m_radius);
const c = b2Vec2.SubVV(t.p2, t.p1, b2CircleShape.RayCast_s_r);
const h = b2Vec2.DotVV(b, c);
const o = b2Vec2.DotVV(c, c);
const p = h * h - o * n;
if (p < 0 || o < b2_epsilon) {
return false;
}
let a = -(h + b2Sqrt(p));
if (0 <= a && a <= t.maxFraction * o) {
a /= o;
e.fraction = a;
b2Vec2.AddVMulSV(b, a, c, e.normal).SelfNormalize();
return true;
}
return false;
}
ComputeAABB(e, t, s) {
const i = b2Transform.MulXV(t, this.m_p, b2CircleShape.ComputeAABB_s_p);
e.lowerBound.Set(i.x - this.m_radius, i.y - this.m_radius);
e.upperBound.Set(i.x + this.m_radius, i.y + this.m_radius);
}
ComputeMass(e, t) {
const s = b2Sq(this.m_radius);
e.mass = t * b2_pi * s;
e.center.Copy(this.m_p);
e.I = e.mass * (.5 * s + b2Vec2.DotVV(this.m_p, this.m_p));
}
SetupDistanceProxy(e, t) {
e.m_vertices = e.m_buffer;
e.m_vertices[0].Copy(this.m_p);
e.m_count = 1;
e.m_radius = this.m_radius;
}
ComputeSubmergedArea(e, t, s, i) {
const r = b2Transform.MulXV(s, this.m_p, new b2Vec2);
const b = -(b2Vec2.DotVV(e, r) - t);
if (b < -this.m_radius + b2_epsilon) {
return 0;
}
if (b > this.m_radius) {
i.Copy(r);
return b2_pi * this.m_radius * this.m_radius;
}
const n = this.m_radius * this.m_radius;
const c = b * b;
const h = n * (b2Asin(b / this.m_radius) + b2_pi / 2) + b * b2Sqrt(n - c);
const o = -2 / 3 * b2Pow(n - c, 1.5) / h;
i.x = r.x + e.x * o;
i.y = r.y + e.y * o;
return h;
}
Dump(e) {
e(" const shape: b2CircleShape = new b2CircleShape();\n");
e(" shape.m_radius = %.15f;\n", this.m_radius);
e(" shape.m_p.Set(%.15f, %.15f);\n", this.m_p.x, this.m_p.y);
}
}
b2CircleShape.TestPoint_s_center = new b2Vec2;
b2CircleShape.TestPoint_s_d = new b2Vec2;
b2CircleShape.ComputeDistance_s_center = new b2Vec2;
b2CircleShape.RayCast_s_position = new b2Vec2;
b2CircleShape.RayCast_s_s = new b2Vec2;
b2CircleShape.RayCast_s_r = new b2Vec2;
b2CircleShape.ComputeAABB_s_p = new b2Vec2;