Callbacks now actually fire when they're supposed to, instead of post-step (means PreSolve collision filtering works)

--HG--
branch : box2d-update
This commit is contained in:
Bill Meltsner
2011-09-26 20:22:03 -04:00
parent 413f5026fa
commit 16fb73e92a
2 changed files with 39 additions and 90 deletions
+38 -83
View File
@@ -45,89 +45,49 @@ namespace box2d
delete ref; delete ref;
} }
void World::ContactCallback::add(b2Contact* contact) void World::ContactCallback::process(b2Contact* contact, const b2ContactImpulse* impulse)
{
/**
* We must copy contacts, since we're not allowed to process
* them inside this function. Removing bodies in this function
* pretty much guarantees segfault. ^^
**/
if(ref != 0)
contacts.push_back(new Contact(contact));
}
void World::ContactCallback::add(b2Contact* contact, const b2ContactImpulse* impulse)
{
if(ref != 0) {
contacts.push_back(new Contact(contact));
// copy the impulse struct
b2ContactImpulse * i = new b2ContactImpulse();
i->normalImpulses[0] = impulse->normalImpulses[0];
i->normalImpulses[1] = impulse->normalImpulses[1];
i->tangentImpulses[0] = impulse->tangentImpulses[0];
i->tangentImpulses[1] = impulse->tangentImpulses[1];
i->count = impulse->count;
impulses.push_back(i);
}
}
void World::ContactCallback::process()
{ {
// Process contacts. // Process contacts.
if(ref != 0) if(ref != 0)
{ {
lua_State * L = ref->getL(); lua_State * L = ref->getL();
for(int i = 0;i<(int)contacts.size();i++) ref->push();
// Push first fixture.
{ {
// Push the function. Fixture * a = (Fixture *)Memoizer::find(contact->GetFixtureA());
ref->push(); if(a != 0) {
a->retain();
// Push first fixture. luax_newtype(L, "Fixture", PHYSICS_FIXTURE_T, (void*)a);
{
Fixture * a = (Fixture *)Memoizer::find(contacts[i]->contact->GetFixtureA());
if(a != 0) {
a->retain();
luax_newtype(L, "Fixture", PHYSICS_FIXTURE_T, (void*)a);
}
else
throw love::Exception("A fixture has escaped Memoizer!");
} }
else
// Push second userdata. throw love::Exception("A fixture has escaped Memoizer!");
{
Fixture * b = (Fixture *)Memoizer::find(contacts[i]->contact->GetFixtureB());
if(b != 0) {
b->retain();
luax_newtype(L, "Fixture", PHYSICS_FIXTURE_T, (void*)b);
}
else
throw love::Exception("A fixture has escaped Memoizer!");
}
luax_newtype(L, "Contact", (PHYSICS_CONTACT_T), (void*)contacts[i], false);
int args = 3;
if ((int)impulses.size() > i) {
const b2ContactImpulse * impulse = impulses[i];
for (int c = 0; c < impulse->count; c++) {
lua_pushnumber(L, Physics::scaleUp(impulse->normalImpulses[c]));
lua_pushnumber(L, Physics::scaleUp(impulse->tangentImpulses[c]));
args += 2;
}
}
lua_call(L, args, 0);
} }
// Clear contacts. // Push second userdata.
for(int i = 0;i<(int)contacts.size();i++) {
delete contacts[i]; Fixture * b = (Fixture *)Memoizer::find(contact->GetFixtureB());
contacts.clear(); if(b != 0) {
// Clear impulses. b->retain();
for(int i = 0;i<(int)impulses.size();i++) luax_newtype(L, "Fixture", PHYSICS_FIXTURE_T, (void*)b);
delete impulses[i]; }
impulses.clear(); else
throw love::Exception("A fixture has escaped Memoizer!");
}
Contact * c = new Contact(contact);
luax_newtype(L, "Contact", (PHYSICS_CONTACT_T), (void*)c, false);
int args = 3;
if (impulse) {
for (int c = 0; c < impulse->count; c++) {
lua_pushnumber(L, Physics::scaleUp(impulse->normalImpulses[c]));
lua_pushnumber(L, Physics::scaleUp(impulse->tangentImpulses[c]));
args += 2;
}
}
lua_call(L, args, 0);
} }
} }
@@ -250,32 +210,27 @@ namespace box2d
void World::update(float dt) void World::update(float dt)
{ {
world->Step(dt, 8, 6); world->Step(dt, 8, 6);
begin.process();
end.process();
presolve.process();
postsolve.process();
} }
void World::BeginContact(b2Contact* contact) void World::BeginContact(b2Contact* contact)
{ {
begin.add(contact); begin.process(contact);
} }
void World::EndContact(b2Contact* contact) void World::EndContact(b2Contact* contact)
{ {
end.add(contact); end.process(contact);
} }
void World::PreSolve(b2Contact* contact, const b2Manifold* oldManifold) void World::PreSolve(b2Contact* contact, const b2Manifold* oldManifold)
{ {
B2_NOT_USED(oldManifold); // not sure what to do with this B2_NOT_USED(oldManifold); // not sure what to do with this
presolve.add(contact); presolve.process(contact);
} }
void World::PostSolve(b2Contact* contact, const b2ContactImpulse* impulse) void World::PostSolve(b2Contact* contact, const b2ContactImpulse* impulse)
{ {
postsolve.add(contact, impulse); postsolve.process(contact, impulse);
} }
bool World::ShouldCollide(b2Fixture * fixtureA, b2Fixture * fixtureB) bool World::ShouldCollide(b2Fixture * fixtureA, b2Fixture * fixtureB)
+1 -7
View File
@@ -67,15 +67,9 @@ namespace box2d
{ {
public: public:
Reference * ref; Reference * ref;
std::vector<Contact *> contacts;
std::vector<const b2ContactImpulse *> impulses;
b2Manifold* oldManifold;
b2ContactImpulse* impulse;
ContactCallback(); ContactCallback();
~ContactCallback(); ~ContactCallback();
void add(b2Contact* contact); void process(b2Contact* contact, const b2ContactImpulse* impulse = NULL);
void add(b2Contact* contact, const b2ContactImpulse* impulse);
void process();
}; };
class ContactFilter class ContactFilter