Added Contact:getFixtures and Body:getContactList (see issue #905).

The list of Contacts associated with bodies changes during World:update (potentially multiple times), so you might miss collisions if you don't use the World callbacks at all.
This commit is contained in:
Alex Szpakowski
2014-07-07 15:24:24 -03:00
parent dac9f4eaaa
commit 9ab9a393d5
9 changed files with 74 additions and 3 deletions
+24
View File
@@ -444,6 +444,30 @@ int Body::getFixtureList(lua_State *L) const
return 1;
}
int Body::getContactList(lua_State *L) const
{
lua_newtable(L);
const b2ContactEdge *ce = body->GetContactList();
int i = 1;
do
{
if (!ce)
break;
Contact *contact = (Contact *) Memoizer::find(ce->contact);
if (!contact)
contact = new Contact(ce->contact);
else
contact->retain();
luax_pushtype(L, "Contact", PHYSICS_CONTACT_T, contact);
lua_rawseti(L, -2, i);
i++;
}
while ((ce = ce->next));
return 1;
}
b2Vec2 Body::getVector(lua_State *L)
{
love::luax_assert_argc(L, 2, 2);
+7
View File
@@ -393,6 +393,13 @@ public:
**/
int getFixtureList(lua_State *L) const;
/**
* Get an array of all active Contacts attached to this Body.
* This list changes during World:update and you may miss some collisions
* if you don't use the collision callbacks.
**/
int getContactList(lua_State *L) const;
/**
* Destroy this body.
**/
+9
View File
@@ -142,6 +142,15 @@ void Contact::getChildren(int &childA, int &childB)
childB = contact->GetChildIndexB();
}
void Contact::getFixtures(Fixture *&fixtureA, Fixture *&fixtureB)
{
fixtureA = (Fixture *) Memoizer::find(contact->GetFixtureA());
fixtureB = (Fixture *) Memoizer::find(contact->GetFixtureB());
if (!fixtureA || !fixtureB)
throw love::Exception("A fixture has escaped Memoizer!");
}
} // box2d
} // physics
} // love
+5
View File
@@ -148,6 +148,11 @@ public:
void getChildren(int &childA, int &childB);
/**
* Gets the Fixtures associated with this Contact.
**/
void getFixtures(Fixture *&fixtureA, Fixture *&fixtureB);
private:
// The Box2D contact.
+1 -3
View File
@@ -318,10 +318,8 @@ 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)
if (!a || !b)
throw love::Exception("A fixture has escaped Memoizer!");
return filter.process(a, b);
}
+10
View File
@@ -540,6 +540,15 @@ int w_Body_getFixtureList(lua_State *L)
return n;
}
int w_Body_getContactList(lua_State *L)
{
Body *t = luax_checkbody(L, 1);
lua_remove(L, 1);
int n = 0;
luax_catchexcept(L, [&](){ n = t->getContactList(L); });
return n;
}
int w_Body_destroy(lua_State *L)
{
Body *t = luax_checkbody(L, 1);
@@ -615,6 +624,7 @@ static const luaL_Reg functions[] =
{ "isFixedRotation", w_Body_isFixedRotation },
{ "getWorld", w_Body_getWorld },
{ "getFixtureList", w_Body_getFixtureList },
{ "getContactList", w_Body_getContactList },
{ "destroy", w_Body_destroy },
{ "setUserData", w_Body_setUserData },
{ "getUserData", w_Body_getUserData },
+1
View File
@@ -85,6 +85,7 @@ int w_Body_setFixedRotation(lua_State *L);
int w_Body_isFixedRotation(lua_State *L);
int w_Body_getWorld(lua_State *L);
int w_Body_getFixtureList(lua_State *L);
int w_Body_getContactList(lua_State *L);
int w_Body_destroy(lua_State *L);
int w_Body_setUserData(lua_State *L);
int w_Body_getUserData(lua_State *L);
@@ -19,6 +19,7 @@
**/
#include "wrap_Contact.h"
#include "Fixture.h"
namespace love
{
@@ -138,6 +139,20 @@ int w_Contact_getChildren(lua_State *L)
return 2;
}
int w_Contact_getFixtures(lua_State *L)
{
Contact *t = luax_checkcontact(L, 1);
Fixture *a = nullptr;
Fixture *b = nullptr;
luax_catchexcept(L, [&](){ t->getFixtures(a, b); });
a->retain();
luax_pushtype(L, "Fixture", PHYSICS_FIXTURE_T, a);
b->retain();
luax_pushtype(L, "Fixture", PHYSICS_FIXTURE_T, b);
return 2;
}
extern "C" int luaopen_contact(lua_State *L)
{
static const luaL_Reg functions[] =
@@ -156,6 +171,7 @@ extern "C" int luaopen_contact(lua_State *L)
{ "setTangentSpeed", w_Contact_setTangentSpeed },
{ "getTangentSpeed", w_Contact_getTangentSpeed },
{ "getChildren", w_Contact_getChildren },
{ "getFixtures", w_Contact_getFixtures },
{ 0, 0 }
};
+1
View File
@@ -47,6 +47,7 @@ int w_Contact_resetRestitution(lua_State *L);
int w_Contact_setTangentSpeed(lua_State *L);
int w_Contact_getTangentSpeed(lua_State *L);
int w_Contact_getChildren(lua_State *L);
int w_Contact_getFixtures(lua_State *L);
extern "C" int luaopen_contact(lua_State *L);
} // box2d