Browse Source

Memoize Contacts, and add List-fetching functions to World (they return arrays)

--HG--
branch : box2d-update
Bill Meltsner 14 years ago
parent
commit
6a0c5b485b

+ 4 - 0
src/modules/physics/box2d/Contact.cpp

@@ -22,6 +22,8 @@
 #include "World.h"
 #include "Physics.h"
 
+#include <common/Memoizer.h>
+
 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)

+ 50 - 0
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;

+ 24 - 0
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.

+ 32 - 0
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 }

+ 4 - 0
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);