UNPKG

the-world-engine

Version:

three.js based, unity like game engine for browser

292 lines (291 loc) 10.3 kB
import { Vector2 } from "three/src/Three"; export class Physics2DProcessor { yi=null; Pi=8; Ti=3; Ii=true; xi=null; Mi=null; Ni=new Map; Oi=null; Bi=null; applyPhysicsSettings(t) { if (!t.loader) return; this.Oi = t.loader; this.Mi = new this.Oi.World(new this.Oi.Vec2(0, -9.81)); const i = class extends this.Oi.ContactListener { Li; ji; qi; Hi; constructor(t) { super(); this.Li = t; this.ji = new this.Li.Oi.Collision2DPool; this.qi = new this.Li.Oi.TriggerEventPool; this.Hi = new this.Li.Oi.CollisionEventPool; } BeginContact(t) { const i = t.GetFixtureA().GetUserData(); const s = t.GetFixtureB().GetUserData(); if (i.isTrigger || s.isTrigger) { this.qi.insert(0, i, s); } else { if (this.Li.reuseCollisionCallbacks) { const e = this.ji.getInstance(); e.setData(t); this.Hi.insert(0, i, s, e, this.ji); } else { const e = new this.Li.Oi.Collision2D; e.setData(t); this.Hi.insert(0, i, s, e); } } } EndContact(t) { const i = t.GetFixtureA().GetUserData(); const s = t.GetFixtureB().GetUserData(); if (i.isTrigger || s.isTrigger) { this.qi.insert(2, i, s); } else { if (this.Li.reuseCollisionCallbacks) { const e = this.ji.getInstance(); e.setData(t); this.Hi.insert(2, i, s, e, this.ji); } else { const e = new this.Li.Oi.Collision2D; e.setData(t); this.Hi.insert(2, i, s, e); } } } PreSolve(t, i) { const s = t.GetFixtureA().GetUserData(); const e = t.GetFixtureB().GetUserData(); if (s.isTrigger || e.isTrigger) { this.qi.insert(1, s, e); } else { if (this.Li.reuseCollisionCallbacks) { const i = this.ji.getInstance(); i.setData(t); this.Hi.insert(1, s, e, i, this.ji); } else { const i = new this.Li.Oi.Collision2D; i.setData(t); this.Hi.insert(1, s, e, i); } } } onTriggerInvoke() { this.qi.invoke(); } onCollisionInvoke() { this.Hi.invoke(); } }; const s = new i(this); this.Bi = s; this.Mi.SetContactListener(s); if (t.gravity) this.Mi?.SetGravity(t.gravity); if (t.defaultMaterial) this.yi = t.defaultMaterial.clone(); if (t.velocityIterations) this.Pi = t.velocityIterations; if (t.positionIterations) this.Ti = t.positionIterations; if (t.queriesHitTriggers) this.Ii = t.queriesHitTriggers; if (t.reuseCollisionCallbacks) this.reuseCollisionCallbacks = t.reuseCollisionCallbacks; if (t.collisionLayerMaskMatrix) { this.xi = new this.Oi.CollisionLayerMaskConverter(t.collisionLayerMaskMatrix); } else { this.xi = new this.Oi.CollisionLayerMaskConverter({ default: { default: true } }); } this.Ri = new this.Oi.RayCastOneCallback(this); this.Ai = new this.Oi.RayCastFilterCallback; } update(t) { if (!this.Mi) return; { let t = this.Mi.GetBodyList(); while (t) { const i = t; t = t.GetNext(); const s = i.GetUserData(); const e = s.gameObject.transform; const r = e.position; const o = e.eulerAngles; const h = i.GetPosition(); const n = i.GetAngle(); if (r.x !== h.x || r.y !== h.y) { i.SetPosition(r); i.SetAwake(true); } if (o.z !== n) { i.SetAngle(o.z); i.SetAwake(true); } } } this.Mi.Step(t, this.Pi, this.Ti); { let t = this.Mi.GetBodyList(); while (t) { const i = t; t = t.GetNext(); const s = i.GetUserData(); const e = s.gameObject.transform; e.position.x = i.GetPosition().x; e.position.y = i.GetPosition().y; e.eulerAngles.z = i.GetAngle(); } } this.Bi.onTriggerInvoke(); this.Bi.onCollisionInvoke(); } addRigidBody(t, i, s) { if (!this.Mi) throw new Error("Physics2D is not loaded."); let e = this.Ni.get(t); if (!e) { e = new this.Oi.PhysicsObject2D(t, this.Mi.CreateBody(s), (() => this.Ni.delete(t))); this.Ni.set(t, e); return e.addRigidBody(i); } else { const t = e.addRigidBody(i); const r = t.body; r.SetType(s.type); r.SetPosition(s.position); r.SetAngle(s.angle); r.SetLinearVelocity(s.linearVelocity); r.SetAngularVelocity(s.angularVelocity); r.SetLinearDamping(s.linearDamping); r.SetAngularDamping(s.angularDamping); r.SetSleepingAllowed(s.allowSleep); r.SetAwake(s.awake); r.SetFixedRotation(s.fixedRotation); r.SetBullet(s.bullet); r.SetEnabled(s.enabled); r.SetUserData(s.userData); r.SetGravityScale(s.gravityScale); return t; } } removeRigidBody(t) { const i = this.Ni.get(t); if (!i) throw new Error("PhysicsObject2D not found"); i.removeRigidBody(); } Fi(t) { const i = new this.Oi.BodyDef; i.type = this.Oi.BodyType.b2_kinematicBody; i.position.x = t.transform.position.x; i.position.y = t.transform.position.y; i.angle = t.transform.eulerAngles.z; return i; } addCollider(t, i) { if (!this.Mi) throw new Error("Physics2D is not loaded."); let s = this.Ni.get(t); if (!s) { s = new this.Oi.PhysicsObject2D(t, this.Mi.CreateBody(this.Fi(t)), (() => this.Ni.delete(t))); } this.Ni.set(t, s); return s.addCollider(i); } removeCollider(t, i, s) { const e = this.Ni.get(t); if (!e) throw new Error("PhysicsObject2D not found"); e.removeCollider(i, s); } get physicsLoader() { return this.Oi; } get gravity() { if (!this.Mi) throw new Error("Physics2D is not loaded."); const t = this.Mi.GetGravity(); return new Vector2(t.x, t.y); } set gravity(t) { if (!this.Mi) throw new Error("Physics2D is not loaded."); this.Mi.SetGravity(new this.Oi.Vec2(t.x, t.y)); } get defaultMaterial() { return this.yi; } get velocityIterations() { return this.Pi; } set velocityIterations(t) { this.Pi = t; } get positionIterations() { return this.Ti; } set positionIterations(t) { this.Ti = t; } get maxLinearCorrection() { if (!this.Oi) throw new Error("Physics2D is not loaded."); return this.Oi.maxLinearCorrection; } get maxAngularCorrection() { if (!this.Oi) throw new Error("Physics2D is not loaded."); return this.Oi.maxAngularCorrection; } get maxTranslationSpeed() { if (!this.Oi) throw new Error("Physics2D is not loaded."); return this.Oi.maxTranslation; } get maxRotationSpeed() { if (!this.Oi) throw new Error("Physics2D is not loaded."); return this.Oi.maxRotation; } get baumgarteScale() { if (!this.Oi) throw new Error("Physics2D is not loaded."); return this.Oi.baumgarte; } get baumgarteTimeOfImpactScale() { if (!this.Oi) throw new Error("Physics2D is not loaded."); return this.Oi.toiBaumgarte; } get timeToSleep() { if (!this.Oi) throw new Error("Physics2D is not loaded."); return this.Oi.timeToSleep; } get linearSleepTolerance() { if (!this.Oi) throw new Error("Physics2D is not loaded."); return this.Oi.linearSleepTolerance; } get angularSleepTolerance() { if (!this.Oi) throw new Error("Physics2D is not loaded."); return this.Oi.angularSleepTolerance; } get queriesHitTriggers() { return this.Ii; } set queriesHitTriggers(t) { this.Ii = t; } reuseCollisionCallbacks=true; get collisionLayerMask() { return this.xi; } static _raycastEndPoint=new Vector2; Ri=null; Ai=null; raycastOne(t, i, s, e = Number.POSITIVE_INFINITY, r = 4294967295, o = Number.NEGATIVE_INFINITY, h = Number.POSITIVE_INFINITY) { if (!this.Mi) throw new Error("Physics2D is not loaded."); if (!s) s = new this.Oi.RaycastHit2D; const n = Physics2DProcessor._raycastEndPoint.copy(i).multiplyScalar(e === Number.POSITIVE_INFINITY ? 1e7 : e).add(t); this.Ri.setRaycastData(s, t, r, o, h); this.Mi.RayCast(this.Ri, t, n); return this.Ri.hit ? s : null; } raycast(t, i, s, e, r = Number.POSITIVE_INFINITY) { if (!this.Mi) throw new Error("Physics2D is not loaded."); const o = Physics2DProcessor._raycastEndPoint.copy(i).multiplyScalar(r === Number.POSITIVE_INFINITY ? 1e7 : r).add(t); this.Ai.setRaycastData(e, t, s); this.Mi.RayCast(this.Ai, t, o); return this.Ai.hitCount; } }