mirror of
https://github.com/love2d/love.git
synced 2026-08-15 15:51:12 +02:00
love.physics: simplify Body and Shape API.
#1130 - Shapes are now directly attached to Bodies when they're created (similar to love 0.7 and older). - Fixtures are removed. - All methods that were in Fixtures now exist in Shapes. - All APIs that used or returned a Fixture now do the same with a Shape. - Add new love.physics.new*Shape variants that take a Body as the first parameter. - Deprecate the new*Shape APIs that don't take a Body. - Deprecate love.physics.newFixture (the deprecated function now returns a Shape). - Replace Body:getFixture and Body:getFixtures with Body:getShape and Body:getShapes (Body:getFixtures is deprecated). - Replace World:queryFixturesInArea and World:getFixturesInArea with World:queryShapesInArea and World:getShapesInArea (queryFixturesInArea is deprecated). - Replace Contact:getFixtures with Contact:getShapes (Contact:getFixtures is deprecated). - Replace all love.physics callback Fixture parameters with Shape parameters. - Deprecate ChainShape:getChildEdge.
This commit is contained in:
@@ -23,12 +23,12 @@
|
||||
#include "common/math.h"
|
||||
|
||||
#include "Shape.h"
|
||||
#include "Fixture.h"
|
||||
#include "World.h"
|
||||
#include "Physics.h"
|
||||
|
||||
// Needed for luax_pushjoint.
|
||||
#include "wrap_Joint.h"
|
||||
#include "wrap_Shape.h"
|
||||
|
||||
namespace love
|
||||
{
|
||||
@@ -461,20 +461,20 @@ World *Body::getWorld() const
|
||||
return world;
|
||||
}
|
||||
|
||||
Fixture *Body::getFixture() const
|
||||
Shape *Body::getShape() const
|
||||
{
|
||||
b2Fixture *f = body->GetFixtureList();
|
||||
if (f == nullptr)
|
||||
return nullptr;
|
||||
|
||||
Fixture *fixture = (Fixture *)(f->GetUserData().pointer);
|
||||
if (!fixture)
|
||||
throw love::Exception("A fixture has escaped Memoizer!");
|
||||
Shape *shape = (Shape *)(f->GetUserData().pointer);
|
||||
if (!shape)
|
||||
throw love::Exception("A Shape has escaped Memoizer!");
|
||||
|
||||
return fixture;
|
||||
return shape;
|
||||
}
|
||||
|
||||
int Body::getFixtures(lua_State *L) const
|
||||
int Body::getShapes(lua_State *L) const
|
||||
{
|
||||
lua_newtable(L);
|
||||
b2Fixture *f = body->GetFixtureList();
|
||||
@@ -483,10 +483,10 @@ int Body::getFixtures(lua_State *L) const
|
||||
{
|
||||
if (!f)
|
||||
break;
|
||||
Fixture *fixture = (Fixture *)(f->GetUserData().pointer);
|
||||
if (!fixture)
|
||||
throw love::Exception("A fixture has escaped Memoizer!");
|
||||
luax_pushtype(L, fixture);
|
||||
Shape *shape = (Shape *)(f->GetUserData().pointer);
|
||||
if (!shape)
|
||||
throw love::Exception("A Shape has escaped Memoizer!");
|
||||
luax_pushshape(L, shape);
|
||||
lua_rawseti(L, -2, i);
|
||||
i++;
|
||||
}
|
||||
|
||||
@@ -39,7 +39,6 @@ namespace box2d
|
||||
// Forward declarations.
|
||||
class World;
|
||||
class Shape;
|
||||
class Fixture;
|
||||
|
||||
/**
|
||||
* A Body is an entity which has position and orientation
|
||||
@@ -57,7 +56,6 @@ public:
|
||||
friend class CircleShape;
|
||||
friend class PolygonShape;
|
||||
friend class Shape;
|
||||
friend class Fixture;
|
||||
|
||||
// Public because joints et al ask for b2body
|
||||
b2Body *body;
|
||||
@@ -391,15 +389,14 @@ public:
|
||||
World *getWorld() const;
|
||||
|
||||
/**
|
||||
* Gets the first Fixture attached to this Body.
|
||||
* Gets the first Shape attached to this Body.
|
||||
**/
|
||||
Fixture *getFixture() const;
|
||||
Shape *getShape() const;
|
||||
|
||||
/**
|
||||
* Get an array of all the Fixtures attached to this Body.
|
||||
* @return An array of Fixtures.
|
||||
* Get an array of all the Shapes attached to this Body.
|
||||
**/
|
||||
int getFixtures(lua_State *L) const;
|
||||
int getShapes(lua_State *L) const;
|
||||
|
||||
/**
|
||||
* Get an array of all Joints attached to this Body.
|
||||
|
||||
@@ -34,8 +34,8 @@ namespace box2d
|
||||
|
||||
love::Type ChainShape::type("ChainShape", &Shape::type);
|
||||
|
||||
ChainShape::ChainShape(b2ChainShape *c, bool own)
|
||||
: Shape(c, own)
|
||||
ChainShape::ChainShape(Body *body, const b2ChainShape &c)
|
||||
: Shape(body, c)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -45,6 +45,7 @@ ChainShape::~ChainShape()
|
||||
|
||||
void ChainShape::setNextVertex(float x, float y)
|
||||
{
|
||||
throwIfShapeNotValid();
|
||||
b2Vec2 v(x, y);
|
||||
b2ChainShape *c = (b2ChainShape *)shape;
|
||||
c->m_nextVertex = Physics::scaleDown(v);
|
||||
@@ -52,6 +53,7 @@ void ChainShape::setNextVertex(float x, float y)
|
||||
|
||||
void ChainShape::setPreviousVertex(float x, float y)
|
||||
{
|
||||
throwIfShapeNotValid();
|
||||
b2Vec2 v(x, y);
|
||||
b2ChainShape *c = (b2ChainShape *)shape;
|
||||
c->m_prevVertex = Physics::scaleDown(v);
|
||||
@@ -59,44 +61,40 @@ void ChainShape::setPreviousVertex(float x, float y)
|
||||
|
||||
b2Vec2 ChainShape::getNextVertex() const
|
||||
{
|
||||
throwIfShapeNotValid();
|
||||
b2ChainShape *c = (b2ChainShape *)shape;
|
||||
|
||||
return Physics::scaleUp(c->m_nextVertex);
|
||||
}
|
||||
|
||||
b2Vec2 ChainShape::getPreviousVertex() const
|
||||
{
|
||||
throwIfShapeNotValid();
|
||||
b2ChainShape *c = (b2ChainShape *)shape;
|
||||
|
||||
return Physics::scaleUp(c->m_prevVertex);
|
||||
}
|
||||
|
||||
EdgeShape *ChainShape::getChildEdge(int index) const
|
||||
{
|
||||
throwIfShapeNotValid();
|
||||
|
||||
b2ChainShape *c = (b2ChainShape *)shape;
|
||||
b2EdgeShape *e = new b2EdgeShape;
|
||||
|
||||
try
|
||||
{
|
||||
c->GetChildEdge(e, index);
|
||||
}
|
||||
catch (love::Exception &)
|
||||
{
|
||||
delete e;
|
||||
throw;
|
||||
}
|
||||
b2EdgeShape e;
|
||||
c->GetChildEdge(&e, index);
|
||||
|
||||
return new EdgeShape(e, true);
|
||||
return new EdgeShape(nullptr, e);
|
||||
}
|
||||
|
||||
int ChainShape::getVertexCount() const
|
||||
{
|
||||
throwIfShapeNotValid();
|
||||
b2ChainShape *c = (b2ChainShape *)shape;
|
||||
return c->m_count;
|
||||
}
|
||||
|
||||
b2Vec2 ChainShape::getPoint(int index) const
|
||||
{
|
||||
throwIfShapeNotValid();
|
||||
b2ChainShape *c = (b2ChainShape *)shape;
|
||||
if (index < 0 || index >= c->m_count)
|
||||
throw love::Exception("Physics error: index out of bounds");
|
||||
@@ -106,6 +104,7 @@ b2Vec2 ChainShape::getPoint(int index) const
|
||||
|
||||
const b2Vec2 *ChainShape::getPoints() const
|
||||
{
|
||||
throwIfShapeNotValid();
|
||||
b2ChainShape *c = (b2ChainShape *)shape;
|
||||
return c->m_vertices;
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@ public:
|
||||
* Create a new ChainShape from a Box2D chain shape.
|
||||
* @param c The chain shape.
|
||||
**/
|
||||
ChainShape(b2ChainShape *c, bool own = true);
|
||||
ChainShape(Body *body, const b2ChainShape &c);
|
||||
|
||||
virtual ~ChainShape();
|
||||
|
||||
|
||||
@@ -34,8 +34,8 @@ namespace box2d
|
||||
|
||||
love::Type CircleShape::type("CircleShape", &Shape::type);
|
||||
|
||||
CircleShape::CircleShape(b2CircleShape *c, bool own)
|
||||
: Shape(c, own)
|
||||
CircleShape::CircleShape(Body *body, const b2CircleShape &c)
|
||||
: Shape(body, c)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -45,16 +45,19 @@ CircleShape::~CircleShape()
|
||||
|
||||
float CircleShape::getRadius() const
|
||||
{
|
||||
throwIfShapeNotValid();
|
||||
return Physics::scaleUp(shape->m_radius);
|
||||
}
|
||||
|
||||
void CircleShape::setRadius(float r)
|
||||
{
|
||||
throwIfShapeNotValid();
|
||||
shape->m_radius = Physics::scaleDown(r);
|
||||
}
|
||||
|
||||
void CircleShape::getPoint(float &x_o, float &y_o) const
|
||||
{
|
||||
throwIfShapeNotValid();
|
||||
b2CircleShape *c = (b2CircleShape *) shape;
|
||||
x_o = Physics::scaleUp(c->m_p.x);
|
||||
y_o = Physics::scaleUp(c->m_p.y);
|
||||
@@ -62,6 +65,7 @@ void CircleShape::getPoint(float &x_o, float &y_o) const
|
||||
|
||||
void CircleShape::setPoint(float x, float y)
|
||||
{
|
||||
throwIfShapeNotValid();
|
||||
b2CircleShape *c = (b2CircleShape *) shape;
|
||||
c->m_p = Physics::scaleDown(b2Vec2(x, y));
|
||||
}
|
||||
|
||||
@@ -50,7 +50,7 @@ public:
|
||||
* Create a new CircleShape from the a Box2D CircleShape definition.
|
||||
* @param c The CircleShape definition.
|
||||
**/
|
||||
CircleShape(b2CircleShape *c, bool own = true);
|
||||
CircleShape(Body *body, const b2CircleShape &c);
|
||||
|
||||
virtual ~CircleShape();
|
||||
|
||||
|
||||
@@ -35,7 +35,6 @@ Contact::Contact(World *world, b2Contact *contact)
|
||||
: contact(contact)
|
||||
, world(world)
|
||||
{
|
||||
//contact->user
|
||||
world->registerObject(contact, this);
|
||||
}
|
||||
|
||||
@@ -46,16 +45,16 @@ Contact::~Contact()
|
||||
|
||||
void Contact::invalidate()
|
||||
{
|
||||
if (contact != NULL)
|
||||
if (contact != nullptr)
|
||||
{
|
||||
world->unregisterObject(contact);
|
||||
contact = NULL;
|
||||
contact = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
bool Contact::isValid()
|
||||
{
|
||||
return contact != NULL;
|
||||
return contact != nullptr;
|
||||
}
|
||||
|
||||
int Contact::getPositions(lua_State *L)
|
||||
@@ -144,13 +143,13 @@ void Contact::getChildren(int &childA, int &childB)
|
||||
childB = contact->GetChildIndexB();
|
||||
}
|
||||
|
||||
void Contact::getFixtures(Fixture *&fixtureA, Fixture *&fixtureB)
|
||||
void Contact::getShapes(Shape *&shapeA, Shape *&shapeB)
|
||||
{
|
||||
fixtureA = (Fixture *) (contact->GetFixtureA()->GetUserData().pointer);
|
||||
fixtureB = (Fixture *) (contact->GetFixtureB()->GetUserData().pointer);
|
||||
shapeA = (Shape *) (contact->GetFixtureA()->GetUserData().pointer);
|
||||
shapeB = (Shape *) (contact->GetFixtureB()->GetUserData().pointer);
|
||||
|
||||
if (!fixtureA || !fixtureB)
|
||||
throw love::Exception("A fixture has escaped Memoizer!");
|
||||
if (!shapeA || !shapeB)
|
||||
throw love::Exception("A Shape has escaped Memoizer!");
|
||||
}
|
||||
|
||||
} // box2d
|
||||
|
||||
@@ -151,9 +151,9 @@ public:
|
||||
void getChildren(int &childA, int &childB);
|
||||
|
||||
/**
|
||||
* Gets the Fixtures associated with this Contact.
|
||||
* Gets the Shapes associated with this Contact.
|
||||
**/
|
||||
void getFixtures(Fixture *&fixtureA, Fixture *&fixtureB);
|
||||
void getShapes(Shape *&shapeA, Shape *&shapeB);
|
||||
|
||||
private:
|
||||
|
||||
|
||||
@@ -34,8 +34,8 @@ namespace box2d
|
||||
|
||||
love::Type EdgeShape::type("EdgeShape", &Shape::type);
|
||||
|
||||
EdgeShape::EdgeShape(b2EdgeShape *e, bool own)
|
||||
: Shape(e, own)
|
||||
EdgeShape::EdgeShape(Body *body, const b2EdgeShape &e)
|
||||
: Shape(body, e)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -45,6 +45,7 @@ EdgeShape::~EdgeShape()
|
||||
|
||||
void EdgeShape::setNextVertex(float x, float y)
|
||||
{
|
||||
throwIfShapeNotValid();
|
||||
b2EdgeShape *e = (b2EdgeShape *)shape;
|
||||
b2Vec2 v(x, y);
|
||||
e->m_vertex3 = Physics::scaleDown(v);
|
||||
@@ -52,13 +53,14 @@ void EdgeShape::setNextVertex(float x, float y)
|
||||
|
||||
b2Vec2 EdgeShape::getNextVertex() const
|
||||
{
|
||||
throwIfShapeNotValid();
|
||||
b2EdgeShape *e = (b2EdgeShape *)shape;
|
||||
|
||||
return Physics::scaleUp(e->m_vertex3);
|
||||
}
|
||||
|
||||
void EdgeShape::setPreviousVertex(float x, float y)
|
||||
{
|
||||
throwIfShapeNotValid();
|
||||
b2EdgeShape *e = (b2EdgeShape *)shape;
|
||||
b2Vec2 v(x, y);
|
||||
e->m_vertex0 = Physics::scaleDown(v);
|
||||
@@ -66,13 +68,14 @@ void EdgeShape::setPreviousVertex(float x, float y)
|
||||
|
||||
b2Vec2 EdgeShape::getPreviousVertex() const
|
||||
{
|
||||
throwIfShapeNotValid();
|
||||
b2EdgeShape *e = (b2EdgeShape *)shape;
|
||||
|
||||
return Physics::scaleUp(e->m_vertex0);
|
||||
}
|
||||
|
||||
int EdgeShape::getPoints(lua_State *L)
|
||||
{
|
||||
throwIfShapeNotValid();
|
||||
b2EdgeShape *e = (b2EdgeShape *)shape;
|
||||
b2Vec2 v1 = Physics::scaleUp(e->m_vertex1);
|
||||
b2Vec2 v2 = Physics::scaleUp(e->m_vertex2);
|
||||
|
||||
@@ -45,7 +45,7 @@ public:
|
||||
* Create a new EdgeShape from a Box2D edge shape.
|
||||
* @param e The edge shape.
|
||||
**/
|
||||
EdgeShape(b2EdgeShape *e, bool own = true);
|
||||
EdgeShape(Body *body, const b2EdgeShape &e);
|
||||
|
||||
virtual ~EdgeShape();
|
||||
|
||||
|
||||
@@ -1,349 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2006-2023 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 "Fixture.h"
|
||||
|
||||
// Module
|
||||
#include "Body.h"
|
||||
#include "World.h"
|
||||
#include "Physics.h"
|
||||
|
||||
// STD
|
||||
#include <bitset>
|
||||
|
||||
namespace love
|
||||
{
|
||||
namespace physics
|
||||
{
|
||||
namespace box2d
|
||||
{
|
||||
|
||||
love::Type Fixture::type("Fixture", &Object::type);
|
||||
|
||||
Fixture::Fixture(Body *body, Shape *shape, float density)
|
||||
: body(body)
|
||||
, fixture(nullptr)
|
||||
{
|
||||
b2FixtureDef def;
|
||||
def.shape = shape->shape;
|
||||
def.userData.pointer = (uintptr_t)this;
|
||||
def.density = density;
|
||||
fixture = body->body->CreateFixture(&def);
|
||||
this->retain();
|
||||
}
|
||||
|
||||
Fixture::~Fixture()
|
||||
{
|
||||
if (ref)
|
||||
delete ref;
|
||||
}
|
||||
|
||||
void Fixture::checkCreateShape()
|
||||
{
|
||||
if (shape.get() != nullptr || fixture == nullptr || fixture->GetShape() == nullptr)
|
||||
return;
|
||||
|
||||
b2Shape *bshape = fixture->GetShape();
|
||||
|
||||
switch (bshape->GetType())
|
||||
{
|
||||
case b2Shape::e_circle:
|
||||
shape.set(new CircleShape((b2CircleShape *) bshape, false), Acquire::NORETAIN);
|
||||
break;
|
||||
case b2Shape::e_edge:
|
||||
shape.set(new EdgeShape((b2EdgeShape *) bshape, false), Acquire::NORETAIN);
|
||||
break;
|
||||
case b2Shape::e_polygon:
|
||||
shape.set(new PolygonShape((b2PolygonShape *) bshape, false), Acquire::NORETAIN);
|
||||
break;
|
||||
case b2Shape::e_chain:
|
||||
shape.set(new ChainShape((b2ChainShape *) bshape, false), Acquire::NORETAIN);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Shape::Type Fixture::getType()
|
||||
{
|
||||
checkCreateShape();
|
||||
if (shape.get() == nullptr)
|
||||
return Shape::SHAPE_INVALID;
|
||||
else
|
||||
return shape->getType();
|
||||
}
|
||||
|
||||
void Fixture::setFriction(float friction)
|
||||
{
|
||||
fixture->SetFriction(friction);
|
||||
}
|
||||
|
||||
void Fixture::setRestitution(float restitution)
|
||||
{
|
||||
fixture->SetRestitution(restitution);
|
||||
}
|
||||
|
||||
void Fixture::setDensity(float density)
|
||||
{
|
||||
fixture->SetDensity(density);
|
||||
}
|
||||
|
||||
void Fixture::setSensor(bool sensor)
|
||||
{
|
||||
fixture->SetSensor(sensor);
|
||||
}
|
||||
|
||||
float Fixture::getFriction() const
|
||||
{
|
||||
return fixture->GetFriction();
|
||||
}
|
||||
|
||||
float Fixture::getRestitution() const
|
||||
{
|
||||
return fixture->GetRestitution();
|
||||
}
|
||||
|
||||
float Fixture::getDensity() const
|
||||
{
|
||||
return fixture->GetDensity();
|
||||
}
|
||||
|
||||
bool Fixture::isSensor() const
|
||||
{
|
||||
return fixture->IsSensor();
|
||||
}
|
||||
|
||||
Body *Fixture::getBody() const
|
||||
{
|
||||
return body;
|
||||
}
|
||||
|
||||
Shape *Fixture::getShape()
|
||||
{
|
||||
checkCreateShape();
|
||||
return shape;
|
||||
}
|
||||
|
||||
bool Fixture::isValid() const
|
||||
{
|
||||
return fixture != nullptr;
|
||||
}
|
||||
|
||||
void Fixture::setFilterData(int *v)
|
||||
{
|
||||
b2Filter f;
|
||||
f.categoryBits = (uint16) v[0];
|
||||
f.maskBits = (uint16) v[1];
|
||||
f.groupIndex = (int16) v[2];
|
||||
fixture->SetFilterData(f);
|
||||
}
|
||||
|
||||
void Fixture::getFilterData(int *v)
|
||||
{
|
||||
b2Filter f = fixture->GetFilterData();
|
||||
v[0] = (int) f.categoryBits;
|
||||
v[1] = (int) f.maskBits;
|
||||
v[2] = (int) f.groupIndex;
|
||||
}
|
||||
|
||||
int Fixture::setCategory(lua_State *L)
|
||||
{
|
||||
b2Filter f = fixture->GetFilterData();
|
||||
f.categoryBits = (uint16)getBits(L);
|
||||
fixture->SetFilterData(f);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Fixture::setMask(lua_State *L)
|
||||
{
|
||||
b2Filter f = fixture->GetFilterData();
|
||||
f.maskBits = ~(uint16)getBits(L);
|
||||
fixture->SetFilterData(f);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Fixture::setGroupIndex(int index)
|
||||
{
|
||||
b2Filter f = fixture->GetFilterData();
|
||||
f.groupIndex = (uint16)index;
|
||||
fixture->SetFilterData(f);
|
||||
}
|
||||
|
||||
int Fixture::getGroupIndex() const
|
||||
{
|
||||
b2Filter f = fixture->GetFilterData();
|
||||
return f.groupIndex;
|
||||
}
|
||||
|
||||
int Fixture::getCategory(lua_State *L)
|
||||
{
|
||||
return pushBits(L, fixture->GetFilterData().categoryBits);
|
||||
}
|
||||
|
||||
int Fixture::getMask(lua_State *L)
|
||||
{
|
||||
return pushBits(L, ~(fixture->GetFilterData().maskBits));
|
||||
}
|
||||
|
||||
uint16 Fixture::getBits(lua_State *L)
|
||||
{
|
||||
// Get number of args.
|
||||
bool istable = lua_istable(L, 1);
|
||||
int argc = istable ? (int) luax_objlen(L, 1) : lua_gettop(L);
|
||||
|
||||
// The new bitset.
|
||||
std::bitset<16> b;
|
||||
|
||||
for (int i = 1; i <= argc; i++)
|
||||
{
|
||||
size_t bpos = 0;
|
||||
|
||||
if (istable)
|
||||
{
|
||||
lua_rawgeti(L, 1, i);
|
||||
bpos = (size_t) (lua_tointeger(L, -1) - 1);
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
else
|
||||
bpos = (size_t) (lua_tointeger(L, i) - 1);
|
||||
|
||||
if (bpos >= 16)
|
||||
luaL_error(L, "Values must be in range 1-16.");
|
||||
|
||||
b.set(bpos, true);
|
||||
}
|
||||
|
||||
return (uint16)b.to_ulong();
|
||||
}
|
||||
|
||||
int Fixture::pushBits(lua_State *L, uint16 bits)
|
||||
{
|
||||
// Create a bitset.
|
||||
std::bitset<16> b((int)bits);
|
||||
|
||||
// Push all set bits.
|
||||
for (int i = 0; i<16; i++)
|
||||
if (b.test(i))
|
||||
lua_pushinteger(L, i+1);
|
||||
|
||||
// Count number of set bits.
|
||||
return (int)b.count();
|
||||
}
|
||||
|
||||
int Fixture::setUserData(lua_State *L)
|
||||
{
|
||||
love::luax_assert_argc(L, 1, 1);
|
||||
|
||||
if(!ref)
|
||||
ref = new Reference();
|
||||
|
||||
ref->ref(L);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Fixture::getUserData(lua_State *L)
|
||||
{
|
||||
if (ref != nullptr)
|
||||
ref->push(L);
|
||||
else
|
||||
lua_pushnil(L);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool Fixture::testPoint(float x, float y) const
|
||||
{
|
||||
return fixture->TestPoint(Physics::scaleDown(b2Vec2(x, y)));
|
||||
}
|
||||
|
||||
int Fixture::rayCast(lua_State *L) const
|
||||
{
|
||||
float p1x = Physics::scaleDown((float)luaL_checknumber(L, 1));
|
||||
float p1y = Physics::scaleDown((float)luaL_checknumber(L, 2));
|
||||
float p2x = Physics::scaleDown((float)luaL_checknumber(L, 3));
|
||||
float p2y = Physics::scaleDown((float)luaL_checknumber(L, 4));
|
||||
float maxFraction = (float)luaL_checknumber(L, 5);
|
||||
int childIndex = (int) luaL_optinteger(L, 6, 1) - 1; // Convert from 1-based index
|
||||
b2RayCastInput input;
|
||||
input.p1.Set(p1x, p1y);
|
||||
input.p2.Set(p2x, p2y);
|
||||
input.maxFraction = maxFraction;
|
||||
b2RayCastOutput output;
|
||||
if (!fixture->RayCast(&output, input, childIndex))
|
||||
return 0; // Nothing hit.
|
||||
lua_pushnumber(L, output.normal.x);
|
||||
lua_pushnumber(L, output.normal.y);
|
||||
lua_pushnumber(L, output.fraction);
|
||||
return 3;
|
||||
}
|
||||
|
||||
int Fixture::getBoundingBox(lua_State *L) const
|
||||
{
|
||||
int childIndex = (int) luaL_optinteger(L, 1, 1) - 1; // Convert from 1-based index
|
||||
b2AABB box;
|
||||
luax_catchexcept(L, [&]() { box = fixture->GetAABB(childIndex); });
|
||||
box = Physics::scaleUp(box);
|
||||
lua_pushnumber(L, box.lowerBound.x);
|
||||
lua_pushnumber(L, box.lowerBound.y);
|
||||
lua_pushnumber(L, box.upperBound.x);
|
||||
lua_pushnumber(L, box.upperBound.y);
|
||||
return 4;
|
||||
}
|
||||
|
||||
int Fixture::getMassData(lua_State *L) const
|
||||
{
|
||||
b2MassData data;
|
||||
fixture->GetMassData(&data);
|
||||
b2Vec2 center = Physics::scaleUp(data.center);
|
||||
lua_pushnumber(L, center.x);
|
||||
lua_pushnumber(L, center.y);
|
||||
lua_pushnumber(L, data.mass);
|
||||
lua_pushnumber(L, data.I);
|
||||
return 4;
|
||||
}
|
||||
|
||||
void Fixture::destroy(bool implicit)
|
||||
{
|
||||
if (body->world->world->IsLocked())
|
||||
{
|
||||
// Called during time step. Save reference for destruction afterwards.
|
||||
this->retain();
|
||||
body->world->destructFixtures.push_back(this);
|
||||
return;
|
||||
}
|
||||
|
||||
shape.set(nullptr);
|
||||
|
||||
if (!implicit && fixture != nullptr)
|
||||
body->body->DestroyFixture(fixture);
|
||||
fixture = nullptr;
|
||||
|
||||
// Remove userdata reference to avoid it sticking around after GC
|
||||
if (ref)
|
||||
ref->unref();
|
||||
|
||||
// Box2D fixture destroyed. Release its reference to the love Fixture.
|
||||
this->release();
|
||||
}
|
||||
|
||||
} // box2d
|
||||
} // physics
|
||||
} // love
|
||||
@@ -1,216 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2006-2023 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_FIXTURE_H
|
||||
#define LOVE_PHYSICS_BOX2D_FIXTURE_H
|
||||
|
||||
// LOVE
|
||||
#include "physics/Shape.h"
|
||||
#include "physics/box2d/Body.h"
|
||||
#include "physics/box2d/Shape.h"
|
||||
#include "common/Object.h"
|
||||
#include "common/Reference.h"
|
||||
|
||||
// Box2D
|
||||
#include <box2d/Box2D.h>
|
||||
|
||||
namespace love
|
||||
{
|
||||
namespace physics
|
||||
{
|
||||
namespace box2d
|
||||
{
|
||||
|
||||
class World;
|
||||
|
||||
/**
|
||||
* A Fixture is used to attach a shape to a body for collision detection.
|
||||
* A Fixture inherits its transform from its parent. Fixtures hold
|
||||
* additional non-geometric data such as friction, collision filters,
|
||||
* etc.
|
||||
**/
|
||||
class Fixture : public Object
|
||||
{
|
||||
public:
|
||||
friend class Physics;
|
||||
|
||||
static love::Type type;
|
||||
|
||||
/**
|
||||
* Creates a Fixture.
|
||||
**/
|
||||
Fixture(Body *body, Shape *shape, float density);
|
||||
|
||||
virtual ~Fixture();
|
||||
|
||||
/**
|
||||
* Gets the type of the Fixture's Shape. Useful for
|
||||
* debug drawing.
|
||||
**/
|
||||
Shape::Type getType();
|
||||
|
||||
/**
|
||||
* Gets the Shape attached to this Fixture.
|
||||
**/
|
||||
Shape *getShape();
|
||||
|
||||
/**
|
||||
* Returns true if the fixture is active in a Box2D world.
|
||||
**/
|
||||
bool isValid() const;
|
||||
|
||||
/**
|
||||
* Checks whether this Fixture acts as a sensor.
|
||||
* @return True if sensor, false otherwise.
|
||||
**/
|
||||
bool isSensor() const;
|
||||
|
||||
/**
|
||||
* Set whether this Fixture should be a sensor or not.
|
||||
* @param sensor True if sensor, false if not.
|
||||
**/
|
||||
void setSensor(bool sensor);
|
||||
|
||||
/**
|
||||
* Gets the Body this Fixture is attached to.
|
||||
**/
|
||||
Body *getBody() const;
|
||||
|
||||
/**
|
||||
* Sets the filter data. An integer array is used even though the
|
||||
* first two elements are unsigned shorts. The elements are:
|
||||
* category (16-bits), mask (16-bits) and group (32-bits/int).
|
||||
**/
|
||||
void setFilterData(int *v);
|
||||
|
||||
/**
|
||||
* Gets the filter data. An integer array is used even though the
|
||||
* first two elements are unsigned shorts. The elements are:
|
||||
* category (16-bits), mask (16-bits) and group (32-bits/int).
|
||||
**/
|
||||
void getFilterData(int *v);
|
||||
|
||||
/**
|
||||
* This function stores an in-C reference to
|
||||
* arbitrary Lua data in the Box2D Fixture object.
|
||||
**/
|
||||
int setUserData(lua_State *L);
|
||||
|
||||
/**
|
||||
* Gets the data set with setData. If no
|
||||
* data is set, nil is returned.
|
||||
**/
|
||||
int getUserData(lua_State *L);
|
||||
|
||||
/**
|
||||
* Sets the friction of the Fixture.
|
||||
* @param friction The new friction.
|
||||
**/
|
||||
void setFriction(float friction);
|
||||
|
||||
/**
|
||||
* Sets the restitution for the Fixture.
|
||||
* @param restitution The restitution.
|
||||
**/
|
||||
void setRestitution(float restitution);
|
||||
|
||||
/**
|
||||
* Sets the density of the Fixture.
|
||||
* @param density The density of the Fixture.
|
||||
**/
|
||||
void setDensity(float density);
|
||||
|
||||
/**
|
||||
* Gets the friction of the Fixture.
|
||||
* @returns The friction.
|
||||
**/
|
||||
float getFriction() const;
|
||||
|
||||
/**
|
||||
* Gets the restitution of the Fixture.
|
||||
* @return The restitution of the Fixture.
|
||||
**/
|
||||
float getRestitution() const;
|
||||
|
||||
/**
|
||||
* Gets the density of the Fixture.
|
||||
* @return The density.
|
||||
**/
|
||||
float getDensity() const;
|
||||
|
||||
/**
|
||||
* Checks if a point is inside the Fixture.
|
||||
* @param x The x-component of the point.
|
||||
* @param y The y-component of the point.
|
||||
**/
|
||||
bool testPoint(float x, float y) const;
|
||||
|
||||
/**
|
||||
* Cast a ray against this Fixture.
|
||||
**/
|
||||
int rayCast(lua_State *L) const;
|
||||
|
||||
void setGroupIndex(int index);
|
||||
int getGroupIndex() const;
|
||||
|
||||
int setCategory(lua_State *L);
|
||||
int setMask(lua_State *L);
|
||||
int getCategory(lua_State *L);
|
||||
int getMask(lua_State *L);
|
||||
uint16 getBits(lua_State *L);
|
||||
int pushBits(lua_State *L, uint16 bits);
|
||||
|
||||
/**
|
||||
* Gets the bounding box for this Fixture.
|
||||
* The function returns eight values which can be
|
||||
* passed directly to love.graphics.polygon.
|
||||
**/
|
||||
int getBoundingBox(lua_State *L) const;
|
||||
|
||||
/**
|
||||
* Gets the mass data for this Fixture.
|
||||
* This operation may be expensive.
|
||||
**/
|
||||
int getMassData(lua_State *L) const;
|
||||
|
||||
/**
|
||||
* Destroys this fixture.
|
||||
**/
|
||||
void destroy(bool implicit = false);
|
||||
|
||||
protected:
|
||||
|
||||
void checkCreateShape();
|
||||
|
||||
Body *body;
|
||||
b2Fixture *fixture;
|
||||
|
||||
// Reference to arbitrary data.
|
||||
Reference* ref = nullptr;
|
||||
|
||||
StrongRef<Shape> shape;
|
||||
|
||||
};
|
||||
|
||||
} // box2d
|
||||
} // physics
|
||||
} // love
|
||||
|
||||
#endif // LOVE_PHYSICS_BOX2D_FIXTURE_H
|
||||
@@ -35,6 +35,7 @@ namespace box2d
|
||||
float Physics::meter = Physics::DEFAULT_METER;
|
||||
|
||||
Physics::Physics()
|
||||
: blockAllocator()
|
||||
{
|
||||
meter = DEFAULT_METER;
|
||||
}
|
||||
@@ -66,8 +67,7 @@ Body *Physics::newBody(World *world, Body::Type type)
|
||||
Body *Physics::newCircleBody(World *world, Body::Type type, float x, float y, float radius)
|
||||
{
|
||||
StrongRef<Body> body(newBody(world, x, y, type), Acquire::NORETAIN);
|
||||
StrongRef<CircleShape> shape(newCircleShape(0, 0, radius), Acquire::NORETAIN);
|
||||
StrongRef<Fixture> fixture(newFixture(body, shape, 1.0f), Acquire::NORETAIN);
|
||||
StrongRef<CircleShape> shape(newCircleShape(body, 0, 0, radius), Acquire::NORETAIN);
|
||||
body->retain();
|
||||
return body.get();
|
||||
}
|
||||
@@ -75,8 +75,7 @@ Body *Physics::newCircleBody(World *world, Body::Type type, float x, float y, fl
|
||||
Body *Physics::newRectangleBody(World *world, Body::Type type, float x, float y, float w, float h, float angle)
|
||||
{
|
||||
StrongRef<Body> body(newBody(world, x, y, type), Acquire::NORETAIN);
|
||||
StrongRef<PolygonShape> shape(newRectangleShape(0, 0, w, h, angle), Acquire::NORETAIN);
|
||||
StrongRef<Fixture> fixture(newFixture(body, shape, 1.0f), Acquire::NORETAIN);
|
||||
StrongRef<PolygonShape> shape(newRectangleShape(body, 0, 0, w, h, angle), Acquire::NORETAIN);
|
||||
body->retain();
|
||||
return body.get();
|
||||
}
|
||||
@@ -93,8 +92,7 @@ Body *Physics::newPolygonBody(World *world, Body::Type type, const Vector2 *coor
|
||||
localcoords.push_back(coords[i] - origin);
|
||||
|
||||
StrongRef<Body> body(newBody(world, origin.x, origin.y, type), Acquire::NORETAIN);
|
||||
StrongRef<PolygonShape> shape(newPolygonShape(localcoords.data(), count), Acquire::NORETAIN);
|
||||
StrongRef<Fixture> fixture(newFixture(body, shape, 1.0f), Acquire::NORETAIN);
|
||||
StrongRef<PolygonShape> shape(newPolygonShape(body, localcoords.data(), count), Acquire::NORETAIN);
|
||||
body->retain();
|
||||
return body.get();
|
||||
}
|
||||
@@ -104,8 +102,7 @@ Body *Physics::newEdgeBody(World *world, Body::Type type, float x1, float y1, fl
|
||||
float wx = (x2 - x1) / 2.0f;
|
||||
float wy = (y2 - y1) / 2.0f;
|
||||
StrongRef<Body> body(newBody(world, wx, wy, type), Acquire::NORETAIN);
|
||||
StrongRef<EdgeShape> shape(newEdgeShape(x1 - wx, y1 - wy, x2 - wx, y2 - wy, oneSided), Acquire::NORETAIN);
|
||||
StrongRef<Fixture> fixture(newFixture(body, shape, 1.0f), Acquire::NORETAIN);
|
||||
StrongRef<EdgeShape> shape(newEdgeShape(body, x1 - wx, y1 - wy, x2 - wx, y2 - wy, oneSided), Acquire::NORETAIN);
|
||||
body->retain();
|
||||
return body.get();
|
||||
}
|
||||
@@ -122,44 +119,75 @@ Body *Physics::newChainBody(World *world, Body::Type type, bool loop, const Vect
|
||||
localcoords.push_back(coords[i] - origin);
|
||||
|
||||
StrongRef<Body> body(newBody(world, origin.x, origin.y, type), Acquire::NORETAIN);
|
||||
StrongRef<ChainShape> shape(newChainShape(loop, localcoords.data(), count), Acquire::NORETAIN);
|
||||
StrongRef<Fixture> fixture(newFixture(body, shape, 1.0f), Acquire::NORETAIN);
|
||||
StrongRef<ChainShape> shape(newChainShape(body, loop, localcoords.data(), count), Acquire::NORETAIN);
|
||||
body->retain();
|
||||
return body.get();
|
||||
}
|
||||
|
||||
CircleShape *Physics::newCircleShape(float x, float y, float radius)
|
||||
Shape *Physics::newAttachedShape(Body *body, Shape *prototype, float density)
|
||||
{
|
||||
b2CircleShape *s = new b2CircleShape();
|
||||
s->m_p = Physics::scaleDown(b2Vec2(x, y));
|
||||
s->m_radius = Physics::scaleDown(radius);
|
||||
return new CircleShape(s);
|
||||
if (prototype->isValid())
|
||||
throw love::Exception("The given Shape must not be part of the World.");
|
||||
|
||||
Shape *shape = nullptr;
|
||||
|
||||
switch (prototype->getType())
|
||||
{
|
||||
case Shape::SHAPE_CIRCLE:
|
||||
shape = new CircleShape(body, *(b2CircleShape *) prototype->shape);
|
||||
break;
|
||||
case Shape::SHAPE_POLYGON:
|
||||
shape = new PolygonShape(body, *(b2PolygonShape *) prototype->shape);
|
||||
break;
|
||||
case Shape::SHAPE_EDGE:
|
||||
shape = new EdgeShape(body, *(b2EdgeShape *) prototype->shape);
|
||||
break;
|
||||
case Shape::SHAPE_CHAIN:
|
||||
shape = new ChainShape(body, *(b2ChainShape *) prototype->shape);
|
||||
break;
|
||||
default:
|
||||
throw love::Exception("Unknown shape type.");
|
||||
break;
|
||||
}
|
||||
|
||||
shape->setDensity(density);
|
||||
body->resetMassData();
|
||||
|
||||
return shape;
|
||||
}
|
||||
|
||||
PolygonShape *Physics::newRectangleShape(float x, float y, float w, float h, float angle)
|
||||
CircleShape *Physics::newCircleShape(Body *body, float x, float y, float radius)
|
||||
{
|
||||
b2PolygonShape *s = new b2PolygonShape();
|
||||
s->SetAsBox(Physics::scaleDown(w/2.0f), Physics::scaleDown(h/2.0f), Physics::scaleDown(b2Vec2(x, y)), angle);
|
||||
return new PolygonShape(s);
|
||||
b2CircleShape s;
|
||||
s.m_p = Physics::scaleDown(b2Vec2(x, y));
|
||||
s.m_radius = Physics::scaleDown(radius);
|
||||
return new CircleShape(body, s);
|
||||
}
|
||||
|
||||
EdgeShape *Physics::newEdgeShape(float x1, float y1, float x2, float y2, bool oneSided)
|
||||
PolygonShape *Physics::newRectangleShape(Body *body, float x, float y, float w, float h, float angle)
|
||||
{
|
||||
b2EdgeShape *s = new b2EdgeShape();
|
||||
b2PolygonShape s;
|
||||
s.SetAsBox(Physics::scaleDown(w/2.0f), Physics::scaleDown(h/2.0f), Physics::scaleDown(b2Vec2(x, y)), angle);
|
||||
return new PolygonShape(body, s);
|
||||
}
|
||||
|
||||
EdgeShape *Physics::newEdgeShape(Body *body, float x1, float y1, float x2, float y2, bool oneSided)
|
||||
{
|
||||
b2EdgeShape s;
|
||||
if (oneSided)
|
||||
{
|
||||
b2Vec2 v1 = Physics::scaleDown(b2Vec2(x1, y1));
|
||||
b2Vec2 v2 = Physics::scaleDown(b2Vec2(x2, y2));
|
||||
s->SetOneSided(v1, v1, v2, v2);
|
||||
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(s);
|
||||
return new EdgeShape(body, s);
|
||||
}
|
||||
|
||||
PolygonShape *Physics::newPolygonShape(const Vector2 *coords, int count)
|
||||
PolygonShape *Physics::newPolygonShape(Body *body, const Vector2 *coords, int count)
|
||||
{
|
||||
// 3 to 8 (b2_maxPolygonVertices) vertices
|
||||
if (count < 3)
|
||||
@@ -172,44 +200,28 @@ PolygonShape *Physics::newPolygonShape(const Vector2 *coords, int count)
|
||||
for (int i = 0; i < count; i++)
|
||||
vecs[i] = Physics::scaleDown(b2Vec2(coords[i].x, coords[i].y));
|
||||
|
||||
b2PolygonShape *s = new b2PolygonShape();
|
||||
b2PolygonShape s;
|
||||
|
||||
try
|
||||
{
|
||||
s->Set(vecs, count);
|
||||
}
|
||||
catch (love::Exception &)
|
||||
{
|
||||
delete s;
|
||||
throw;
|
||||
}
|
||||
s.Set(vecs, count);
|
||||
|
||||
return new PolygonShape(s);
|
||||
return new PolygonShape(body, s);
|
||||
}
|
||||
|
||||
ChainShape *Physics::newChainShape(bool loop, const Vector2 *coords, int count)
|
||||
ChainShape *Physics::newChainShape(Body *body, bool loop, const Vector2 *coords, int count)
|
||||
{
|
||||
std::vector<b2Vec2> vecs;
|
||||
|
||||
for (int i = 0; i < count; i++)
|
||||
vecs.push_back(Physics::scaleDown(b2Vec2(coords[i].x, coords[i].y)));
|
||||
|
||||
b2ChainShape *s = new b2ChainShape();
|
||||
b2ChainShape s;
|
||||
|
||||
try
|
||||
{
|
||||
if (loop)
|
||||
s->CreateLoop(vecs.data(), count);
|
||||
else
|
||||
s->CreateChain(vecs.data(), count, vecs[0], vecs[count - 1]);
|
||||
}
|
||||
catch (love::Exception &)
|
||||
{
|
||||
delete s;
|
||||
throw;
|
||||
}
|
||||
if (loop)
|
||||
s.CreateLoop(vecs.data(), count);
|
||||
else
|
||||
s.CreateChain(vecs.data(), count, vecs[0], vecs[count - 1]);
|
||||
|
||||
return new ChainShape(s);
|
||||
return new ChainShape(body, s);
|
||||
}
|
||||
|
||||
DistanceJoint *Physics::newDistanceJoint(Body *body1, Body *body2, float x1, float y1, float x2, float y2, bool collideConnected)
|
||||
@@ -287,16 +299,10 @@ MotorJoint *Physics::newMotorJoint(Body *body1, Body *body2, float correctionFac
|
||||
return new MotorJoint(body1, body2, correctionFactor, collideConnected);
|
||||
}
|
||||
|
||||
|
||||
Fixture *Physics::newFixture(Body *body, Shape *shape, float density)
|
||||
{
|
||||
return new Fixture(body, shape, density);
|
||||
}
|
||||
|
||||
int Physics::getDistance(lua_State *L)
|
||||
{
|
||||
Fixture *fixtureA = luax_checktype<Fixture>(L, 1);
|
||||
Fixture *fixtureB = luax_checktype<Fixture>(L, 2);
|
||||
Shape *shapeA = luax_checktype<Shape>(L, 1);
|
||||
Shape *shapeB = luax_checktype<Shape>(L, 2);
|
||||
b2DistanceProxy pA, pB;
|
||||
b2DistanceInput i;
|
||||
b2DistanceOutput o;
|
||||
@@ -304,12 +310,15 @@ int Physics::getDistance(lua_State *L)
|
||||
c.count = 0;
|
||||
|
||||
luax_catchexcept(L, [&]() {
|
||||
pA.Set(fixtureA->fixture->GetShape(), 0);
|
||||
pB.Set(fixtureB->fixture->GetShape(), 0);
|
||||
if (!shapeA->isValid() || !shapeB->isValid())
|
||||
throw love::Exception("The given Shape is not active in the physics World.");
|
||||
|
||||
pA.Set(shapeA->fixture->GetShape(), 0);
|
||||
pB.Set(shapeB->fixture->GetShape(), 0);
|
||||
i.proxyA = pA;
|
||||
i.proxyB = pB;
|
||||
i.transformA = fixtureA->fixture->GetBody()->GetTransform();
|
||||
i.transformB = fixtureB->fixture->GetBody()->GetTransform();
|
||||
i.transformA = shapeA->fixture->GetBody()->GetTransform();
|
||||
i.transformB = shapeB->fixture->GetBody()->GetTransform();
|
||||
i.useRadii = true;
|
||||
b2Distance(&o, &c, &i);
|
||||
});
|
||||
|
||||
@@ -28,7 +28,6 @@
|
||||
#include "World.h"
|
||||
#include "Contact.h"
|
||||
#include "Body.h"
|
||||
#include "Fixture.h"
|
||||
#include "Shape.h"
|
||||
#include "CircleShape.h"
|
||||
#include "PolygonShape.h"
|
||||
@@ -95,9 +94,9 @@ public:
|
||||
Body *newBody(World *world, Body::Type type);
|
||||
|
||||
/**
|
||||
* Convenience functions for creating a Body, Shape, and Fixture all in one
|
||||
* call. The body's world position is the center/average of the given
|
||||
* coordinates, and the shape is centered at the local origin.
|
||||
* Convenience functions for creating a Body and Shape all in one call. The
|
||||
* body's world position is the center/average of the given coordinates,
|
||||
* and the shape is centered at the local origin.
|
||||
**/
|
||||
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);
|
||||
@@ -105,13 +104,16 @@ public:
|
||||
Body *newEdgeBody(World *world, Body::Type type, float x1, float y1, float x2, float y2, bool oneSided);
|
||||
Body *newChainBody(World *world, Body::Type type, bool loop, const Vector2 *coords, int count);
|
||||
|
||||
// Necessary to support the deprecated newFixture API.
|
||||
Shape *newAttachedShape(Body *body, Shape *prototype, float density);
|
||||
|
||||
/**
|
||||
* Creates a new CircleShape at (x,y) in local coordinates.
|
||||
* @param x The offset along the x-axis.
|
||||
* @param y The offset along the y-axis.
|
||||
* @param radius The radius of the circle.
|
||||
**/
|
||||
CircleShape *newCircleShape(float x, float y, float radius);
|
||||
CircleShape *newCircleShape(Body *body, float x, float y, float radius);
|
||||
|
||||
/**
|
||||
* Shorthand for creating rectangular PolygonShapes. The rectangle
|
||||
@@ -122,7 +124,7 @@ public:
|
||||
* @param h The height of the rectangle.
|
||||
* @param angle The angle of the rectangle. (rad)
|
||||
**/
|
||||
PolygonShape *newRectangleShape(float x, float y, float w, float h, float angle);
|
||||
PolygonShape *newRectangleShape(Body *body, float x, float y, float w, float h, float angle);
|
||||
|
||||
/**
|
||||
* Creates a new EdgeShape. The edge will be created from
|
||||
@@ -132,18 +134,17 @@ public:
|
||||
* @param x2 The x coordinate of the second point.
|
||||
* @param y2 The y coordinate of the second point.
|
||||
**/
|
||||
EdgeShape *newEdgeShape(float x1, float y1, float x2, float y2, bool oneSided);
|
||||
EdgeShape *newEdgeShape(Body *body, float x1, float y1, float x2, float y2, bool oneSided);
|
||||
|
||||
/**
|
||||
* Creates a new PolygonShape from a variable number of vertices.
|
||||
**/
|
||||
//int newPolygonShape(lua_State *L);
|
||||
PolygonShape *newPolygonShape(const Vector2 *coords, int count);
|
||||
PolygonShape *newPolygonShape(Body *body, const Vector2 *coords, int count);
|
||||
|
||||
/**
|
||||
* Creates a new ChainShape from a variable number of vertices.
|
||||
**/
|
||||
ChainShape *newChainShape(bool loop, const Vector2 *coords, int count);
|
||||
ChainShape *newChainShape(Body *body, bool loop, const Vector2 *coords, int count);
|
||||
|
||||
/**
|
||||
* Creates a new DistanceJoint connecting body1 with body2.
|
||||
@@ -263,15 +264,6 @@ public:
|
||||
MotorJoint *newMotorJoint(Body *body1, Body *body2);
|
||||
MotorJoint *newMotorJoint(Body *body1, Body *body2, float correctionFactor, bool collideConnected);
|
||||
|
||||
/**
|
||||
* Creates a new Fixture attaching shape to body.
|
||||
* @param body The body to attach the Fixture to.
|
||||
* @param shape The shape to attach to the Fixture,
|
||||
* @param density The density of the Fixture.
|
||||
**/
|
||||
|
||||
Fixture *newFixture(Body *body, Shape *shape, float density);
|
||||
|
||||
/**
|
||||
* Calculates the distance between two Fixtures.
|
||||
* @param fixtureA The first Fixture.
|
||||
@@ -393,10 +385,15 @@ public:
|
||||
**/
|
||||
static void computeAngularFrequency(float &frequency, float &ratio, float stiffness, float damping, b2Body *bodyA, b2Body *bodyB);
|
||||
|
||||
b2BlockAllocator *getBlockAllocator() { return &blockAllocator; }
|
||||
|
||||
private:
|
||||
|
||||
// The length of one meter in pixels.
|
||||
static float meter;
|
||||
|
||||
b2BlockAllocator blockAllocator;
|
||||
|
||||
}; // Physics
|
||||
|
||||
} // box2d
|
||||
|
||||
@@ -34,8 +34,8 @@ namespace box2d
|
||||
|
||||
love::Type PolygonShape::type("PolygonShape", &Shape::type);
|
||||
|
||||
PolygonShape::PolygonShape(b2PolygonShape *p, bool own)
|
||||
: Shape(p, own)
|
||||
PolygonShape::PolygonShape(Body *body, const b2PolygonShape &p)
|
||||
: Shape(body, p)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -45,6 +45,7 @@ PolygonShape::~PolygonShape()
|
||||
|
||||
int PolygonShape::getPoints(lua_State *L)
|
||||
{
|
||||
throwIfShapeNotValid();
|
||||
love::luax_assert_argc(L, 0);
|
||||
b2PolygonShape *p = (b2PolygonShape *)shape;
|
||||
int count = p->m_count;
|
||||
@@ -59,6 +60,7 @@ int PolygonShape::getPoints(lua_State *L)
|
||||
|
||||
bool PolygonShape::validate() const
|
||||
{
|
||||
throwIfShapeNotValid();
|
||||
b2PolygonShape *p = (b2PolygonShape *)shape;
|
||||
return p->Validate();
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ public:
|
||||
* Create a new PolygonShape from a Box2D polygon definition.
|
||||
* @param p The polygon definition.
|
||||
**/
|
||||
PolygonShape(b2PolygonShape *p, bool own = true);
|
||||
PolygonShape(Body *body, const b2PolygonShape &p);
|
||||
|
||||
virtual ~PolygonShape();
|
||||
|
||||
|
||||
@@ -35,54 +35,348 @@ namespace physics
|
||||
namespace box2d
|
||||
{
|
||||
|
||||
Shape::Shape()
|
||||
Shape::Shape(Body *body, const b2Shape &shape)
|
||||
: shape(nullptr)
|
||||
, own(false)
|
||||
, shapeType(SHAPE_INVALID)
|
||||
, body(body)
|
||||
, fixture(nullptr)
|
||||
{
|
||||
}
|
||||
if (body)
|
||||
{
|
||||
b2FixtureDef def;
|
||||
def.shape = &shape;
|
||||
def.userData.pointer = (uintptr_t)this;
|
||||
def.density = 1.0f;
|
||||
fixture = body->body->CreateFixture(&def);
|
||||
this->shape = fixture->GetShape();
|
||||
retain(); // Shape::destroy does the release().
|
||||
}
|
||||
else
|
||||
{
|
||||
// Path to support deprecated APIs.
|
||||
auto physics = Module::getInstance<Physics>(Module::M_PHYSICS);
|
||||
this->shape = shape.Clone(physics->getBlockAllocator());
|
||||
own = true;
|
||||
}
|
||||
|
||||
Shape::Shape(b2Shape *shape, bool own)
|
||||
: shape(shape)
|
||||
, own(own)
|
||||
{
|
||||
switch (this->shape->GetType())
|
||||
{
|
||||
case b2Shape::e_circle:
|
||||
shapeType = SHAPE_CIRCLE;
|
||||
break;
|
||||
case b2Shape::e_polygon:
|
||||
shapeType = SHAPE_POLYGON;
|
||||
break;
|
||||
case b2Shape::e_edge:
|
||||
shapeType = SHAPE_EDGE;
|
||||
break;
|
||||
case b2Shape::e_chain:
|
||||
shapeType = SHAPE_CHAIN;
|
||||
break;
|
||||
default:
|
||||
shapeType = SHAPE_INVALID;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Shape::~Shape()
|
||||
{
|
||||
if (shape && own)
|
||||
delete shape;
|
||||
{
|
||||
auto physics = Module::getInstance<Physics>(Module::M_PHYSICS);
|
||||
auto allocator = physics->getBlockAllocator();
|
||||
|
||||
// Taken from b2Fixture::Destroy. Not very pretty...
|
||||
switch (shapeType)
|
||||
{
|
||||
case SHAPE_CIRCLE:
|
||||
{
|
||||
b2CircleShape *s = (b2CircleShape*)shape;
|
||||
s->~b2CircleShape();
|
||||
allocator->Free(s, sizeof(b2CircleShape));
|
||||
break;
|
||||
}
|
||||
case SHAPE_EDGE:
|
||||
{
|
||||
b2EdgeShape *s = (b2EdgeShape*)shape;
|
||||
s->~b2EdgeShape();
|
||||
allocator->Free(s, sizeof(b2EdgeShape));
|
||||
break;
|
||||
}
|
||||
case SHAPE_POLYGON:
|
||||
{
|
||||
b2PolygonShape *s = (b2PolygonShape*)shape;
|
||||
s->~b2PolygonShape();
|
||||
allocator->Free(s, sizeof(b2PolygonShape));
|
||||
break;
|
||||
}
|
||||
case SHAPE_CHAIN:
|
||||
{
|
||||
b2ChainShape *s = (b2ChainShape*)shape;
|
||||
s->~b2ChainShape();
|
||||
allocator->Free(s, sizeof(b2ChainShape));
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (ref)
|
||||
delete ref;
|
||||
}
|
||||
|
||||
void Shape::destroy(bool implicit)
|
||||
{
|
||||
if (fixture == nullptr)
|
||||
return;
|
||||
|
||||
if (body->world->world->IsLocked())
|
||||
{
|
||||
// Called during time step. Save reference for destruction afterwards.
|
||||
this->retain();
|
||||
body->world->destructShapes.push_back(this);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!implicit && fixture != nullptr)
|
||||
body->body->DestroyFixture(fixture);
|
||||
|
||||
fixture = nullptr;
|
||||
shape = nullptr;
|
||||
body = nullptr;
|
||||
|
||||
// Remove userdata reference to avoid it sticking around after GC
|
||||
if (ref)
|
||||
ref->unref();
|
||||
|
||||
// Box2D fixture destroyed. Release its reference to the love Shape.
|
||||
release();
|
||||
}
|
||||
|
||||
void Shape::throwIfFixtureNotValid() const
|
||||
{
|
||||
if (fixture == nullptr)
|
||||
throw love::Exception("Shape must be active in the physics World to use this method.");
|
||||
}
|
||||
|
||||
void Shape::throwIfShapeNotValid() const
|
||||
{
|
||||
if (shape == nullptr)
|
||||
throw love::Exception("Cannot call this method on a destroyed Shape.");
|
||||
}
|
||||
|
||||
Shape::Type Shape::getType() const
|
||||
{
|
||||
switch (shape->GetType())
|
||||
{
|
||||
case b2Shape::e_circle:
|
||||
return SHAPE_CIRCLE;
|
||||
case b2Shape::e_polygon:
|
||||
return SHAPE_POLYGON;
|
||||
case b2Shape::e_edge:
|
||||
return SHAPE_EDGE;
|
||||
case b2Shape::e_chain:
|
||||
return SHAPE_CHAIN;
|
||||
default:
|
||||
return SHAPE_INVALID;
|
||||
}
|
||||
return shapeType;
|
||||
}
|
||||
|
||||
void Shape::setFriction(float friction)
|
||||
{
|
||||
throwIfFixtureNotValid();
|
||||
fixture->SetFriction(friction);
|
||||
}
|
||||
|
||||
void Shape::setRestitution(float restitution)
|
||||
{
|
||||
throwIfFixtureNotValid();
|
||||
fixture->SetRestitution(restitution);
|
||||
}
|
||||
|
||||
void Shape::setDensity(float density)
|
||||
{
|
||||
throwIfFixtureNotValid();
|
||||
fixture->SetDensity(density);
|
||||
}
|
||||
|
||||
void Shape::setSensor(bool sensor)
|
||||
{
|
||||
throwIfFixtureNotValid();
|
||||
fixture->SetSensor(sensor);
|
||||
}
|
||||
|
||||
float Shape::getFriction() const
|
||||
{
|
||||
throwIfFixtureNotValid();
|
||||
return fixture->GetFriction();
|
||||
}
|
||||
|
||||
float Shape::getRestitution() const
|
||||
{
|
||||
throwIfFixtureNotValid();
|
||||
return fixture->GetRestitution();
|
||||
}
|
||||
|
||||
float Shape::getDensity() const
|
||||
{
|
||||
throwIfFixtureNotValid();
|
||||
return fixture->GetDensity();
|
||||
}
|
||||
|
||||
bool Shape::isSensor() const
|
||||
{
|
||||
throwIfFixtureNotValid();
|
||||
return fixture->IsSensor();
|
||||
}
|
||||
|
||||
Body *Shape::getBody() const
|
||||
{
|
||||
return body;
|
||||
}
|
||||
|
||||
float Shape::getRadius() const
|
||||
{
|
||||
throwIfShapeNotValid();
|
||||
return Physics::scaleUp(shape->m_radius);
|
||||
}
|
||||
|
||||
int Shape::getChildCount() const
|
||||
{
|
||||
throwIfShapeNotValid();
|
||||
return shape->GetChildCount();
|
||||
}
|
||||
|
||||
void Shape::setFilterData(int *v)
|
||||
{
|
||||
throwIfFixtureNotValid();
|
||||
b2Filter f;
|
||||
f.categoryBits = (uint16) v[0];
|
||||
f.maskBits = (uint16) v[1];
|
||||
f.groupIndex = (int16) v[2];
|
||||
fixture->SetFilterData(f);
|
||||
}
|
||||
|
||||
void Shape::getFilterData(int *v)
|
||||
{
|
||||
throwIfFixtureNotValid();
|
||||
b2Filter f = fixture->GetFilterData();
|
||||
v[0] = (int) f.categoryBits;
|
||||
v[1] = (int) f.maskBits;
|
||||
v[2] = (int) f.groupIndex;
|
||||
}
|
||||
|
||||
int Shape::setCategory(lua_State *L)
|
||||
{
|
||||
throwIfFixtureNotValid();
|
||||
b2Filter f = fixture->GetFilterData();
|
||||
f.categoryBits = (uint16)getBits(L);
|
||||
fixture->SetFilterData(f);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Shape::setMask(lua_State *L)
|
||||
{
|
||||
throwIfFixtureNotValid();
|
||||
b2Filter f = fixture->GetFilterData();
|
||||
f.maskBits = ~(uint16)getBits(L);
|
||||
fixture->SetFilterData(f);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Shape::setGroupIndex(int index)
|
||||
{
|
||||
throwIfFixtureNotValid();
|
||||
b2Filter f = fixture->GetFilterData();
|
||||
f.groupIndex = (uint16)index;
|
||||
fixture->SetFilterData(f);
|
||||
}
|
||||
|
||||
int Shape::getGroupIndex() const
|
||||
{
|
||||
throwIfFixtureNotValid();
|
||||
b2Filter f = fixture->GetFilterData();
|
||||
return f.groupIndex;
|
||||
}
|
||||
|
||||
int Shape::getCategory(lua_State *L)
|
||||
{
|
||||
throwIfFixtureNotValid();
|
||||
return pushBits(L, fixture->GetFilterData().categoryBits);
|
||||
}
|
||||
|
||||
int Shape::getMask(lua_State *L)
|
||||
{
|
||||
throwIfFixtureNotValid();
|
||||
return pushBits(L, ~(fixture->GetFilterData().maskBits));
|
||||
}
|
||||
|
||||
uint16 Shape::getBits(lua_State *L)
|
||||
{
|
||||
// Get number of args.
|
||||
bool istable = lua_istable(L, 1);
|
||||
int argc = istable ? (int) luax_objlen(L, 1) : lua_gettop(L);
|
||||
|
||||
// The new bitset.
|
||||
std::bitset<16> b;
|
||||
|
||||
for (int i = 1; i <= argc; i++)
|
||||
{
|
||||
size_t bpos = 0;
|
||||
|
||||
if (istable)
|
||||
{
|
||||
lua_rawgeti(L, 1, i);
|
||||
bpos = (size_t) (lua_tointeger(L, -1) - 1);
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
else
|
||||
bpos = (size_t) (lua_tointeger(L, i) - 1);
|
||||
|
||||
if (bpos >= 16)
|
||||
luaL_error(L, "Values must be in range 1-16.");
|
||||
|
||||
b.set(bpos, true);
|
||||
}
|
||||
|
||||
return (uint16)b.to_ulong();
|
||||
}
|
||||
|
||||
int Shape::pushBits(lua_State *L, uint16 bits)
|
||||
{
|
||||
// Create a bitset.
|
||||
std::bitset<16> b((int)bits);
|
||||
|
||||
// Push all set bits.
|
||||
for (int i = 0; i<16; i++)
|
||||
if (b.test(i))
|
||||
lua_pushinteger(L, i+1);
|
||||
|
||||
// Count number of set bits.
|
||||
return (int)b.count();
|
||||
}
|
||||
|
||||
int Shape::setUserData(lua_State *L)
|
||||
{
|
||||
love::luax_assert_argc(L, 1, 1);
|
||||
|
||||
if(!ref)
|
||||
ref = new Reference();
|
||||
|
||||
ref->ref(L);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Shape::getUserData(lua_State *L)
|
||||
{
|
||||
if (ref != nullptr)
|
||||
ref->push(L);
|
||||
else
|
||||
lua_pushnil(L);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool Shape::testPoint(float x, float y) const
|
||||
{
|
||||
throwIfFixtureNotValid();
|
||||
return fixture->TestPoint(Physics::scaleDown(b2Vec2(x, y)));
|
||||
}
|
||||
|
||||
bool Shape::testPoint(float x, float y, float r, float px, float py) const
|
||||
{
|
||||
throwIfShapeNotValid();
|
||||
b2Vec2 point(px, py);
|
||||
b2Transform transform(Physics::scaleDown(b2Vec2(x, y)), b2Rot(r));
|
||||
return shape->TestPoint(transform, Physics::scaleDown(point));
|
||||
@@ -95,18 +389,34 @@ int Shape::rayCast(lua_State *L) const
|
||||
float p2x = Physics::scaleDown((float)luaL_checknumber(L, 3));
|
||||
float p2y = Physics::scaleDown((float)luaL_checknumber(L, 4));
|
||||
float maxFraction = (float)luaL_checknumber(L, 5);
|
||||
float x = Physics::scaleDown((float)luaL_checknumber(L, 6));
|
||||
float y = Physics::scaleDown((float)luaL_checknumber(L, 7));
|
||||
float r = (float)luaL_checknumber(L, 8);
|
||||
int childIndex = (int) luaL_optinteger(L, 9, 1) - 1; // Convert from 1-based index
|
||||
|
||||
b2RayCastInput input;
|
||||
b2RayCastOutput output;
|
||||
input.p1.Set(p1x, p1y);
|
||||
input.p2.Set(p2x, p2y);
|
||||
input.maxFraction = maxFraction;
|
||||
b2Transform transform(b2Vec2(x, y), b2Rot(r));
|
||||
b2RayCastOutput output;
|
||||
if (!shape->RayCast(&output, input, transform, childIndex))
|
||||
return 0; // No hit.
|
||||
|
||||
if (lua_isnoneornil(L, 7))
|
||||
{
|
||||
throwIfFixtureNotValid();
|
||||
int childIndex = (int) luaL_optinteger(L, 6, 1) - 1; // Convert from 1-based index
|
||||
if (!fixture->RayCast(&output, input, childIndex))
|
||||
return 0; // Nothing hit.
|
||||
}
|
||||
else
|
||||
{
|
||||
throwIfShapeNotValid();
|
||||
float x = Physics::scaleDown((float)luaL_checknumber(L, 6));
|
||||
float y = Physics::scaleDown((float)luaL_checknumber(L, 7));
|
||||
float r = (float)luaL_checknumber(L, 8);
|
||||
int childIndex = (int) luaL_optinteger(L, 9, 1) - 1; // Convert from 1-based index
|
||||
|
||||
b2Transform transform(b2Vec2(x, y), b2Rot(r));
|
||||
|
||||
if (!shape->RayCast(&output, input, transform, childIndex))
|
||||
return 0; // No hit.
|
||||
}
|
||||
|
||||
lua_pushnumber(L, output.normal.x);
|
||||
lua_pushnumber(L, output.normal.y);
|
||||
lua_pushnumber(L, output.fraction);
|
||||
@@ -115,6 +425,7 @@ int Shape::rayCast(lua_State *L) const
|
||||
|
||||
int Shape::computeAABB(lua_State *L) const
|
||||
{
|
||||
throwIfShapeNotValid();
|
||||
float x = Physics::scaleDown((float)luaL_checknumber(L, 1));
|
||||
float y = Physics::scaleDown((float)luaL_checknumber(L, 2));
|
||||
float r = (float)luaL_checknumber(L, 3);
|
||||
@@ -132,6 +443,7 @@ int Shape::computeAABB(lua_State *L) const
|
||||
|
||||
int Shape::computeMass(lua_State *L) const
|
||||
{
|
||||
throwIfShapeNotValid();
|
||||
float density = (float)luaL_checknumber(L, 1);
|
||||
b2MassData data;
|
||||
shape->ComputeMass(&data, density);
|
||||
@@ -143,6 +455,33 @@ int Shape::computeMass(lua_State *L) const
|
||||
return 4;
|
||||
}
|
||||
|
||||
int Shape::getBoundingBox(lua_State *L) const
|
||||
{
|
||||
throwIfFixtureNotValid();
|
||||
int childIndex = (int) luaL_optinteger(L, 1, 1) - 1; // Convert from 1-based index
|
||||
b2AABB box;
|
||||
luax_catchexcept(L, [&]() { box = fixture->GetAABB(childIndex); });
|
||||
box = Physics::scaleUp(box);
|
||||
lua_pushnumber(L, box.lowerBound.x);
|
||||
lua_pushnumber(L, box.lowerBound.y);
|
||||
lua_pushnumber(L, box.upperBound.x);
|
||||
lua_pushnumber(L, box.upperBound.y);
|
||||
return 4;
|
||||
}
|
||||
|
||||
int Shape::getMassData(lua_State *L) const
|
||||
{
|
||||
throwIfFixtureNotValid();
|
||||
b2MassData data;
|
||||
fixture->GetMassData(&data);
|
||||
b2Vec2 center = Physics::scaleUp(data.center);
|
||||
lua_pushnumber(L, center.x);
|
||||
lua_pushnumber(L, center.y);
|
||||
lua_pushnumber(L, data.mass);
|
||||
lua_pushnumber(L, data.I);
|
||||
return 4;
|
||||
}
|
||||
|
||||
} // box2d
|
||||
} // physics
|
||||
} // love
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
// LOVE
|
||||
#include "physics/Shape.h"
|
||||
#include "physics/box2d/Body.h"
|
||||
#include "common/Reference.h"
|
||||
|
||||
// Box2D
|
||||
#include <box2d/Box2D.h>
|
||||
@@ -45,34 +46,155 @@ class Shape : public love::physics::Shape
|
||||
{
|
||||
public:
|
||||
|
||||
friend class Fixture;
|
||||
friend class Physics;
|
||||
|
||||
/**
|
||||
* Creates a Shape.
|
||||
**/
|
||||
Shape();
|
||||
Shape(b2Shape *shape, bool own = true);
|
||||
Shape(Body *body, const b2Shape &shape);
|
||||
|
||||
virtual ~Shape();
|
||||
|
||||
void destroy(bool implicit = false);
|
||||
|
||||
/**
|
||||
* Returns true if the shape is active in a Box2D world.
|
||||
**/
|
||||
bool isValid() const { return fixture != nullptr; }
|
||||
|
||||
/**
|
||||
* Returns true if the shape has not been destroyed.
|
||||
**/
|
||||
bool isShapeValid() const { return shape != nullptr; }
|
||||
|
||||
/**
|
||||
* Checks whether this Shape acts as a sensor.
|
||||
**/
|
||||
bool isSensor() const;
|
||||
|
||||
/**
|
||||
* Set whether this Shape should be a sensor or not.
|
||||
**/
|
||||
void setSensor(bool sensor);
|
||||
|
||||
/**
|
||||
* Gets the Body this Shape is attached to.
|
||||
**/
|
||||
Body *getBody() const;
|
||||
|
||||
/**
|
||||
* Sets the filter data. An integer array is used even though the
|
||||
* first two elements are unsigned shorts. The elements are:
|
||||
* category (16-bits), mask (16-bits) and group (32-bits/int).
|
||||
**/
|
||||
void setFilterData(int *v);
|
||||
|
||||
/**
|
||||
* Gets the filter data. An integer array is used even though the
|
||||
* first two elements are unsigned shorts. The elements are:
|
||||
* category (16-bits), mask (16-bits) and group (32-bits/int).
|
||||
**/
|
||||
void getFilterData(int *v);
|
||||
|
||||
/**
|
||||
* This function stores an in-C reference to
|
||||
* arbitrary Lua data in the Shape object.
|
||||
**/
|
||||
int setUserData(lua_State *L);
|
||||
|
||||
/**
|
||||
* Gets the data set with setUserData. If no
|
||||
* data is set, nil is returned.
|
||||
**/
|
||||
int getUserData(lua_State *L);
|
||||
|
||||
/**
|
||||
* Sets the friction of the Shape.
|
||||
**/
|
||||
void setFriction(float friction);
|
||||
|
||||
/**
|
||||
* Sets the restitution for the Shape.
|
||||
**/
|
||||
void setRestitution(float restitution);
|
||||
|
||||
/**
|
||||
* Sets the density of the Shape.
|
||||
**/
|
||||
void setDensity(float density);
|
||||
|
||||
/**
|
||||
* Gets the friction of the Shape.
|
||||
**/
|
||||
float getFriction() const;
|
||||
|
||||
/**
|
||||
* Gets the restitution of the Shape.
|
||||
**/
|
||||
float getRestitution() const;
|
||||
|
||||
/**
|
||||
* Gets the density of the Shape.
|
||||
**/
|
||||
float getDensity() const;
|
||||
|
||||
/**
|
||||
* Checks if a point is inside the Shape.
|
||||
**/
|
||||
bool testPoint(float x, float y) const;
|
||||
bool testPoint(float x, float y, float r, float px, float py) const;
|
||||
|
||||
/**
|
||||
* Gets the type of Shape. Useful for
|
||||
* debug drawing.
|
||||
**/
|
||||
Type getType() const;
|
||||
|
||||
float getRadius() const;
|
||||
int getChildCount() const;
|
||||
bool testPoint(float x, float y, float r, float px, float py) const;
|
||||
int rayCast(lua_State *L) const;
|
||||
int computeAABB(lua_State *L) const;
|
||||
int computeMass(lua_State *L) const;
|
||||
|
||||
void setGroupIndex(int index);
|
||||
int getGroupIndex() const;
|
||||
|
||||
int setCategory(lua_State *L);
|
||||
int setMask(lua_State *L);
|
||||
int getCategory(lua_State *L);
|
||||
int getMask(lua_State *L);
|
||||
uint16 getBits(lua_State *L);
|
||||
int pushBits(lua_State *L, uint16 bits);
|
||||
|
||||
/**
|
||||
* Gets the bounding box for this Shape.
|
||||
**/
|
||||
int getBoundingBox(lua_State *L) const;
|
||||
|
||||
/**
|
||||
* Gets the mass data for this Shape.
|
||||
* This operation may be expensive.
|
||||
**/
|
||||
int getMassData(lua_State *L) const;
|
||||
|
||||
void throwIfFixtureNotValid() const;
|
||||
void throwIfShapeNotValid() const;
|
||||
|
||||
protected:
|
||||
|
||||
// The Box2D shape.
|
||||
b2Shape *shape;
|
||||
bool own;
|
||||
};
|
||||
|
||||
Shape::Type shapeType;
|
||||
|
||||
Body *body;
|
||||
b2Fixture *fixture;
|
||||
|
||||
// Reference to arbitrary data.
|
||||
Reference* ref = nullptr;
|
||||
|
||||
}; // Shape
|
||||
|
||||
} // box2d
|
||||
} // physics
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
|
||||
#include "World.h"
|
||||
|
||||
#include "Fixture.h"
|
||||
#include "Shape.h"
|
||||
#include "Contact.h"
|
||||
#include "Physics.h"
|
||||
@@ -28,6 +27,7 @@
|
||||
|
||||
// Needed for World::getJoints. It should be moved to wrapper code...
|
||||
#include "wrap_Joint.h"
|
||||
#include "wrap_Shape.h"
|
||||
|
||||
namespace love
|
||||
{
|
||||
@@ -58,22 +58,22 @@ void World::ContactCallback::process(b2Contact *contact, const b2ContactImpulse
|
||||
{
|
||||
ref->push(L);
|
||||
|
||||
// Push first fixture.
|
||||
// Push first shape.
|
||||
{
|
||||
Fixture *a = (Fixture *)(contact->GetFixtureA()->GetUserData().pointer);
|
||||
Shape *a = (Shape *)(contact->GetFixtureA()->GetUserData().pointer);
|
||||
if (a != nullptr)
|
||||
luax_pushtype(L, a);
|
||||
luax_pushshape(L, a);
|
||||
else
|
||||
throw love::Exception("A fixture has escaped Memoizer!");
|
||||
throw love::Exception("A Shape has escaped Memoizer!");
|
||||
}
|
||||
|
||||
// Push second fixture.
|
||||
// Push second shape.
|
||||
{
|
||||
Fixture *b = (Fixture *)(contact->GetFixtureB()->GetUserData().pointer);
|
||||
Shape *b = (Shape *)(contact->GetFixtureB()->GetUserData().pointer);
|
||||
if (b != nullptr)
|
||||
luax_pushtype(L, b);
|
||||
luax_pushshape(L, b);
|
||||
else
|
||||
throw love::Exception("A fixture has escaped Memoizer!");
|
||||
throw love::Exception("A Shape has escaped Memoizer!");
|
||||
}
|
||||
|
||||
Contact *cobj = (Contact *)world->findObject(contact);
|
||||
@@ -112,7 +112,7 @@ World::ContactFilter::~ContactFilter()
|
||||
delete ref;
|
||||
}
|
||||
|
||||
bool World::ContactFilter::process(Fixture *a, Fixture *b)
|
||||
bool World::ContactFilter::process(Shape *a, Shape *b)
|
||||
{
|
||||
// Handle masks, reimplemented from the manual
|
||||
int filterA[3], filterB[3];
|
||||
@@ -133,8 +133,8 @@ bool World::ContactFilter::process(Fixture *a, Fixture *b)
|
||||
if (ref != nullptr && L != nullptr)
|
||||
{
|
||||
ref->push(L);
|
||||
luax_pushtype(L, a);
|
||||
luax_pushtype(L, b);
|
||||
luax_pushshape(L, a);
|
||||
luax_pushshape(L, b);
|
||||
lua_call(L, 2, 1);
|
||||
return luax_toboolean(L, -1);
|
||||
}
|
||||
@@ -159,10 +159,10 @@ bool World::QueryCallback::ReportFixture(b2Fixture *fixture)
|
||||
if (L != nullptr)
|
||||
{
|
||||
lua_pushvalue(L, funcidx);
|
||||
Fixture *f = (Fixture *)(fixture->GetUserData().pointer);
|
||||
Shape *f = (Shape *)(fixture->GetUserData().pointer);
|
||||
if (!f)
|
||||
throw love::Exception("A fixture has escaped Memoizer!");
|
||||
luax_pushtype(L, f);
|
||||
throw love::Exception("A Shape has escaped Memoizer!");
|
||||
luax_pushshape(L, f);
|
||||
for (int i = 1; i <= userargs; i++)
|
||||
lua_pushvalue(L, funcidx + i);
|
||||
lua_call(L, 1 + userargs, 1);
|
||||
@@ -191,10 +191,10 @@ bool World::CollectCallback::ReportFixture(b2Fixture *f)
|
||||
if (categoryMask != 0xFFFF && (categoryMask & f->GetFilterData().categoryBits) == 0)
|
||||
return true;
|
||||
|
||||
Fixture *fixture = (Fixture *)(f->GetUserData().pointer);
|
||||
if (!fixture)
|
||||
throw love::Exception("A fixture has escaped Memoizer!");
|
||||
luax_pushtype(L, fixture);
|
||||
Shape *shape = (Shape *)(f->GetUserData().pointer);
|
||||
if (!shape)
|
||||
throw love::Exception("A Shape has escaped Memoizer!");
|
||||
luax_pushshape(L, shape);
|
||||
lua_rawseti(L, -2, i);
|
||||
i++;
|
||||
return true;
|
||||
@@ -218,10 +218,10 @@ float World::RayCastCallback::ReportFixture(b2Fixture *fixture, const b2Vec2 &po
|
||||
if (L != nullptr)
|
||||
{
|
||||
lua_pushvalue(L, funcidx);
|
||||
Fixture *f = (Fixture *)(fixture->GetUserData().pointer);
|
||||
Shape *f = (Shape *)(fixture->GetUserData().pointer);
|
||||
if (!f)
|
||||
throw love::Exception("A fixture has escaped Memoizer!");
|
||||
luax_pushtype(L, f);
|
||||
throw love::Exception("A Shape has escaped Memoizer!");
|
||||
luax_pushshape(L, f);
|
||||
b2Vec2 scaledPoint = Physics::scaleUp(point);
|
||||
lua_pushnumber(L, scaledPoint.x);
|
||||
lua_pushnumber(L, scaledPoint.y);
|
||||
@@ -267,9 +267,9 @@ float World::RayCastOneCallback::ReportFixture(b2Fixture *fixture, const b2Vec2
|
||||
|
||||
void World::SayGoodbye(b2Fixture *fixture)
|
||||
{
|
||||
Fixture *f = (Fixture *)(fixture->GetUserData().pointer);
|
||||
Shape *s = (Shape *)(fixture->GetUserData().pointer);
|
||||
// Hint implicit destruction with true.
|
||||
if (f) f->destroy(true);
|
||||
if (s) s->destroy(true);
|
||||
}
|
||||
|
||||
void World::SayGoodbye(b2Joint *joint)
|
||||
@@ -336,11 +336,11 @@ void World::update(float dt, int velocityIterations, int positionIterations)
|
||||
// Release for reference in vector.
|
||||
b->release();
|
||||
}
|
||||
for (Fixture *f : destructFixtures)
|
||||
for (Shape *s : destructShapes)
|
||||
{
|
||||
if (f->isValid()) f->destroy();
|
||||
if (s->isValid()) s->destroy();
|
||||
// Release for reference in vector.
|
||||
f->release();
|
||||
s->release();
|
||||
}
|
||||
for (Joint *j : destructJoints)
|
||||
{
|
||||
@@ -349,7 +349,7 @@ void World::update(float dt, int velocityIterations, int positionIterations)
|
||||
j->release();
|
||||
}
|
||||
destructBodies.clear();
|
||||
destructFixtures.clear();
|
||||
destructShapes.clear();
|
||||
destructJoints.clear();
|
||||
|
||||
if (destructWorld)
|
||||
@@ -384,11 +384,11 @@ void World::PostSolve(b2Contact *contact, const b2ContactImpulse *impulse)
|
||||
|
||||
bool World::ShouldCollide(b2Fixture *fixtureA, b2Fixture *fixtureB)
|
||||
{
|
||||
// Fixtures should be memoized, if we created them
|
||||
Fixture *a = (Fixture *)(fixtureA->GetUserData().pointer);
|
||||
Fixture *b = (Fixture *)(fixtureB->GetUserData().pointer);
|
||||
// Shapes should be memoized, if we created them
|
||||
Shape *a = (Shape *)(fixtureA->GetUserData().pointer);
|
||||
Shape *b = (Shape *)(fixtureB->GetUserData().pointer);
|
||||
if (!a || !b)
|
||||
throw love::Exception("A fixture has escaped Memoizer!");
|
||||
throw love::Exception("A Shape has escaped Memoizer!");
|
||||
return filter.process(a, b);
|
||||
}
|
||||
|
||||
@@ -597,7 +597,7 @@ b2Body *World::getGroundBody() const
|
||||
return groundBody;
|
||||
}
|
||||
|
||||
int World::queryFixturesInArea(lua_State *L)
|
||||
int World::queryShapesInArea(lua_State *L)
|
||||
{
|
||||
b2AABB box;
|
||||
float lx = (float)luaL_checknumber(L, 1);
|
||||
@@ -612,7 +612,7 @@ int World::queryFixturesInArea(lua_State *L)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int World::getFixturesInArea(lua_State *L)
|
||||
int World::getShapesInArea(lua_State *L)
|
||||
{
|
||||
float lx = (float)luaL_checknumber(L, 1);
|
||||
float ly = (float)luaL_checknumber(L, 2);
|
||||
@@ -654,10 +654,10 @@ int World::rayCastAny(lua_State *L)
|
||||
world->RayCast(&raycast, v1, v2);
|
||||
if (raycast.hitFixture)
|
||||
{
|
||||
Fixture *f = (Fixture *)(raycast.hitFixture->GetUserData().pointer);
|
||||
Shape *f = (Shape *)(raycast.hitFixture->GetUserData().pointer);
|
||||
if (f == nullptr)
|
||||
return luaL_error(L, "A fixture has escaped Memoizer!");
|
||||
luax_pushtype(L, f);
|
||||
return luaL_error(L, "A Shape has escaped Memoizer!");
|
||||
luax_pushshape(L, f);
|
||||
|
||||
b2Vec2 hitPoint = Physics::scaleUp(raycast.hitPoint);
|
||||
lua_pushnumber(L, hitPoint.x);
|
||||
@@ -683,10 +683,10 @@ int World::rayCastClosest(lua_State *L)
|
||||
world->RayCast(&raycast, v1, v2);
|
||||
if (raycast.hitFixture)
|
||||
{
|
||||
Fixture *f = (Fixture *)(raycast.hitFixture->GetUserData().pointer);
|
||||
Shape *f = (Shape *)(raycast.hitFixture->GetUserData().pointer);
|
||||
if (f == nullptr)
|
||||
return luaL_error(L, "A fixture has escaped Memoizer!");
|
||||
luax_pushtype(L, f);
|
||||
return luaL_error(L, "A Shape has escaped Memoizer!");
|
||||
luax_pushshape(L, f);
|
||||
|
||||
b2Vec2 hitPoint = Physics::scaleUp(raycast.hitPoint);
|
||||
lua_pushnumber(L, hitPoint.x);
|
||||
|
||||
@@ -42,7 +42,6 @@ namespace box2d
|
||||
|
||||
class Contact;
|
||||
class Body;
|
||||
class Fixture;
|
||||
class Joint;
|
||||
|
||||
/**
|
||||
@@ -65,7 +64,7 @@ public:
|
||||
friend class DistanceJoint;
|
||||
friend class MouseJoint;
|
||||
friend class Body;
|
||||
friend class Fixture;
|
||||
friend class Shape;
|
||||
|
||||
static love::Type type;
|
||||
|
||||
@@ -87,7 +86,7 @@ public:
|
||||
lua_State *L;
|
||||
ContactFilter();
|
||||
~ContactFilter();
|
||||
bool process(Fixture *a, Fixture *b);
|
||||
bool process(Shape *a, Shape *b);
|
||||
};
|
||||
|
||||
class QueryCallback : public b2QueryCallback
|
||||
@@ -302,14 +301,14 @@ public:
|
||||
b2Body *getGroundBody() const;
|
||||
|
||||
/**
|
||||
* Calls a callback on all fixtures that overlap a given bounding box.
|
||||
* Calls a callback on all Shapes that overlap a given bounding box.
|
||||
**/
|
||||
int queryFixturesInArea(lua_State *L);
|
||||
int queryShapesInArea(lua_State *L);
|
||||
|
||||
/**
|
||||
* Gets all fixtures that overlap a given bounding box.
|
||||
* Gets all Shapes that overlap a given bounding box.
|
||||
**/
|
||||
int getFixturesInArea(lua_State *L);
|
||||
int getShapesInArea(lua_State *L);
|
||||
|
||||
/**
|
||||
* Raycasts the World for all Fixtures in the path of the ray.
|
||||
@@ -338,7 +337,7 @@ private:
|
||||
|
||||
// The list of to be destructed bodies.
|
||||
std::vector<Body *> destructBodies;
|
||||
std::vector<Fixture *> destructFixtures;
|
||||
std::vector<Shape *> destructShapes;
|
||||
std::vector<Joint *> destructJoints;
|
||||
bool destructWorld;
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
|
||||
#include "wrap_Body.h"
|
||||
#include "wrap_Physics.h"
|
||||
#include "wrap_Shape.h"
|
||||
|
||||
namespace love
|
||||
{
|
||||
@@ -599,26 +600,32 @@ int w_Body_getWorld(lua_State *L)
|
||||
return 1;
|
||||
}
|
||||
|
||||
int w_Body_getFixture(lua_State *L)
|
||||
int w_Body_getShape(lua_State *L)
|
||||
{
|
||||
Body *t = luax_checkbody(L, 1);
|
||||
Fixture *f = t->getFixture();
|
||||
if (f)
|
||||
luax_pushtype(L, f);
|
||||
Shape *s = t->getShape();
|
||||
if (s)
|
||||
luax_pushshape(L, s);
|
||||
else
|
||||
lua_pushnil(L);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int w_Body_getFixtures(lua_State *L)
|
||||
int w_Body_getShapes(lua_State *L)
|
||||
{
|
||||
Body *t = luax_checkbody(L, 1);
|
||||
lua_remove(L, 1);
|
||||
int n = 0;
|
||||
luax_catchexcept(L, [&](){ n = t->getFixtures(L); });
|
||||
luax_catchexcept(L, [&](){ n = t->getShapes(L); });
|
||||
return n;
|
||||
}
|
||||
|
||||
int w_Body_getFixtures(lua_State *L)
|
||||
{
|
||||
luax_markdeprecated(L, 1, "Body:getFixtures", API_METHOD, DEPRECATED_REPLACED, "Body:getShapes");
|
||||
return w_Body_getShapes(L);
|
||||
}
|
||||
|
||||
int w_Body_getJoints(lua_State *L)
|
||||
{
|
||||
Body *t = luax_checkbody(L, 1);
|
||||
@@ -724,8 +731,8 @@ static const luaL_Reg w_Body_functions[] =
|
||||
{ "isFixedRotation", w_Body_isFixedRotation },
|
||||
{ "isTouching", w_Body_isTouching },
|
||||
{ "getWorld", w_Body_getWorld },
|
||||
{ "getFixture", w_Body_getFixture },
|
||||
{ "getFixtures", w_Body_getFixtures },
|
||||
{ "getShape", w_Body_getShape },
|
||||
{ "getShapes", w_Body_getShapes },
|
||||
{ "getJoints", w_Body_getJoints },
|
||||
{ "getContacts", w_Body_getContacts },
|
||||
{ "destroy", w_Body_destroy },
|
||||
@@ -733,6 +740,9 @@ static const luaL_Reg w_Body_functions[] =
|
||||
{ "setUserData", w_Body_setUserData },
|
||||
{ "getUserData", w_Body_getUserData },
|
||||
|
||||
// Deprecated
|
||||
{ "getFixtures", w_Body_getFixtures },
|
||||
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
|
||||
@@ -54,9 +54,10 @@ int w_ChainShape_setPreviousVertex(lua_State *L)
|
||||
|
||||
int w_ChainShape_getChildEdge(lua_State *L)
|
||||
{
|
||||
luax_markdeprecated(L, 1, "ChainShape:getChildEdge", API_METHOD, DEPRECATED_NO_REPLACEMENT, nullptr);
|
||||
ChainShape *c = luax_checkchainshape(L, 1);
|
||||
int index = (int) luaL_checkinteger(L, 2) - 1; // Convert from 1-based index
|
||||
EdgeShape *e = 0;
|
||||
EdgeShape *e = nullptr;
|
||||
luax_catchexcept(L, [&](){ e = c->getChildEdge(index); });
|
||||
luax_pushtype(L, e);
|
||||
e->release();
|
||||
@@ -66,7 +67,8 @@ int w_ChainShape_getChildEdge(lua_State *L)
|
||||
int w_ChainShape_getVertexCount(lua_State *L)
|
||||
{
|
||||
ChainShape *c = luax_checkchainshape(L, 1);
|
||||
int count = c->getVertexCount();
|
||||
int count = 0;
|
||||
luax_catchexcept(L, [&]() { count = c->getVertexCount(); });
|
||||
lua_pushinteger(L, count);
|
||||
return 1;
|
||||
}
|
||||
@@ -85,7 +87,8 @@ int w_ChainShape_getPoint(lua_State *L)
|
||||
int w_ChainShape_getNextVertex(lua_State *L)
|
||||
{
|
||||
ChainShape *c = luax_checkchainshape(L, 1);
|
||||
b2Vec2 v = c->getNextVertex();
|
||||
b2Vec2 v;
|
||||
luax_catchexcept(L, [&]() { v = c->getNextVertex(); });
|
||||
lua_pushnumber(L, v.x);
|
||||
lua_pushnumber(L, v.y);
|
||||
return 2;
|
||||
@@ -94,7 +97,8 @@ int w_ChainShape_getNextVertex(lua_State *L)
|
||||
int w_ChainShape_getPreviousVertex(lua_State *L)
|
||||
{
|
||||
ChainShape *c = luax_checkchainshape(L, 1);
|
||||
b2Vec2 v = c->getPreviousVertex();
|
||||
b2Vec2 v;
|
||||
luax_catchexcept(L, [&]() { v = c->getPreviousVertex(); });
|
||||
lua_pushnumber(L, v.x);
|
||||
lua_pushnumber(L, v.y);
|
||||
return 2;
|
||||
@@ -103,7 +107,8 @@ int w_ChainShape_getPreviousVertex(lua_State *L)
|
||||
int w_ChainShape_getPoints(lua_State *L)
|
||||
{
|
||||
ChainShape *c = luax_checkchainshape(L, 1);
|
||||
const b2Vec2 *verts = c->getPoints();
|
||||
const b2Vec2 *verts;
|
||||
luax_catchexcept(L, [&]() { verts = c->getPoints(); });
|
||||
int count = c->getVertexCount();
|
||||
if (!lua_checkstack(L, count*2))
|
||||
return luaL_error(L, "Too many return values");
|
||||
|
||||
@@ -35,7 +35,9 @@ CircleShape *luax_checkcircleshape(lua_State *L, int idx)
|
||||
int w_CircleShape_getRadius(lua_State *L)
|
||||
{
|
||||
CircleShape *c = luax_checkcircleshape(L, 1);
|
||||
lua_pushnumber(L, c->getRadius());
|
||||
float r = 0;
|
||||
luax_catchexcept(L, [&]() { r = c->getRadius(); });
|
||||
lua_pushnumber(L, r);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -43,7 +45,7 @@ int w_CircleShape_setRadius(lua_State *L)
|
||||
{
|
||||
CircleShape *c = luax_checkcircleshape(L, 1);
|
||||
float r = (float)luaL_checknumber(L, 2);
|
||||
c->setRadius(r);
|
||||
luax_catchexcept(L, [&]() { c->setRadius(r); });
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -51,7 +53,7 @@ int w_CircleShape_getPoint(lua_State *L)
|
||||
{
|
||||
CircleShape *c = luax_checkcircleshape(L, 1);
|
||||
float x, y;
|
||||
c->getPoint(x, y);
|
||||
luax_catchexcept(L, [&]() { c->getPoint(x, y); });
|
||||
lua_pushnumber(L, x);
|
||||
lua_pushnumber(L, y);
|
||||
return 2;
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
**/
|
||||
|
||||
#include "wrap_Contact.h"
|
||||
#include "Fixture.h"
|
||||
#include "wrap_Shape.h"
|
||||
|
||||
namespace love
|
||||
{
|
||||
@@ -139,18 +139,24 @@ int w_Contact_getChildren(lua_State *L)
|
||||
return 2;
|
||||
}
|
||||
|
||||
int w_Contact_getFixtures(lua_State *L)
|
||||
int w_Contact_getShapes(lua_State *L)
|
||||
{
|
||||
Contact *t = luax_checkcontact(L, 1);
|
||||
Fixture *a = nullptr;
|
||||
Fixture *b = nullptr;
|
||||
luax_catchexcept(L, [&](){ t->getFixtures(a, b); });
|
||||
Shape *a = nullptr;
|
||||
Shape *b = nullptr;
|
||||
luax_catchexcept(L, [&](){ t->getShapes(a, b); });
|
||||
|
||||
luax_pushtype(L, a);
|
||||
luax_pushtype(L, b);
|
||||
luax_pushshape(L, a);
|
||||
luax_pushshape(L, b);
|
||||
return 2;
|
||||
}
|
||||
|
||||
int w_Contact_getFixtures(lua_State *L)
|
||||
{
|
||||
luax_markdeprecated(L, 1, "Contact:getFixtures", API_METHOD, DEPRECATED_REPLACED, "Contact:getShapes");
|
||||
return w_Contact_getShapes(L);
|
||||
}
|
||||
|
||||
int w_Contact_isDestroyed(lua_State *L)
|
||||
{
|
||||
Contact *c = luax_checktype<Contact>(L, 1);
|
||||
@@ -174,8 +180,12 @@ static const luaL_Reg w_Contact_functions[] =
|
||||
{ "setTangentSpeed", w_Contact_setTangentSpeed },
|
||||
{ "getTangentSpeed", w_Contact_getTangentSpeed },
|
||||
{ "getChildren", w_Contact_getChildren },
|
||||
{ "getFixtures", w_Contact_getFixtures },
|
||||
{ "getShapes", w_Contact_getShapes },
|
||||
{ "isDestroyed", w_Contact_isDestroyed },
|
||||
|
||||
// Deprecated
|
||||
{ "getFixtures", w_Contact_getFixtures },
|
||||
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@ int w_EdgeShape_setNextVertex(lua_State *L)
|
||||
EdgeShape *t = luax_checkedgeshape(L, 1);
|
||||
float x = (float)luaL_checknumber(L, 2);
|
||||
float y = (float)luaL_checknumber(L, 3);
|
||||
t->setNextVertex(x, y);
|
||||
luax_catchexcept(L, [&]() { t->setNextVertex(x, y); });
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -46,14 +46,15 @@ int w_EdgeShape_setPreviousVertex(lua_State *L)
|
||||
EdgeShape *t = luax_checkedgeshape(L, 1);
|
||||
float x = (float)luaL_checknumber(L, 2);
|
||||
float y = (float)luaL_checknumber(L, 3);
|
||||
t->setPreviousVertex(x, y);
|
||||
luax_catchexcept(L, [&]() { t->setPreviousVertex(x, y); });
|
||||
return 0;
|
||||
}
|
||||
|
||||
int w_EdgeShape_getNextVertex(lua_State *L)
|
||||
{
|
||||
EdgeShape *t = luax_checkedgeshape(L, 1);
|
||||
b2Vec2 v = t->getNextVertex();
|
||||
b2Vec2 v;
|
||||
luax_catchexcept(L, [&]() { v = t->getNextVertex(); });
|
||||
lua_pushnumber(L, v.x);
|
||||
lua_pushnumber(L, v.y);
|
||||
return 2;
|
||||
@@ -62,7 +63,8 @@ int w_EdgeShape_getNextVertex(lua_State *L)
|
||||
int w_EdgeShape_getPreviousVertex(lua_State *L)
|
||||
{
|
||||
EdgeShape *t = luax_checkedgeshape(L, 1);
|
||||
b2Vec2 v = t->getPreviousVertex();
|
||||
b2Vec2 v;
|
||||
luax_catchexcept(L, [&]() { v = t->getPreviousVertex(); });
|
||||
lua_pushnumber(L, v.x);
|
||||
lua_pushnumber(L, v.y);
|
||||
return 2;
|
||||
@@ -72,7 +74,9 @@ int w_EdgeShape_getPoints(lua_State *L)
|
||||
{
|
||||
EdgeShape *t = luax_checkedgeshape(L, 1);
|
||||
lua_remove(L, 1);
|
||||
return t->getPoints(L);
|
||||
int ret = 0;
|
||||
luax_catchexcept(L, [&]() { ret = t->getPoints(L); });
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const luaL_Reg w_EdgeShape_functions[] =
|
||||
|
||||
@@ -1,311 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2006-2023 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_Fixture.h"
|
||||
#include "common/StringMap.h"
|
||||
|
||||
namespace love
|
||||
{
|
||||
namespace physics
|
||||
{
|
||||
namespace box2d
|
||||
{
|
||||
|
||||
Fixture *luax_checkfixture(lua_State *L, int idx)
|
||||
{
|
||||
Fixture *f = luax_checktype<Fixture>(L, idx);
|
||||
if (!f->isValid())
|
||||
luaL_error(L, "Attempt to use destroyed fixture.");
|
||||
return f;
|
||||
}
|
||||
|
||||
int w_Fixture_getType(lua_State *L)
|
||||
{
|
||||
Fixture *t = luax_checkfixture(L, 1);
|
||||
const char *type = "";
|
||||
Shape::getConstant(t->getType(), type);
|
||||
lua_pushstring(L, type);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int w_Fixture_setFriction(lua_State *L)
|
||||
{
|
||||
Fixture *t = luax_checkfixture(L, 1);
|
||||
float arg1 = (float)luaL_checknumber(L, 2);
|
||||
t->setFriction(arg1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int w_Fixture_setRestitution(lua_State *L)
|
||||
{
|
||||
Fixture *t = luax_checkfixture(L, 1);
|
||||
float arg1 = (float)luaL_checknumber(L, 2);
|
||||
t->setRestitution(arg1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int w_Fixture_setDensity(lua_State *L)
|
||||
{
|
||||
Fixture *t = luax_checkfixture(L, 1);
|
||||
float arg1 = (float)luaL_checknumber(L, 2);
|
||||
luax_catchexcept(L, [&](){ t->setDensity(arg1); });
|
||||
return 0;
|
||||
}
|
||||
|
||||
int w_Fixture_setSensor(lua_State *L)
|
||||
{
|
||||
Fixture *t = luax_checkfixture(L, 1);
|
||||
bool arg1 = luax_checkboolean(L, 2);
|
||||
t->setSensor(arg1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int w_Fixture_getFriction(lua_State *L)
|
||||
{
|
||||
Fixture *t = luax_checkfixture(L, 1);
|
||||
lua_pushnumber(L, t->getFriction());
|
||||
return 1;
|
||||
}
|
||||
|
||||
int w_Fixture_getRestitution(lua_State *L)
|
||||
{
|
||||
Fixture *t = luax_checkfixture(L, 1);
|
||||
lua_pushnumber(L, t->getRestitution());
|
||||
return 1;
|
||||
}
|
||||
|
||||
int w_Fixture_getDensity(lua_State *L)
|
||||
{
|
||||
Fixture *t = luax_checkfixture(L, 1);
|
||||
lua_pushnumber(L, t->getDensity());
|
||||
return 1;
|
||||
}
|
||||
|
||||
int w_Fixture_isSensor(lua_State *L)
|
||||
{
|
||||
Fixture *t = luax_checkfixture(L, 1);
|
||||
luax_pushboolean(L, t->isSensor());
|
||||
return 1;
|
||||
}
|
||||
|
||||
int w_Fixture_getBody(lua_State *L)
|
||||
{
|
||||
Fixture *t = luax_checkfixture(L, 1);
|
||||
Body *body = t->getBody();
|
||||
if (body == 0)
|
||||
return 0;
|
||||
luax_pushtype(L, body);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int w_Fixture_getShape(lua_State *L)
|
||||
{
|
||||
Fixture *t = luax_checkfixture(L, 1);
|
||||
Shape * shape = t->getShape();
|
||||
if (shape == nullptr)
|
||||
return 0;
|
||||
switch (shape->getType())
|
||||
{
|
||||
case Shape::SHAPE_EDGE:
|
||||
luax_pushtype(L, dynamic_cast<EdgeShape *>(shape));
|
||||
break;
|
||||
case Shape::SHAPE_CHAIN:
|
||||
luax_pushtype(L, dynamic_cast<ChainShape *>(shape));
|
||||
break;
|
||||
case Shape::SHAPE_CIRCLE:
|
||||
luax_pushtype(L, dynamic_cast<CircleShape *>(shape));
|
||||
break;
|
||||
case Shape::SHAPE_POLYGON:
|
||||
luax_pushtype(L, dynamic_cast<PolygonShape *>(shape));
|
||||
break;
|
||||
default:
|
||||
luax_pushtype(L, shape);
|
||||
break;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int w_Fixture_testPoint(lua_State *L)
|
||||
{
|
||||
Fixture *t = luax_checkfixture(L, 1);
|
||||
float x = (float)luaL_checknumber(L, 2);
|
||||
float y = (float)luaL_checknumber(L, 3);
|
||||
luax_pushboolean(L, t->testPoint(x, y));
|
||||
return 1;
|
||||
}
|
||||
|
||||
int w_Fixture_rayCast(lua_State *L)
|
||||
{
|
||||
Fixture *t = luax_checkfixture(L, 1);
|
||||
lua_remove(L, 1);
|
||||
int ret = 0;
|
||||
luax_catchexcept(L, [&](){ ret = t->rayCast(L); });
|
||||
return ret;
|
||||
}
|
||||
|
||||
int w_Fixture_setFilterData(lua_State *L)
|
||||
{
|
||||
Fixture *t = luax_checkfixture(L, 1);
|
||||
int v[3];
|
||||
v[0] = (int) luaL_checkinteger(L, 2);
|
||||
v[1] = (int) luaL_checkinteger(L, 3);
|
||||
v[2] = (int) luaL_checkinteger(L, 4);
|
||||
t->setFilterData(v);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int w_Fixture_getFilterData(lua_State *L)
|
||||
{
|
||||
Fixture *t = luax_checkfixture(L, 1);
|
||||
int v[3];
|
||||
t->getFilterData(v);
|
||||
lua_pushinteger(L, v[0]);
|
||||
lua_pushinteger(L, v[1]);
|
||||
lua_pushinteger(L, v[2]);
|
||||
return 3;
|
||||
}
|
||||
|
||||
int w_Fixture_setCategory(lua_State *L)
|
||||
{
|
||||
Fixture *t = luax_checkfixture(L, 1);
|
||||
lua_remove(L, 1);
|
||||
return t->setCategory(L);
|
||||
}
|
||||
|
||||
int w_Fixture_getCategory(lua_State *L)
|
||||
{
|
||||
Fixture *t = luax_checkfixture(L, 1);
|
||||
lua_remove(L, 1);
|
||||
return t->getCategory(L);
|
||||
}
|
||||
|
||||
int w_Fixture_setMask(lua_State *L)
|
||||
{
|
||||
Fixture *t = luax_checkfixture(L, 1);
|
||||
lua_remove(L, 1);
|
||||
return t->setMask(L);
|
||||
}
|
||||
|
||||
int w_Fixture_getMask(lua_State *L)
|
||||
{
|
||||
Fixture *t = luax_checkfixture(L, 1);
|
||||
lua_remove(L, 1);
|
||||
return t->getMask(L);
|
||||
}
|
||||
|
||||
int w_Fixture_setUserData(lua_State *L)
|
||||
{
|
||||
Fixture *t = luax_checkfixture(L, 1);
|
||||
lua_remove(L, 1);
|
||||
return t->setUserData(L);
|
||||
}
|
||||
|
||||
int w_Fixture_getUserData(lua_State *L)
|
||||
{
|
||||
Fixture *t = luax_checkfixture(L, 1);
|
||||
lua_remove(L, 1);
|
||||
return t->getUserData(L);
|
||||
}
|
||||
|
||||
int w_Fixture_getBoundingBox(lua_State *L)
|
||||
{
|
||||
Fixture *t = luax_checkfixture(L, 1);
|
||||
lua_remove(L, 1);
|
||||
return t->getBoundingBox(L);
|
||||
}
|
||||
|
||||
int w_Fixture_getMassData(lua_State *L)
|
||||
{
|
||||
Fixture *t = luax_checkfixture(L, 1);
|
||||
lua_remove(L, 1);
|
||||
return t->getMassData(L);
|
||||
}
|
||||
|
||||
int w_Fixture_getGroupIndex(lua_State *L)
|
||||
{
|
||||
Fixture *t = luax_checkfixture(L, 1);
|
||||
int i = t->getGroupIndex();
|
||||
lua_pushinteger(L, i);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int w_Fixture_setGroupIndex(lua_State *L)
|
||||
{
|
||||
Fixture *t = luax_checkfixture(L, 1);
|
||||
int i = (int) luaL_checkinteger(L, 2);
|
||||
t->setGroupIndex(i);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int w_Fixture_destroy(lua_State *L)
|
||||
{
|
||||
Fixture *t = luax_checkfixture(L, 1);
|
||||
luax_catchexcept(L, [&](){ t->destroy(); });
|
||||
return 0;
|
||||
}
|
||||
|
||||
int w_Fixture_isDestroyed(lua_State *L)
|
||||
{
|
||||
Fixture *f = luax_checktype<Fixture>(L, 1);
|
||||
luax_pushboolean(L, !f->isValid());
|
||||
return 1;
|
||||
}
|
||||
|
||||
static const luaL_Reg w_Fixture_functions[] =
|
||||
{
|
||||
{ "getType", w_Fixture_getType },
|
||||
{ "setFriction", w_Fixture_setFriction },
|
||||
{ "setRestitution", w_Fixture_setRestitution },
|
||||
{ "setDensity", w_Fixture_setDensity },
|
||||
{ "setSensor", w_Fixture_setSensor },
|
||||
{ "getFriction", w_Fixture_getFriction },
|
||||
{ "getRestitution", w_Fixture_getRestitution },
|
||||
{ "getDensity", w_Fixture_getDensity },
|
||||
{ "getBody", w_Fixture_getBody },
|
||||
{ "getShape", w_Fixture_getShape },
|
||||
{ "isSensor", w_Fixture_isSensor },
|
||||
{ "testPoint", w_Fixture_testPoint },
|
||||
{ "rayCast", w_Fixture_rayCast },
|
||||
{ "setFilterData", w_Fixture_setFilterData },
|
||||
{ "getFilterData", w_Fixture_getFilterData },
|
||||
{ "setCategory", w_Fixture_setCategory },
|
||||
{ "getCategory", w_Fixture_getCategory },
|
||||
{ "setMask", w_Fixture_setMask },
|
||||
{ "getMask", w_Fixture_getMask },
|
||||
{ "setUserData", w_Fixture_setUserData },
|
||||
{ "getUserData", w_Fixture_getUserData },
|
||||
{ "getBoundingBox", w_Fixture_getBoundingBox },
|
||||
{ "getMassData", w_Fixture_getMassData },
|
||||
{ "getGroupIndex", w_Fixture_getGroupIndex },
|
||||
{ "setGroupIndex", w_Fixture_setGroupIndex },
|
||||
{ "destroy", w_Fixture_destroy },
|
||||
{ "isDestroyed", w_Fixture_isDestroyed },
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
extern "C" int luaopen_fixture(lua_State *L)
|
||||
{
|
||||
return luax_register_type(L, &Fixture::type, w_Fixture_functions, nullptr);
|
||||
}
|
||||
|
||||
} // box2d
|
||||
} // physics
|
||||
} // love
|
||||
|
||||
@@ -1,43 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2006-2023 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_FIXTURE_H
|
||||
#define LOVE_PHYSICS_BOX2D_WRAP_FIXTURE_H
|
||||
|
||||
// LOVE
|
||||
#include "common/runtime.h"
|
||||
#include "Fixture.h"
|
||||
#include "wrap_Physics.h"
|
||||
|
||||
namespace love
|
||||
{
|
||||
namespace physics
|
||||
{
|
||||
namespace box2d
|
||||
{
|
||||
|
||||
Fixture *luax_checkfixture(lua_State *L, int idx);
|
||||
extern "C" int luaopen_fixture(lua_State *L);
|
||||
|
||||
} // box2d
|
||||
} // physics
|
||||
} // love
|
||||
|
||||
#endif // LOVE_PHYSICS_BOX2D_WRAP_FIXTURE_H
|
||||
@@ -23,7 +23,6 @@
|
||||
#include "wrap_World.h"
|
||||
#include "wrap_Contact.h"
|
||||
#include "wrap_Body.h"
|
||||
#include "wrap_Fixture.h"
|
||||
#include "wrap_Shape.h"
|
||||
#include "wrap_CircleShape.h"
|
||||
#include "wrap_PolygonShape.h"
|
||||
@@ -256,36 +255,56 @@ int w_newChainBody(lua_State *L)
|
||||
|
||||
int w_newFixture(lua_State *L)
|
||||
{
|
||||
luax_markdeprecated(L, 1, "love.physics.newFixture", API_FUNCTION, DEPRECATED_REPLACED, "love.physics.newCircle/Rectangle/Polygon/Edge/ChainShape");
|
||||
|
||||
Body *body = luax_checkbody(L, 1);
|
||||
Shape *shape = luax_checkshape(L, 2);
|
||||
float density = (float)luaL_optnumber(L, 3, 1.0f);
|
||||
Fixture *fixture;
|
||||
luax_catchexcept(L, [&](){ fixture = instance()->newFixture(body, shape, density); });
|
||||
luax_pushtype(L, fixture);
|
||||
fixture->release();
|
||||
|
||||
Shape *newShape;
|
||||
luax_catchexcept(L, [&]() {
|
||||
newShape = instance()->newAttachedShape(body, shape, density);
|
||||
newShape->setDensity(density);
|
||||
body->resetMassData();
|
||||
});
|
||||
|
||||
luax_pushshape(L, newShape);
|
||||
newShape->release();
|
||||
return 1;
|
||||
}
|
||||
|
||||
static Body *luax_optbodyforshape(lua_State *L, int idx, const char *name)
|
||||
{
|
||||
if (luax_istype(L, idx, Body::type))
|
||||
return luax_checkbody(L, idx);
|
||||
|
||||
luax_markdeprecated(L, 1, name, API_FUNCTION_VARIANT, DEPRECATED_REPLACED, "variant with Body parameter");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
int w_newCircleShape(lua_State *L)
|
||||
{
|
||||
int top = lua_gettop(L);
|
||||
Body *body = luax_optbodyforshape(L, 1, "love.physics.newCircleShape");
|
||||
int bodyidx = body ? 1 : 0;
|
||||
|
||||
int top = lua_gettop(L) - bodyidx;
|
||||
|
||||
if (top == 1)
|
||||
{
|
||||
float radius = (float)luaL_checknumber(L, 1);
|
||||
float radius = (float)luaL_checknumber(L, bodyidx + 1);
|
||||
CircleShape *shape;
|
||||
luax_catchexcept(L, [&](){ shape = instance()->newCircleShape(0, 0, radius); });
|
||||
luax_catchexcept(L, [&](){ shape = instance()->newCircleShape(body, 0, 0, radius); });
|
||||
luax_pushtype(L, shape);
|
||||
shape->release();
|
||||
return 1;
|
||||
}
|
||||
else if (top == 3)
|
||||
{
|
||||
float x = (float)luaL_checknumber(L, 1);
|
||||
float y = (float)luaL_checknumber(L, 2);
|
||||
float radius = (float)luaL_checknumber(L, 3);
|
||||
float x = (float)luaL_checknumber(L, bodyidx + 1);
|
||||
float y = (float)luaL_checknumber(L, bodyidx + 2);
|
||||
float radius = (float)luaL_checknumber(L, bodyidx + 3);
|
||||
CircleShape *shape;
|
||||
luax_catchexcept(L, [&](){ shape = instance()->newCircleShape(x, y, radius); });
|
||||
luax_catchexcept(L, [&](){ shape = instance()->newCircleShape(body, x, y, radius); });
|
||||
luax_pushtype(L, shape);
|
||||
shape->release();
|
||||
return 1;
|
||||
@@ -296,27 +315,30 @@ int w_newCircleShape(lua_State *L)
|
||||
|
||||
int w_newRectangleShape(lua_State *L)
|
||||
{
|
||||
int top = lua_gettop(L);
|
||||
Body *body = luax_optbodyforshape(L, 1, "love.physics.newRectangleShape");
|
||||
int bodyidx = body ? 1 : 0;
|
||||
|
||||
int top = lua_gettop(L) - bodyidx;
|
||||
|
||||
if (top == 2)
|
||||
{
|
||||
float w = (float)luaL_checknumber(L, 1);
|
||||
float h = (float)luaL_checknumber(L, 2);
|
||||
float w = (float)luaL_checknumber(L, bodyidx + 1);
|
||||
float h = (float)luaL_checknumber(L, bodyidx + 2);
|
||||
PolygonShape *shape;
|
||||
luax_catchexcept(L, [&](){ shape = instance()->newRectangleShape(0, 0, w, h, 0); });
|
||||
luax_catchexcept(L, [&](){ shape = instance()->newRectangleShape(body, 0, 0, w, h, 0); });
|
||||
luax_pushtype(L, shape);
|
||||
shape->release();
|
||||
return 1;
|
||||
}
|
||||
else if (top == 4 || top == 5)
|
||||
{
|
||||
float x = (float)luaL_checknumber(L, 1);
|
||||
float y = (float)luaL_checknumber(L, 2);
|
||||
float w = (float)luaL_checknumber(L, 3);
|
||||
float h = (float)luaL_checknumber(L, 4);
|
||||
float angle = (float)luaL_optnumber(L, 5, 0);
|
||||
float x = (float)luaL_checknumber(L, bodyidx + 1);
|
||||
float y = (float)luaL_checknumber(L, bodyidx + 2);
|
||||
float w = (float)luaL_checknumber(L, bodyidx + 3);
|
||||
float h = (float)luaL_checknumber(L, bodyidx + 4);
|
||||
float angle = (float)luaL_optnumber(L, bodyidx + 5, 0);
|
||||
PolygonShape *shape;
|
||||
luax_catchexcept(L, [&](){ shape = instance()->newRectangleShape(x, y, w, h, angle); });
|
||||
luax_catchexcept(L, [&](){ shape = instance()->newRectangleShape(body, x, y, w, h, angle); });
|
||||
luax_pushtype(L, shape);
|
||||
shape->release();
|
||||
return 1;
|
||||
@@ -327,13 +349,16 @@ int w_newRectangleShape(lua_State *L)
|
||||
|
||||
int w_newEdgeShape(lua_State *L)
|
||||
{
|
||||
float x1 = (float)luaL_checknumber(L, 1);
|
||||
float y1 = (float)luaL_checknumber(L, 2);
|
||||
float x2 = (float)luaL_checknumber(L, 3);
|
||||
float y2 = (float)luaL_checknumber(L, 4);
|
||||
bool oneSided = luax_optboolean(L, 5, false);
|
||||
Body *body = luax_optbodyforshape(L, 1, "love.physics.newEdgeShape");
|
||||
int bodyidx = body ? 1 : 0;
|
||||
|
||||
float x1 = (float)luaL_checknumber(L, bodyidx + 1);
|
||||
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(x1, y1, x2, y2, oneSided); });
|
||||
luax_catchexcept(L, [&](){ shape = instance()->newEdgeShape(body, x1, y1, x2, y2, oneSided); });
|
||||
luax_pushtype(L, shape);
|
||||
shape->release();
|
||||
return 1;
|
||||
@@ -341,12 +366,15 @@ int w_newEdgeShape(lua_State *L)
|
||||
|
||||
int w_newPolygonShape(lua_State *L)
|
||||
{
|
||||
int argc = lua_gettop(L);
|
||||
Body *body = luax_optbodyforshape(L, 1, "love.physics.newPolygonShape");
|
||||
int bodyidx = body ? 1 : 0;
|
||||
|
||||
bool istable = lua_istable(L, 1);
|
||||
int argc = lua_gettop(L) - bodyidx;
|
||||
|
||||
bool istable = lua_istable(L, bodyidx + 1);
|
||||
|
||||
if (istable)
|
||||
argc = (int)luax_objlen(L, 1);
|
||||
argc = (int)luax_objlen(L, bodyidx + 1);
|
||||
|
||||
if (argc % 2 != 0)
|
||||
return luaL_error(L, "Number of vertex components must be a multiple of two.");
|
||||
@@ -358,8 +386,8 @@ int w_newPolygonShape(lua_State *L)
|
||||
{
|
||||
for (int i = 0; i < vcount; i++)
|
||||
{
|
||||
lua_rawgeti(L, 1, 1 + i * 2);
|
||||
lua_rawgeti(L, 1, 2 + i * 2);
|
||||
lua_rawgeti(L, bodyidx + 1, 1 + i * 2);
|
||||
lua_rawgeti(L, bodyidx + 1, 2 + i * 2);
|
||||
float x = (float)luaL_checknumber(L, -2);
|
||||
float y = (float)luaL_checknumber(L, -1);
|
||||
coords.emplace_back(x, y);
|
||||
@@ -370,14 +398,14 @@ int w_newPolygonShape(lua_State *L)
|
||||
{
|
||||
for (int i = 0; i < vcount; i++)
|
||||
{
|
||||
float x = (float)luaL_checknumber(L, 1 + i * 2);
|
||||
float y = (float)luaL_checknumber(L, 2 + i * 2);
|
||||
float x = (float)luaL_checknumber(L, bodyidx + 1 + i * 2);
|
||||
float y = (float)luaL_checknumber(L, bodyidx + 2 + i * 2);
|
||||
coords.emplace_back(x, y);
|
||||
}
|
||||
}
|
||||
|
||||
PolygonShape *shape = nullptr;
|
||||
luax_catchexcept(L, [&](){ shape = instance()->newPolygonShape(coords.data(), (int)coords.size()); });
|
||||
luax_catchexcept(L, [&](){ shape = instance()->newPolygonShape(body, coords.data(), (int)coords.size()); });
|
||||
luax_pushtype(L, shape);
|
||||
shape->release();
|
||||
return 1;
|
||||
@@ -385,26 +413,29 @@ int w_newPolygonShape(lua_State *L)
|
||||
|
||||
int w_newChainShape(lua_State *L)
|
||||
{
|
||||
int argc = lua_gettop(L) - 1; // first argument is looping
|
||||
Body *body = luax_optbodyforshape(L, 1, "love.physics.newChainShape");
|
||||
int bodyidx = body ? 1 : 0;
|
||||
|
||||
bool istable = lua_istable(L, 2);
|
||||
int argc = lua_gettop(L) - 1 - bodyidx; // first argument is looping
|
||||
|
||||
bool istable = lua_istable(L, bodyidx + 2);
|
||||
|
||||
if (istable)
|
||||
argc = (int)luax_objlen(L, 2);
|
||||
argc = (int)luax_objlen(L, bodyidx + 2);
|
||||
|
||||
if (argc == 0 || argc % 2 != 0)
|
||||
return luaL_error(L, "Number of vertex components must be a multiple of two.");
|
||||
|
||||
int vcount = argc / 2;
|
||||
bool loop = luax_checkboolean(L, 1);
|
||||
bool loop = luax_checkboolean(L, bodyidx + 1);
|
||||
std::vector<Vector2> coords;
|
||||
|
||||
if (istable)
|
||||
{
|
||||
for (int i = 0; i < vcount; i++)
|
||||
{
|
||||
lua_rawgeti(L, 2, 1 + i * 2);
|
||||
lua_rawgeti(L, 2, 2 + i * 2);
|
||||
lua_rawgeti(L, bodyidx + 2, 1 + i * 2);
|
||||
lua_rawgeti(L, bodyidx + 2, 2 + i * 2);
|
||||
float x = (float)lua_tonumber(L, -2);
|
||||
float y = (float)lua_tonumber(L, -1);
|
||||
coords.emplace_back(x, y);
|
||||
@@ -415,14 +446,14 @@ int w_newChainShape(lua_State *L)
|
||||
{
|
||||
for (int i = 0; i < vcount; i++)
|
||||
{
|
||||
float x = (float)luaL_checknumber(L, 2 + i * 2);
|
||||
float y = (float)luaL_checknumber(L, 3 + i * 2);
|
||||
float x = (float)luaL_checknumber(L, bodyidx + 2 + i * 2);
|
||||
float y = (float)luaL_checknumber(L, bodyidx + 3 + i * 2);
|
||||
coords.emplace_back(x, y);
|
||||
}
|
||||
}
|
||||
|
||||
ChainShape *shape = nullptr;
|
||||
luax_catchexcept(L, [&]() { shape = instance()->newChainShape(loop, coords.data(), coords.size()); });
|
||||
luax_catchexcept(L, [&]() { shape = instance()->newChainShape(body, loop, coords.data(), coords.size()); });
|
||||
luax_pushtype(L, shape);
|
||||
shape->release();
|
||||
return 1;
|
||||
@@ -824,7 +855,6 @@ static const luaL_Reg functions[] =
|
||||
{ "newPolygonBody", w_newPolygonBody },
|
||||
{ "newEdgeBody", w_newEdgeBody },
|
||||
{ "newChainBody", w_newChainBody },
|
||||
{ "newFixture", w_newFixture },
|
||||
{ "newCircleShape", w_newCircleShape },
|
||||
{ "newRectangleShape", w_newRectangleShape },
|
||||
{ "newPolygonShape", w_newPolygonShape },
|
||||
@@ -848,6 +878,10 @@ static const luaL_Reg functions[] =
|
||||
{ "computeLinearFrequency", w_computeLinearFrequency },
|
||||
{ "computeAngularStiffness", w_computeAngularStiffness },
|
||||
{ "computeAngularFrequency", w_computeAngularFrequency },
|
||||
|
||||
// Deprecated
|
||||
{ "newFixture", w_newFixture },
|
||||
|
||||
{ 0, 0 },
|
||||
};
|
||||
|
||||
@@ -856,7 +890,6 @@ static const lua_CFunction types[] =
|
||||
luaopen_world,
|
||||
luaopen_contact,
|
||||
luaopen_body,
|
||||
luaopen_fixture,
|
||||
luaopen_shape,
|
||||
luaopen_circleshape,
|
||||
luaopen_polygonshape,
|
||||
|
||||
@@ -36,13 +36,17 @@ int w_PolygonShape_getPoints(lua_State *L)
|
||||
{
|
||||
PolygonShape *t = luax_checkpolygonshape(L, 1);
|
||||
lua_remove(L, 1);
|
||||
return t->getPoints(L);
|
||||
int ret = 0;
|
||||
luax_catchexcept(L, [&]() { ret = t->getPoints(L); });
|
||||
return ret;
|
||||
}
|
||||
|
||||
int w_PolygonShape_validate(lua_State *L)
|
||||
{
|
||||
PolygonShape *t = luax_checkpolygonshape(L, 1);
|
||||
luax_pushboolean(L, t->validate());
|
||||
bool valid = false;
|
||||
luax_catchexcept(L, [&]() { valid = t->validate(); });
|
||||
luax_pushboolean(L, valid);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -33,6 +33,35 @@ Shape *luax_checkshape(lua_State *L, int idx)
|
||||
return luax_checktype<Shape>(L, idx);
|
||||
}
|
||||
|
||||
void luax_pushshape(lua_State *L, Shape *shape)
|
||||
{
|
||||
if (shape != nullptr)
|
||||
{
|
||||
switch (shape->getType())
|
||||
{
|
||||
case Shape::SHAPE_CIRCLE:
|
||||
luax_pushtype(L, (CircleShape *) shape);
|
||||
break;
|
||||
case Shape::SHAPE_POLYGON:
|
||||
luax_pushtype(L, (PolygonShape *) shape);
|
||||
break;
|
||||
case Shape::SHAPE_EDGE:
|
||||
luax_pushtype(L, (EdgeShape *) shape);
|
||||
break;
|
||||
case Shape::SHAPE_CHAIN:
|
||||
luax_pushtype(L, (ChainShape *) shape);
|
||||
break;
|
||||
default:
|
||||
luax_pushtype(L, shape);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
lua_pushnil(L);
|
||||
}
|
||||
}
|
||||
|
||||
int w_Shape_getType(lua_State *L)
|
||||
{
|
||||
Shape *t = luax_checkshape(L, 1);
|
||||
@@ -45,7 +74,8 @@ int w_Shape_getType(lua_State *L)
|
||||
int w_Shape_getRadius(lua_State *L)
|
||||
{
|
||||
Shape *t = luax_checkshape(L, 1);
|
||||
float radius = t->getRadius();
|
||||
float radius = 0;
|
||||
luax_catchexcept(L, [&]() { radius = t->getRadius(); });
|
||||
lua_pushnumber(L, radius);
|
||||
return 1;
|
||||
}
|
||||
@@ -53,20 +83,115 @@ int w_Shape_getRadius(lua_State *L)
|
||||
int w_Shape_getChildCount(lua_State *L)
|
||||
{
|
||||
Shape *t = luax_checkshape(L, 1);
|
||||
int childCount = t->getChildCount();
|
||||
int childCount = 0;
|
||||
luax_catchexcept(L, [&]() { childCount = t->getChildCount(); });
|
||||
lua_pushinteger(L, childCount);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int w_Shape_setFriction(lua_State *L)
|
||||
{
|
||||
Shape *t = luax_checkshape(L, 1);
|
||||
float arg1 = (float)luaL_checknumber(L, 2);
|
||||
luax_catchexcept(L, [&]() { t->setFriction(arg1); });
|
||||
return 0;
|
||||
}
|
||||
|
||||
int w_Shape_setRestitution(lua_State *L)
|
||||
{
|
||||
Shape *t = luax_checkshape(L, 1);
|
||||
float arg1 = (float)luaL_checknumber(L, 2);
|
||||
luax_catchexcept(L, [&]() { t->setRestitution(arg1); });
|
||||
return 0;
|
||||
}
|
||||
|
||||
int w_Shape_setDensity(lua_State *L)
|
||||
{
|
||||
Shape *t = luax_checkshape(L, 1);
|
||||
float arg1 = (float)luaL_checknumber(L, 2);
|
||||
luax_catchexcept(L, [&](){ t->setDensity(arg1); });
|
||||
return 0;
|
||||
}
|
||||
|
||||
int w_Shape_setSensor(lua_State *L)
|
||||
{
|
||||
Shape *t = luax_checkshape(L, 1);
|
||||
bool arg1 = luax_checkboolean(L, 2);
|
||||
luax_catchexcept(L, [&]() { t->setSensor(arg1); });
|
||||
return 0;
|
||||
}
|
||||
|
||||
int w_Shape_getFriction(lua_State *L)
|
||||
{
|
||||
Shape *t = luax_checkshape(L, 1);
|
||||
float friction = 0;
|
||||
luax_catchexcept(L, [&]() { friction = t->getFriction(); });
|
||||
lua_pushnumber(L, friction);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int w_Shape_getRestitution(lua_State *L)
|
||||
{
|
||||
Shape *t = luax_checkshape(L, 1);
|
||||
float r = 0;
|
||||
luax_catchexcept(L, [&]() { r = t->getRestitution(); });
|
||||
lua_pushnumber(L, r);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int w_Shape_getDensity(lua_State *L)
|
||||
{
|
||||
Shape *t = luax_checkshape(L, 1);
|
||||
float d = 0;
|
||||
luax_catchexcept(L, [&]() { d = t->getDensity(); });
|
||||
lua_pushnumber(L, d);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int w_Shape_isSensor(lua_State *L)
|
||||
{
|
||||
Shape *t = luax_checkshape(L, 1);
|
||||
bool sensor = false;
|
||||
luax_catchexcept(L, [&]() { sensor = t->isSensor(); });
|
||||
luax_pushboolean(L, sensor);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int w_Shape_getBody(lua_State *L)
|
||||
{
|
||||
Shape *t = luax_checkshape(L, 1);
|
||||
Body *body = t->getBody();
|
||||
if (body == nullptr)
|
||||
return 0;
|
||||
luax_pushtype(L, body);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int w_Shape_getShape(lua_State *L)
|
||||
{
|
||||
luax_markdeprecated(L, 1, "Fixture:getShape", API_METHOD, DEPRECATED_NO_REPLACEMENT, nullptr);
|
||||
Shape *t = luax_checkshape(L, 1);
|
||||
luax_pushshape(L, t);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int w_Shape_testPoint(lua_State *L)
|
||||
{
|
||||
Shape *t = luax_checkshape(L, 1);
|
||||
float x = (float)luaL_checknumber(L, 2);
|
||||
float y = (float)luaL_checknumber(L, 3);
|
||||
float r = (float)luaL_checknumber(L, 4);
|
||||
float px = (float)luaL_checknumber(L, 5);
|
||||
float py = (float)luaL_checknumber(L, 6);
|
||||
bool result = t->testPoint(x, y, r, px, py);
|
||||
bool result = false;
|
||||
if (!lua_isnoneornil(L, 4))
|
||||
{
|
||||
float r = (float)luaL_checknumber(L, 4);
|
||||
float px = (float)luaL_checknumber(L, 5);
|
||||
float py = (float)luaL_checknumber(L, 6);
|
||||
result = luax_catchexcept(L, [&]() { t->testPoint(x, y, r, px, py); });
|
||||
}
|
||||
else
|
||||
{
|
||||
result = luax_catchexcept(L, [&]() { t->testPoint(x, y); });
|
||||
}
|
||||
lua_pushboolean(L, result);
|
||||
return 1;
|
||||
}
|
||||
@@ -84,14 +209,143 @@ int w_Shape_computeAABB(lua_State *L)
|
||||
{
|
||||
Shape *t = luax_checkshape(L, 1);
|
||||
lua_remove(L, 1);
|
||||
return t->computeAABB(L);
|
||||
int ret = 0;
|
||||
luax_catchexcept(L, [&]() { ret = t->computeAABB(L); });
|
||||
return ret;
|
||||
}
|
||||
|
||||
int w_Shape_computeMass(lua_State *L)
|
||||
{
|
||||
Shape *t = luax_checkshape(L, 1);
|
||||
lua_remove(L, 1);
|
||||
return t->computeMass(L);
|
||||
int ret = 0;
|
||||
luax_catchexcept(L, [&]() { ret = t->computeMass(L); });
|
||||
return ret;
|
||||
}
|
||||
|
||||
int w_Shape_setFilterData(lua_State *L)
|
||||
{
|
||||
Shape *t = luax_checkshape(L, 1);
|
||||
int v[3];
|
||||
v[0] = (int) luaL_checkinteger(L, 2);
|
||||
v[1] = (int) luaL_checkinteger(L, 3);
|
||||
v[2] = (int) luaL_checkinteger(L, 4);
|
||||
luax_catchexcept(L, [&]() { t->setFilterData(v); });
|
||||
return 0;
|
||||
}
|
||||
|
||||
int w_Shape_getFilterData(lua_State *L)
|
||||
{
|
||||
Shape *t = luax_checkshape(L, 1);
|
||||
int v[3];
|
||||
luax_catchexcept(L, [&]() { t->getFilterData(v); });
|
||||
lua_pushinteger(L, v[0]);
|
||||
lua_pushinteger(L, v[1]);
|
||||
lua_pushinteger(L, v[2]);
|
||||
return 3;
|
||||
}
|
||||
|
||||
int w_Shape_setCategory(lua_State *L)
|
||||
{
|
||||
Shape *t = luax_checkshape(L, 1);
|
||||
lua_remove(L, 1);
|
||||
int ret = 0;
|
||||
luax_catchexcept(L, [&]() { ret = t->setCategory(L); });
|
||||
return ret;
|
||||
}
|
||||
|
||||
int w_Shape_getCategory(lua_State *L)
|
||||
{
|
||||
Shape *t = luax_checkshape(L, 1);
|
||||
lua_remove(L, 1);
|
||||
int ret = 0;
|
||||
luax_catchexcept(L, [&]() { ret = t->getCategory(L); });
|
||||
return ret;
|
||||
}
|
||||
|
||||
int w_Shape_setMask(lua_State *L)
|
||||
{
|
||||
Shape *t = luax_checkshape(L, 1);
|
||||
lua_remove(L, 1);
|
||||
int ret = 0;
|
||||
luax_catchexcept(L, [&]() { ret = t->setMask(L); });
|
||||
return ret;
|
||||
}
|
||||
|
||||
int w_Shape_getMask(lua_State *L)
|
||||
{
|
||||
Shape *t = luax_checkshape(L, 1);
|
||||
lua_remove(L, 1);
|
||||
int ret = 0;
|
||||
luax_catchexcept(L, [&]() { ret = t->getMask(L); });
|
||||
return ret;
|
||||
}
|
||||
|
||||
int w_Shape_setUserData(lua_State *L)
|
||||
{
|
||||
Shape *t = luax_checkshape(L, 1);
|
||||
lua_remove(L, 1);
|
||||
int ret = 0;
|
||||
luax_catchexcept(L, [&]() { ret = t->setUserData(L); });
|
||||
return ret;
|
||||
}
|
||||
|
||||
int w_Shape_getUserData(lua_State *L)
|
||||
{
|
||||
Shape *t = luax_checkshape(L, 1);
|
||||
lua_remove(L, 1);
|
||||
int ret = 0;
|
||||
luax_catchexcept(L, [&]() { ret = t->getUserData(L); });
|
||||
return ret;
|
||||
}
|
||||
|
||||
int w_Shape_getBoundingBox(lua_State *L)
|
||||
{
|
||||
Shape *t = luax_checkshape(L, 1);
|
||||
lua_remove(L, 1);
|
||||
int ret = 0;
|
||||
luax_catchexcept(L, [&]() { ret = t->getBoundingBox(L); });
|
||||
return ret;
|
||||
}
|
||||
|
||||
int w_Shape_getMassData(lua_State *L)
|
||||
{
|
||||
Shape *t = luax_checkshape(L, 1);
|
||||
lua_remove(L, 1);
|
||||
int ret = 0;
|
||||
luax_catchexcept(L, [&]() { ret = t->getMassData(L); });
|
||||
return ret;
|
||||
}
|
||||
|
||||
int w_Shape_getGroupIndex(lua_State *L)
|
||||
{
|
||||
Shape *t = luax_checkshape(L, 1);
|
||||
int i = 0;
|
||||
luax_catchexcept(L, [&]() { i = t->getGroupIndex(); });
|
||||
lua_pushinteger(L, i);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int w_Shape_setGroupIndex(lua_State *L)
|
||||
{
|
||||
Shape *t = luax_checkshape(L, 1);
|
||||
int i = (int) luaL_checkinteger(L, 2);
|
||||
luax_catchexcept(L, [&]() { t->setGroupIndex(i); });
|
||||
return 0;
|
||||
}
|
||||
|
||||
int w_Shape_destroy(lua_State *L)
|
||||
{
|
||||
Shape *t = luax_checkshape(L, 1);
|
||||
luax_catchexcept(L, [&](){ t->destroy(); });
|
||||
return 0;
|
||||
}
|
||||
|
||||
int w_Shape_isDestroyed(lua_State *L)
|
||||
{
|
||||
Shape *f = luax_checktype<Shape>(L, 1);
|
||||
luax_pushboolean(L, !f->isValid());
|
||||
return 1;
|
||||
}
|
||||
|
||||
const luaL_Reg w_Shape_functions[] =
|
||||
@@ -99,10 +353,33 @@ const luaL_Reg w_Shape_functions[] =
|
||||
{ "getType", w_Shape_getType },
|
||||
{ "getRadius", w_Shape_getRadius },
|
||||
{ "getChildCount", w_Shape_getChildCount },
|
||||
{ "setFriction", w_Shape_setFriction },
|
||||
{ "setRestitution", w_Shape_setRestitution },
|
||||
{ "setDensity", w_Shape_setDensity },
|
||||
{ "setSensor", w_Shape_setSensor },
|
||||
{ "getFriction", w_Shape_getFriction },
|
||||
{ "getRestitution", w_Shape_getRestitution },
|
||||
{ "getDensity", w_Shape_getDensity },
|
||||
{ "getBody", w_Shape_getBody },
|
||||
{ "isSensor", w_Shape_isSensor },
|
||||
{ "testPoint", w_Shape_testPoint },
|
||||
{ "rayCast", w_Shape_rayCast },
|
||||
{ "computeAABB", w_Shape_computeAABB },
|
||||
{ "computeMass", w_Shape_computeMass },
|
||||
{ "setFilterData", w_Shape_setFilterData },
|
||||
{ "getFilterData", w_Shape_getFilterData },
|
||||
{ "setCategory", w_Shape_setCategory },
|
||||
{ "getCategory", w_Shape_getCategory },
|
||||
{ "setMask", w_Shape_setMask },
|
||||
{ "getMask", w_Shape_getMask },
|
||||
{ "setUserData", w_Shape_setUserData },
|
||||
{ "getUserData", w_Shape_getUserData },
|
||||
{ "getBoundingBox", w_Shape_getBoundingBox },
|
||||
{ "getMassData", w_Shape_getMassData },
|
||||
{ "getGroupIndex", w_Shape_getGroupIndex },
|
||||
{ "setGroupIndex", w_Shape_setGroupIndex },
|
||||
{ "destroy", w_Shape_destroy },
|
||||
{ "isDestroyed", w_Shape_isDestroyed },
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
|
||||
@@ -34,6 +34,7 @@ namespace box2d
|
||||
{
|
||||
|
||||
Shape *luax_checkshape(lua_State *L, int idx);
|
||||
void luax_pushshape(lua_State *L, Shape *shape);
|
||||
extern "C" int luaopen_shape(lua_State *L);
|
||||
|
||||
extern const luaL_Reg w_Shape_functions[];
|
||||
|
||||
@@ -178,25 +178,25 @@ int w_World_getContacts(lua_State *L)
|
||||
return ret;
|
||||
}
|
||||
|
||||
int w_World_queryFixturesInArea(lua_State *L)
|
||||
int w_World_queryShapesInArea(lua_State *L)
|
||||
{
|
||||
World *t = luax_checkworld(L, 1);
|
||||
lua_remove(L, 1);
|
||||
return t->queryFixturesInArea(L);
|
||||
return t->queryShapesInArea(L);
|
||||
}
|
||||
|
||||
int w_World_queryBoundingBox(lua_State *L)
|
||||
{
|
||||
luax_markdeprecated(L, 1, "World:queryBoundingBox", API_METHOD, DEPRECATED_RENAMED, "World:queryFixturesInArea");
|
||||
return w_World_queryFixturesInArea(L);
|
||||
luax_markdeprecated(L, 1, "World:queryBoundingBox", API_METHOD, DEPRECATED_RENAMED, "World:queryShapesInArea");
|
||||
return w_World_queryShapesInArea(L);
|
||||
}
|
||||
|
||||
int w_World_getFixturesInArea(lua_State *L)
|
||||
int w_World_getShapesInArea(lua_State *L)
|
||||
{
|
||||
World *t = luax_checkworld(L, 1);
|
||||
lua_remove(L, 1);
|
||||
int ret = 0;
|
||||
luax_catchexcept(L, [&](){ ret = t->getFixturesInArea(L); });
|
||||
luax_catchexcept(L, [&](){ ret = t->getShapesInArea(L); });
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -260,8 +260,8 @@ static const luaL_Reg w_World_functions[] =
|
||||
{ "getBodies", w_World_getBodies },
|
||||
{ "getJoints", w_World_getJoints },
|
||||
{ "getContacts", w_World_getContacts },
|
||||
{ "queryFixturesInArea", w_World_queryFixturesInArea },
|
||||
{ "getFixturesInArea", w_World_getFixturesInArea },
|
||||
{ "queryShapesInArea", w_World_queryShapesInArea },
|
||||
{ "getShapesInArea", w_World_getShapesInArea },
|
||||
{ "rayCast", w_World_rayCast },
|
||||
{ "rayCastAny", w_World_rayCastAny },
|
||||
{ "rayCastClosest", w_World_rayCastClosest },
|
||||
|
||||
Reference in New Issue
Block a user