From 154f7cbc7e69f422b555d728785d1a1e73198c4a Mon Sep 17 00:00:00 2001 From: airstruck Date: Fri, 19 Aug 2016 14:36:36 +0200 Subject: [PATCH] Support reference angle on revolute, prismatic, and weld joints (fixes #1194) --- src/modules/physics/box2d/Physics.cpp | 15 ++++++++++ src/modules/physics/box2d/Physics.h | 9 ++++++ src/modules/physics/box2d/PrismaticJoint.cpp | 29 +++++++++++++++---- src/modules/physics/box2d/PrismaticJoint.h | 9 ++++++ src/modules/physics/box2d/RevoluteJoint.cpp | 26 +++++++++++++++-- src/modules/physics/box2d/RevoluteJoint.h | 9 ++++++ src/modules/physics/box2d/WeldJoint.cpp | 26 +++++++++++++++-- src/modules/physics/box2d/WeldJoint.h | 9 ++++++ src/modules/physics/box2d/wrap_Physics.cpp | 12 ++++++-- .../physics/box2d/wrap_PrismaticJoint.cpp | 8 +++++ .../physics/box2d/wrap_RevoluteJoint.cpp | 8 +++++ src/modules/physics/box2d/wrap_WeldJoint.cpp | 8 +++++ 12 files changed, 154 insertions(+), 14 deletions(-) diff --git a/src/modules/physics/box2d/Physics.cpp b/src/modules/physics/box2d/Physics.cpp index 778cc4566..e55be0c5e 100644 --- a/src/modules/physics/box2d/Physics.cpp +++ b/src/modules/physics/box2d/Physics.cpp @@ -228,11 +228,21 @@ RevoluteJoint *Physics::newRevoluteJoint(Body *body1, Body *body2, float xA, flo return new RevoluteJoint(body1, body2, xA, yA, xB, yB, collideConnected); } +RevoluteJoint *Physics::newRevoluteJoint(Body *body1, Body *body2, float xA, float yA, float xB, float yB, bool collideConnected, float referenceAngle) +{ + return new RevoluteJoint(body1, body2, xA, yA, xB, yB, collideConnected, referenceAngle); +} + PrismaticJoint *Physics::newPrismaticJoint(Body *body1, Body *body2, float xA, float yA, float xB, float yB, float ax, float ay, bool collideConnected) { return new PrismaticJoint(body1, body2, xA, yA, xB, yB, ax, ay, collideConnected); } +PrismaticJoint *Physics::newPrismaticJoint(Body *body1, Body *body2, float xA, float yA, float xB, float yB, float ax, float ay, bool collideConnected, float referenceAngle) +{ + return new PrismaticJoint(body1, body2, xA, yA, xB, yB, ax, ay, collideConnected, referenceAngle); +} + PulleyJoint *Physics::newPulleyJoint(Body *body1, Body *body2, b2Vec2 groundAnchor1, b2Vec2 groundAnchor2, b2Vec2 anchor1, b2Vec2 anchor2, float ratio, bool collideConnected) { return new PulleyJoint(body1, body2, groundAnchor1, groundAnchor2, anchor1, anchor2, ratio, collideConnected); @@ -253,6 +263,11 @@ WeldJoint *Physics::newWeldJoint(Body *body1, Body *body2, float xA, float yA, f return new WeldJoint(body1, body2, xA, yA, xB, yB, collideConnected); } +WeldJoint *Physics::newWeldJoint(Body *body1, Body *body2, float xA, float yA, float xB, float yB, bool collideConnected, float referenceAngle) +{ + return new WeldJoint(body1, body2, xA, yA, xB, yB, collideConnected, referenceAngle); +} + WheelJoint *Physics::newWheelJoint(Body *body1, Body *body2, float xA, float yA, float xB, float yB, float ax, float ay, bool collideConnected) { return new WheelJoint(body1, body2, xA, yA, xB, yB, ax, ay, collideConnected); diff --git a/src/modules/physics/box2d/Physics.h b/src/modules/physics/box2d/Physics.h index febe272b9..48089f5f9 100644 --- a/src/modules/physics/box2d/Physics.h +++ b/src/modules/physics/box2d/Physics.h @@ -176,9 +176,12 @@ public: * @param xB Anchor for body 2 along the x-axis. (World coordinates) * @param yB Anchor for body 2 along the y-axis. (World coordinates) * @param collideConnected Whether the connected bodies should collide with each other. Defaults to false. + * @param referenceAngle The reference angle. **/ RevoluteJoint *newRevoluteJoint(Body *body1, Body *body2, float xA, float yA, float xB, float yB, bool collideConnected); + RevoluteJoint *newRevoluteJoint(Body *body1, Body *body2, float xA, float yA, float xB, float yB, bool collideConnected, float referenceAngle); + /** * Creates a new PrismaticJoint connecting body1 with body2. * @param xA World-anchor for body1 along the x-axis. @@ -188,9 +191,12 @@ public: * @param ax The x-component of the world-axis. * @param ay The y-component of the world-axis. * @param collideConnected Whether the connected bodies should collide with each other. Defaults to false. + * @param referenceAngle The reference angle. **/ PrismaticJoint *newPrismaticJoint(Body *body1, Body *body2, float xA, float yA, float xB, float yB, float ax, float ay, bool collideConnected); + PrismaticJoint *newPrismaticJoint(Body *body1, Body *body2, float xA, float yA, float xB, float yB, float ax, float ay, bool collideConnected, float referenceAngle); + /** * Creates a new PulleyJoint connecting body1 with body2. * @param groundAnchor1 World ground-anchor for body1. @@ -228,9 +234,12 @@ public: * @param xB Anchor for body 2 along the x-axis. (World coordinates) * @param yB Anchor for body 2 along the y-axis. (World coordinates) * @param collideConnected Whether the connected bodies should collide with each other. Defaults to false. + * @param referenceAngle The reference angle. **/ WeldJoint *newWeldJoint(Body *body1, Body *body2, float xA, float yA, float xB, float yB, bool collideConnected); + WeldJoint *newWeldJoint(Body *body1, Body *body2, float xA, float yA, float xB, float yB, bool collideConnected, float referenceAngle); + /** * Creates a new WheelJoint connecting body1 with body2. * @param xA Anchor for body 1 along the x-axis. (World coordinates) diff --git a/src/modules/physics/box2d/PrismaticJoint.cpp b/src/modules/physics/box2d/PrismaticJoint.cpp index e390405e8..8ee1e1084 100644 --- a/src/modules/physics/box2d/PrismaticJoint.cpp +++ b/src/modules/physics/box2d/PrismaticJoint.cpp @@ -37,18 +37,32 @@ PrismaticJoint::PrismaticJoint(Body *body1, Body *body2, float xA, float yA, flo , joint(NULL) { b2PrismaticJointDef def; + init(def, body1, body2, xA, yA, xB, yB, ax, ay, collideConnected); + joint = (b2PrismaticJoint *)createJoint(&def); +} +PrismaticJoint::PrismaticJoint(Body *body1, Body *body2, float xA, float yA, float xB, float yB, float ax, float ay, bool collideConnected, float referenceAngle) + : Joint(body1, body2) + , joint(NULL) +{ + b2PrismaticJointDef def; + init(def, body1, body2, xA, yA, xB, yB, ax, ay, collideConnected); + def.referenceAngle = referenceAngle; + joint = (b2PrismaticJoint *)createJoint(&def); +} + +PrismaticJoint::~PrismaticJoint() +{ +} + +void PrismaticJoint::init(b2PrismaticJointDef &def, Body *body1, Body *body2, float xA, float yA, float xB, float yB, float ax, float ay, bool collideConnected) +{ def.Initialize(body1->body, body2->body, Physics::scaleDown(b2Vec2(xA,yA)), b2Vec2(ax,ay)); def.localAnchorB = body2->body->GetLocalPoint(Physics::scaleDown(b2Vec2(xB, yB))); def.lowerTranslation = 0.0f; def.upperTranslation = 100.0f; def.enableLimit = true; def.collideConnected = collideConnected; - joint = (b2PrismaticJoint *)createJoint(&def); -} - -PrismaticJoint::~PrismaticJoint() -{ } float PrismaticJoint::getJointTranslation() const @@ -147,6 +161,11 @@ int PrismaticJoint::getAxis(lua_State *L) return 2; } +float PrismaticJoint::getReferenceAngle() const +{ + return joint->GetReferenceAngle(); +} + } // box2d } // physics } // love diff --git a/src/modules/physics/box2d/PrismaticJoint.h b/src/modules/physics/box2d/PrismaticJoint.h index 584691544..dba1d4e70 100644 --- a/src/modules/physics/box2d/PrismaticJoint.h +++ b/src/modules/physics/box2d/PrismaticJoint.h @@ -44,6 +44,8 @@ public: **/ PrismaticJoint(Body *body1, Body *body2, float xA, float yA, float xB, float yB, float ax, float ay, bool collideConnected); + PrismaticJoint(Body *body1, Body *body2, float xA, float yA, float xB, float yB, float ax, float ay, bool collideConnected, float referenceAngle); + virtual ~PrismaticJoint(); /** @@ -141,10 +143,17 @@ public: **/ int getAxis(lua_State *L); + /** + * Gets the reference angle. + **/ + float getReferenceAngle() const; + private: // The Box2D prismatic joint object. b2PrismaticJoint *joint; + + void init(b2PrismaticJointDef &def, Body *body1, Body *body2, float xA, float yA, float xB, float yB, float ax, float ay, bool collideConnected); }; } // box2d diff --git a/src/modules/physics/box2d/RevoluteJoint.cpp b/src/modules/physics/box2d/RevoluteJoint.cpp index de9596328..ba1e1e87b 100644 --- a/src/modules/physics/box2d/RevoluteJoint.cpp +++ b/src/modules/physics/box2d/RevoluteJoint.cpp @@ -39,9 +39,17 @@ RevoluteJoint::RevoluteJoint(Body *body1, Body *body2, float xA, float yA, float , joint(NULL) { b2RevoluteJointDef def; - def.Initialize(body1->body, body2->body, Physics::scaleDown(b2Vec2(xA,yA))); - def.localAnchorB = body2->body->GetLocalPoint(Physics::scaleDown(b2Vec2(xB, yB))); - def.collideConnected = collideConnected; + init(def, body1, body2, xA, yA, xB, yB, collideConnected); + joint = (b2RevoluteJoint *)createJoint(&def); +} + +RevoluteJoint::RevoluteJoint(Body *body1, Body *body2, float xA, float yA, float xB, float yB, bool collideConnected, float referenceAngle) + : Joint(body1, body2) + , joint(NULL) +{ + b2RevoluteJointDef def; + init(def, body1, body2, xA, yA, xB, yB, collideConnected); + def.referenceAngle = referenceAngle; joint = (b2RevoluteJoint *)createJoint(&def); } @@ -49,6 +57,13 @@ RevoluteJoint::~RevoluteJoint() { } +void RevoluteJoint::init(b2RevoluteJointDef &def, Body *body1, Body *body2, float xA, float yA, float xB, float yB, bool collideConnected) +{ + def.Initialize(body1->body, body2->body, Physics::scaleDown(b2Vec2(xA,yA))); + def.localAnchorB = body2->body->GetLocalPoint(Physics::scaleDown(b2Vec2(xB, yB))); + def.collideConnected = collideConnected; +} + float RevoluteJoint::getJointAngle() const { return joint->GetJointAngle(); @@ -136,6 +151,11 @@ int RevoluteJoint::getLimits(lua_State *L) return 2; } +float RevoluteJoint::getReferenceAngle() const +{ + return joint->GetReferenceAngle(); +} + } // box2d } // physics } // love diff --git a/src/modules/physics/box2d/RevoluteJoint.h b/src/modules/physics/box2d/RevoluteJoint.h index ee490380d..f54026be5 100644 --- a/src/modules/physics/box2d/RevoluteJoint.h +++ b/src/modules/physics/box2d/RevoluteJoint.h @@ -44,6 +44,8 @@ public: **/ RevoluteJoint(Body *body1, Body *body2, float xA, float yA, float xB, float yB, bool collideConnected); + RevoluteJoint(Body *body1, Body *body2, float xA, float yA, float xB, float yB, bool collideConnected, float referenceAngle); + virtual ~RevoluteJoint(); /** @@ -134,10 +136,17 @@ public: **/ int getLimits(lua_State *L); + /** + * Gets the reference angle. + **/ + float getReferenceAngle() const; + private: // The Box2D revolute joint object. b2RevoluteJoint *joint; + + void init(b2RevoluteJointDef &def, Body *body1, Body *body2, float xA, float yA, float xB, float yB, bool collideConnected); }; } // box2d diff --git a/src/modules/physics/box2d/WeldJoint.cpp b/src/modules/physics/box2d/WeldJoint.cpp index 51b6b9f50..bc21a28f3 100644 --- a/src/modules/physics/box2d/WeldJoint.cpp +++ b/src/modules/physics/box2d/WeldJoint.cpp @@ -39,9 +39,17 @@ WeldJoint::WeldJoint(Body *body1, Body *body2, float xA, float yA, float xB, flo , joint(NULL) { b2WeldJointDef def; - def.Initialize(body1->body, body2->body, Physics::scaleDown(b2Vec2(xA,yA))); - def.localAnchorB = body2->body->GetLocalPoint(Physics::scaleDown(b2Vec2(xB, yB))); - def.collideConnected = collideConnected; + init(def, body1, body2, xA, yA, xB, yB, collideConnected); + joint = (b2WeldJoint *)createJoint(&def); +} + +WeldJoint::WeldJoint(Body *body1, Body *body2, float xA, float yA, float xB, float yB, bool collideConnected, float referenceAngle) + : Joint(body1, body2) + , joint(NULL) +{ + b2WeldJointDef def; + init(def, body1, body2, xA, yA, xB, yB, collideConnected); + def.referenceAngle = referenceAngle; joint = (b2WeldJoint *)createJoint(&def); } @@ -49,6 +57,13 @@ WeldJoint::~WeldJoint() { } +void WeldJoint::init(b2WeldJointDef &def, Body *body1, Body *body2, float xA, float yA, float xB, float yB, bool collideConnected) +{ + def.Initialize(body1->body, body2->body, Physics::scaleDown(b2Vec2(xA,yA))); + def.localAnchorB = body2->body->GetLocalPoint(Physics::scaleDown(b2Vec2(xB, yB))); + def.collideConnected = collideConnected; +} + void WeldJoint::setFrequency(float hz) { joint->SetFrequency(hz); @@ -69,6 +84,11 @@ float WeldJoint::getDampingRatio() const return joint->GetDampingRatio(); } +float WeldJoint::getReferenceAngle() const +{ + return joint->GetReferenceAngle(); +} + } // box2d } // physics } // love diff --git a/src/modules/physics/box2d/WeldJoint.h b/src/modules/physics/box2d/WeldJoint.h index 8ddbb9c8f..c3fa0a3d6 100644 --- a/src/modules/physics/box2d/WeldJoint.h +++ b/src/modules/physics/box2d/WeldJoint.h @@ -43,6 +43,8 @@ public: **/ WeldJoint(Body *body1, Body *body2, float xA, float yA, float xB, float yB, bool collideConnected); + WeldJoint(Body *body1, Body *body2, float xA, float yA, float xB, float yB, bool collideConnected, float referenceAngle); + virtual ~WeldJoint(); /** @@ -67,10 +69,17 @@ public: **/ float getDampingRatio() const; + /** + * Gets the reference angle. + **/ + float getReferenceAngle() const; + private: // The Box2D weld joint object. b2WeldJoint *joint; + + void init(b2WeldJointDef &def, Body *body1, Body *body2, float xA, float yA, float xB, float yB, bool collideConnected); }; } // box2d diff --git a/src/modules/physics/box2d/wrap_Physics.cpp b/src/modules/physics/box2d/wrap_Physics.cpp index 8ed78b48e..27dc7101a 100644 --- a/src/modules/physics/box2d/wrap_Physics.cpp +++ b/src/modules/physics/box2d/wrap_Physics.cpp @@ -219,11 +219,13 @@ int w_newRevoluteJoint(lua_State *L) float yA = (float)luaL_checknumber(L, 4); float xB, yB; bool collideConnected; + float referenceAngle = 0.0f; if (lua_gettop(L) >= 6) { xB = (float)luaL_checknumber(L, 5); yB = (float)luaL_checknumber(L, 6); collideConnected = luax_optboolean(L, 7, false); + referenceAngle = (float)luaL_optnumber(L, 8, referenceAngle); } else { @@ -233,7 +235,7 @@ int w_newRevoluteJoint(lua_State *L) } RevoluteJoint *j; luax_catchexcept(L, [&]() { - j = instance()->newRevoluteJoint(body1, body2, xA, yA, xB, yB, collideConnected); + j = instance()->newRevoluteJoint(body1, body2, xA, yA, xB, yB, collideConnected, referenceAngle); }); luax_pushtype(L, PHYSICS_REVOLUTE_JOINT_ID, j); j->release(); @@ -248,6 +250,7 @@ int w_newPrismaticJoint(lua_State *L) float yA = (float)luaL_checknumber(L, 4); float xB, yB, ax, ay; bool collideConnected; + float referenceAngle = 0.0f; if (lua_gettop(L) >= 8) { xB = (float)luaL_checknumber(L, 5); @@ -255,6 +258,7 @@ int w_newPrismaticJoint(lua_State *L) ax = (float)luaL_checknumber(L, 7); ay = (float)luaL_checknumber(L, 8); collideConnected = luax_optboolean(L, 9, false); + referenceAngle = (float)luaL_optnumber(L, 10, referenceAngle); } else { @@ -266,7 +270,7 @@ int w_newPrismaticJoint(lua_State *L) } PrismaticJoint *j; luax_catchexcept(L, [&]() { - j = instance()->newPrismaticJoint(body1, body2, xA, yA, xB, yB, ax, ay, collideConnected); + j = instance()->newPrismaticJoint(body1, body2, xA, yA, xB, yB, ax, ay, collideConnected, referenceAngle); }); luax_pushtype(L, PHYSICS_PRISMATIC_JOINT_ID, j); j->release(); @@ -350,11 +354,13 @@ int w_newWeldJoint(lua_State *L) float yA = (float)luaL_checknumber(L, 4); float xB, yB; bool collideConnected; + float referenceAngle = 0.0f; if (lua_gettop(L) >= 6) { xB = (float)luaL_checknumber(L, 5); yB = (float)luaL_checknumber(L, 6); collideConnected = luax_optboolean(L, 7, false); + referenceAngle = (float)luaL_optnumber(L, 8, referenceAngle); } else { @@ -364,7 +370,7 @@ int w_newWeldJoint(lua_State *L) } WeldJoint *j; luax_catchexcept(L, [&]() { - j = instance()->newWeldJoint(body1, body2, xA, yA, xB, yB, collideConnected); + j = instance()->newWeldJoint(body1, body2, xA, yA, xB, yB, collideConnected, referenceAngle); }); luax_pushtype(L, PHYSICS_WELD_JOINT_ID, j); j->release(); diff --git a/src/modules/physics/box2d/wrap_PrismaticJoint.cpp b/src/modules/physics/box2d/wrap_PrismaticJoint.cpp index c9e1b972c..a8c07331e 100644 --- a/src/modules/physics/box2d/wrap_PrismaticJoint.cpp +++ b/src/modules/physics/box2d/wrap_PrismaticJoint.cpp @@ -171,6 +171,13 @@ int w_PrismaticJoint_getAxis(lua_State *L) return t->getAxis(L); } +int w_PrismaticJoint_getReferenceAngle(lua_State *L) +{ + PrismaticJoint *t = luax_checkprismaticjoint(L, 1); + lua_pushnumber(L, t->getReferenceAngle()); + return 1; +} + static const luaL_Reg w_PrismaticJoint_functions[] = { { "getJointTranslation", w_PrismaticJoint_getJointTranslation }, @@ -191,6 +198,7 @@ static const luaL_Reg w_PrismaticJoint_functions[] = { "getUpperLimit", w_PrismaticJoint_getUpperLimit }, { "getLimits", w_PrismaticJoint_getLimits }, { "getAxis", w_PrismaticJoint_getAxis }, + { "getReferenceAngle", w_PrismaticJoint_getReferenceAngle }, { 0, 0 } }; diff --git a/src/modules/physics/box2d/wrap_RevoluteJoint.cpp b/src/modules/physics/box2d/wrap_RevoluteJoint.cpp index 9716e9944..10ef10580 100644 --- a/src/modules/physics/box2d/wrap_RevoluteJoint.cpp +++ b/src/modules/physics/box2d/wrap_RevoluteJoint.cpp @@ -164,6 +164,13 @@ int w_RevoluteJoint_getLimits(lua_State *L) return t->getLimits(L); } +int w_RevoluteJoint_getReferenceAngle(lua_State *L) +{ + RevoluteJoint *t = luax_checkrevolutejoint(L, 1); + lua_pushnumber(L, t->getReferenceAngle()); + return 1; +} + static const luaL_Reg w_RevoluteJoint_functions[] = { { "getJointAngle", w_RevoluteJoint_getJointAngle }, @@ -183,6 +190,7 @@ static const luaL_Reg w_RevoluteJoint_functions[] = { "getLowerLimit", w_RevoluteJoint_getLowerLimit }, { "getUpperLimit", w_RevoluteJoint_getUpperLimit }, { "getLimits", w_RevoluteJoint_getLimits }, + { "getReferenceAngle", w_RevoluteJoint_getReferenceAngle }, { 0, 0 } }; diff --git a/src/modules/physics/box2d/wrap_WeldJoint.cpp b/src/modules/physics/box2d/wrap_WeldJoint.cpp index 6b9ed8e75..92efc52a6 100644 --- a/src/modules/physics/box2d/wrap_WeldJoint.cpp +++ b/src/modules/physics/box2d/wrap_WeldJoint.cpp @@ -65,12 +65,20 @@ int w_WeldJoint_getDampingRatio(lua_State *L) return 1; } +int w_WeldJoint_getReferenceAngle(lua_State *L) +{ + WeldJoint *t = luax_checkweldjoint(L, 1); + lua_pushnumber(L, t->getReferenceAngle()); + return 1; +} + static const luaL_Reg w_WeldJoint_functions[] = { { "setFrequency", w_WeldJoint_setFrequency }, { "getFrequency", w_WeldJoint_getFrequency }, { "setDampingRatio", w_WeldJoint_setDampingRatio }, { "getDampingRatio", w_WeldJoint_getDampingRatio }, + { "getReferenceAngle", w_WeldJoint_getReferenceAngle }, { 0, 0 } };