the-world-engine
Version:
three.js based, unity like game engine for browser
420 lines (404 loc) • 11.1 kB
JavaScript
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);
}
}