Add ChainShape

--HG--
branch : box2d-update
This commit is contained in:
Bill Meltsner
2011-09-15 17:17:28 -04:00
parent e69cafe868
commit a565668183
9 changed files with 429 additions and 1 deletions
+95
View File
@@ -0,0 +1,95 @@
/**
* Copyright (c) 2006-2011 LOVE Development Team
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
**/
#include "ChainShape.h"
// Module
#include "Body.h"
#include "World.h"
#include "Physics.h"
namespace love
{
namespace physics
{
namespace box2d
{
ChainShape::ChainShape(b2ChainShape * c, bool loop)
: loop(loop)
{
shape = c;
}
ChainShape::~ChainShape()
{
}
void ChainShape::setNextVertex(float x, float y)
{
if (loop) {
throw love::Exception("Physics error: Can't call setNextVertex on a loop ChainShape");
return;
}
b2Vec2 v(x, y);
b2ChainShape * c = (b2ChainShape *)shape;
c->SetNextVertex(Physics::scaleDown(v));
}
void ChainShape::setPrevVertex(float x, float y)
{
if (loop) {
throw love::Exception("Physics error: Can't call setPrevVertex on a loop ChainShape");
return;
}
b2Vec2 v(x, y);
b2ChainShape * c = (b2ChainShape *)shape;
c->SetNextVertex(Physics::scaleDown(v));
}
EdgeShape * ChainShape::getChildEdge(int index) const
{
b2ChainShape * c = (b2ChainShape *)shape;
b2EdgeShape e;
c->GetChildEdge(&e, index);
return new EdgeShape(&e);
}
int ChainShape::getVertexCount() const
{
b2ChainShape * c = (b2ChainShape *)shape;
return c->GetVertexCount();
}
b2Vec2 ChainShape::getVertex(int index) const
{
b2ChainShape * c = (b2ChainShape *)shape;
const b2Vec2 & v = c->GetVertex(index);
return Physics::scaleUp(v);
}
const b2Vec2 * ChainShape::getVertices() const
{
b2ChainShape * c = (b2ChainShape *)shape;
return c->GetVertices();
}
} // box2d
} // physics
} // love
+101
View File
@@ -0,0 +1,101 @@
/**
* Copyright (c) 2006-2011 LOVE Development Team
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
**/
#ifndef LOVE_PHYSICS_BOX2D_CHAIN_SHAPE_H
#define LOVE_PHYSICS_BOX2D_CHAIN_SHAPE_H
// Module
#include "Shape.h"
#include "EdgeShape.h"
namespace love
{
namespace physics
{
namespace box2d
{
/**
* A ChainShape is a freeform collection of line segments.
**/
class ChainShape : public Shape
{
private:
// True if this ChainShape is a loop.
bool loop;
public:
/**
* Create a new ChainShape from a Box2D chain shape.
* @param c The chain shape.
**/
ChainShape(b2ChainShape * c, bool loop = false);
virtual ~ChainShape();
/**
* Establish connectivity to a vertex that follows
* the last vertex. Fails if called on a loop.
* @param x The x-coordinate of the vertex.
* @param y The y-coordinate of the vertex.
**/
void setNextVertex(float x, float y);
/**
* Establish connectivity to a vertex that precedes
* the first vertex. Fails if called on a loop.
* @param x The x-coordinate of the vertex.
* @param y The y-coordinate of the vertex.
**/
void setPrevVertex(float x, float y);
/**
* Returns a child EdgeShape.
* @param index The index of the child shape.
* @returns The specified child.
**/
EdgeShape * getChildEdge(int index) const;
/**
* Returns the number of vertices in the shape.
* @returns The number of vertices in the shape.
**/
int getVertexCount() const;
/**
* Returns the vertex at the given index.
* @param index The index of the vertex.
* @returns The specified vertex.
**/
b2Vec2 getVertex(int index) const;
/**
* Returns all of the vertices.
* @returns The vertices the shape comprises.
**/
const b2Vec2 * getVertices() const;
};
} // box2d
} // physics
} // love
#endif // LOVE_PHYSICS_BOX2D_CHAIN_SHAPE_H
+33 -1
View File
@@ -128,7 +128,7 @@ namespace box2d
if(count < 3)
return luaL_error(L, "Polygon degenerated to less than three points.");
b2Vec2 vecs[] = new b2vec2[count];
b2Vec2 * vecs = new b2Vec2[count];
for (int i = 0; i < count; i++) {
vecs[i].Set(convex_hull[i].x, convex_hull[i].y);
@@ -143,6 +143,38 @@ namespace box2d
return 1;
}
int Physics::newChainShape(lua_State * L)
{
int argc = lua_gettop(L)-1; // first argument is looping
int vcount = (int)argc/2;
b2ChainShape s;
bool loop = luax_toboolean(L, 1);
b2Vec2 * vecs = new b2Vec2[vcount];
for(int i = 0;i<vcount;i++)
{
float x = (float)lua_tonumber(L, -2);
float y = (float)lua_tonumber(L, -1);
vecs[i].Set(x, y);
lua_pop(L, 2);
}
if (loop)
s.CreateLoop(vecs, vcount);
else
s.CreateChain(vecs, vcount);
ChainShape * c = new ChainShape(&s);
delete[] vecs;
luax_newtype(L, "ChainShape", PHYSICS_CHAIN_SHAPE_T, (void*)c);
return 1;
}
DistanceJoint * Physics::newDistanceJoint(Body * body1, Body * body2, float x1, float y1, float x2, float y2, bool collideConnected)
{
+7
View File
@@ -30,6 +30,7 @@
#include "CircleShape.h"
#include "PolygonShape.h"
#include "EdgeShape.h"
#include "ChainShape.h"
#include "Joint.h"
#include "MouseJoint.h"
#include "DistanceJoint.h"
@@ -155,6 +156,12 @@ namespace box2d
* @param ... A variable number of vertices.
**/
int newPolygonShape(lua_State * L);
/**
* Creates a new ChainShape.
* @param ... A variable number of vertices.
**/
int newChainShape(lua_State * L);
/**
* Creates a new DistanceJoint connecting body1 with body2.
@@ -0,0 +1,122 @@
/**
* Copyright (c) 2006-2011 LOVE Development Team
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
**/
#include "wrap_ChainShape.h"
#include "Physics.h"
namespace love
{
namespace physics
{
namespace box2d
{
ChainShape * luax_checkchainshape(lua_State * L, int idx)
{
return luax_checktype<ChainShape>(L, idx, "ChainShape", PHYSICS_CHAIN_SHAPE_T);
}
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);
c->setNextVertex(x, y);
return 0;
}
int w_ChainShape_setPrevVertex(lua_State * L)
{
ChainShape * c = luax_checkchainshape(L, 1);
float x = (float)luaL_checknumber(L, 2);
float y = (float)luaL_checknumber(L, 3);
c->setPrevVertex(x, y);
return 0;
}
int w_ChainShape_getChildEdge(lua_State * L)
{
ChainShape * c = luax_checkchainshape(L, 1);
int index = luaL_checkint(L, 2);
EdgeShape * e = c->getChildEdge(index);
luax_newtype(L, "EdgeShape", PHYSICS_EDGE_SHAPE_T, e);
return 1;
}
int w_ChainShape_getVertexCount(lua_State * L)
{
ChainShape * c = luax_checkchainshape(L, 1);
int count = c->getVertexCount();
lua_pushinteger(L, count);
return 1;
}
int w_ChainShape_getVertex(lua_State * L)
{
ChainShape * c = luax_checkchainshape(L, 1);
int index = luaL_checkint(L, 2);
b2Vec2 v = c->getVertex(index);
lua_pushnumber(L, v.x);
lua_pushnumber(L, v.y);
return 2;
}
int w_ChainShape_getVertices(lua_State * L)
{
ChainShape * c = luax_checkchainshape(L, 1);
const b2Vec2 * verts = c->getVertices();
int count = c->getVertexCount();
lua_createtable(L, count*2, 0);
for (int i = 0; i < count; i++) {
b2Vec2 v = Physics::scaleUp(verts[i]);
lua_pushnumber(L, v.x);
lua_rawseti(L, -2, i*2+1);
lua_pushnumber(L, v.y);
lua_rawseti(L, -2, i*2+2);
}
return 1;
}
static const luaL_Reg functions[] = {
{ "setNextVertex", w_ChainShape_setNextVertex },
{ "setPrevVertex", w_ChainShape_setPrevVertex },
{ "getChildEdge", w_ChainShape_getChildEdge },
{ "getVertexCount", w_ChainShape_getVertexCount },
{ "getVertex", w_ChainShape_getVertex },
{ "getVertices", w_ChainShape_getVertices },
// 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 }
};
int luaopen_chainshape(lua_State * L)
{
return luax_register_type(L, "ChainShape", functions);
}
} // box2d
} // physics
} // love
@@ -0,0 +1,50 @@
/**
* Copyright (c) 2006-2011 LOVE Development Team
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
**/
#ifndef LOVE_PHYSICS_BOX2D_WRAP_CHAIN_SHAPE_H
#define LOVE_PHYSICS_BOX2D_WRAP_CHAIN_SHAPE_H
// LOVE
#include <common/runtime.h>
#include "wrap_Shape.h"
#include "ChainShape.h"
namespace love
{
namespace physics
{
namespace box2d
{
ChainShape * luax_checkchainshape(lua_State * L, int idx);
int w_ChainShape_setNextVertex(lua_State * L);
int w_ChainShape_setPrevVertex(lua_State * L);
int w_ChainShape_getChildEdge(lua_State * L);
int w_ChainShape_getVertexCount(lua_State * L);
int w_ChainShape_getVertex(lua_State * L);
int w_ChainShape_getVertices(lua_State * L);
int luaopen_chainshape(lua_State * L);
} // box2d
} // physics
} // love
#endif // LOVE_PHYSICS_BOX2D_WRAP_CHAIN_SHAPE_H
@@ -127,6 +127,11 @@ namespace box2d
{
return instance->newPolygonShape(L);
}
int w_newChainShape(lua_State * L)
{
return instance->newChainShape(L);
}
int w_newDistanceJoint(lua_State * L)
{
@@ -284,6 +289,7 @@ namespace box2d
{ "newRectangleShape", w_newRectangleShape },
{ "newPolygonShape", w_newPolygonShape },
{ "newEdgeShape", w_newEdgeShape },
{ "newChainShape", w_newChainShape },
{ "newDistanceJoint", w_newDistanceJoint },
{ "newMouseJoint", w_newMouseJoint },
{ "newRevoluteJoint", w_newRevoluteJoint },
@@ -307,6 +313,7 @@ namespace box2d
luaopen_circleshape,
luaopen_polygonshape,
luaopen_edgeshape,
luaopen_chainshape,
luaopen_joint,
luaopen_mousejoint,
luaopen_distancejoint,
+2
View File
@@ -31,6 +31,7 @@
#include "wrap_CircleShape.h"
#include "wrap_PolygonShape.h"
#include "wrap_EdgeShape.h"
#include "wrap_ChainShape.h"
#include "wrap_Joint.h"
#include "wrap_MouseJoint.h"
#include "wrap_DistanceJoint.h"
@@ -55,6 +56,7 @@ namespace box2d
int w_newRectangleShape(lua_State * L);
int w_newPolygonShape(lua_State * L);
int w_newEdgeShape(lua_State * L);
int w_newChainShape(lua_State * L);
int w_newDistanceJoint(lua_State * L);
int w_newMouseJoint(lua_State * L);
int w_newRevoluteJoint(lua_State * L);