diff --git a/src/modules/physics/box2d/Shape.cpp b/src/modules/physics/box2d/Shape.cpp index e5ab9f7c7..177ebfad7 100644 --- a/src/modules/physics/box2d/Shape.cpp +++ b/src/modules/physics/box2d/Shape.cpp @@ -33,8 +33,8 @@ namespace physics { namespace box2d { - Shape::Shape() - : shape(NULL) + Shape::Shape(World * world) + : world(world), shape(NULL) { } @@ -59,6 +59,77 @@ namespace box2d return SHAPE_INVALID; } } + + float Shape::getRadius() const + { + return world->scaleUp(shape->m_radius); + } + + int Shape::getChildCount() const + { + return shape->GetChildCount(); + } + + bool Shape::testPoint(float x, float y, float r, float px, float py) const + { + b2Vec2 point(px, py); + b2Transform transform(world->scaleDown(b2Vec2(x, y)), b2Rot(r)); + return shape->TestPoint(transform, world->scaleDown(point)); + } + + int Shape::rayCast(lua_State * L) const + { + float p1x = world->scaleDown((float)luaL_checknumber(L, 1)); + float p1y = world->scaleDown((float)luaL_checknumber(L, 2)); + float p2x = world->scaleDown((float)luaL_checknumber(L, 3)); + float p2y = world->scaleDown((float)luaL_checknumber(L, 4)); + float maxFraction = (float)luaL_checknumber(L, 5); + float x = world->scaleDown((float)luaL_checknumber(L, 6)); + float y = world->scaleDown((float)luaL_checknumber(L, 7)); + float r = (float)luaL_checknumber(L, 8); + int childIndex = (int)luaL_optint(L, 9, 0); + b2RayCastInput input; + input.p1.Set(p1x, p1y); + input.p2.Set(p2x, p2y); + input.maxFraction = maxFraction; + b2Transform transform(b2Vec2(x, y), b2Rot(r)); + b2RayCastOutput output; + shape->RayCast(&output, input, transform, childIndex); + lua_pushnumber(L, world->scaleUp(output.normal.x)); + lua_pushnumber(L, world->scaleUp(output.normal.y)); + lua_pushnumber(L, output.fraction); + return 3; + } + + int Shape::computeAABB(lua_State * L) const + { + float x = world->scaleDown((float)luaL_checknumber(L, 1)); + float y = world->scaleDown((float)luaL_checknumber(L, 2)); + float r = (float)luaL_checknumber(L, 3); + int childIndex = (int)luaL_optint(L, 4, 0); + b2Transform transform(b2Vec2(x, y), b2Rot(r)); + b2AABB box; + shape->ComputeAABB(&box, transform, childIndex); + box = world->scaleUp(box); + lua_pushnumber(L, box.lowerBound.x); + lua_pushnumber(L, box.lowerBound.y); + lua_pushnumber(L, box.upperBound.x); + lua_pushnumber(L, box.upperBound.y); + return 4; + } + + int Shape::computeMass(lua_State * L) const + { + float density = world->scaleDown((float)luaL_checknumber(L, 1)); + b2MassData data; + shape->ComputeMass(&data, density); + b2Vec2 center = world->scaleUp(data.center); + lua_pushnumber(L, center.x); + lua_pushnumber(L, center.y); + lua_pushnumber(L, data.mass); + lua_pushnumber(L, data.I); + return 4; + } } // box2d } // physics diff --git a/src/modules/physics/box2d/Shape.h b/src/modules/physics/box2d/Shape.h index bb77239f3..e89e10d2e 100644 --- a/src/modules/physics/box2d/Shape.h +++ b/src/modules/physics/box2d/Shape.h @@ -44,6 +44,9 @@ namespace box2d **/ class Shape : public love::physics::Shape { + private: + World * world; // We need a reference for scaling up/down + protected: // The Box2D shape. @@ -54,7 +57,7 @@ namespace box2d /** * Creates a Shape. **/ - Shape(); + Shape(World * world); virtual ~Shape(); @@ -63,6 +66,12 @@ namespace box2d * debug drawing. **/ Type getType() const; + float getRadius() const; + int getChildCount() const; + bool testPoint(float x, float y, float r, float px, float py) const; + int rayCast(lua_State * L) const; + int computeAABB(lua_State * L) const; + int computeMass(lua_State * L) const; }; } // box2d diff --git a/src/modules/physics/box2d/wrap_CircleShape.cpp b/src/modules/physics/box2d/wrap_CircleShape.cpp index a17bef0d9..f205dfa5e 100644 --- a/src/modules/physics/box2d/wrap_CircleShape.cpp +++ b/src/modules/physics/box2d/wrap_CircleShape.cpp @@ -51,6 +51,12 @@ namespace box2d { "setRadius", w_CircleShape_setRadius }, // From Shape. { "getType", w_Shape_getType }, + { "getRadius", w_Shape_getRadius }, + { "getChildCount", w_Shape_getChildCount }, + { "testPoint", w_Shape_testPoint }, + { "rayCast", w_Shape_rayCast }, + { "computeAABB", w_Shape_computeAABB }, + { "computeMass", w_Shape_computeMass }, { "destroy", w_Shape_destroy }, { 0, 0 } }; diff --git a/src/modules/physics/box2d/wrap_EdgeShape.cpp b/src/modules/physics/box2d/wrap_EdgeShape.cpp index be64c4feb..3a8f23276 100644 --- a/src/modules/physics/box2d/wrap_EdgeShape.cpp +++ b/src/modules/physics/box2d/wrap_EdgeShape.cpp @@ -34,6 +34,12 @@ namespace box2d static const luaL_Reg functions[] = { // From Shape. { "getType", w_Shape_getType }, + { "getRadius", w_Shape_getRadius }, + { "getChildCount", w_Shape_getChildCount }, + { "testPoint", w_Shape_testPoint }, + { "rayCast", w_Shape_rayCast }, + { "computeAABB", w_Shape_computeAABB }, + { "computeMass", w_Shape_computeMass }, { "destroy", w_Shape_destroy }, { 0, 0 } }; diff --git a/src/modules/physics/box2d/wrap_PolygonShape.cpp b/src/modules/physics/box2d/wrap_PolygonShape.cpp index 8b8a5cc28..e86029fc6 100644 --- a/src/modules/physics/box2d/wrap_PolygonShape.cpp +++ b/src/modules/physics/box2d/wrap_PolygonShape.cpp @@ -42,6 +42,12 @@ namespace box2d { "getPoints", w_PolygonShape_getPoints }, // From Shape. { "getType", w_Shape_getType }, + { "getRadius", w_Shape_getRadius }, + { "getChildCount", w_Shape_getChildCount }, + { "testPoint", w_Shape_testPoint }, + { "rayCast", w_Shape_rayCast }, + { "computeAABB", w_Shape_computeAABB }, + { "computeMass", w_Shape_computeMass }, { "destroy", w_Shape_destroy }, { 0, 0 } }; diff --git a/src/modules/physics/box2d/wrap_Shape.cpp b/src/modules/physics/box2d/wrap_Shape.cpp index 510b75b16..23ebe6284 100644 --- a/src/modules/physics/box2d/wrap_Shape.cpp +++ b/src/modules/physics/box2d/wrap_Shape.cpp @@ -40,6 +40,56 @@ namespace box2d lua_pushstring(L, type); return 1; } + + int w_Shape_getRadius(lua_State * L) + { + Shape * t = luax_checkshape(L, 1); + float radius = t->getRadius(); + lua_pushnumber(L, radius); + return 1; + } + + int w_Shape_getChildCount(lua_State * L) + { + Shape * t = luax_checkshape(L, 1); + int childCount = t->getChildCount(); + lua_pushinteger(L, childCount); + return 1; + } + + int w_Shape_testPoint(lua_State * L) + { + Shape * t = luax_checkshape(L, 1); + float x = (float)luaL_checknumber(L, 1); + float y = (float)luaL_checknumber(L, 2); + float r = (float)luaL_checknumber(L, 3); + float px = (float)luaL_checknumber(L, 4); + float py = (float)luaL_checknumber(L, 5); + bool result = t->testPoint(x, y, r, px, py); + lua_pushboolean(L, result); + return 1; + } + + int w_Shape_rayCast(lua_State * L) + { + Shape * t = luax_checkshape(L, 1); + lua_remove(L, 1); + return t->rayCast(L); + } + + int w_Shape_computeAABB(lua_State * L) + { + Shape * t = luax_checkshape(L, 1); + lua_remove(L, 1); + return t->computeAABB(L); + } + + int w_Shape_computeMass(lua_State * L) + { + Shape * t = luax_checkshape(L, 1); + lua_remove(L, 1); + return t->computeMass(L); + } int w_Shape_destroy(lua_State * L) { @@ -53,6 +103,12 @@ namespace box2d static const luaL_Reg functions[] = { { "getType", w_Shape_getType }, + { "getRadius", w_Shape_getRadius }, + { "getChildCount", w_Shape_getChildCount }, + { "testPoint", w_Shape_testPoint }, + { "rayCast", w_Shape_rayCast }, + { "computeAABB", w_Shape_computeAABB }, + { "computeMass", w_Shape_computeMass }, { "destroy", w_Shape_destroy }, { 0, 0 } }; diff --git a/src/modules/physics/box2d/wrap_Shape.h b/src/modules/physics/box2d/wrap_Shape.h index 02950111d..cc26c5c2b 100644 --- a/src/modules/physics/box2d/wrap_Shape.h +++ b/src/modules/physics/box2d/wrap_Shape.h @@ -33,6 +33,14 @@ namespace box2d { Shape * luax_checkshape(lua_State * L, int idx); int w_Shape_getType(lua_State * L); + int w_Shape_getRadius(lua_State * L); + + int w_Shape_getChildCount(lua_State * L); + int w_Shape_testPoint(lua_State * L); + int w_Shape_rayCast(lua_State * L); + int w_Shape_computeAABB(lua_State * L); + int w_Shape_computeMass(lua_State * L); + int w_Shape_destroy(lua_State * L); int luaopen_shape(lua_State * L);