UNPKG

the-world-engine

Version:

three.js based, unity like game engine for browser

236 lines (225 loc) 7.01 kB
import { b2_linearSlop } from "../common/b2_settings.js"; import { b2Sqrt } from "../common/b2_math.js"; import { b2Manifold } from "../collision/b2_collision.js"; import { b2TestOverlapShape } from "../collision/b2_collision.js"; import { b2TimeOfImpact, b2TOIInput, b2TOIOutput } from "../collision/b2_time_of_impact.js"; export function b2MixFriction(t, i) { return b2Sqrt(t * i); } export function b2MixRestitution(t, i) { return t > i ? t : i; } export function b2MixRestitutionThreshold(t, i) { return t < i ? t : i; } export class b2ContactEdge { constructor(t) { this._other = null; this.prev = null; this.next = null; this.contact = t; } get other() { if (this._other === null) { throw new Error; } return this._other; } set other(t) { if (this._other !== null) { throw new Error; } this._other = t; } Reset() { this._other = null; this.prev = null; this.next = null; } } export class b2Contact { constructor() { this.m_islandFlag = false; this.m_touchingFlag = false; this.m_enabledFlag = false; this.m_filterFlag = false; this.m_bulletHitFlag = false; this.m_toiFlag = false; this.m_prev = null; this.m_next = null; this.m_nodeA = new b2ContactEdge(this); this.m_nodeB = new b2ContactEdge(this); this.m_indexA = 0; this.m_indexB = 0; this.m_manifold = new b2Manifold; this.m_toiCount = 0; this.m_toi = 0; this.m_friction = 0; this.m_restitution = 0; this.m_restitutionThreshold = 0; this.m_tangentSpeed = 0; this.m_oldManifold = new b2Manifold; } GetManifold() { return this.m_manifold; } GetWorldManifold(t) { const i = this.m_fixtureA.GetBody(); const s = this.m_fixtureB.GetBody(); const h = this.GetShapeA(); const e = this.GetShapeB(); t.Initialize(this.m_manifold, i.GetTransform(), h.m_radius, s.GetTransform(), e.m_radius); } IsTouching() { return this.m_touchingFlag; } SetEnabled(t) { this.m_enabledFlag = t; } IsEnabled() { return this.m_enabledFlag; } GetNext() { return this.m_next; } GetFixtureA() { return this.m_fixtureA; } GetChildIndexA() { return this.m_indexA; } GetShapeA() { return this.m_fixtureA.GetShape(); } GetFixtureB() { return this.m_fixtureB; } GetChildIndexB() { return this.m_indexB; } GetShapeB() { return this.m_fixtureB.GetShape(); } FlagForFiltering() { this.m_filterFlag = true; } SetFriction(t) { this.m_friction = t; } GetFriction() { return this.m_friction; } ResetFriction() { this.m_friction = b2MixFriction(this.m_fixtureA.m_friction, this.m_fixtureB.m_friction); } SetRestitution(t) { this.m_restitution = t; } GetRestitution() { return this.m_restitution; } ResetRestitution() { this.m_restitution = b2MixRestitution(this.m_fixtureA.m_restitution, this.m_fixtureB.m_restitution); } SetRestitutionThreshold(t) { this.m_restitutionThreshold = t; } GetRestitutionThreshold() { return this.m_restitutionThreshold; } ResetRestitutionThreshold() { this.m_restitutionThreshold = b2MixRestitutionThreshold(this.m_fixtureA.m_restitutionThreshold, this.m_fixtureB.m_restitutionThreshold); } SetTangentSpeed(t) { this.m_tangentSpeed = t; } GetTangentSpeed() { return this.m_tangentSpeed; } Reset(t, i, s, h) { this.m_islandFlag = false; this.m_touchingFlag = false; this.m_enabledFlag = true; this.m_filterFlag = false; this.m_bulletHitFlag = false; this.m_toiFlag = false; this.m_fixtureA = t; this.m_fixtureB = s; this.m_indexA = i; this.m_indexB = h; this.m_manifold.pointCount = 0; this.m_prev = null; this.m_next = null; this.m_nodeA.Reset(); this.m_nodeB.Reset(); this.m_toiCount = 0; this.m_friction = b2MixFriction(this.m_fixtureA.m_friction, this.m_fixtureB.m_friction); this.m_restitution = b2MixRestitution(this.m_fixtureA.m_restitution, this.m_fixtureB.m_restitution); this.m_restitutionThreshold = b2MixRestitutionThreshold(this.m_fixtureA.m_restitutionThreshold, this.m_fixtureB.m_restitutionThreshold); } Update(t) { const i = this.m_oldManifold; this.m_oldManifold = this.m_manifold; this.m_manifold = i; this.m_enabledFlag = true; let s = false; const h = this.m_touchingFlag; const e = this.m_fixtureA.IsSensor(); const n = this.m_fixtureB.IsSensor(); const o = e || n; const r = this.m_fixtureA.GetBody(); const l = this.m_fixtureB.GetBody(); const u = r.GetTransform(); const c = l.GetTransform(); if (o) { const t = this.GetShapeA(); const i = this.GetShapeB(); s = b2TestOverlapShape(t, this.m_indexA, i, this.m_indexB, u, c); this.m_manifold.pointCount = 0; } else { this.Evaluate(this.m_manifold, u, c); s = this.m_manifold.pointCount > 0; for (let t = 0; t < this.m_manifold.pointCount; ++t) { const i = this.m_manifold.points[t]; i.normalImpulse = 0; i.tangentImpulse = 0; const s = i.id; for (let t = 0; t < this.m_oldManifold.pointCount; ++t) { const h = this.m_oldManifold.points[t]; if (h.id.key === s.key) { i.normalImpulse = h.normalImpulse; i.tangentImpulse = h.tangentImpulse; break; } } } if (s !== h) { r.SetAwake(true); l.SetAwake(true); } } this.m_touchingFlag = s; if (!h && s && t) { t.BeginContact(this); } if (h && !s && t) { t.EndContact(this); } if (!o && s && t) { t.PreSolve(this, this.m_oldManifold); } } ComputeTOI(t, i) { const s = b2Contact.ComputeTOI_s_input; s.proxyA.SetShape(this.GetShapeA(), this.m_indexA); s.proxyB.SetShape(this.GetShapeB(), this.m_indexB); s.sweepA.Copy(t); s.sweepB.Copy(i); s.tMax = b2_linearSlop; const h = b2Contact.ComputeTOI_s_output; b2TimeOfImpact(h, s); return h.t; } } b2Contact.ComputeTOI_s_input = new b2TOIInput; b2Contact.ComputeTOI_s_output = new b2TOIOutput;