mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-08-25 14:22:54 -06:00
*examples: Finished box2d example, now interacting with shapes is possible
git-svn-id: svn://ultimatepp.org/upp/trunk@2588 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
parent
fa2c8124f9
commit
115a94609c
1 changed files with 83 additions and 108 deletions
|
|
@ -5,10 +5,11 @@ using namespace Upp;
|
|||
|
||||
struct QueryCallback : b2QueryCallback
|
||||
{
|
||||
|
||||
QueryCallback(const b2Vec2& point)
|
||||
{
|
||||
m_point = point;
|
||||
m_fixture = NULL;
|
||||
this->point = point;
|
||||
fixture = NULL;
|
||||
}
|
||||
|
||||
bool ReportFixture(b2Fixture* fixture)
|
||||
|
|
@ -16,10 +17,10 @@ struct QueryCallback : b2QueryCallback
|
|||
b2Body* body = fixture->GetBody();
|
||||
if (body->GetType() == b2_dynamicBody)
|
||||
{
|
||||
bool inside = fixture->TestPoint(m_point);
|
||||
bool inside = fixture->TestPoint(point);
|
||||
if (inside)
|
||||
{
|
||||
m_fixture = fixture;
|
||||
this->fixture = fixture;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -27,8 +28,8 @@ struct QueryCallback : b2QueryCallback
|
|||
return true;
|
||||
}
|
||||
|
||||
b2Vec2 m_point;
|
||||
b2Fixture* m_fixture;
|
||||
b2Vec2 point;
|
||||
b2Fixture* fixture;
|
||||
};
|
||||
|
||||
struct DebugDraw : b2DebugDraw
|
||||
|
|
@ -37,6 +38,7 @@ struct DebugDraw : b2DebugDraw
|
|||
Sizef sz;
|
||||
float cx, cy;
|
||||
float aspect;
|
||||
float zoom;
|
||||
|
||||
void DrawPolygon(const b2Vec2* v, int vertexCount, const b2Color& color)
|
||||
{
|
||||
|
|
@ -120,43 +122,39 @@ struct DebugDraw : b2DebugDraw
|
|||
|
||||
struct App : TopWindow
|
||||
{
|
||||
b2Body* m_middle;
|
||||
b2World* m_world;
|
||||
b2MouseJoint* m_mouseJoint;
|
||||
DebugDraw m_debugDraw;
|
||||
b2Vec2 m_mouseWorld;
|
||||
b2Body* m_groundBody;
|
||||
b2AABB m_worldAABB;
|
||||
b2World world;
|
||||
b2MouseJoint* mouseJoint;
|
||||
DebugDraw debugDraw;
|
||||
b2Vec2 mouseWorld;
|
||||
b2Body* groundBody;
|
||||
|
||||
typedef App CLASSNAME;
|
||||
|
||||
App()
|
||||
App() : world(b2Vec2(0.0, -10.0), true)
|
||||
{
|
||||
Title("Box2D Example");
|
||||
SetRectX(0, 640);
|
||||
SetRectY(0, 480);
|
||||
Sizeable().Zoomable();
|
||||
Bridge();
|
||||
SetTimeCallback(-10, THISBACK(Render0));
|
||||
BackPaint();
|
||||
m_mouseJoint = NULL;
|
||||
}
|
||||
~App()
|
||||
{
|
||||
delete m_world;
|
||||
SetTimeCallback(-10, THISBACK(Render));
|
||||
mouseJoint = NULL;
|
||||
b2Vec2 gravity;
|
||||
gravity.Set(0.0f, -10.0f);
|
||||
world.SetGravity(gravity);
|
||||
world.SetDebugDraw(&debugDraw);
|
||||
b2BodyDef bodyDef;
|
||||
groundBody = world.CreateBody(&bodyDef);
|
||||
debugDraw.zoom = 15.0f;
|
||||
Bridge();
|
||||
}
|
||||
|
||||
void Bridge()
|
||||
{
|
||||
const int e_count = 30;
|
||||
b2Vec2 gravity;
|
||||
gravity.Set(0.0f, -10.0f);
|
||||
|
||||
bool doSleep = true;
|
||||
|
||||
m_world = new b2World(gravity, doSleep);
|
||||
m_world->SetDebugDraw(&m_debugDraw);
|
||||
|
||||
const int ecount = 30;
|
||||
|
||||
b2BodyDef bd;
|
||||
b2Body* ground = m_world->CreateBody(&bd);
|
||||
b2Body* ground = world.CreateBody(&bd);
|
||||
|
||||
b2PolygonShape shape;
|
||||
shape.SetAsEdge(b2Vec2(-40.0f, 0.0f), b2Vec2(40.0f, 0.0f));
|
||||
|
|
@ -172,28 +170,24 @@ struct App : TopWindow
|
|||
b2RevoluteJointDef jd;
|
||||
|
||||
b2Body* prevBody = ground;
|
||||
for(int i = 0; i < e_count; ++i)
|
||||
for(int i = 0; i < ecount; ++i)
|
||||
{
|
||||
b2BodyDef bd;
|
||||
bd.type = b2_dynamicBody;
|
||||
bd.position.Set(-14.5f + 1.0f * i, 5.0f);
|
||||
b2Body* body = m_world->CreateBody(&bd);
|
||||
b2Body* body = world.CreateBody(&bd);
|
||||
body->CreateFixture(&fd);
|
||||
|
||||
b2Vec2 anchor(-15.0f + 1.0f * i, 5.0f);
|
||||
jd.Initialize(prevBody, body, anchor);
|
||||
m_world->CreateJoint(&jd);
|
||||
world.CreateJoint(&jd);
|
||||
|
||||
if (i == (e_count >> 1))
|
||||
{
|
||||
m_middle = body;
|
||||
}
|
||||
prevBody = body;
|
||||
}
|
||||
|
||||
b2Vec2 anchor(-15.0f + 1.0f * e_count, 5.0f);
|
||||
b2Vec2 anchor(-15.0f + 1.0f * ecount, 5.0f);
|
||||
jd.Initialize(prevBody, ground, anchor);
|
||||
m_world->CreateJoint(&jd);
|
||||
world.CreateJoint(&jd);
|
||||
|
||||
for(int i = 0; i < 2; ++i)
|
||||
{
|
||||
|
|
@ -212,7 +206,7 @@ struct App : TopWindow
|
|||
b2BodyDef bd;
|
||||
bd.type = b2_dynamicBody;
|
||||
bd.position.Set(-8.0f + 8.0f * i, 12.0f);
|
||||
b2Body* body = m_world->CreateBody(&bd);
|
||||
b2Body* body = world.CreateBody(&bd);
|
||||
body->CreateFixture(&fd);
|
||||
}
|
||||
|
||||
|
|
@ -228,76 +222,57 @@ struct App : TopWindow
|
|||
b2BodyDef bd;
|
||||
bd.type = b2_dynamicBody;
|
||||
bd.position.Set(-6.0f + 6.0f * i, 10.0f);
|
||||
b2Body* body = m_world->CreateBody(&bd);
|
||||
b2Body* body = world.CreateBody(&bd);
|
||||
body->CreateFixture(&fd);
|
||||
}
|
||||
}
|
||||
|
||||
void Step(float hz = 60, int velocityIterations = 8, int positionIterations = 3)
|
||||
{
|
||||
float32 timeStep = 1.0f / hz;
|
||||
|
||||
int flags = 0;
|
||||
flags += b2DebugDraw::e_shapeBit;
|
||||
m_debugDraw.SetFlags(flags);
|
||||
|
||||
m_world->SetWarmStarting(1);
|
||||
m_world->SetContinuousPhysics(1);
|
||||
m_world->Step(timeStep, velocityIterations, positionIterations);
|
||||
m_world->DrawDebugData();
|
||||
}
|
||||
|
||||
b2Vec2 ConvertScreenToWorld(int x, int y)
|
||||
{
|
||||
Size sz = GetSize();
|
||||
x += sz.cx / 2;
|
||||
y = sz.cy / 2 - y;
|
||||
float32 u = x / float32(sz.cx);
|
||||
float32 v = (sz.cy - y) / float32(sz.cy);
|
||||
|
||||
float32 ratio = float32(sz.cx) / float32(sz.cy);
|
||||
b2Vec2 extents(ratio * 25.0f, 25.0f);
|
||||
|
||||
b2Vec2 viewCenter(0.0f, 0.0f);
|
||||
b2Vec2 lower = viewCenter - extents;
|
||||
b2Vec2 upper = viewCenter + extents;
|
||||
|
||||
b2Vec2 p;
|
||||
p.x = (1.0f - u) * lower.x + u * upper.x;
|
||||
p.y = (1.0f - v) * lower.y + v * upper.y;
|
||||
p.x = (x - debugDraw.cx) / debugDraw.aspect;
|
||||
p.y = (debugDraw.cy - y) / debugDraw.aspect;
|
||||
return p;
|
||||
}
|
||||
|
||||
void Render0()
|
||||
{
|
||||
Refresh();
|
||||
}
|
||||
|
||||
void Render(Draw& w)
|
||||
{
|
||||
Size sz = GetSize();
|
||||
m_debugDraw.w = &w;
|
||||
m_debugDraw.sz = sz;
|
||||
m_debugDraw.cx = sz.cx / 2.0f;
|
||||
m_debugDraw.cy = sz.cy / 2.0f;
|
||||
m_debugDraw.aspect = 18.0f;
|
||||
|
||||
Step();
|
||||
}
|
||||
void Render() { Refresh(); }
|
||||
|
||||
virtual void Paint(Draw& w)
|
||||
{
|
||||
Size sz = GetSize();
|
||||
w.DrawRect(sz, White);
|
||||
Render(w);
|
||||
|
||||
debugDraw.w = &w;
|
||||
debugDraw.sz = sz;
|
||||
debugDraw.cx = sz.cx / 2.0f;
|
||||
debugDraw.cy = sz.cy / 2.0f + 150.0f;
|
||||
debugDraw.aspect = sz.cx / (float) sz.cy;
|
||||
debugDraw.aspect *= debugDraw.zoom;
|
||||
|
||||
float hz = 60;
|
||||
int velocityIterations = 8;
|
||||
int positionIterations = 3;
|
||||
|
||||
float32 timeStep = 1.0f / hz;
|
||||
|
||||
debugDraw.SetFlags(b2DebugDraw::e_shapeBit);
|
||||
|
||||
world.SetWarmStarting(1);
|
||||
world.SetContinuousPhysics(1);
|
||||
world.Step(timeStep, velocityIterations, positionIterations);
|
||||
world.DrawDebugData();
|
||||
|
||||
int px = int(mouseWorld.x * debugDraw.aspect + debugDraw.cx);
|
||||
int py = int(debugDraw.cy - mouseWorld.y * debugDraw.aspect);
|
||||
w.DrawEllipse(px - 3, py - 3, 6, 6, Green);
|
||||
}
|
||||
|
||||
virtual void LeftDown(Point p0, dword keyflags)
|
||||
{
|
||||
b2Vec2 p(float32(p0.x), float32(p0.y));
|
||||
m_mouseWorld = ConvertScreenToWorld(p0.x, p0.y);
|
||||
b2Vec2 p = ConvertScreenToWorld(p0.x, p0.y);
|
||||
mouseWorld = p;
|
||||
|
||||
if(m_mouseJoint != NULL)
|
||||
if(mouseJoint != NULL)
|
||||
return;
|
||||
|
||||
b2AABB aabb;
|
||||
|
|
@ -307,41 +282,41 @@ struct App : TopWindow
|
|||
aabb.upperBound = p + d;
|
||||
|
||||
QueryCallback callback(p);
|
||||
m_world->QueryAABB(&callback, aabb);
|
||||
world.QueryAABB(&callback, aabb);
|
||||
|
||||
if (callback.m_fixture)
|
||||
if (callback.fixture)
|
||||
{
|
||||
b2Body* body = callback.m_fixture->GetBody();
|
||||
b2Body* body = callback.fixture->GetBody();
|
||||
b2MouseJointDef md;
|
||||
md.bodyA = m_groundBody;
|
||||
md.bodyA = groundBody;
|
||||
md.bodyB = body;
|
||||
md.target = p;
|
||||
md.maxForce = 1000.0f * body->GetMass();
|
||||
m_mouseJoint = (b2MouseJoint*)m_world->CreateJoint(&md);
|
||||
mouseJoint = (b2MouseJoint*) world.CreateJoint(&md);
|
||||
body->SetAwake(true);
|
||||
}
|
||||
}
|
||||
|
||||
virtual void LeftUp(Point p0, dword keyflags)
|
||||
{
|
||||
b2Vec2 p = ConvertScreenToWorld(p0.x, p0.y);
|
||||
if (m_mouseJoint)
|
||||
if (mouseJoint)
|
||||
{
|
||||
m_world->DestroyJoint(m_mouseJoint);
|
||||
m_mouseJoint = NULL;
|
||||
world.DestroyJoint(mouseJoint);
|
||||
mouseJoint = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
virtual void MouseMove(Point p0, dword keyflags)
|
||||
virtual void MouseMove(Point p, dword keyflags)
|
||||
{
|
||||
b2Vec2 p = ConvertScreenToWorld(p0.x, p0.y);
|
||||
mouseWorld = ConvertScreenToWorld(p.x, p.y);
|
||||
|
||||
m_mouseWorld = p;
|
||||
|
||||
if (m_mouseJoint)
|
||||
{
|
||||
m_mouseJoint->SetTarget(p);
|
||||
}
|
||||
if(mouseJoint)
|
||||
mouseJoint->SetTarget(mouseWorld);
|
||||
}
|
||||
|
||||
virtual void MouseWheel(Point p, int zdelta, dword keyflags)
|
||||
{
|
||||
debugDraw.zoom += zdelta / 80.0f;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue