Browse Source

Add World:queryBoundingBox

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

+ 42 - 1
src/modules/physics/box2d/World.cpp

@@ -142,6 +142,32 @@ namespace box2d
 		}
 		return true;
 	}
+	
+	World::QueryCallback::QueryCallback()
+	: ref(0)
+	{
+	}
+	
+	World::QueryCallback::~QueryCallback()
+	{
+		if(ref != 0)
+			delete ref;
+	}
+	
+	bool World::QueryCallback::ReportFixture(b2Fixture * fixture)
+	{
+		if (ref != 0)
+		{
+			lua_State * L = ref->getL();
+			ref->push();
+			Fixture * f = (Fixture *)Memoizer::find(fixture);
+			if (!f) throw love::Exception("A fixture has escaped Memoizer!");
+			luax_newtype(L, "Fixture", PHYSICS_FIXTURE_T, (void*)f);
+			lua_call(L, 1, 1);
+			return luax_toboolean(L, -1);
+		}
+		return true;
+	}
 
 	World::World()
 		: world(NULL)
@@ -176,7 +202,6 @@ namespace box2d
 	{
 		world->Step(dt, 8, 6);
 
-
 		begin.process();
 		end.process();
 		presolve.process();
@@ -298,6 +323,22 @@ namespace box2d
 	{
 		return groundBody;
 	}
+	
+	int World::queryBoundingBox(lua_State * L)
+	{
+		luax_assert_argc(L, 5);
+		b2AABB box;
+		float lx = (float)luaL_checknumber(L, 1);
+		float ly = (float)luaL_checknumber(L, 2);
+		float ux = (float)luaL_checknumber(L, 3);
+		float uy = (float)luaL_checknumber(L, 4);
+		box.lowerBound = Physics::scaleDown(b2Vec2(lx, ly));
+		box.upperBound = Physics::scaleDown(b2Vec2(ux, uy));
+		if (query.ref) delete query.ref;
+		query.ref = luax_refif(L, LUA_TFUNCTION);
+		world->QueryAABB(&query, box);
+		return 0;
+	}
 
 } // box2d
 } // physics

+ 15 - 0
src/modules/physics/box2d/World.h

@@ -86,6 +86,15 @@ namespace box2d
 			~ContactFilter();
 			bool process(Fixture * a, Fixture * b);
 		};
+		
+		class QueryCallback : public b2QueryCallback
+		{
+		public:
+			Reference * ref;
+			QueryCallback();
+			~QueryCallback();
+			virtual bool ReportFixture(b2Fixture * fixture);
+		};
 
 	private:
 
@@ -98,6 +107,7 @@ namespace box2d
 		// Contact callbacks.
 		ContactCallback begin, end, presolve, postsolve;
 		ContactFilter filter;
+		QueryCallback query;
 
 	public:
 
@@ -200,6 +210,11 @@ namespace box2d
         * @return The ground body.
         **/
         b2Body * getGroundBody();
+		
+		/**
+		* Gets all fixtures that overlap a given bounding box.
+		**/
+		int queryBoundingBox(lua_State * L);
 
 	};
 

+ 8 - 0
src/modules/physics/box2d/wrap_World.cpp

@@ -112,6 +112,13 @@ namespace box2d
 		lua_pushinteger(L, t->getJointCount());
 		return 1;
 	}
+	
+	int w_World_queryBoundingBox(lua_State * L)
+	{
+		World * t = luax_checkworld(L, 1);
+		lua_remove(L, 1);
+		return t->queryBoundingBox(L);
+	}
 
 	static const luaL_Reg functions[] = {
 		{ "update", w_World_update },
@@ -125,6 +132,7 @@ namespace box2d
 		{ "getAllowSleeping", w_World_getAllowSleeping },
 		{ "getBodyCount", w_World_getBodyCount },
 		{ "getJointCount", w_World_getJointCount },
+		{ "queryBoundingBox", w_World_queryBoundingBox },
 		{ 0, 0 }
 	};
 

+ 1 - 0
src/modules/physics/box2d/wrap_World.h

@@ -43,6 +43,7 @@ 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_queryBoundingBox(lua_State * L);
 	int luaopen_world(lua_State * L);
 
 } // box2d