the-world-engine
Version:
three.js based, unity like game engine for browser
230 lines (219 loc) • 6.88 kB
JavaScript
import { b2Maybe, b2_lengthUnitsPerMeter } from "../common/b2_settings.js";
import { b2Vec2 } from "../common/b2_math.js";
import { b2AABB } from "../collision/b2_collision.js";
import { b2MassData } from "../collision/b2_shape.js";
export class b2Filter {
constructor() {
this.categoryBits = 1;
this.maskBits = 65535;
this.groupIndex = 0;
}
Clone() {
return (new b2Filter).Copy(this);
}
Copy(t) {
this.categoryBits = t.categoryBits;
this.maskBits = t.maskBits;
this.groupIndex = t.groupIndex || 0;
return this;
}
}
b2Filter.DEFAULT = new b2Filter;
export class b2FixtureDef {
constructor() {
this.userData = null;
this.friction = .2;
this.restitution = 0;
this.restitutionThreshold = 1 * b2_lengthUnitsPerMeter;
this.density = 0;
this.isSensor = false;
this.filter = new b2Filter;
}
}
export class b2FixtureProxy {
constructor(t, s) {
this.aabb = new b2AABB;
this.childIndex = 0;
this.fixture = t;
this.childIndex = s;
this.fixture.m_shape.ComputeAABB(this.aabb, this.fixture.m_body.GetTransform(), s);
this.treeNode = this.fixture.m_body.m_world.m_contactManager.m_broadPhase.CreateProxy(this.aabb, this);
}
Reset() {
this.fixture.m_body.m_world.m_contactManager.m_broadPhase.DestroyProxy(this.treeNode);
}
Touch() {
this.fixture.m_body.m_world.m_contactManager.m_broadPhase.TouchProxy(this.treeNode);
}
Synchronize(t, s) {
if (t === s) {
this.fixture.m_shape.ComputeAABB(this.aabb, t, this.childIndex);
this.fixture.m_body.m_world.m_contactManager.m_broadPhase.MoveProxy(this.treeNode, this.aabb, b2Vec2.ZERO);
} else {
const i = b2FixtureProxy.Synchronize_s_aabb1;
const e = b2FixtureProxy.Synchronize_s_aabb2;
this.fixture.m_shape.ComputeAABB(i, t, this.childIndex);
this.fixture.m_shape.ComputeAABB(e, s, this.childIndex);
this.aabb.Combine2(i, e);
const h = b2FixtureProxy.Synchronize_s_displacement;
h.Copy(e.GetCenter()).SelfSub(i.GetCenter());
this.fixture.m_body.m_world.m_contactManager.m_broadPhase.MoveProxy(this.treeNode, this.aabb, h);
}
}
}
b2FixtureProxy.Synchronize_s_aabb1 = new b2AABB;
b2FixtureProxy.Synchronize_s_aabb2 = new b2AABB;
b2FixtureProxy.Synchronize_s_displacement = new b2Vec2;
export class b2Fixture {
constructor(t, s) {
this.m_density = 0;
this.m_next = null;
this.m_friction = 0;
this.m_restitution = 0;
this.m_restitutionThreshold = 1 * b2_lengthUnitsPerMeter;
this.m_proxies = [];
this.m_filter = new b2Filter;
this.m_isSensor = false;
this.m_userData = null;
this.m_body = t;
this.m_shape = s.shape.Clone();
this.m_userData = b2Maybe(s.userData, null);
this.m_friction = b2Maybe(s.friction, .2);
this.m_restitution = b2Maybe(s.restitution, 0);
this.m_restitutionThreshold = b2Maybe(s.restitutionThreshold, 0);
this.m_filter.Copy(b2Maybe(s.filter, b2Filter.DEFAULT));
this.m_isSensor = b2Maybe(s.isSensor, false);
this.m_density = b2Maybe(s.density, 0);
}
get m_proxyCount() {
return this.m_proxies.length;
}
Reset() {}
GetType() {
return this.m_shape.GetType();
}
GetShape() {
return this.m_shape;
}
SetSensor(t) {
if (t !== this.m_isSensor) {
this.m_body.SetAwake(true);
this.m_isSensor = t;
}
}
IsSensor() {
return this.m_isSensor;
}
SetFilterData(t) {
this.m_filter.Copy(t);
this.Refilter();
}
GetFilterData() {
return this.m_filter;
}
Refilter() {
let t = this.m_body.GetContactList();
while (t) {
const s = t.contact;
const i = s.GetFixtureA();
const e = s.GetFixtureB();
if (i === this || e === this) {
s.FlagForFiltering();
}
t = t.next;
}
this.TouchProxies();
}
GetBody() {
return this.m_body;
}
GetNext() {
return this.m_next;
}
GetUserData() {
return this.m_userData;
}
SetUserData(t) {
this.m_userData = t;
}
TestPoint(t) {
return this.m_shape.TestPoint(this.m_body.GetTransform(), t);
}
ComputeDistance(t, s, i) {
return this.m_shape.ComputeDistance(this.m_body.GetTransform(), t, s, i);
}
RayCast(t, s, i) {
return this.m_shape.RayCast(t, s, this.m_body.GetTransform(), i);
}
GetMassData(t = new b2MassData) {
this.m_shape.ComputeMass(t, this.m_density);
return t;
}
SetDensity(t) {
this.m_density = t;
}
GetDensity() {
return this.m_density;
}
GetFriction() {
return this.m_friction;
}
SetFriction(t) {
this.m_friction = t;
}
GetRestitution() {
return this.m_restitution;
}
SetRestitution(t) {
this.m_restitution = t;
}
GetRestitutionThreshold() {
return this.m_restitutionThreshold;
}
SetRestitutionThreshold(t) {
this.m_restitutionThreshold = t;
}
GetAABB(t) {
return this.m_proxies[t].aabb;
}
Dump(t, s) {
t(" const fd: b2FixtureDef = new b2FixtureDef();\n");
t(" fd.friction = %.15f;\n", this.m_friction);
t(" fd.restitution = %.15f;\n", this.m_restitution);
t(" fd.restitutionThreshold = %.15f;\n", this.m_restitutionThreshold);
t(" fd.density = %.15f;\n", this.m_density);
t(" fd.isSensor = %s;\n", this.m_isSensor ? "true" : "false");
t(" fd.filter.categoryBits = %d;\n", this.m_filter.categoryBits);
t(" fd.filter.maskBits = %d;\n", this.m_filter.maskBits);
t(" fd.filter.groupIndex = %d;\n", this.m_filter.groupIndex);
this.m_shape.Dump(t);
t("\n");
t(" fd.shape = shape;\n");
t("\n");
t(" bodies[%d].CreateFixture(fd);\n", s);
}
CreateProxies() {
if (this.m_proxies.length !== 0) {
throw new Error;
}
for (let t = 0; t < this.m_shape.GetChildCount(); ++t) {
this.m_proxies[t] = new b2FixtureProxy(this, t);
}
}
DestroyProxies() {
for (const t of this.m_proxies) {
t.Reset();
}
this.m_proxies.length = 0;
}
TouchProxies() {
for (const t of this.m_proxies) {
t.Touch();
}
}
SynchronizeProxies(t, s) {
for (const i of this.m_proxies) {
i.Synchronize(t, s);
}
}
}