mirror of
https://github.com/love2d/love.git
synced 2026-08-16 00:02:12 +02:00
A first attempt at overhauling collision. New everything.
--HG-- branch : box2d-update
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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();
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
/**
|
||||
|
||||
@@ -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 }
|
||||
};
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user