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
{
Contact::Contact(World * world, b2Contact * contact)
: contact(contact), world(world)
Contact::Contact(b2Contact * contact)
: contact(contact)
{
world->retain();
}
Contact::~Contact()
{
world->release();
}
int Contact::getPosition(lua_State * L)
int Contact::getPositions(lua_State * L)
{
love::luax_assert_argc(L, 1, 1);
lua_pushnumber(L, Physics::scaleUp(point.position.x));
lua_pushnumber(L, Physics::scaleUp(point.position.y));
return 2;
}
int Contact::getVelocity(lua_State * L)
{
love::luax_assert_argc(L, 1, 1);
lua_pushnumber(L, Physics::scaleUp(point.velocity.x));
lua_pushnumber(L, Physics::scaleUp(point.velocity.y));
return 2;
b2WorldManifold manifold;
contact->GetWorldManifold(&manifold);
int points = contact->GetManifold()->pointCount;
for (int i = 0; i < points; i++) {
b2Vec2 position = Physics::scaleUp(manifold.points[i]);
lua_pushnumber(L, position.x);
lua_pushnumber(L, position.y);
}
return points*2;
}
int Contact::getNormal(lua_State * L)
{
love::luax_assert_argc(L, 1, 1);
lua_pushnumber(L, Physics::scaleUp(point.normal.x));
lua_pushnumber(L, Physics::scaleUp(point.normal.y));
b2WorldManifold manifold;
contact->GetWorldManifold(&manifold);
lua_pushnumber(L, Physics::scaleUp(manifold.normal.x));
lua_pushnumber(L, Physics::scaleUp(manifold.normal.y));
return 2;
}
float Contact::getSeparation() const
{
return Physics::scaleUp(point.separation);
}
float Contact::getFriction() const
{
return point.friction;
return contact->GetFriction();
}
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
+45 -22
View File
@@ -51,10 +51,7 @@ namespace box2d
// The Box2D contact.
b2Contact* contact;
// The parent world. Needed for scaling.
World * world;
public:
/**
@@ -63,23 +60,16 @@ namespace box2d
* data pointed to.
* @param point Pointer to the Box2D contact.
**/
Contact(World * world, const b2Contact * contact);
Contact(b2Contact * 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 y-axis.
**/
int getPosition(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);
int getPositions(lua_State * L);
/**
* Gets the collision normal.
@@ -89,22 +79,55 @@ namespace box2d
int getNormal(lua_State * L);
/**
* How far apart the shapes are. If they are intersecting
* this value is negative.
**/
float getSeparation() const;
/**
* The mixed friction between the two shapes at
* The mixed friction between the two fixtures at
* the point of impact.
**/
float getFriction() const;
/**
* The mixed restitution of the two shapes
* The mixed restitution of the two fixtures
* at the point of impact.
**/
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;
}
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
@@ -53,7 +53,15 @@ namespace box2d
**/
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()
@@ -86,13 +94,25 @@ namespace box2d
}
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.
for(int i = 0;i<(int)contacts.size();i++)
delete contacts[i];
contacts.clear();
// Clear impulses.
impulses.clear();
}
}
@@ -134,22 +154,22 @@ namespace box2d
void World::BeginContact(b2Contact* contact)
{
begin.add(this, contact);
begin.add(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)
{
postsolve.add(this, contact);
postsolve.add(contact, impulse);
}
int World::setCallbacks(lua_State * L)
+6 -2
View File
@@ -67,9 +67,13 @@ namespace box2d
public:
Reference * ref;
std::vector<Contact *> contacts;
std::vector<const b2ContactImpulse *> impulses;
b2Manifold* oldManifold;
b2ContactImpulse* impulse;
ContactCallback();
~ContactCallback();
void add(World * world, const b2Contact* contact);
void add(b2Contact* contact);
void add(b2Contact* contact, const b2ContactImpulse* impulse);
void process();
};
@@ -113,7 +117,7 @@ namespace box2d
// From b2ContactListener
void BeginContact(b2Contact* contact);
void EndContact(b2Contact* contact);
void PreSolve(b2Contact* contact, const b2Manifold* oldManifold);
void PreSolve(b2Contact* contact);
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);
}
int w_Contact_getPosition(lua_State * L)
int w_Contact_getPositions(lua_State * L)
{
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)
{
Contact * t = luax_checkcontact(L, 1);
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)
{
Contact * t = luax_checkcontact(L, 1);
@@ -70,16 +57,73 @@ namespace box2d
lua_pushnumber(L, t->getRestitution());
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)
{
static const luaL_Reg functions[] = {
{ "getPosition", w_Contact_getPosition },
{ "getVelocity", w_Contact_getVelocity },
{ "getPositions", w_Contact_getPositions },
{ "getNormal", w_Contact_getNormal },
{ "getSeparation", w_Contact_getSeparation },
{ "getFriction", w_Contact_getFriction },
{ "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 }
};
+8 -3
View File
@@ -32,12 +32,17 @@ namespace physics
namespace box2d
{
Contact * luax_checkcontact(lua_State * L, int idx);
int w_Contact_getPosition(lua_State * L);
int w_Contact_getVelocity(lua_State * L);
int w_Contact_getPositions(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_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);
} // box2d