From 47e7edf95c3c256a1009e92dde80563c094a19a8 Mon Sep 17 00:00:00 2001 From: Ketmar Dark Date: Sun, 30 Oct 2016 10:20:54 +0200 Subject: [PATCH] even more cosmetix --- b2dlite.d | 31 +++-- xmain.d | 454 ++++++++++++++++++++++++++------------------------------------ 2 files changed, 212 insertions(+), 273 deletions(-) diff --git a/b2dlite.d b/b2dlite.d index 0d4e81c..a3f175d 100644 --- a/b2dlite.d +++ b/b2dlite.d @@ -362,20 +362,30 @@ public: Vec2[] verts; // vertices Vec2[] norms; // normals -public: +protected: this () @trusted { super(); computeMass(VFloatNum!1); } - static PolyBody Box() (in auto ref Vec2 width, VFloat density) { +public: + this (World w, const(Vec2)[] averts, VFloat adensity, scope void delegate (typeof(this) self) dg=null) { + super(); + set(averts, adensity); + if (dg !is null) dg(this); + if (w !is null) w ~= this; + } + + static PolyBody Box() (World w, in auto ref Vec2 size, VFloat density, scope void delegate (typeof(this) self, Vec2 size) dg=null) { auto res = new PolyBody(); - res.setBox(width); + res.setBox(size); res.computeMass(density); + if (dg !is null) dg(res, size); + if (w !is null) w ~= res; return res; } - void set() (const(Vec2)[] averts, VFloat m) { + void set() (const(Vec2)[] averts, VFloat adensity) { mPosition.set(VFloatNum!0, VFloatNum!0); mRotation = VFloatNum!0; velocity.set(VFloatNum!0, VFloatNum!0); @@ -384,7 +394,7 @@ public: torque = VFloatNum!0; friction = VFloatNum!(0.2); setVerts(averts); - computeMass(m); + computeMass(adensity); updateWorld(); } @@ -423,7 +433,7 @@ public: if (area > 0 && density < VFloat.max) { mass = density*area; invMass = VFloatNum!1/mass; - //i = mass*(width.x*width.x+width.y*width.y)/VFloatNum!12; + //i = mass*(size.x*size.x+size.y*size.y)/VFloatNum!12; i = I*density; invI = VFloatNum!1/i; } else { @@ -589,12 +599,17 @@ public: Vec2 r1, r2; Vec2 bias; Vec2 accimp = Vec2(0, 0); // accumulated impulse - BodyBase body0; - BodyBase body1; + BodyBase body0, body1; VFloat biasFactor = VFloatNum!(0.2); VFloat softness = VFloatNum!0; public: + this() (World w, BodyBase b0, BodyBase b1, in auto ref Vec2 anchor, scope void delegate (typeof(this) self) dg=null) { + set(b0, b1, anchor); + if (dg !is null) dg(this); + if (w !is null) w ~= this; + } + void set() (BodyBase b0, BodyBase b1, in auto ref Vec2 anchor) { body0 = b0; body1 = b1; diff --git a/xmain.d b/xmain.d index 80e025a..888ba86 100644 --- a/xmain.d +++ b/xmain.d @@ -57,6 +57,9 @@ __gshared int iterations = 10; __gshared Vec2 gravity = Vec2(VFloatNum!0, -VFloatNum!10); __gshared int demoIndex = 0; +__gshared string demoTitle; + +__gshared bool onlyOneBomb = false; __gshared World world; shared static this () { world = new World(gravity, iterations); } @@ -64,8 +67,7 @@ shared static this () { world = new World(gravity, iterations); } // ////////////////////////////////////////////////////////////////////////// // void launchBomb (SimpleWindow sdwin) { - if (true/*bomb is null*/) { - auto bb = new PolyBody(); + if (!onlyOneBomb || bomb is null) { Vec2[] vtx; foreach (int ang; 0..10) { import std.math : cos, sin; @@ -73,33 +75,28 @@ void launchBomb (SimpleWindow sdwin) { Vec2 v = Vec2(0.6*cos(deg2rad(360/10*ang))*uniform!"[]"(0.7, 1.3), 0.6*sin(deg2rad(360/10*ang))*uniform!"[]"(0.7, 1.3)); vtx ~= v; } - bb.set(vtx, 50); - bomb = bb; + bomb = new PolyBody(world, vtx, 50); //bomb = PolyBody.Box(Vec2(VFloatNum!1, VFloatNum!1), VFloatNum!50); bomb.friction = VFloatNum!(0.2); - //world ~= bomb; } bomb.setPosition(rnd(-VFloatNum!15, VFloatNum!15), VFloatNum!15); bomb.rotation = rnd(-VFloatNum!(1.5), VFloatNum!(1.5)); bomb.velocity = bomb.position*(-VFloatNum!(1.5)); bomb.angularVelocity = rnd(-VFloatNum!20, VFloatNum!20); - world ~= bomb; import std.format : format; - sdwin.title = "bodies: %s".format(world.bodies.length); + sdwin.title = "%s -- bodies: %s".format(demoTitle, world.bodies.length); } // ////////////////////////////////////////////////////////////////////////// // void drawBody (BodyBase bodyb) { if (auto booody = cast(PolyBody)bodyb) { - auto rmt = Mat22(booody.rotation); - if (booody is bomb) { glColor3f(VFloatNum!(0.4), VFloatNum!(0.9), VFloatNum!(0.4)); } else { glColor3f(VFloatNum!(0.8), VFloatNum!(0.8), VFloatNum!(0.9)); } - + auto rmt = Mat22(booody.rotation); glBegin(GL_LINE_LOOP); foreach (const ref vx; booody.verts) { auto vp = booody.position+rmt*vx; @@ -114,14 +111,14 @@ void drawJoint (Joint joint) { auto b1 = joint.body0; auto b2 = joint.body1; - auto R1 = Mat22(b1.rotation); - auto R2 = Mat22(b2.rotation); + auto r1 = Mat22(b1.rotation); + auto r2 = Mat22(b2.rotation); Vec2 x1 = b1.position; - Vec2 p1 = x1+R1*joint.localAnchor1; + Vec2 p1 = x1+r1*joint.localAnchor1; Vec2 x2 = b2.position; - Vec2 p2 = x2+R2*joint.localAnchor2; + Vec2 p2 = x2+r2*joint.localAnchor2; glColor3f(VFloatNum!(0.5), VFloatNum!(0.5), VFloatNum!(0.8)); glBegin(GL_LINES); @@ -133,6 +130,41 @@ void drawJoint (Joint joint) { } +void drawWorld () { + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glTranslatef(VFloatNum!0, -VFloatNum!7, -VFloatNum!25); + + // draw world + foreach (BodyBase b; world.bodies) b.drawBody(); + foreach (Joint j; world.joints) j.drawJoint(); + + // draw contacts + { + import iv.glbinds; + glPointSize(VFloatNum!4); + glColor3f(VFloatNum!1, VFloatNum!0, VFloatNum!0); + glBegin(GL_POINTS); + foreach (const ref cxy; contacts) glVertex2f(cxy.position.x, cxy.position.y); + glEnd(); + glPointSize(VFloatNum!1); + } + + if (optDrawBVH) { + // draw BVH + world.drawBVH((Vec2 min, Vec2 max) { + glColor3f(VFloatNum!1, VFloatNum!1, VFloatNum!0); + glBegin(GL_LINE_LOOP); + glVertex2f(min.x, min.y); + glVertex2f(max.x, min.y); + glVertex2f(max.x, max.y); + glVertex2f(min.x, max.y); + glEnd(); + }); + } +} + + // ////////////////////////////////////////////////////////////////////////// // // demos enum BoxW = VFloatNum!100; @@ -143,124 +175,112 @@ struct DemoInfo { string dsc; } // single box @DemoInfo("A Single Box") void demo1 () { - if (auto b = PolyBody.Box(Vec2(BoxW, BoxH), VFloat.max)) { - b.setPosition(VFloatNum!0, -VFloatNum!(0.5)*BoxH/*b.width.y*/); - world ~= b; - } - if (auto b = PolyBody.Box(Vec2(VFloatNum!1, VFloatNum!1), VFloatNum!200)) { + PolyBody.Box(world, Vec2(BoxW, BoxH), VFloat.max, (b, size) { + b.setPosition(VFloatNum!0, -VFloatNum!(0.5)*size.y); + }); + PolyBody.Box(world, Vec2(VFloatNum!1, VFloatNum!1), VFloatNum!200, (b, size) { b.setPosition(VFloatNum!0, VFloatNum!4); - world ~= b; - } + }); } // a simple pendulum @DemoInfo("Simple Pendulum") void demo2 () { - auto b1 = PolyBody.Box(Vec2(BoxW, BoxH), VFloat.max); - b1.friction = VFloatNum!(0.2); - b1.setPosition(VFloatNum!0, -VFloatNum!(0.5)*BoxH/*b1.width.y*/); - b1.rotation = VFloatNum!0; - world ~= b1; - - auto b2 = PolyBody.Box(Vec2(VFloatNum!1, VFloatNum!1), VFloatNum!100); - b2.friction = VFloatNum!(0.2); - b2.setPosition(VFloatNum!9, VFloatNum!11); - b2.rotation = VFloatNum!0; - world ~= b2; - - if (auto j = new Joint()) { - j.set(b1, b2, Vec2(VFloatNum!0, VFloatNum!11)); - world ~= j; - } + auto b1 = PolyBody.Box(world, Vec2(BoxW, BoxH), VFloat.max, (b, size) { + b.friction = VFloatNum!(0.2); + b.setPosition(VFloatNum!0, -VFloatNum!(0.5)*size.y); + b.rotation = VFloatNum!0; + }); + + auto b2 = PolyBody.Box(world, Vec2(VFloatNum!1, VFloatNum!1), VFloatNum!100, (b, size) { + b.friction = VFloatNum!(0.2); + b.setPosition(VFloatNum!9, VFloatNum!11); + b.rotation = VFloatNum!0; + }); + + new Joint(world, b1, b2, Vec2(VFloatNum!0, VFloatNum!11)); } // varying friction coefficients @DemoInfo("Varying Friction Coefficients") void demo3 () { - if (auto b = PolyBody.Box(Vec2(BoxW, BoxH), VFloat.max)) { - b.setPosition(VFloatNum!0, -VFloatNum!(0.5)*BoxH/*b.width.y*/); - world ~= b; - } + PolyBody.Box(world, Vec2(BoxW, BoxH), VFloat.max, (b, size) { + b.setPosition(VFloatNum!0, -VFloatNum!(0.5)*size.y); + }); - if (auto b = PolyBody.Box(Vec2(VFloatNum!13, VFloatNum!(0.25)), VFloat.max)) { + PolyBody.Box(world, Vec2(VFloatNum!13, VFloatNum!(0.25)), VFloat.max, (b, size) { b.setPosition(-VFloatNum!2, VFloatNum!11); b.rotation = -VFloatNum!(0.25); - world ~= b; - } + }); - if (auto b = PolyBody.Box(Vec2(VFloatNum!(0.25), VFloatNum!1), VFloat.max)) { + PolyBody.Box(world, Vec2(VFloatNum!(0.25), VFloatNum!1), VFloat.max, (b, size) { b.setPosition(VFloatNum!(5.25), VFloatNum!(9.5)); - world ~= b; - } + }); - if (auto b = PolyBody.Box(Vec2(VFloatNum!13, VFloatNum!(0.25)), VFloat.max)) { + PolyBody.Box(world, Vec2(VFloatNum!13, VFloatNum!(0.25)), VFloat.max, (b, size) { b.setPosition(VFloatNum!2, VFloatNum!7); b.rotation = VFloatNum!(0.25); - world ~= b; - } + }); - if (auto b = PolyBody.Box(Vec2(VFloatNum!(0.25), VFloatNum!1), VFloat.max)) { + PolyBody.Box(world, Vec2(VFloatNum!(0.25), VFloatNum!1), VFloat.max, (b, size) { b.setPosition(-VFloatNum!(5.25), VFloatNum!(5.5)); - world ~= b; - } + }); - if (auto b = PolyBody.Box(Vec2(VFloatNum!13, VFloatNum!(0.25)), VFloat.max)) { + PolyBody.Box(world, Vec2(VFloatNum!13, VFloatNum!(0.25)), VFloat.max, (b, size) { b.setPosition(-VFloatNum!2, VFloatNum!3); b.rotation = -VFloatNum!(0.25); - world ~= b; - } - - static immutable VFloat[5] frictions = [VFloatNum!(0.75), VFloatNum!(0.5), VFloatNum!(0.35), VFloatNum!(0.1), VFloatNum!0]; - for (int idx = 0; idx < 5; ++idx) { - if (auto b = PolyBody.Box(Vec2(VFloatNum!(0.5), VFloatNum!(0.5)), VFloatNum!25)) { - b.friction = frictions[idx]; - b.setPosition(-VFloatNum!(7.5)+VFloatNum!2*idx, VFloatNum!14); - world ~= b; - } + }); + + static immutable VFloat[5] frictions = [ + VFloatNum!(0.75), + VFloatNum!(0.5), + VFloatNum!(0.35), + VFloatNum!(0.1), + VFloatNum!0 + ]; + foreach (immutable idx, VFloat frc; frictions) { + PolyBody.Box(world, Vec2(VFloatNum!(0.5), VFloatNum!(0.5)), VFloatNum!25, (b, size) { + b.friction = frc; + b.setPosition(-VFloatNum!(7.5)+VFloatNum!2*cast(int)idx, VFloatNum!14); + }); } } // a vertical stack @DemoInfo("Randomized Stacking") void demo4 () { - if (auto b = PolyBody.Box(Vec2(BoxW, BoxH), VFloat.max)) { + PolyBody.Box(world, Vec2(BoxW, BoxH), VFloat.max, (b, size) { b.friction = VFloatNum!(0.2); - b.setPosition(VFloatNum!0, -VFloatNum!(0.5)*BoxH/*b.width.y*/); + b.setPosition(VFloatNum!0, -VFloatNum!(0.5)*size.y); b.rotation = VFloatNum!0; - world ~= b; - } + }); - for (int idx = 0; idx < 10; ++idx) { - if (auto b = PolyBody.Box(Vec2(VFloatNum!1, VFloatNum!1), VFloatNum!1)) { + foreach (int idx; 0..10) { + PolyBody.Box(world, Vec2(VFloatNum!1, VFloatNum!1), VFloatNum!1, (b, size) { b.friction = VFloatNum!(0.2); VFloat x = rnd(-VFloatNum!(0.1), VFloatNum!(0.1)); b.setPosition(x, VFloatNum!(0.51)+VFloatNum!(1.05)*idx); - world ~= b; - } + }); } } // a pyramid @DemoInfo("Pyramid Stacking") void demo5 () { - if (auto b = PolyBody.Box(Vec2(BoxW, BoxH), VFloat.max)) { + PolyBody.Box(world, Vec2(BoxW, BoxH), VFloat.max, (b, size) { b.friction = VFloatNum!(0.2); - b.setPosition(VFloatNum!0, -VFloatNum!(0.5)*BoxH/*b.width.y*/); + b.setPosition(VFloatNum!0, -VFloatNum!(0.5)*size.y); b.rotation = VFloatNum!0; - world ~= b; - } + }); Vec2 x = Vec2(-VFloatNum!6, VFloatNum!(0.75)); - Vec2 y; - - for (int idx = 0; idx < 12; ++idx) { - y = x; - for (int j = idx; j < 12; ++j) { - if (auto b = PolyBody.Box(Vec2(VFloatNum!1, VFloatNum!1), VFloatNum!10)) { + foreach (int idx; 0..12) { + auto y = x; + foreach (int j; idx..12) { + PolyBody.Box(world, Vec2(VFloatNum!1, VFloatNum!1), VFloatNum!10, (b, size) { b.friction = VFloatNum!(0.2); b.position = y; - world ~= b; - } + }); y += Vec2(VFloatNum!(1.125), VFloatNum!0); } //x += Vec2(VFloatNum!(0.5625), VFloatNum!(1.125)); @@ -271,30 +291,27 @@ struct DemoInfo { string dsc; } // a teeter @DemoInfo("A Teeter") void demo6 () { - BodyBase b1 = PolyBody.Box(Vec2(BoxW, BoxH), VFloat.max); - b1.setPosition(VFloatNum!0, -VFloatNum!(0.5)*BoxH/*b1.width.y*/); - world ~= b1; + auto b1 = PolyBody.Box(world, Vec2(BoxW, BoxH), VFloat.max, (b, size) { + b.setPosition(VFloatNum!0, -VFloatNum!(0.5)*size.y); + }); - BodyBase b2 = PolyBody.Box(Vec2(VFloatNum!12, VFloatNum!(0.25)), VFloatNum!100); - b2.setPosition(VFloatNum!0, VFloatNum!1); - world ~= b2; + auto b2 = PolyBody.Box(world, Vec2(VFloatNum!12, VFloatNum!(0.25)), VFloatNum!100, (b, size) { + b.setPosition(VFloatNum!0, VFloatNum!1); + }); - BodyBase b3 = PolyBody.Box(Vec2(VFloatNum!(0.5), VFloatNum!(0.5)), VFloatNum!25); - b3.setPosition(-VFloatNum!5, VFloatNum!2); - world ~= b3; + new Joint(world, b1, b2, Vec2(VFloatNum!0, VFloatNum!1)); - BodyBase b4 = PolyBody.Box(Vec2(VFloatNum!(0.5), VFloatNum!(0.5)), VFloatNum!25); - b4.setPosition(-VFloatNum!(5.5), VFloatNum!2); - world ~= b4; + PolyBody.Box(world, Vec2(VFloatNum!(0.5), VFloatNum!(0.5)), VFloatNum!25, (b, size) { + b.setPosition(-VFloatNum!5, VFloatNum!2); + }); - BodyBase b5 = PolyBody.Box(Vec2(VFloatNum!1, VFloatNum!1), VFloatNum!100); - b5.setPosition(VFloatNum!(5.5), VFloatNum!15); - world ~= b5; + PolyBody.Box(world, Vec2(VFloatNum!(0.5), VFloatNum!(0.5)), VFloatNum!25, (b, size) { + b.setPosition(-VFloatNum!(5.5), VFloatNum!2); + }); - if (auto j = new Joint()) { - j.set(b1, b2, Vec2(VFloatNum!0, VFloatNum!1)); - world ~= j; - } + PolyBody.Box(world, Vec2(VFloatNum!1, VFloatNum!1), VFloatNum!100, (b, size) { + b.setPosition(VFloatNum!(5.5), VFloatNum!15); + }); } @@ -302,123 +319,99 @@ struct DemoInfo { string dsc; } @DemoInfo("A Suspension Bridge") void demo7 () { import std.math : PI; - if (auto b = PolyBody.Box(Vec2(BoxW, BoxH), VFloat.max)) { + PolyBody.Box(world, Vec2(BoxW, BoxH), VFloat.max, (b, size) { b.friction = VFloatNum!(0.2); - b.setPosition(VFloatNum!0, -VFloatNum!(0.5)*BoxH/*b.width.y*/); + b.setPosition(VFloatNum!0, -VFloatNum!(0.5)*size.y); b.rotation = VFloatNum!0; - world ~= b; - } + }); enum numPlanks = 15; VFloat mass = VFloatNum!50; - - for (int idx = 0; idx < numPlanks; ++idx) { - auto b = PolyBody.Box(Vec2(VFloatNum!1, VFloatNum!(0.25)), mass); - b.friction = VFloatNum!(0.2); - b.setPosition(-VFloatNum!(8.5)+VFloatNum!(1.25)*idx, VFloatNum!5); - world ~= b; + foreach (int idx; 0..numPlanks) { + PolyBody.Box(world, Vec2(VFloatNum!1, VFloatNum!(0.25)), mass, (b, size) { + b.friction = VFloatNum!(0.2); + b.setPosition(-VFloatNum!(8.5)+VFloatNum!(1.25)*idx, VFloatNum!5); + }); } // tuning VFloat frequencyHz = VFloatNum!2; VFloat dampingRatio = VFloatNum!(0.7); - // frequency in radians VFloat omega = VFloatNum!2*PI*frequencyHz; - // damping coefficient VFloat d = VFloatNum!2*mass*dampingRatio*omega; - // spring stifness VFloat k = mass*omega*omega; - // magic formulas VFloat softnesss = VFloatNum!1/(d+timeStep*k); VFloat biasFactorr = timeStep*k/(d+timeStep*k); - for (int idx = 0; idx < numPlanks; ++idx) { - auto j = new Joint(); - j.set(world.bodies[idx], world.bodies[idx+1], Vec2(-VFloatNum!(9.125)+VFloatNum!(1.25)*idx, VFloatNum!5)); - j.softness = softnesss; - j.biasFactor = biasFactorr; - world ~= j; + foreach (int idx; 0..numPlanks) { + new Joint(world, world.bodies[idx], world.bodies[idx+1], Vec2(-VFloatNum!(9.125)+VFloatNum!(1.25)*idx, VFloatNum!5), (j) { + j.softness = softnesss; + j.biasFactor = biasFactorr; + }); } - if (auto j = new Joint()) { - j.set(world.bodies[numPlanks], world.bodies[0], Vec2(-VFloatNum!(9.125)+VFloatNum!(1.25)*numPlanks, VFloatNum!5)); + new Joint(world, world.bodies[numPlanks], world.bodies[0], Vec2(-VFloatNum!(9.125)+VFloatNum!(1.25)*numPlanks, VFloatNum!5), (j) { j.softness = softnesss; j.biasFactor = biasFactorr; - world ~= j; - } + }); } // dominos @DemoInfo("Dominos") void demo8 () { - BodyBase b1 = PolyBody.Box(Vec2(BoxW, BoxH), VFloat.max); - b1.setPosition(VFloatNum!0, -VFloatNum!(0.5)*BoxH/*b1.width.y*/); - world ~= b1; + auto b1 = PolyBody.Box(world, Vec2(BoxW, BoxH), VFloat.max, (b, size) { + b.setPosition(VFloatNum!0, -VFloatNum!(0.5)*size.y); + }); - if (auto b = PolyBody.Box(Vec2(VFloatNum!12, VFloatNum!(0.5)), VFloat.max)) { + PolyBody.Box(world, Vec2(VFloatNum!12, VFloatNum!(0.5)), VFloat.max, (b, size) { b.setPosition(-VFloatNum!(1.5), VFloatNum!10); - world ~= b; - } + }); - for (int idx = 0; idx < 10; ++idx) { - if (auto b = PolyBody.Box(Vec2(VFloatNum!(0.2), VFloatNum!2), VFloatNum!100)) { + foreach (int idx; 0..10) { + PolyBody.Box(world, Vec2(VFloatNum!(0.2), VFloatNum!2), VFloatNum!100, (b, size) { b.setPosition(-VFloatNum!6+VFloatNum!1*idx, VFloatNum!(11.125)); b.friction = VFloatNum!(0.1); - world ~= b; - } + }); } - if (auto b = PolyBody.Box(Vec2(VFloatNum!14, VFloatNum!(0.5)), VFloat.max)) { + PolyBody.Box(world, Vec2(VFloatNum!14, VFloatNum!(0.5)), VFloat.max, (b, size) { b.setPosition(VFloatNum!1, VFloatNum!6); b.rotation = VFloatNum!(0.3); - world ~= b; - } + }); - BodyBase b2 = PolyBody.Box(Vec2(VFloatNum!(0.5), VFloatNum!3), VFloat.max); - b2.setPosition(-VFloatNum!7, VFloatNum!4); - world ~= b2; + auto b2 = PolyBody.Box(world, Vec2(VFloatNum!(0.5), VFloatNum!3), VFloat.max, (b, size) { + b.setPosition(-VFloatNum!7, VFloatNum!4); + }); - BodyBase b3 = PolyBody.Box(Vec2(VFloatNum!12, VFloatNum!(0.25)), VFloatNum!20); - b3.setPosition(-VFloatNum!(0.9), VFloatNum!1); - world ~= b3; + auto b3 = PolyBody.Box(world, Vec2(VFloatNum!12, VFloatNum!(0.25)), VFloatNum!20, (b, size) { + b.setPosition(-VFloatNum!(0.9), VFloatNum!1); + }); - if (auto j = new Joint()) { - j.set(b1, b3, Vec2(-VFloatNum!2, VFloatNum!1)); - world ~= j; - } + new Joint(world, b1, b3, Vec2(-VFloatNum!2, VFloatNum!1)); - BodyBase b4 = PolyBody.Box(Vec2(VFloatNum!(0.5), VFloatNum!(0.5)), VFloatNum!10); - b4.setPosition(-VFloatNum!10, VFloatNum!15); - world ~= b4; + auto b4 = PolyBody.Box(world, Vec2(VFloatNum!(0.5), VFloatNum!(0.5)), VFloatNum!10, (b, size) { + b.setPosition(-VFloatNum!10, VFloatNum!15); + }); - if (auto j = new Joint()) { - j.set(b2, b4, Vec2(-VFloatNum!7, VFloatNum!15)); - world ~= j; - } + new Joint(world, b2, b4, Vec2(-VFloatNum!7, VFloatNum!15)); - BodyBase b5 = PolyBody.Box(Vec2(VFloatNum!2, VFloatNum!2), VFloatNum!12); - b5.setPosition(VFloatNum!6, VFloatNum!(2.5)); - b5.friction = VFloatNum!(0.1); - world ~= b5; + auto b5 = PolyBody.Box(world, Vec2(VFloatNum!2, VFloatNum!2), VFloatNum!12, (b, size) { + b.setPosition(VFloatNum!6, VFloatNum!(2.5)); + b.friction = VFloatNum!(0.1); + }); - if (auto j = new Joint()) { - j.set(b1, b5, Vec2(VFloatNum!6, VFloatNum!(2.6))); - world ~= j; - } + new Joint(world, b1, b5, Vec2(VFloatNum!6, VFloatNum!(2.6))); // box cap - BodyBase b6 = PolyBody.Box(Vec2(VFloatNum!2, VFloatNum!(0.2)), VFloatNum!10); - b6.setPosition(VFloatNum!6, VFloatNum!(3.6)); - world ~= b6; + auto b6 = PolyBody.Box(world, Vec2(VFloatNum!2, VFloatNum!(0.2)), VFloatNum!10, (b, size) { + b.setPosition(VFloatNum!6, VFloatNum!(3.6)); + }); - if (auto j = new Joint()) { - j.set(b5, b6, Vec2(VFloatNum!7, VFloatNum!(3.5))); - world ~= j; - } + new Joint(world, b5, b6, Vec2(VFloatNum!7, VFloatNum!(3.5))); } @@ -426,47 +419,40 @@ struct DemoInfo { string dsc; } @DemoInfo("Multi-pendulum") void demo9 () { import std.math : PI; - BodyBase b1 = PolyBody.Box(Vec2(BoxW, BoxH), VFloat.max); - b1.friction = VFloatNum!(0.2); - b1.setPosition(VFloatNum!0, -VFloatNum!(0.5)*BoxH/*b1.width.y*/); - b1.rotation = VFloatNum!0; - world ~= b1; + auto b1 = PolyBody.Box(world, Vec2(BoxW, BoxH), VFloat.max, (b, size) { + b.friction = VFloatNum!(0.2); + b.setPosition(VFloatNum!0, -VFloatNum!(0.5)*size.y); + b.rotation = VFloatNum!0; + }); - VFloat mass = VFloatNum!10; + enum VFloat mass = VFloatNum!10; // tuning - VFloat frequencyHz = VFloatNum!4; - VFloat dampingRatio = VFloatNum!(0.7); - + enum VFloat frequencyHz = VFloatNum!4; + enum VFloat dampingRatio = VFloatNum!(0.7); // frequency in radians - VFloat omega = VFloatNum!2*PI*frequencyHz; - + enum VFloat omega = VFloatNum!2*PI*frequencyHz; // damping coefficient - VFloat d = VFloatNum!2*mass*dampingRatio*omega; - + enum VFloat d = VFloatNum!2*mass*dampingRatio*omega; // spring stiffness - VFloat k = mass*omega*omega; - + enum VFloat k = mass*omega*omega; // magic formulas VFloat softnesss = VFloatNum!1/(d+timeStep*k); VFloat biasFactorr = timeStep*k/(d+timeStep*k); - const VFloat y = VFloatNum!12; - - for (int idx = 0; idx < 15; ++idx) { - Vec2 x = Vec2(VFloatNum!(0.5)+idx, y); - auto b = PolyBody.Box(Vec2(VFloatNum!(0.75), VFloatNum!(0.25)), mass); - b.friction = VFloatNum!(0.2); - b.position = x; - b.rotation = VFloatNum!0; - world ~= b; + enum VFloat y = VFloatNum!12; + foreach (int idx; 0..15) { + auto x = Vec2(VFloatNum!(0.5)+idx, y); + auto b = PolyBody.Box(world, Vec2(VFloatNum!(0.75), VFloatNum!(0.25)), mass, (b, size) { + b.friction = VFloatNum!(0.2); + b.position = x; + b.rotation = VFloatNum!0; + }); - if (auto j = new Joint()) { - j.set(b1, b, Vec2(idx, y)); + new Joint(world, b1, b, Vec2(idx, y), (j) { j.softness = softnesss; j.biasFactor = biasFactorr; - world ~= j; - } + }); b1 = b; } @@ -485,7 +471,8 @@ bool setupDemo (int index, SimpleWindow w) { alias sms = getSymbolsByUDA!(mixin(__MODULE__), DemoInfo); foreach (immutable idx, const memb; sms) { if (index == idx) { - w.title = getUDAs!(memb, DemoInfo)[0].dsc; + demoTitle = getUDAs!(memb, DemoInfo)[0].dsc; + w.title = demoTitle; world.clear(); bomb = null; memb(); @@ -498,65 +485,11 @@ bool setupDemo (int index, SimpleWindow w) { // ////////////////////////////////////////////////////////////////////////// // -void drawWorld () { - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - glTranslatef(VFloatNum!0, -VFloatNum!7, -VFloatNum!25); - - // draw world - foreach (BodyBase b; world.bodies) b.drawBody(); - foreach (Joint j; world.joints) j.drawJoint(); - - // draw contacts - { - import iv.glbinds; - glPointSize(VFloatNum!4); - glColor3f(VFloatNum!1, VFloatNum!0, VFloatNum!0); - glBegin(GL_POINTS); - foreach (const ref cxy; contacts) glVertex2f(cxy.position.x, cxy.position.y); - glEnd(); - glPointSize(VFloatNum!1); - } - - if (optDrawBVH) { - // draw BVH - world.drawBVH((Vec2 min, Vec2 max) { - glColor3f(VFloatNum!1, VFloatNum!1, VFloatNum!0); - glBegin(GL_LINE_LOOP); - glVertex2f(min.x, min.y); - glVertex2f(max.x, min.y); - glVertex2f(max.x, max.y); - glVertex2f(min.x, max.y); - glEnd(); - }); - } -} - - -// ////////////////////////////////////////////////////////////////////////// // void simulationStep (SimpleWindow sdwin) { static double accumulator = 0; glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); - /* - char[128] buf; - - snprintf(buf, sizeof(buf), "Demo %d: %s", demoIndex+1, demos[demoIndex].name); - DrawText(5, 15, buf); - DrawText(5, 45, "Keys: 1-9 Demos, Space to Launch the Bomb"); - - static char buffer[512]; - sprintf(buffer, "(A)ccumulation %s", (World::accumulateImpulses ? "ON" : "OFF")); - DrawText(5, 75, buffer); - - sprintf(buffer, "(P)osition Correction %s", (World::positionCorrection ? "ON" : "OFF")); - DrawText(5, 105, buffer); - - sprintf(buffer, "(W)arm Starting %s", (World::warmStarting ? "ON" : "OFF")); - DrawText(5, 135, buffer); - */ - glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glTranslatef(VFloatNum!0, -VFloatNum!7, -VFloatNum!25); @@ -598,8 +531,6 @@ void main () { auto sdwin = new SimpleWindow(GWidth, GHeight, "Box2DLite Physics", OpenGlOptions.yes, Resizablity.fixedSize); //sdwin.hideCursor(); - //sdwin.closeQuery = delegate () { concmd("quit"); }; - sdwin.redrawOpenGlScene = delegate () { glClear(GL_COLOR_BUFFER_BIT); drawWorld(); @@ -609,14 +540,6 @@ void main () { showOpts(); setupDemo(0, sdwin); sdwin.setAsCurrentOpenGlContext(); // make this window active - // init matrices - /* - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - glOrtho(0, GWidth, GHeight, 0, -1, 1); - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - */ glViewport(0, 0, GWidth, GHeight); glMatrixMode(GL_PROJECTION); glLoadIdentity(); @@ -669,6 +592,7 @@ void main () { if (ch == 'z') { doOneStep = true; return; } if (ch == 'T') { optShowTimes = !optShowTimes; return; } if (ch == 'A') { optDrawBVH = !optDrawBVH; return; } + if (ch == 'O') { onlyOneBomb = !onlyOneBomb; return; } }, ); } -- 2.11.4.GIT