Browse Source

Support reference angle on revolute, prismatic, and weld joints (fixes #1194)

airstruck 9 years ago
parent
commit
154f7cbc7e

+ 15 - 0
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);

+ 9 - 0
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)

+ 24 - 5
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

+ 9 - 0
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

+ 23 - 3
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

+ 9 - 0
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

+ 23 - 3
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

+ 9 - 0
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

+ 9 - 3
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();

+ 8 - 0
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 }
 };
 

+ 8 - 0
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 }
 };
 

+ 8 - 0
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 }
 };