diff --git a/src/modules/physics/box2d/EdgeShape.cpp b/src/modules/physics/box2d/EdgeShape.cpp index f394664e0..3c612738b 100644 --- a/src/modules/physics/box2d/EdgeShape.cpp +++ b/src/modules/physics/box2d/EdgeShape.cpp @@ -49,6 +49,7 @@ void EdgeShape::setNextVertex(float x, float y) b2EdgeShape *e = (b2EdgeShape *)shape; b2Vec2 v(x, y); e->m_vertex3 = Physics::scaleDown(v); + e->m_oneSided = true; } b2Vec2 EdgeShape::getNextVertex() const @@ -64,6 +65,7 @@ void EdgeShape::setPreviousVertex(float x, float y) b2EdgeShape *e = (b2EdgeShape *)shape; b2Vec2 v(x, y); e->m_vertex0 = Physics::scaleDown(v); + e->m_oneSided = true; } b2Vec2 EdgeShape::getPreviousVertex() const diff --git a/src/modules/physics/box2d/Physics.cpp b/src/modules/physics/box2d/Physics.cpp index c3b3d5189..8b5e70d9d 100644 --- a/src/modules/physics/box2d/Physics.cpp +++ b/src/modules/physics/box2d/Physics.cpp @@ -93,12 +93,22 @@ Body *Physics::newPolygonBody(World *world, Body::Type type, const Vector2 *coor return body.get(); } -Body *Physics::newEdgeBody(World *world, Body::Type type, float x1, float y1, float x2, float y2, bool oneSided) +Body *Physics::newEdgeBody(World *world, Body::Type type, float x1, float y1, float x2, float y2) { float wx = (x2 - x1) / 2.0f; float wy = (y2 - y1) / 2.0f; StrongRef body(newBody(world, wx, wy, type), Acquire::NORETAIN); - StrongRef shape(newEdgeShape(body, x1 - wx, y1 - wy, x2 - wx, y2 - wy, oneSided), Acquire::NORETAIN); + StrongRef shape(newEdgeShape(body, x1 - wx, y1 - wy, x2 - wx, y2 - wy), Acquire::NORETAIN); + body->retain(); + return body.get(); +} + +Body *Physics::newEdgeBody(World *world, Body::Type type, float x1, float y1, float x2, float y2, float prevx, float prevy, float nextx, float nexty) +{ + float wx = (x2 - x1) / 2.0f; + float wy = (y2 - y1) / 2.0f; + StrongRef body(newBody(world, wx, wy, type), Acquire::NORETAIN); + StrongRef shape(newEdgeShape(body, x1 - wx, y1 - wy, x2 - wx, y2 - wy, prevx - wx, prevy - wy, nextx - wx, nexty - wy), Acquire::NORETAIN); body->retain(); return body.get(); } @@ -167,19 +177,21 @@ PolygonShape *Physics::newRectangleShape(Body *body, float x, float y, float w, return new PolygonShape(body, s); } -EdgeShape *Physics::newEdgeShape(Body *body, float x1, float y1, float x2, float y2, bool oneSided) +EdgeShape *Physics::newEdgeShape(Body *body, float x1, float y1, float x2, float y2) { b2EdgeShape s; - if (oneSided) - { - b2Vec2 v1 = Physics::scaleDown(b2Vec2(x1, y1)); - b2Vec2 v2 = Physics::scaleDown(b2Vec2(x2, y2)); - s.SetOneSided(v1, v1, v2, v2); - } - else - { - s.SetTwoSided(Physics::scaleDown(b2Vec2(x1, y1)), Physics::scaleDown(b2Vec2(x2, y2))); - } + s.SetTwoSided(Physics::scaleDown(b2Vec2(x1, y1)), Physics::scaleDown(b2Vec2(x2, y2))); + return new EdgeShape(body, s); +} + +EdgeShape *Physics::newEdgeShape(Body *body, float x1, float y1, float x2, float y2, float prevx, float prevy, float nextx, float nexty) +{ + b2EdgeShape s; + b2Vec2 v0 = Physics::scaleDown(b2Vec2(prevx, prevy)); + b2Vec2 v1 = Physics::scaleDown(b2Vec2(x1, y1)); + b2Vec2 v2 = Physics::scaleDown(b2Vec2(x2, y2)); + b2Vec2 v3 = Physics::scaleDown(b2Vec2(nextx, nexty)); + s.SetOneSided(v0, v1, v2, v3); return new EdgeShape(body, s); } diff --git a/src/modules/physics/box2d/Physics.h b/src/modules/physics/box2d/Physics.h index 41da7d0fd..c67411e37 100644 --- a/src/modules/physics/box2d/Physics.h +++ b/src/modules/physics/box2d/Physics.h @@ -97,7 +97,8 @@ public: Body *newCircleBody(World *world, Body::Type type, float x, float y, float radius); Body *newRectangleBody(World *world, Body::Type type, float x, float y, float w, float h, float angle); Body *newPolygonBody(World *world, Body::Type type, const Vector2 *coords, int count); - Body *newEdgeBody(World *world, Body::Type type, float x1, float y1, float x2, float y2, bool oneSided); + Body *newEdgeBody(World *world, Body::Type type, float x1, float y1, float x2, float y2); + Body *newEdgeBody(World *world, Body::Type type, float x1, float y1, float x2, float y2, float prevx, float prevy, float nextx, float nexty); Body *newChainBody(World *world, Body::Type type, bool loop, const Vector2 *coords, int count); // Necessary to support the deprecated newFixture API. @@ -130,7 +131,8 @@ public: * @param x2 The x coordinate of the second point. * @param y2 The y coordinate of the second point. **/ - EdgeShape *newEdgeShape(Body *body, float x1, float y1, float x2, float y2, bool oneSided); + EdgeShape *newEdgeShape(Body *body, float x1, float y1, float x2, float y2); + EdgeShape *newEdgeShape(Body *body, float x1, float y1, float x2, float y2, float prevx, float prevy, float nextx, float nexty); /** * Creates a new PolygonShape from a variable number of vertices. diff --git a/src/modules/physics/box2d/wrap_Physics.cpp b/src/modules/physics/box2d/wrap_Physics.cpp index 680973d36..f05402787 100644 --- a/src/modules/physics/box2d/wrap_Physics.cpp +++ b/src/modules/physics/box2d/wrap_Physics.cpp @@ -190,10 +190,21 @@ int w_newEdgeBody(lua_State *L) float y1 = (float)luaL_checknumber(L, 4); float x2 = (float)luaL_checknumber(L, 5); float y2 = (float)luaL_checknumber(L, 6); - bool oneSided = luax_optboolean(L, 7, false); Body *body = nullptr; - luax_catchexcept(L, [&]() { body = instance()->newEdgeBody(world, btype, x1, y1, x2, y2, oneSided); }); + + if (lua_isnoneornil(L, 7)) + { + luax_catchexcept(L, [&]() { body = instance()->newEdgeBody(world, btype, x1, y1, x2, y2); }); + } + else + { + float prevx = (float)luaL_checknumber(L, 7); + float prevy = (float)luaL_checknumber(L, 8); + float nextx = (float)luaL_checknumber(L, 9); + float nexty = (float)luaL_checknumber(L, 10); + luax_catchexcept(L, [&]() { body = instance()->newEdgeBody(world, btype, x1, y1, x2, y2, prevx, prevy, nextx, nexty); }); + } luax_pushtype(L, body); body->release(); @@ -352,9 +363,19 @@ int w_newEdgeShape(lua_State *L) float y1 = (float)luaL_checknumber(L, bodyidx + 2); float x2 = (float)luaL_checknumber(L, bodyidx + 3); float y2 = (float)luaL_checknumber(L, bodyidx + 4); - bool oneSided = luax_optboolean(L, bodyidx + 5, false); EdgeShape *shape; - luax_catchexcept(L, [&](){ shape = instance()->newEdgeShape(body, x1, y1, x2, y2, oneSided); }); + if (lua_isnoneornil(L, bodyidx + 5)) + { + luax_catchexcept(L, [&](){ shape = instance()->newEdgeShape(body, x1, y1, x2, y2); }); + } + else + { + float prevx = (float)luaL_checknumber(L, bodyidx + 5); + float prevy = (float)luaL_checknumber(L, bodyidx + 6); + float nextx = (float)luaL_checknumber(L, bodyidx + 7); + float nexty = (float)luaL_checknumber(L, bodyidx + 8); + luax_catchexcept(L, [&]() { shape = instance()->newEdgeShape(body, x1, y1, x2, y2, prevx, prevy, nextx, nexty); }); + } luax_pushtype(L, shape); shape->release(); return 1;