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