Add ContactFilter callback to World

--HG--
branch : box2d-update
This commit is contained in:
Bill Meltsner
2011-09-24 13:45:24 -04:00
parent 1b14dcaeb8
commit 7e039dd1ef
4 changed files with 92 additions and 1 deletions
+49
View File
@@ -118,6 +118,31 @@ namespace box2d
} }
World::ContactFilter::ContactFilter()
: ref(0)
{
}
World::ContactFilter::~ContactFilter()
{
if(ref != 0)
delete ref;
}
bool World::ContactFilter::process(Fixture * a, Fixture * b)
{
if (ref != 0)
{
lua_State * L = ref->getL();
ref->push();
luax_newtype(L, "Fixture", PHYSICS_FIXTURE_T, (void*)a);
luax_newtype(L, "Fixture", PHYSICS_FIXTURE_T, (void*)b);
lua_call(L, 2, 1);
return luax_toboolean(L, -1);
}
return true;
}
World::World() World::World()
: world(NULL) : world(NULL)
{ {
@@ -179,6 +204,16 @@ namespace box2d
postsolve.add(contact, impulse); postsolve.add(contact, impulse);
} }
bool World::ShouldCollide(b2Fixture * fixtureA, b2Fixture * fixtureB)
{
// Fixtures should be memoized, if we created them
Fixture * a = (Fixture *)Memoizer::find(fixtureA);
if (!a) throw love::Exception("A fixture has escaped Memoizer!");
Fixture * b = (Fixture *)Memoizer::find(fixtureB);
if (!b) throw love::Exception("A fixture has escaped Memoizer!");
return filter.process(a, b);
}
int World::setCallbacks(lua_State * L) int World::setCallbacks(lua_State * L)
{ {
int n = lua_gettop(L); int n = lua_gettop(L);
@@ -212,6 +247,20 @@ namespace box2d
return lua_gettop(L); return lua_gettop(L);
} }
int World::setContactFilter(lua_State * L)
{
luax_assert_argc(L, 1);
if (filter.ref) delete filter.ref;
filter.ref = luax_refif(L, LUA_TFUNCTION);
return 0;
}
int World::getContactFilter(lua_State * L)
{
filter.ref ? filter.ref->push() : lua_pushnil(L);
return lua_gettop(L);
}
void World::setGravity(float x, float y) void World::setGravity(float x, float y)
{ {
world->SetGravity(Physics::scaleDown(b2Vec2(x, y))); world->SetGravity(Physics::scaleDown(b2Vec2(x, y)));
+25 -1
View File
@@ -40,6 +40,7 @@ namespace box2d
{ {
class Contact; class Contact;
class Fixture;
/** /**
* The World is the "God" container class, * The World is the "God" container class,
@@ -52,7 +53,7 @@ namespace box2d
* The world also controls global parameters, like * The world also controls global parameters, like
* gravity. * gravity.
**/ **/
class World : public Object, public b2ContactListener class World : public Object, public b2ContactListener, public b2ContactFilter
{ {
// Friends. // Friends.
friend class Joint; friend class Joint;
@@ -77,6 +78,15 @@ namespace box2d
void process(); void process();
}; };
class ContactFilter
{
public:
Reference * ref;
ContactFilter();
~ContactFilter();
bool process(Fixture * a, Fixture * b);
};
private: private:
// Pointer to the Box2D world. // Pointer to the Box2D world.
@@ -87,6 +97,7 @@ namespace box2d
// Contact callbacks. // Contact callbacks.
ContactCallback begin, end, presolve, postsolve; ContactCallback begin, end, presolve, postsolve;
ContactFilter filter;
public: public:
@@ -120,6 +131,9 @@ namespace box2d
void PreSolve(b2Contact* contact, const b2Manifold* oldManifold); void PreSolve(b2Contact* contact, const b2Manifold* oldManifold);
void PostSolve(b2Contact* contact, const b2ContactImpulse* impulse); void PostSolve(b2Contact* contact, const b2ContactImpulse* impulse);
// From b2ContactFilter
bool ShouldCollide(b2Fixture* fixtureA, b2Fixture* fixtureB);
/** /**
* Receives up to four Lua functions as arguments. Each function is * Receives up to four Lua functions as arguments. Each function is
* collision callback for the four events (in order): begin, end, * collision callback for the four events (in order): begin, end,
@@ -133,6 +147,16 @@ namespace box2d
**/ **/
int getCallbacks(lua_State * L); int getCallbacks(lua_State * L);
/**
* Sets the ContactFilter callback.
**/
int setContactFilter(lua_State * L);
/**
* Gets the ContactFilter callback.
**/
int getContactFilter(lua_State * L);
/** /**
* Sets the current gravity of the World. * Sets the current gravity of the World.
* @param x Gravity in the x-direction. * @param x Gravity in the x-direction.
+16
View File
@@ -54,6 +54,20 @@ namespace box2d
return t->getCallbacks(L); return t->getCallbacks(L);
} }
int w_World_setContactFilter(lua_State * L)
{
World * t = luax_checkworld(L, 1);
lua_remove(L, 1);
return t->setContactFilter(L);
}
int w_World_getContactFilter(lua_State * L)
{
World * t = luax_checkworld(L, 1);
lua_remove(L, 1);
return t->getContactFilter(L);
}
int w_World_setGravity(lua_State * L) int w_World_setGravity(lua_State * L)
{ {
World * t = luax_checkworld(L, 1); World * t = luax_checkworld(L, 1);
@@ -103,6 +117,8 @@ namespace box2d
{ "update", w_World_update }, { "update", w_World_update },
{ "setCallbacks", w_World_setCallbacks }, { "setCallbacks", w_World_setCallbacks },
{ "getCallbacks", w_World_getCallbacks }, { "getCallbacks", w_World_getCallbacks },
{ "setContactFilter", w_World_setContactFilter },
{ "getContactFilter", w_World_getContactFilter },
{ "setGravity", w_World_setGravity }, { "setGravity", w_World_setGravity },
{ "getGravity", w_World_getGravity }, { "getGravity", w_World_getGravity },
{ "setAllowSleeping", w_World_setAllowSleeping }, { "setAllowSleeping", w_World_setAllowSleeping },
+2
View File
@@ -35,6 +35,8 @@ namespace box2d
int w_World_update(lua_State * L); int w_World_update(lua_State * L);
int w_World_setCallbacks(lua_State * L); int w_World_setCallbacks(lua_State * L);
int w_World_getCallbacks(lua_State * L); int w_World_getCallbacks(lua_State * L);
int w_World_setContactFilter(lua_State * L);
int w_World_getContactFilter(lua_State * L);
int w_World_setGravity(lua_State * L); int w_World_setGravity(lua_State * L);
int w_World_getGravity(lua_State * L); int w_World_getGravity(lua_State * L);
int w_World_setAllowSleeping(lua_State * L); int w_World_setAllowSleeping(lua_State * L);