UNPKG

the-world-engine

Version:

three.js based, unity like game engine for browser

420 lines (404 loc) 11.1 kB
import { Vector2 } from "three/src/Three"; import { BodyDef, BodyType, MassData, Vec2, WorldManifold } from "../../../box2d.ts/build/index"; import { Component } from "../../hierarchy_object/Component"; import { ContactPoint2D } from "../../physics/2d/ContactPoint2D"; export var RigidbodyType2D; (function(t) { t[t["Dynamic"] = 0] = "Dynamic"; t[t["Kinematic"] = 1] = "Kinematic"; t[t["Static"] = 2] = "Static"; })(RigidbodyType2D || (RigidbodyType2D = {})); export var CollisionDetectionMode2D; (function(t) { t[t["Discrete"] = 0] = "Discrete"; t[t["Continuous"] = 1] = "Continuous"; })(CollisionDetectionMode2D || (CollisionDetectionMode2D = {})); export var RigidbodySleepMode2D; (function(t) { t[t["NeverSleep"] = 0] = "NeverSleep"; t[t["StartAwake"] = 1] = "StartAwake"; t[t["StartAsleep"] = 2] = "StartAsleep"; })(RigidbodySleepMode2D || (RigidbodySleepMode2D = {})); export var ForceMode2D; (function(t) { t[t["Force"] = 0] = "Force"; t[t["Impulse"] = 1] = "Impulse"; })(ForceMode2D || (ForceMode2D = {})); export class RigidBody2D extends Component { disallowMultipleComponent=true; yo=null; jr=null; Mo=BodyType.b2_dynamicBody; Ro=true; Vo=false; So=1; Fo=0; No=.05; Bo=1; Po=CollisionDetectionMode2D.Discrete; Ao=RigidbodySleepMode2D.StartAwake; ko=false; Oo=1; jo=new Vector2(NaN, NaN); zo=new Vector2(NaN, NaN); Eo=NaN; Lo=new Vector2; Uo=0; awake() { if (this.yo) return; const t = new BodyDef; t.userData = this; t.type = this.Mo; t.enabled = this.Ro; t.linearDamping = this.Fo; t.angularDamping = this.No; t.gravityScale = this.Bo; t.bullet = this.Po === CollisionDetectionMode2D.Continuous; t.allowSleep = this.Ao !== RigidbodySleepMode2D.NeverSleep; t.awake = this.Ao === RigidbodySleepMode2D.StartAwake || this.Ao === RigidbodySleepMode2D.NeverSleep; t.fixedRotation = this.ko; t.position.Set(this.transform.position.x, this.transform.position.y); t.angle = this.transform.eulerAngles.z; t.linearVelocity.Copy(this.Lo); t.angularVelocity = this.Uo; this.yo = this.engine.physics2DProcessor.addRigidBody(this.gameObject, this, t); this.Wo(); this.jr = this.yo.body; if (isNaN(this.jo.x)) { const t = this.jr.GetLocalCenter(); this.jo.set(t.x, t.y); } if (isNaN(this.Eo)) { this.Eo = this.jr.GetInertia(); } this.qo(); } onDestroy() { this.yo?.setSharedPhysicsMaterial(null); this.engine.physics2DProcessor.removeRigidBody(this.gameObject); this.yo = null; this.jr = null; this.Wo(); } onEnable() { this.Ro = true; this.Io().SetEnabled(true); this.Wo(); } onDisable() { this.Ro = false; this.jr?.SetEnabled(false); this.Wo(); } Wo() { if (!this.yo) return; const t = this.yo.colliders; for (let e = 0, i = t.length; e < i; ++e) { const i = t[e]; i.updateFixturesFilter(); } } Ko() { if (!this.yo) this.awake(); return this.yo; } Io() { if (!this.jr) this.awake(); return this.jr; } Go=new MassData; qo() { if (!this.jr) return; const t = this.Go; this.jr.GetMassData(t); if (!this.Vo) t.mass = this.So; t.center.Copy(this.jo); t.I = this.Eo; this.jr.SetMassData(t); } updateMass() { if (!this.jr) return; if (!this.Vo) return; const t = this.Go; this.jr.GetMassData(t); t.mass = this.So; this.jr.SetMassData(t); } get bodyType() { switch (this.Mo) { case BodyType.b2_staticBody: return RigidbodyType2D.Static; case BodyType.b2_kinematicBody: return RigidbodyType2D.Kinematic; case BodyType.b2_dynamicBody: return RigidbodyType2D.Dynamic; } throw new Error("Unknown body type"); } set bodyType(t) { switch (t) { case RigidbodyType2D.Dynamic: this.Mo = BodyType.b2_dynamicBody; break; case RigidbodyType2D.Kinematic: this.Mo = BodyType.b2_kinematicBody; break; case RigidbodyType2D.Static: this.Mo = BodyType.b2_staticBody; break; } } get material() { return this.Ko().sharedMaterial; } set material(t) { this.Ko().setSharedPhysicsMaterial(t); } get simulated() { return this.Ro; } set simulated(t) { this.enabled = t; } get useAutoMass() { return this.Vo; } set useAutoMass(t) { this.Vo = t; if (this.jr) { if (this.Vo) this.So = this.jr.GetMass(); } this.qo(); } get mass() { if (this.Vo) { return this.Io().GetMass(); } return this.So; } set mass(t) { if (this.Vo) throw new Error("Cannot set mass when useAutoMass is true"); this.So = t; this.qo(); } get drag() { return this.Fo; } set drag(t) { this.Fo = t; this.jr?.SetLinearDamping(t); } get angularDrag() { return this.No; } set angularDrag(t) { this.No = t; this.jr?.SetAngularDamping(t); } get gravityScale() { return this.Bo; } set gravityScale(t) { this.Bo = t; this.jr?.SetGravityScale(t); } get collisionDetection() { return this.Po; } set collisionDetection(t) { this.Po = t; this.jr?.SetBullet(t === CollisionDetectionMode2D.Continuous); } get sleepMode() { return this.Ao; } set sleepMode(t) { this.Ao = t; this.jr?.SetSleepingAllowed(t !== RigidbodySleepMode2D.NeverSleep); this.jr?.SetAwake(t === RigidbodySleepMode2D.StartAwake || t === RigidbodySleepMode2D.NeverSleep); } get freezeRotation() { return this.ko; } set freezeRotation(t) { this.ko = t; this.jr?.SetFixedRotation(t); } getLayerToName() { return this.engine.physics.collisionLayerMask.layerToName(this.Oo); } setLayerFromName(t) { this.Oo = this.engine.physics.collisionLayerMask.nameToLayer(t); this.Wo(); } get layer() { return this.Oo; } set layer(t) { this.Oo = t; this.Wo(); } get centerOfMass() { const t = this.Io().GetLocalCenter(); this.jo.set(t.x, t.y); return this.jo; } set centerOfMass(t) { this.jo.copy(t); this.qo(); } get worldCenterOfMass() { const t = this.Io().GetWorldCenter(); this.zo.set(t.x, t.y); return this.zo; } get inertia() { return this.Eo; } set inertia(t) { this.Eo = t; this.qo(); } get velocity() { if (this.jr) { const t = this.jr.GetLinearVelocity(); this.Lo.set(t.x, t.y); } return this.Lo; } set velocity(t) { this.Lo.copy(t); if (this.jr) { this.jr.SetLinearVelocity(t); } } get angularVelocity() { if (this.jr) { this.Uo = this.jr.GetAngularVelocity(); } return this.Uo; } set angularVelocity(t) { this.Uo = t; if (this.jr) { this.jr.SetAngularVelocity(t); } } get attachedColliderCount() { return this.Ko().colliders.length; } Ho=new Vec2; addForce(t, e = ForceMode2D.Force) { const i = this.Io(); if (e === ForceMode2D.Impulse) { i.ApplyLinearImpulse(t, i.GetWorldCenter(), true); } else { i.ApplyForce(t, i.GetWorldCenter(), true); } } addForceAtPosition(t, e, i = ForceMode2D.Force) { const s = this.Io(); const o = this.Ho.Copy(e); if (i === ForceMode2D.Impulse) { s.ApplyLinearImpulse(t, o, true); } else { s.ApplyForce(t, o, true); } } addRelativeForce(t, e = ForceMode2D.Force) { const i = this.Io(); const s = i.GetWorldVector(t, this.Ho); if (e === ForceMode2D.Impulse) { i.ApplyLinearImpulse(s, i.GetWorldCenter(), true); } else { i.ApplyForce(s, i.GetWorldCenter(), true); } } addTorque(t, e = ForceMode2D.Force) { const i = this.Io(); if (e === ForceMode2D.Impulse) { i.ApplyAngularImpulse(t, true); } else { i.ApplyTorque(t, true); } } getPoint(t, e) { const i = e ?? new Vector2; const s = this.Ho.Copy(t); return this.Io().GetLocalPoint(s, i); } getPointVelocity(t, e) { const i = e ?? new Vector2; const s = this.Ho.Copy(t); return this.Io().GetLinearVelocityFromWorldPoint(s, i); } getRelativePoint(t, e) { const i = e ?? new Vector2; const s = this.Ho.Copy(t); return this.Io().GetWorldPoint(s, i); } getRelativePointVelocity(t, e) { const i = e ?? new Vector2; const s = this.Ho.Copy(t); return this.Io().GetLinearVelocityFromWorldPoint(s, i); } getRelativeVector(t, e) { const i = e ?? new Vector2; return this.Io().GetWorldVector(t, i); } getVector(t, e) { const i = e ?? new Vector2; return this.Io().GetLocalVector(t, i); } getAttachedColliders(t) { const e = this.Ko().colliders; if (t.length < e.length) { t.length = e.length; } for (let i = 0; i < e.length; ++i) { t[i] = e[i]; } return e.length; } fi=new WorldManifold; getContacts(t) { let e = 0; const i = this.Io(); let s = i.GetContactList(); while (s) { const i = s; s = s.next; const o = i.contact.GetManifold(); for (let s = 0; s < o.pointCount; ++s) { if (!t[e]) t[e] = new ContactPoint2D; i.contact.GetWorldManifold(this.fi); t[e].setData(i.contact, o.points[s], this.fi.normal, this.fi.points[s], this.fi.separations[s]); e += 1; } } return e; } overlapPoint(t) { const e = this.Ho.Copy(t); let i = this.Io().GetFixtureList(); while (i) { if (i.TestPoint(e)) { return true; } i = i.GetNext(); } return false; } isSleeping() { return !this.Io().IsAwake(); } sleep() { this.Io().SetAwake(false); } isAwake() { return this.Io().IsAwake(); } wakeUp() { this.Io().SetAwake(true); } }