A first attempt at overhauling collision. New everything.

--HG--
branch : box2d-update
This commit is contained in:
Bill Meltsner
2011-09-23 21:25:41 -04:00
parent 71abae06c7
commit 0678eac453
6 changed files with 203 additions and 79 deletions
+53 -25
View File
@@ -28,54 +28,82 @@ namespace physics
{ {
namespace box2d namespace box2d
{ {
Contact::Contact(World * world, b2Contact * contact) Contact::Contact(b2Contact * contact)
: contact(contact), world(world) : contact(contact)
{ {
world->retain();
} }
Contact::~Contact() Contact::~Contact()
{ {
world->release();
} }
int Contact::getPosition(lua_State * L) int Contact::getPositions(lua_State * L)
{ {
love::luax_assert_argc(L, 1, 1); love::luax_assert_argc(L, 1, 1);
lua_pushnumber(L, Physics::scaleUp(point.position.x)); b2WorldManifold manifold;
lua_pushnumber(L, Physics::scaleUp(point.position.y)); contact->GetWorldManifold(&manifold);
return 2; int points = contact->GetManifold()->pointCount;
} for (int i = 0; i < points; i++) {
b2Vec2 position = Physics::scaleUp(manifold.points[i]);
int Contact::getVelocity(lua_State * L) lua_pushnumber(L, position.x);
{ lua_pushnumber(L, position.y);
love::luax_assert_argc(L, 1, 1); }
lua_pushnumber(L, Physics::scaleUp(point.velocity.x)); return points*2;
lua_pushnumber(L, Physics::scaleUp(point.velocity.y));
return 2;
} }
int Contact::getNormal(lua_State * L) int Contact::getNormal(lua_State * L)
{ {
love::luax_assert_argc(L, 1, 1); love::luax_assert_argc(L, 1, 1);
lua_pushnumber(L, Physics::scaleUp(point.normal.x)); b2WorldManifold manifold;
lua_pushnumber(L, Physics::scaleUp(point.normal.y)); contact->GetWorldManifold(&manifold);
lua_pushnumber(L, Physics::scaleUp(manifold.normal.x));
lua_pushnumber(L, Physics::scaleUp(manifold.normal.y));
return 2; return 2;
} }
float Contact::getSeparation() const
{
return Physics::scaleUp(point.separation);
}
float Contact::getFriction() const float Contact::getFriction() const
{ {
return point.friction; return contact->GetFriction();
} }
float Contact::getRestitution() const float Contact::getRestitution() const
{ {
return point.restitution; return contact->GetRestitution();
}
bool Contact::isEnabled() const
{
return contact->IsEnabled();
}
bool Contact::isTouching() const
{
return contact->IsTouching();
}
void Contact::setFriction(float friction)
{
contact->SetFriction(friction);
}
void Contact::setRestitution(float restitution)
{
contact->SetRestitution(restitution);
}
void Contact::setEnabled(bool enabled)
{
contact->SetEnabled(enabled);
}
void Contact::resetFriction()
{
contact->ResetFriction();
}
void Contact::resetRestitution()
{
contact->ResetRestitution();
} }
} // box2d } // box2d
+45 -22
View File
@@ -51,10 +51,7 @@ namespace box2d
// The Box2D contact. // The Box2D contact.
b2Contact* contact; b2Contact* contact;
// The parent world. Needed for scaling.
World * world;
public: public:
/** /**
@@ -63,23 +60,16 @@ namespace box2d
* data pointed to. * data pointed to.
* @param point Pointer to the Box2D contact. * @param point Pointer to the Box2D contact.
**/ **/
Contact(World * world, const b2Contact * contact); Contact(b2Contact * contact);
virtual ~Contact(); virtual ~Contact();
/** /**
* Gets the position of the Contact. * Gets the position of each point of contact.
* @return The position along the x-axis. * @return The position along the x-axis.
* @return The position along the y-axis. * @return The position along the y-axis.
**/ **/
int getPosition(lua_State * L); int getPositions(lua_State * L);
/**
* Gets the linear impact velocity.
* @return The velocity along the x-axis.
* @return The velocity along the y-axis.
**/
int getVelocity(lua_State * L);
/** /**
* Gets the collision normal. * Gets the collision normal.
@@ -89,22 +79,55 @@ namespace box2d
int getNormal(lua_State * L); int getNormal(lua_State * L);
/** /**
* How far apart the shapes are. If they are intersecting * The mixed friction between the two fixtures at
* this value is negative.
**/
float getSeparation() const;
/**
* The mixed friction between the two shapes at
* the point of impact. * the point of impact.
**/ **/
float getFriction() const; float getFriction() const;
/** /**
* The mixed restitution of the two shapes * The mixed restitution of the two fixtures
* at the point of impact. * at the point of impact.
**/ **/
float getRestitution() const; float getRestitution() const;
/**
* Check if the contact is enabled.
**/
bool isEnabled() const;
/**
* Check if the contact is touching.
**/
bool isTouching() const;
// Only call the setters in PreSolve
/**
* Override the default friction mixture.
**/
void setFriction(float friction);
/**
* Override the default restitution mixture.
**/
void setRestitution(float restitution);
/**
* Enable/disable this contact.
**/
void setEnabled(bool enabled);
/**
* Reset the friction mixture to the default
* value.
**/
void resetFriction();
/**
* Reset the restitution mixture to the default
* value.
**/
void resetRestitution();
}; };
+28 -8
View File
@@ -44,7 +44,7 @@ namespace box2d
delete ref; delete ref;
} }
void World::ContactCallback::add(World * world, const b2Contact* contact) void World::ContactCallback::add(b2Contact* contact)
{ {
/** /**
* We must copy contacts, since we're not allowed to process * We must copy contacts, since we're not allowed to process
@@ -53,7 +53,15 @@ namespace box2d
**/ **/
if(ref != 0) if(ref != 0)
contacts.push_back(new Contact(world, contact)); contacts.push_back(new Contact(contact));
}
void World::ContactCallback::add(b2Contact* contact, const b2ContactImpulse* impulse)
{
if(ref != 0) {
contacts.push_back(new Contact(contact));
impulses.push_back(impulse);
}
} }
void World::ContactCallback::process() void World::ContactCallback::process()
@@ -86,13 +94,25 @@ namespace box2d
} }
luax_newtype(L, "Contact", (PHYSICS_CONTACT_T), (void*)contacts[i], false); luax_newtype(L, "Contact", (PHYSICS_CONTACT_T), (void*)contacts[i], false);
lua_call(L, 3, 0);
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. // Clear contacts.
for(int i = 0;i<(int)contacts.size();i++) for(int i = 0;i<(int)contacts.size();i++)
delete contacts[i]; delete contacts[i];
contacts.clear(); contacts.clear();
// Clear impulses.
impulses.clear();
} }
} }
@@ -134,22 +154,22 @@ namespace box2d
void World::BeginContact(b2Contact* contact) void World::BeginContact(b2Contact* contact)
{ {
begin.add(this, contact); begin.add(contact);
} }
void World::EndContact(b2Contact* contact) void World::EndContact(b2Contact* contact)
{ {
end.add(this, contact); end.add(contact);
} }
void World::PreSolve(b2Contact* contact, const b2Manifold* oldManifold) void World::PreSolve(b2Contact* contact)
{ {
presolve.add(this, contact); presolve.add(contact);
} }
void World::PostSolve(b2Contact* contact, const b2ContactImpulse* impulse) void World::PostSolve(b2Contact* contact, const b2ContactImpulse* impulse)
{ {
postsolve.add(this, contact); postsolve.add(contact, impulse);
} }
int World::setCallbacks(lua_State * L) int World::setCallbacks(lua_State * L)
+6 -2
View File
@@ -67,9 +67,13 @@ namespace box2d
public: public:
Reference * ref; Reference * ref;
std::vector<Contact *> contacts; std::vector<Contact *> contacts;
std::vector<const b2ContactImpulse *> impulses;
b2Manifold* oldManifold;
b2ContactImpulse* impulse;
ContactCallback(); ContactCallback();
~ContactCallback(); ~ContactCallback();
void add(World * world, const b2Contact* contact); void add(b2Contact* contact);
void add(b2Contact* contact, const b2ContactImpulse* impulse);
void process(); void process();
}; };
@@ -113,7 +117,7 @@ namespace box2d
// From b2ContactListener // From b2ContactListener
void BeginContact(b2Contact* contact); void BeginContact(b2Contact* contact);
void EndContact(b2Contact* contact); void EndContact(b2Contact* contact);
void PreSolve(b2Contact* contact, const b2Manifold* oldManifold); void PreSolve(b2Contact* contact);
void PostSolve(b2Contact* contact, const b2ContactImpulse* impulse); void PostSolve(b2Contact* contact, const b2ContactImpulse* impulse);
/** /**
+63 -19
View File
@@ -32,31 +32,18 @@ namespace box2d
return luax_checktype<Contact>(L, idx, "Contact", PHYSICS_CONTACT_T); return luax_checktype<Contact>(L, idx, "Contact", PHYSICS_CONTACT_T);
} }
int w_Contact_getPosition(lua_State * L) int w_Contact_getPositions(lua_State * L)
{ {
Contact * t = luax_checkcontact(L, 1); Contact * t = luax_checkcontact(L, 1);
return t->getPosition(L); return t->getPositions(L);
} }
int w_Contact_getVelocity(lua_State * L)
{
Contact * t = luax_checkcontact(L, 1);
return t->getVelocity(L);
}
int w_Contact_getNormal(lua_State * L) int w_Contact_getNormal(lua_State * L)
{ {
Contact * t = luax_checkcontact(L, 1); Contact * t = luax_checkcontact(L, 1);
return t->getNormal(L); return t->getNormal(L);
} }
int w_Contact_getSeparation(lua_State * L)
{
Contact * t = luax_checkcontact(L, 1);
lua_pushnumber(L, t->getSeparation());
return 1;
}
int w_Contact_getFriction(lua_State * L) int w_Contact_getFriction(lua_State * L)
{ {
Contact * t = luax_checkcontact(L, 1); Contact * t = luax_checkcontact(L, 1);
@@ -70,16 +57,73 @@ namespace box2d
lua_pushnumber(L, t->getRestitution()); lua_pushnumber(L, t->getRestitution());
return 1; return 1;
} }
int w_Contact_isEnabled(lua_State * L)
{
Contact * t = luax_checkcontact(L, 1);
lua_pushboolean(L, t->isEnabled());
return 1;
}
int w_Contact_isTouching(lua_State * L)
{
Contact * t = luax_checkcontact(L, 1);
lua_pushboolean(L, t->isTouching());
return 1;
}
int w_Contact_setFriction(lua_State * L)
{
Contact * t = luax_checkcontact(L, 1);
float f = (float)luaL_checknumber(L, 2);
t->setFriction(f);
return 0;
}
int w_Contact_setRestitution(lua_State * L)
{
Contact * t = luax_checkcontact(L, 1);
float r = (float)luaL_checknumber(L, 2);
t->setRestitution(r);
return 0;
}
int w_Contact_setEnabled(lua_State * L)
{
Contact * t = luax_checkcontact(L, 1);
bool e = luax_toboolean(L, 2);
t->setEnabled(e);
return 0;
}
int w_Contact_resetFriction(lua_State * L)
{
Contact * t = luax_checkcontact(L, 1);
t->resetFriction();
return 0;
}
int w_Contact_resetRestitution(lua_State * L)
{
Contact * t = luax_checkcontact(L, 1);
t->resetRestitution();
return 0;
}
int luaopen_contact(lua_State * L) int luaopen_contact(lua_State * L)
{ {
static const luaL_Reg functions[] = { static const luaL_Reg functions[] = {
{ "getPosition", w_Contact_getPosition }, { "getPositions", w_Contact_getPositions },
{ "getVelocity", w_Contact_getVelocity },
{ "getNormal", w_Contact_getNormal }, { "getNormal", w_Contact_getNormal },
{ "getSeparation", w_Contact_getSeparation },
{ "getFriction", w_Contact_getFriction }, { "getFriction", w_Contact_getFriction },
{ "getRestitution", w_Contact_getRestitution }, { "getRestitution", w_Contact_getRestitution },
{ "isEnabled", w_Contact_isEnabled },
{ "isTouching", w_Contact_isTouching },
{ "setFriction", w_Contact_setFriction },
{ "setRestitution", w_Contact_setRestitution },
{ "setEnabled", w_Contact_setEnabled },
{ "resetFriction", w_Contact_resetFriction },
{ "resetRestitution", w_Contact_resetRestitution },
{ 0, 0 } { 0, 0 }
}; };
+8 -3
View File
@@ -32,12 +32,17 @@ namespace physics
namespace box2d namespace box2d
{ {
Contact * luax_checkcontact(lua_State * L, int idx); Contact * luax_checkcontact(lua_State * L, int idx);
int w_Contact_getPosition(lua_State * L); int w_Contact_getPositions(lua_State * L);
int w_Contact_getVelocity(lua_State * L);
int w_Contact_getNormal(lua_State * L); int w_Contact_getNormal(lua_State * L);
int w_Contact_getSeparation(lua_State * L);
int w_Contact_getFriction(lua_State * L); int w_Contact_getFriction(lua_State * L);
int w_Contact_getRestitution(lua_State * L); int w_Contact_getRestitution(lua_State * L);
int w_Contact_isEnabled(lua_State * L);
int w_Contact_isTouching(lua_State * L);
int w_Contact_setFriction(lua_State * L);
int w_Contact_setRestitution(lua_State * L);
int w_Contact_setEnabled(lua_State * L);
int w_Contact_resetFriction(lua_State * L);
int w_Contact_resetRestitution(lua_State * L);
int luaopen_contact(lua_State * L); int luaopen_contact(lua_State * L);
} // box2d } // box2d