mirror of
https://github.com/love2d/love.git
synced 2026-08-17 19:23:38 +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
|
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
|
||||||
|
|||||||
@@ -52,9 +52,6 @@ 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,23 +79,56 @@ 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();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // box2d
|
} // box2d
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -32,16 +32,10 @@ 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)
|
||||||
@@ -50,13 +44,6 @@ namespace box2d
|
|||||||
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);
|
||||||
@@ -71,15 +58,72 @@ namespace box2d
|
|||||||
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 }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user