From 6a0c5b485b31a1013e728e120d0e087a3eee1aa0 Mon Sep 17 00:00:00 2001 From: Bill Meltsner Date: Sat, 24 Sep 2011 16:46:07 -0400 Subject: [PATCH] Memoize Contacts, and add List-fetching functions to World (they return arrays) --HG-- branch : box2d-update --- src/modules/physics/box2d/Contact.cpp | 4 ++ src/modules/physics/box2d/World.cpp | 50 ++++++++++++++++++++++++ src/modules/physics/box2d/World.h | 24 ++++++++++++ src/modules/physics/box2d/wrap_World.cpp | 32 +++++++++++++++ src/modules/physics/box2d/wrap_World.h | 4 ++ 5 files changed, 114 insertions(+) diff --git a/src/modules/physics/box2d/Contact.cpp b/src/modules/physics/box2d/Contact.cpp index 7a1b9ffa8..166d66d09 100644 --- a/src/modules/physics/box2d/Contact.cpp +++ b/src/modules/physics/box2d/Contact.cpp @@ -22,6 +22,8 @@ #include "World.h" #include "Physics.h" +#include + namespace love { namespace physics @@ -31,10 +33,12 @@ namespace box2d Contact::Contact(b2Contact * contact) : contact(contact) { + Memoizer::add(contact, this); } Contact::~Contact() { + Memoizer::remove(contact); } int Contact::getPositions(lua_State * L) diff --git a/src/modules/physics/box2d/World.cpp b/src/modules/physics/box2d/World.cpp index 9f1cf7f76..699d1b3d1 100644 --- a/src/modules/physics/box2d/World.cpp +++ b/src/modules/physics/box2d/World.cpp @@ -352,6 +352,56 @@ namespace box2d return world->GetJointCount(); } + int World::getContactCount() + { + return world->GetContactCount(); + } + + int World::getBodyList(lua_State * L) + { + lua_newtable(L); + b2Body * b = world->GetBodyList(); + for (int i = 1; i <= world->GetBodyCount(); i++) { + if (!b) return 1; + Body * body = (Body *)Memoizer::find(b); + if (!body) throw love::Exception("A body has escaped Memoizer!"); + luax_newtype(L, "Body", PHYSICS_BODY_T, (void*)body); + lua_rawseti(L, -1, i); + b = b->GetNext(); + } + return 1; + } + + int World::getJointList(lua_State * L) + { + lua_newtable(L); + b2Joint * j = world->GetJointList(); + for (int i = 1; i <= world->GetJointCount(); i++) { + if (!j) return 1; + Joint * joint = (Joint *)Memoizer::find(j); + if (!joint) throw love::Exception("A joint has escaped Memoizer!"); + luax_newtype(L, "Joint", PHYSICS_JOINT_T, (void*)joint); + lua_rawseti(L, -1, i); + j = j->GetNext(); + } + return 1; + } + + int World::getContactList(lua_State * L) + { + lua_newtable(L); + b2Contact * c = world->GetContactList(); + for (int i = 1; i <= world->GetContactCount(); i++) { + if (!c) return 1; + Contact * contact = (Contact *)Memoizer::find(c); + if (!contact) throw love::Exception("A contact has escaped Memoizer!"); + luax_newtype(L, "Contact", PHYSICS_CONTACT_T, (void*)contact); + lua_rawseti(L, -1, i); + c = c->GetNext(); + } + return 1; + } + b2Body * World::getGroundBody() { return groundBody; diff --git a/src/modules/physics/box2d/World.h b/src/modules/physics/box2d/World.h index 76d84fd98..74987f84f 100644 --- a/src/modules/physics/box2d/World.h +++ b/src/modules/physics/box2d/World.h @@ -214,6 +214,30 @@ namespace box2d * @return The number of joints. **/ int getJointCount(); + + /** + * Get the current contact count. + * @return The number of contacts. + **/ + int getContactCount(); + + /** + * Get an array of all the Bodies in the World. + * @return An array of Bodies. + **/ + int getBodyList(lua_State * L); + + /** + * Get an array of all the Joints in the World. + * @return An array of Joints. + **/ + int getJointList(lua_State * L); + + /** + * Get an array of all the Contacts in the World. + * @return An array of Contacts. + **/ + int getContactList(lua_State * L); /** * Gets the ground body. diff --git a/src/modules/physics/box2d/wrap_World.cpp b/src/modules/physics/box2d/wrap_World.cpp index 9fe819f3f..2b60404a4 100644 --- a/src/modules/physics/box2d/wrap_World.cpp +++ b/src/modules/physics/box2d/wrap_World.cpp @@ -113,6 +113,34 @@ namespace box2d return 1; } + int w_World_getContactCount(lua_State * L) + { + World * t = luax_checkworld(L, 1); + lua_pushinteger(L, t->getContactCount()); + return 1; + } + + int w_World_getBodyList(lua_State * L) + { + World * t = luax_checkworld(L, 1); + lua_remove(L, 1); + return t->getBodyList(L); + } + + int w_World_getJointList(lua_State * L) + { + World * t = luax_checkworld(L, 1); + lua_remove(L, 1); + return t->getJointList(L); + } + + int w_World_getContactList(lua_State * L) + { + World * t = luax_checkworld(L, 1); + lua_remove(L, 1); + return t->getContactList(L); + } + int w_World_queryBoundingBox(lua_State * L) { World * t = luax_checkworld(L, 1); @@ -139,6 +167,10 @@ namespace box2d { "getAllowSleeping", w_World_getAllowSleeping }, { "getBodyCount", w_World_getBodyCount }, { "getJointCount", w_World_getJointCount }, + { "getContactCount", w_World_getContactCount }, + { "getBodyList", w_World_getBodyList }, + { "getJointList", w_World_getJointList }, + { "getContactList", w_World_getContactList }, { "queryBoundingBox", w_World_queryBoundingBox }, { "rayCast", w_World_rayCast }, { 0, 0 } diff --git a/src/modules/physics/box2d/wrap_World.h b/src/modules/physics/box2d/wrap_World.h index 3fddb8ec6..e2a10a19c 100644 --- a/src/modules/physics/box2d/wrap_World.h +++ b/src/modules/physics/box2d/wrap_World.h @@ -43,6 +43,10 @@ namespace box2d int w_World_getAllowSleeping(lua_State * L); int w_World_getBodyCount(lua_State * L); int w_World_getJointCount(lua_State * L); + int w_World_getContactCount(lua_State * L); + int w_World_getBodyList(lua_State * L); + int w_World_getJointList(lua_State * L); + int w_World_getContactList(lua_State * L); int w_World_queryBoundingBox(lua_State * L); int w_World_rayCast(lua_State * L); int luaopen_world(lua_State * L);