Browse Source

Add World:rayCast

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

+ 48 - 0
src/modules/physics/box2d/World.cpp

@@ -168,6 +168,39 @@ namespace box2d
 		}
 		}
 		return true;
 		return true;
 	}
 	}
+	
+	World::RayCastCallback::RayCastCallback()
+	: ref(0)
+	{
+	}
+	
+	World::RayCastCallback::~RayCastCallback()
+	{
+		if(ref != 0)
+			delete ref;
+	}
+	
+	float32 World::RayCastCallback::ReportFixture(b2Fixture * fixture, const b2Vec2& point, const b2Vec2& normal, float32 fraction)
+	{
+		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);
+			b2Vec2 scaledPoint = Physics::scaleUp(point);
+			lua_pushnumber(L, scaledPoint.x);
+			lua_pushnumber(L, scaledPoint.y);
+			b2Vec2 scaledNormal = Physics::scaleUp(normal);
+			lua_pushnumber(L, scaledNormal.x);
+			lua_pushnumber(L, scaledNormal.y);
+			lua_pushnumber(L, fraction);
+			lua_call(L, 6, 1);
+			return (float32)luaL_checknumber(L, -1);
+		}
+		return 0;
+	}
 
 
 	World::World()
 	World::World()
 		: world(NULL)
 		: world(NULL)
@@ -339,6 +372,21 @@ namespace box2d
 		world->QueryAABB(&query, box);
 		world->QueryAABB(&query, box);
 		return 0;
 		return 0;
 	}
 	}
+	
+	int World::rayCast(lua_State * L)
+	{
+		luax_assert_argc(L, 5);
+		float x1 = (float)luaL_checknumber(L, 1);
+		float y1 = (float)luaL_checknumber(L, 2);
+		float x2 = (float)luaL_checknumber(L, 3);
+		float y2 = (float)luaL_checknumber(L, 4);
+		b2Vec2 v1 = Physics::scaleDown(b2Vec2(x1, y1));
+		b2Vec2 v2 = Physics::scaleDown(b2Vec2(x2, y2));
+		if (raycast.ref) delete raycast.ref;
+		raycast.ref = luax_refif(L, LUA_TFUNCTION);
+		world->RayCast(&raycast, v1, v2);
+		return 0;
+	}
 
 
 } // box2d
 } // box2d
 } // physics
 } // physics

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

@@ -95,6 +95,15 @@ namespace box2d
 			~QueryCallback();
 			~QueryCallback();
 			virtual bool ReportFixture(b2Fixture * fixture);
 			virtual bool ReportFixture(b2Fixture * fixture);
 		};
 		};
+		
+		class RayCastCallback : public b2RayCastCallback
+		{
+		public:
+			Reference * ref;
+			RayCastCallback();
+			~RayCastCallback();
+			virtual float32 ReportFixture(b2Fixture * fixture, const b2Vec2& point, const b2Vec2& normal, float32 fraction);
+		};
 
 
 	private:
 	private:
 
 
@@ -108,6 +117,7 @@ namespace box2d
 		ContactCallback begin, end, presolve, postsolve;
 		ContactCallback begin, end, presolve, postsolve;
 		ContactFilter filter;
 		ContactFilter filter;
 		QueryCallback query;
 		QueryCallback query;
+		RayCastCallback	raycast;
 
 
 	public:
 	public:
 
 
@@ -215,6 +225,11 @@ namespace box2d
 		* Gets all fixtures that overlap a given bounding box.
 		* Gets all fixtures that overlap a given bounding box.
 		**/
 		**/
 		int queryBoundingBox(lua_State * L);
 		int queryBoundingBox(lua_State * L);
+		
+		/**
+		* Raycasts the World for all Fixtures in the path of the ray.
+		**/
+		int rayCast(lua_State * L);
 
 
 	};
 	};
 
 

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

@@ -119,6 +119,13 @@ namespace box2d
 		lua_remove(L, 1);
 		lua_remove(L, 1);
 		return t->queryBoundingBox(L);
 		return t->queryBoundingBox(L);
 	}
 	}
+	
+	int w_World_rayCast(lua_State * L)
+	{
+		World * t = luax_checkworld(L, 1);
+		lua_remove(L, 1);
+		return t->rayCast(L);
+	}
 
 
 	static const luaL_Reg functions[] = {
 	static const luaL_Reg functions[] = {
 		{ "update", w_World_update },
 		{ "update", w_World_update },
@@ -133,6 +140,7 @@ namespace box2d
 		{ "getBodyCount", w_World_getBodyCount },
 		{ "getBodyCount", w_World_getBodyCount },
 		{ "getJointCount", w_World_getJointCount },
 		{ "getJointCount", w_World_getJointCount },
 		{ "queryBoundingBox", w_World_queryBoundingBox },
 		{ "queryBoundingBox", w_World_queryBoundingBox },
+		{ "rayCast", w_World_rayCast },
 		{ 0, 0 }
 		{ 0, 0 }
 	};
 	};
 
 

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

@@ -44,6 +44,7 @@ namespace box2d
 	int w_World_getBodyCount(lua_State * L);
 	int w_World_getBodyCount(lua_State * L);
 	int w_World_getJointCount(lua_State * L);
 	int w_World_getJointCount(lua_State * L);
 	int w_World_queryBoundingBox(lua_State * L);
 	int w_World_queryBoundingBox(lua_State * L);
+	int w_World_rayCast(lua_State * L);
 	int luaopen_world(lua_State * L);
 	int luaopen_world(lua_State * L);
 
 
 } // box2d
 } // box2d