Browse Source

Add EdgeShape:set/getNext/PreviousVertex. ChainShape:setNext/PreviousVertex can now take no arguments to disable ghost vertices.

Resolves issue #1191.
Alex Szpakowski 9 years ago
parent
commit
fc2c79ad5f

+ 29 - 13
src/modules/physics/box2d/ChainShape.cpp

@@ -55,6 +55,12 @@ void ChainShape::setNextVertex(float x, float y)
 	c->SetNextVertex(Physics::scaleDown(v));
 }
 
+void ChainShape::setNextVertex()
+{
+	b2ChainShape *c = (b2ChainShape *)shape;
+	c->m_hasNextVertex = false;
+}
+
 void ChainShape::setPreviousVertex(float x, float y)
 {
 	if (loop)
@@ -67,30 +73,40 @@ void ChainShape::setPreviousVertex(float x, float y)
 	c->SetPrevVertex(Physics::scaleDown(v));
 }
 
-bool ChainShape::hasNextVertex() const
+void ChainShape::setPreviousVertex()
 {
 	b2ChainShape *c = (b2ChainShape *)shape;
-	return c->m_hasNextVertex;
+	c->m_hasPrevVertex = false;
 }
 
-bool ChainShape::hasPreviousVertex() const
+bool ChainShape::getNextVertex(float &x, float &y) const
 {
 	b2ChainShape *c = (b2ChainShape *)shape;
-	return c->m_hasPrevVertex;
-}
 
-b2Vec2 ChainShape::getNextVertex() const
-{
-	b2ChainShape *c = (b2ChainShape *)shape;
-	const b2Vec2 &v = c->m_nextVertex;
-	return Physics::scaleUp(v);
+	if (c->m_hasNextVertex)
+	{
+		b2Vec2 v = Physics::scaleUp(c->m_nextVertex);
+		x = v.x;
+		y = v.y;
+		return true;
+	}
+
+	return false;
 }
 
-b2Vec2 ChainShape::getPreviousVertex() const
+bool ChainShape::getPreviousVertex(float &x, float &y) const
 {
 	b2ChainShape *c = (b2ChainShape *)shape;
-	const b2Vec2 &v = c->m_prevVertex;
-	return Physics::scaleUp(v);
+
+	if (c->m_hasPrevVertex)
+	{
+		b2Vec2 v = Physics::scaleUp(c->m_prevVertex);
+		x = v.x;
+		y = v.y;
+		return true;
+	}
+
+	return false;
 }
 
 EdgeShape *ChainShape::getChildEdge(int index) const

+ 6 - 18
src/modules/physics/box2d/ChainShape.h

@@ -54,6 +54,7 @@ public:
 	 * @param y The y-coordinate of the vertex.
 	 **/
 	void setNextVertex(float x, float y);
+	void setNextVertex();
 
 	/**
 	 * Establish connectivity to a vertex that precedes
@@ -62,30 +63,17 @@ public:
 	 * @param y The y-coordinate of the vertex.
 	 **/
 	void setPreviousVertex(float x, float y);
+	void setPreviousVertex();
 
 	/**
-	 * Returns whether a vertex that follows the last vertex exists.
-	 * @returns True if specified vertex exists, else false.
+	 * Gets the vertex that follows the last vertex.
 	 **/
-	bool hasNextVertex() const;
+	bool getNextVertex(float &x, float &y) const;
 
 	/**
-	 * Returns whether a vertex that precedes the first vertex exists.
-	 * @returns True if specified vertex exists, else false.
+	 * Gets the vertex that precedes the first vertex.
 	 **/
-	bool hasPreviousVertex() const;
-
-	/**
-	 * Returns the vertex that follows the last vertex.
-	 * @returns The specified vertex.
-	 **/
-	b2Vec2 getNextVertex() const;
-
-	/**
-	 * Returns the vertex that precedes the first vertex.
-	 * @returns The specified vertex.
-	 **/
-	b2Vec2 getPreviousVertex() const;
+	bool getPreviousVertex(float &x, float &y) const;
 
 	/**
 	 * Returns a child EdgeShape.

+ 58 - 0
src/modules/physics/box2d/EdgeShape.cpp

@@ -43,6 +43,64 @@ EdgeShape::~EdgeShape()
 {
 }
 
+void EdgeShape::setNextVertex(float x, float y)
+{
+	b2EdgeShape *e = (b2EdgeShape *)shape;
+	b2Vec2 v(x, y);
+	e->m_vertex3 = Physics::scaleDown(v);
+	e->m_hasVertex3 = true;
+}
+
+void EdgeShape::setNextVertex()
+{
+	b2EdgeShape *e = (b2EdgeShape *)shape;
+	e->m_hasVertex3 = false;
+}
+
+bool EdgeShape::getNextVertex(float &x, float &y) const
+{
+	b2EdgeShape *e = (b2EdgeShape *)shape;
+
+	if (e->m_hasVertex3)
+	{
+		b2Vec2 v = Physics::scaleUp(e->m_vertex3);
+		x = v.x;
+		y = v.y;
+		return true;
+	}
+
+	return false;
+}
+
+void EdgeShape::setPreviousVertex(float x, float y)
+{
+	b2EdgeShape *e = (b2EdgeShape *)shape;
+	b2Vec2 v(x, y);
+	e->m_vertex0 = Physics::scaleDown(v);
+	e->m_hasVertex0 = true;
+}
+
+void EdgeShape::setPreviousVertex()
+{
+	b2EdgeShape *e = (b2EdgeShape *)shape;
+	e->m_hasVertex0 = false;
+}
+
+bool EdgeShape::getPreviousVertex(float &x, float &y) const
+{
+	b2EdgeShape *e = (b2EdgeShape *)shape;
+
+	if (e->m_hasVertex0)
+	{
+		b2Vec2 v = Physics::scaleUp(e->m_vertex0);
+		x = v.x;
+		y = v.y;
+		return true;
+	}
+
+	return false;
+}
+
 int EdgeShape::getPoints(lua_State *L)
 {
 	b2EdgeShape *e = (b2EdgeShape *)shape;

+ 8 - 0
src/modules/physics/box2d/EdgeShape.h

@@ -47,6 +47,14 @@ public:
 
 	virtual ~EdgeShape();
 
+	void setNextVertex(float x, float y);
+	void setNextVertex();
+	bool getNextVertex(float &x, float &y) const;
+
+	void setPreviousVertex(float x, float y);
+	void setPreviousVertex();
+	bool getPreviousVertex(float &x, float &y) const;
+
 	/**
 	 * Returns the transformed points of the edge shape.
 	 * This function is useful for debug drawing and such.

+ 24 - 16
src/modules/physics/box2d/wrap_ChainShape.cpp

@@ -37,18 +37,28 @@ ChainShape *luax_checkchainshape(lua_State *L, int idx)
 int w_ChainShape_setNextVertex(lua_State *L)
 {
 	ChainShape *c = luax_checkchainshape(L, 1);
-	float x = (float)luaL_checknumber(L, 2);
-	float y = (float)luaL_checknumber(L, 3);
-	luax_catchexcept(L, [&](){ c->setNextVertex(x, y); });
+	if (lua_isnoneornil(L, 2))
+		c->setNextVertex();
+	else
+	{
+		float x = (float)luaL_checknumber(L, 2);
+		float y = (float)luaL_checknumber(L, 3);
+		luax_catchexcept(L, [&](){ c->setNextVertex(x, y); });
+	}
 	return 0;
 }
 
 int w_ChainShape_setPreviousVertex(lua_State *L)
 {
 	ChainShape *c = luax_checkchainshape(L, 1);
-	float x = (float)luaL_checknumber(L, 2);
-	float y = (float)luaL_checknumber(L, 3);
-	luax_catchexcept(L, [&](){ c->setPreviousVertex(x, y); });
+	if (lua_isnoneornil(L, 2))
+		c->setPreviousVertex();
+	else
+	{
+		float x = (float)luaL_checknumber(L, 2);
+		float y = (float)luaL_checknumber(L, 3);
+		luax_catchexcept(L, [&](){ c->setPreviousVertex(x, y); });
+	}
 	return 0;
 }
 
@@ -85,12 +95,11 @@ int w_ChainShape_getPoint(lua_State *L)
 int w_ChainShape_getNextVertex(lua_State *L)
 {
 	ChainShape *c = luax_checkchainshape(L, 1);
-	if (c->hasNextVertex())
+	float x, y;
+	if (c->getNextVertex(x, y))
 	{
-		b2Vec2 v;
-		luax_catchexcept(L, [&](){ v = c->getNextVertex(); });
-		lua_pushnumber(L, v.x);
-		lua_pushnumber(L, v.y);
+		lua_pushnumber(L, x);
+		lua_pushnumber(L, y);
 		return 2;
 	}
 	return 0;
@@ -99,12 +108,11 @@ int w_ChainShape_getNextVertex(lua_State *L)
 int w_ChainShape_getPreviousVertex(lua_State *L)
 {
 	ChainShape *c = luax_checkchainshape(L, 1);
-	if (c->hasPreviousVertex())
+	float x, y;
+	if (c->getPreviousVertex(x, y))
 	{
-		b2Vec2 v;
-		luax_catchexcept(L, [&](){ v = c->getPreviousVertex(); });
-		lua_pushnumber(L, v.x);
-		lua_pushnumber(L, v.y);
+		lua_pushnumber(L, x);
+		lua_pushnumber(L, y);
 		return 2;
 	}
 	return 0;

+ 58 - 0
src/modules/physics/box2d/wrap_EdgeShape.cpp

@@ -32,6 +32,60 @@ EdgeShape *luax_checkedgeshape(lua_State *L, int idx)
 	return luax_checktype<EdgeShape>(L, idx, PHYSICS_EDGE_SHAPE_ID);
 }
 
+int w_EdgeShape_setNextVertex(lua_State *L)
+{
+	EdgeShape *t = luax_checkedgeshape(L, 1);
+	if (lua_isnoneornil(L, 2))
+		t->setNextVertex();
+	else
+	{
+		float x = (float)luaL_checknumber(L, 2);
+		float y = (float)luaL_checknumber(L, 3);
+		t->setNextVertex(x, y);
+	}
+	return 0;
+}
+
+int w_EdgeShape_setPreviousVertex(lua_State *L)
+{
+	EdgeShape *t = luax_checkedgeshape(L, 1);
+	if (lua_isnoneornil(L, 2))
+		t->setPreviousVertex();
+	else
+	{
+		float x = (float)luaL_checknumber(L, 2);
+		float y = (float)luaL_checknumber(L, 3);
+		t->setPreviousVertex(x, y);
+	}
+	return 0;
+}
+
+int w_EdgeShape_getNextVertex(lua_State *L)
+{
+	EdgeShape *t = luax_checkedgeshape(L, 1);
+	float x, y;
+	if (t->getNextVertex(x, y))
+	{
+		lua_pushnumber(L, x);
+		lua_pushnumber(L, y);
+		return 2;
+	}
+	return 0;
+}
+
+int w_EdgeShape_getPreviousVertex(lua_State *L)
+{
+	EdgeShape *t = luax_checkedgeshape(L, 1);
+	float x, y;
+	if (t->getPreviousVertex(x, y))
+	{
+		lua_pushnumber(L, x);
+		lua_pushnumber(L, y);
+		return 2;
+	}
+	return 0;
+}
+
 int w_EdgeShape_getPoints(lua_State *L)
 {
 	EdgeShape *t = luax_checkedgeshape(L, 1);
@@ -41,6 +95,10 @@ int w_EdgeShape_getPoints(lua_State *L)
 
 static const luaL_Reg w_EdgeShape_functions[] =
 {
+	{ "setNextVertex", w_EdgeShape_setNextVertex },
+	{ "setPreviousVertex", w_EdgeShape_setPreviousVertex },
+	{ "getNextVertex", w_EdgeShape_getNextVertex },
+	{ "getPreviousVertex", w_EdgeShape_getPreviousVertex },
 	{ "getPoints", w_EdgeShape_getPoints },
 	{ 0, 0 }
 };