From 1af158dc2c63e04cca4b59b61179c4c81587310d Mon Sep 17 00:00:00 2001 From: Ketmar Dark Date: Mon, 24 Oct 2016 00:49:51 +0300 Subject: [PATCH] more cosmetix --- b2dlite.d | 199 +++++++++++++++++++++++++++++++------------------------------- 1 file changed, 99 insertions(+), 100 deletions(-) diff --git a/b2dlite.d b/b2dlite.d index 8c4af35..fd97a3e 100644 --- a/b2dlite.d +++ b/b2dlite.d @@ -72,6 +72,99 @@ private Vec2 fcross() (VFloat s, in auto ref Vec2 a) { pragma(inline, true); ret // ////////////////////////////////////////////////////////////////////////// // +// world +public class World { +private: + static struct ArbiterKey { + // pointers, actually + Body body0; + Body body1; + this (Body b0, Body b1) { if (b0 < b1) { body0 = b0; body1 = b1; } else { body0 = b1; body1 = b0; } } + } + +public: + Body[] bodies; + Joint[] joints; + Arbiter[ArbiterKey] arbiters; + Vec2 gravity; + int iterations; + Arbiter xarb; // temporary + + // the following are world options + static bool accumulateImpulses = true; + static bool warmStarting = true; + static bool positionCorrection = true; + +public: + this() (in auto ref Vec2 agravity, int aiterations) { + gravity = agravity; + iterations = aiterations; + xarb = new Arbiter(); + } + + void add (Body bbody) { + if (bbody !is null) bodies ~= bbody; + } + + void add (Joint joint) { + if (joint !is null) joints ~= joint; + } + + void opOpAssign(string op:"~", T) (T v) if (is(T : Body) || is(T : Joint)) { + add(v); + } + + void clear () { + bodies = null; + joints = null; + arbiters.clear(); + } + + void step (VFloat dt) { + VFloat invDt = (dt > VFloatNum!(0.0) ? VFloatNum!(1.0)/dt : VFloatNum!(0.0)); + // determine overlapping bodies and update contact points + broadPhase(); + // integrate forces + foreach (Body b; bodies) { + if (b.invMass == VFloatNum!(0.0)) continue; + b.velocity += (gravity+b.force*b.invMass)*dt; + b.angularVelocity += dt*b.invI*b.torque; + } + // perform pre-steps + foreach (Arbiter arb; arbiters.byValue) arb.preStep(invDt); + for (int idx = 0; idx < joints.length; ++idx) joints[idx].preStep(invDt); + // perform iterations + foreach (immutable itnum; 0..iterations) { + foreach (Arbiter arb; arbiters.byValue) arb.applyImpulse(); + foreach (Joint j; joints) j.applyImpulse(); + } + // integrate velocities + foreach (Body b; bodies) { + b.position += b.velocity*dt; + b.rotation += b.angularVelocity*dt; + + b.force.set(VFloatNum!(0.0), VFloatNum!(0.0)); + b.torque = VFloatNum!(0.0); + } + } + + void broadPhase () { + // O(n^2) broad-phase + foreach (immutable idx, Body bi; bodies) { + foreach (Body bj; bodies[idx+1..$]) { + if (bi.invMass == VFloatNum!(0.0) && bj.invMass == VFloatNum!(0.0)) continue; + if (auto arb = ArbiterKey(bi, bj) in arbiters) { + xarb.setup(bi, bj); + arb.update(xarb.contacts.ptr, xarb.numContacts); + } else { + arbiters[ArbiterKey(bi, bj)] = new Arbiter(bi, bj); + } + } + } + } +} + +// ////////////////////////////////////////////////////////////////////////// // // body public class Body { private: @@ -289,10 +382,10 @@ public: // ////////////////////////////////////////////////////////////////////////// // private class Arbiter { public: - enum MAX_POINTS = 2; + enum MaxContactPoints = 2; public: - Contact[MAX_POINTS] contacts; + Contact[MaxContactPoints] contacts; int numContacts; Body body0; @@ -322,7 +415,7 @@ public: } void update (Contact* newContacts, int numNewContacts) { - Contact[MAX_POINTS] mergedContacts; + Contact[MaxContactPoints] mergedContacts; assert(numNewContacts >= 0 && numNewContacts <= mergedContacts.length); foreach (immutable idx; 0..numNewContacts) { Contact* cNew = newContacts+idx; @@ -354,8 +447,8 @@ public: void preStep (VFloat invDt) { import std.algorithm : min; - enum k_allowedPenetration = VFloatNum!(0.01); - VFloat k_biasFactor = (World.positionCorrection ? VFloatNum!(0.2) : VFloatNum!(0.0)); + enum AllowedPenetration = VFloatNum!(0.01); + immutable VFloat biasFactor = (World.positionCorrection ? VFloatNum!(0.2) : VFloatNum!(0.0)); foreach (immutable idx; 0..numContacts) { Contact *c = contacts.ptr+idx; Vec2 r1 = c.position-body0.position; @@ -378,7 +471,7 @@ public: kTangent += body0.invI*((r1*r1)-rt1*rt1)+body1.invI*((r2*r2)-rt2*rt2); c.massTangent = VFloatNum!(1.0)/kTangent; - c.bias = -k_biasFactor*invDt*min(VFloatNum!(0.0), c.separation+k_allowedPenetration); + c.bias = -biasFactor*invDt*min(VFloatNum!(0.0), c.separation+AllowedPenetration); if (World.accumulateImpulses) { // apply normal + friction impulse @@ -750,97 +843,3 @@ private int collide (Contact* contacts, Body bodyA, Body bodyB) { return numContacts; } - - -// ////////////////////////////////////////////////////////////////////////// // -// world -public class World { -private: - static struct ArbiterKey { - // pointers, actually - Body body0; - Body body1; - this (Body b0, Body b1) { if (b0 < b1) { body0 = b0; body1 = b1; } else { body0 = b1; body1 = b0; } } - } - -public: - Body[] bodies; - Joint[] joints; - Arbiter[ArbiterKey] arbiters; - Vec2 gravity; - int iterations; - Arbiter xarb; // temporary - - // the following are world options - static bool accumulateImpulses = true; - static bool warmStarting = true; - static bool positionCorrection = true; - -public: - this() (in auto ref Vec2 agravity, int aiterations) { - gravity = agravity; - iterations = aiterations; - xarb = new Arbiter(); - } - - void add (Body bbody) { - if (bbody !is null) bodies ~= bbody; - } - - void add (Joint joint) { - if (joint !is null) joints ~= joint; - } - - void opOpAssign(string op:"~", T) (T v) if (is(T : Body) || is(T : Joint)) { - add(v); - } - - void clear () { - bodies = null; - joints = null; - arbiters.clear(); - } - - void step (VFloat dt) { - VFloat invDt = (dt > VFloatNum!(0.0) ? VFloatNum!(1.0)/dt : VFloatNum!(0.0)); - // determine overlapping bodies and update contact points - broadPhase(); - // integrate forces - foreach (Body b; bodies) { - if (b.invMass == VFloatNum!(0.0)) continue; - b.velocity += (gravity+b.force*b.invMass)*dt; - b.angularVelocity += dt*b.invI*b.torque; - } - // perform pre-steps - foreach (Arbiter arb; arbiters.byValue) arb.preStep(invDt); - for (int idx = 0; idx < joints.length; ++idx) joints[idx].preStep(invDt); - // perform iterations - foreach (immutable itnum; 0..iterations) { - foreach (Arbiter arb; arbiters.byValue) arb.applyImpulse(); - foreach (Joint j; joints) j.applyImpulse(); - } - // integrate velocities - foreach (Body b; bodies) { - b.position += b.velocity*dt; - b.rotation += b.angularVelocity*dt; - - b.force.set(VFloatNum!(0.0), VFloatNum!(0.0)); - b.torque = VFloatNum!(0.0); - } - } - - void broadPhase () { - // O(n^2) broad-phase - foreach (immutable idx, Body bi; bodies) { - foreach (Body bj; bodies[idx+1..$]) { - if (bi.invMass == VFloatNum!(0.0) && bj.invMass == VFloatNum!(0.0)) continue; - if (auto arb = ArbiterKey(bi, bj) in arbiters) { - xarb.setup(bi, bj); - arb.update(xarb.contacts.ptr, xarb.numContacts); - } else { - arbiters[ArbiterKey(bi, bj)] = new Arbiter(bi, bj); - } - } - } - } -} -- 2.11.4.GIT