UNPKG

the-world-engine

Version:

three.js based, unity like game engine for browser

82 lines (78 loc) 2.71 kB
import { b2Controller } from "./b2_controller.js"; import { b2Vec2 } from "../common/b2_math.js"; import { b2_epsilon } from "../common/b2_settings.js"; import { b2Color } from "../common/b2_draw.js"; export class b2BuoyancyController extends b2Controller { constructor() { super(...arguments); this.normal = new b2Vec2(0, 1); this.offset = 0; this.density = 0; this.velocity = new b2Vec2(0, 0); this.linearDrag = 0; this.angularDrag = 0; this.useDensity = false; this.useWorldGravity = true; this.gravity = new b2Vec2(0, 0); } Step(t) { if (!this.m_bodyList) { return; } if (this.useWorldGravity) { this.gravity.Copy(this.m_bodyList.body.GetWorld().GetGravity()); } for (let t = this.m_bodyList; t; t = t.nextBody) { const s = t.body; if (!s.IsAwake()) { continue; } const i = new b2Vec2; const o = new b2Vec2; let e = 0; let n = 0; for (let t = s.GetFixtureList(); t; t = t.m_next) { const h = new b2Vec2; const c = t.GetShape().ComputeSubmergedArea(this.normal, this.offset, s.GetTransform(), h); e += c; i.x += c * h.x; i.y += c * h.y; let r = 0; if (this.useDensity) { r = t.GetDensity(); } else { r = 1; } n += c * r; o.x += c * h.x * r; o.y += c * h.y * r; } i.x /= e; i.y /= e; o.x /= n; o.y /= n; if (e < b2_epsilon) { continue; } const h = this.gravity.Clone().SelfNeg(); h.SelfMul(this.density * e); s.ApplyForce(h, o); const c = s.GetLinearVelocityFromWorldPoint(i, new b2Vec2); c.SelfSub(this.velocity); c.SelfMul(-this.linearDrag * e); s.ApplyForce(c, i); s.ApplyTorque(-s.GetInertia() / s.GetMass() * e * s.GetAngularVelocity() * this.angularDrag); } } Draw(t) { const s = 100; const i = new b2Vec2; const o = new b2Vec2; i.x = this.normal.x * this.offset + this.normal.y * s; i.y = this.normal.y * this.offset - this.normal.x * s; o.x = this.normal.x * this.offset - this.normal.y * s; o.y = this.normal.y * this.offset + this.normal.x * s; const e = new b2Color(0, 0, .8); t.DrawSegment(i, o, e); } }