Also no expressions in luax_pushtype;
This commit is contained in:
bjorn 2017-05-24 17:38:03 -07:00
parent 19908a7d38
commit f1a74c34c3
9 changed files with 228 additions and 25 deletions

View File

@ -296,7 +296,8 @@ int l_lovrGraphicsSetScissor(lua_State* L) {
}
int l_lovrGraphicsGetShader(lua_State* L) {
luax_pushtype(L, Shader, lovrGraphicsGetShader());
Shader* shader = lovrGraphicsGetShader();
luax_pushtype(L, Shader, shader);
return 1;
}
@ -307,7 +308,8 @@ int l_lovrGraphicsSetShader(lua_State* L) {
}
int l_lovrGraphicsGetFont(lua_State* L) {
luax_pushtype(L, Font, lovrGraphicsGetFont());
Font* font = lovrGraphicsGetFont();
luax_pushtype(L, Font, font);
return 1;
}

View File

@ -15,6 +15,7 @@ int l_lovrPhysicsInit(lua_State* L);
int l_lovrTimerInit(lua_State* L);
extern const luaL_Reg lovrAudio[];
extern const luaL_Reg lovrBallJoint[];
extern const luaL_Reg lovrBoxShape[];
extern const luaL_Reg lovrCapsuleShape[];
extern const luaL_Reg lovrController[];
@ -26,6 +27,7 @@ extern const luaL_Reg lovrFilesystem[];
extern const luaL_Reg lovrFont[];
extern const luaL_Reg lovrGraphics[];
extern const luaL_Reg lovrHeadset[];
extern const luaL_Reg lovrJoint[];
extern const luaL_Reg lovrMath[];
extern const luaL_Reg lovrMesh[];
extern const luaL_Reg lovrModel[];
@ -50,6 +52,7 @@ extern map_int_t EventTypes;
extern map_int_t FilterModes;
extern map_int_t HeadsetEyes;
extern map_int_t HorizontalAligns;
extern map_int_t JointTypes;
extern map_int_t MeshAttributeTypes;
extern map_int_t MeshDrawModes;
extern map_int_t MeshUsages;
@ -64,3 +67,4 @@ void luax_checkmeshformat(lua_State* L, int index, MeshFormat* format);
int luax_readtransform(lua_State* L, int index, mat4 transform);
Blob* luax_readblob(lua_State* L, int index, const char* debug);
int luax_pushshape(lua_State* L, Shape* shape);
int luax_pushjoint(lua_State* L, Joint* joint);

View File

@ -2,17 +2,22 @@
#include "physics/physics.h"
map_int_t ShapeTypes;
map_int_t JointTypes;
int l_lovrPhysicsInit(lua_State* L) {
lua_newtable(L);
luaL_register(L, NULL, lovrPhysics);
luax_registertype(L, "World", lovrWorld);
luax_registertype(L, "Collider", lovrCollider);
luax_extendtype(L, "Joint", "BallJoint", lovrJoint, lovrBallJoint);
luax_extendtype(L, "Shape", "SphereShape", lovrShape, lovrSphereShape);
luax_extendtype(L, "Shape", "BoxShape", lovrShape, lovrBoxShape);
luax_extendtype(L, "Shape", "CapsuleShape", lovrShape, lovrCapsuleShape);
luax_extendtype(L, "Shape", "CylinderShape", lovrShape, lovrCylinderShape);
map_init(&JointTypes);
map_set(&ShapeTypes, "ball", JOINT_BALL);
map_init(&ShapeTypes);
map_set(&ShapeTypes, "sphere", SHAPE_SPHERE);
map_set(&ShapeTypes, "box", SHAPE_BOX);
@ -24,13 +29,19 @@ int l_lovrPhysicsInit(lua_State* L) {
}
int l_lovrPhysicsNewWorld(lua_State* L) {
luax_pushtype(L, World, lovrWorldCreate());
World* world = lovrWorldCreate();
luax_pushtype(L, World, world);
return 1;
}
int l_lovrPhysicsNewSphereShape(lua_State* L) {
float radius = luaL_optnumber(L, 1, 1.f);
luax_pushtype(L, SphereShape, lovrSphereShapeCreate(radius));
int l_lovrPhysicsNewBallJoint(lua_State* L) {
Collider* a = luax_checktype(L, 1, Collider);
Collider* b = luax_checktype(L, 2, Collider);
float x = luaL_optnumber(L, 3, 0.f);
float y = luaL_optnumber(L, 4, 0.f);
float z = luaL_optnumber(L, 5, 0.f);
Joint* joint = lovrBallJointCreate(a, b, x, y, z);
luax_pushtype(L, BallJoint, joint);
return 1;
}
@ -38,29 +49,40 @@ int l_lovrPhysicsNewBoxShape(lua_State* L) {
float x = luaL_optnumber(L, 1, 1.f);
float y = luaL_optnumber(L, 2, x);
float z = luaL_optnumber(L, 3, x);
luax_pushtype(L, BoxShape, lovrBoxShapeCreate(x, y, z));
BoxShape* box = lovrBoxShapeCreate(x, y, z);
luax_pushtype(L, BoxShape, box);
return 1;
}
int l_lovrPhysicsNewCapsuleShape(lua_State* L) {
float radius = luaL_optnumber(L, 1, 1.f);
float length = luaL_optnumber(L, 2, 1.f);
luax_pushtype(L, CapsuleShape, lovrCapsuleShapeCreate(radius, length));
CapsuleShape* capsule = lovrCapsuleShapeCreate(radius, length);
luax_pushtype(L, CapsuleShape, capsule);
return 1;
}
int l_lovrPhysicsNewCylinderShape(lua_State* L) {
float radius = luaL_optnumber(L, 1, 1.f);
float length = luaL_optnumber(L, 2, 1.f);
luax_pushtype(L, CylinderShape, lovrCylinderShapeCreate(radius, length));
CylinderShape* cylinder = lovrCylinderShapeCreate(radius, length);
luax_pushtype(L, CylinderShape, cylinder);
return 1;
}
int l_lovrPhysicsNewSphereShape(lua_State* L) {
float radius = luaL_optnumber(L, 1, 1.f);
SphereShape* sphere = lovrSphereShapeCreate(radius);
luax_pushtype(L, SphereShape, sphere);
return 1;
}
const luaL_Reg lovrPhysics[] = {
{ "newWorld", l_lovrPhysicsNewWorld },
{ "newSphereShape", l_lovrPhysicsNewSphereShape },
{ "newBallJoint", l_lovrPhysicsNewBallJoint },
{ "newBoxShape", l_lovrPhysicsNewBoxShape },
{ "newCapsuleShape", l_lovrPhysicsNewCapsuleShape },
{ "newCylinderShape", l_lovrPhysicsNewCylinderShape },
{ "newSphereShape", l_lovrPhysicsNewSphereShape },
{ NULL, NULL }
};

View File

@ -9,7 +9,8 @@ int l_lovrColliderDestroy(lua_State* L) {
int l_lovrColliderGetWorld(lua_State* L) {
Collider* collider = luax_checktype(L, 1, Collider);
luax_pushtype(L, World, lovrColliderGetWorld(collider));
World* world = lovrColliderGetWorld(collider);
luax_pushtype(L, World, world);
return 1;
}
@ -30,14 +31,22 @@ int l_lovrColliderRemoveShape(lua_State* L) {
int l_lovrColliderGetShapeList(lua_State* L) {
Collider* collider = luax_checktype(L, 1, Collider);
lua_newtable(L);
int i;
Shape* shape;
for (i = 1, shape = lovrColliderGetFirstShape(collider); shape; shape = lovrColliderGetNextShape(collider, shape), i++) {
luax_pushshape(L, shape);
vec_void_t* shapes = lovrColliderGetShapes(collider);
for (int i = 0; i < shapes->length; i++) {
luax_pushshape(L, shapes->data[i]);
lua_rawseti(L, -2, i);
}
return 1;
}
int l_lovrColliderGetJointList(lua_State* L) {
Collider* collider = luax_checktype(L, 1, Collider);
lua_newtable(L);
vec_void_t* joints = lovrColliderGetJoints(collider);
for (int i = 0; i < joints->length; i++) {
luax_pushshape(L, joints->data[i]);
lua_rawseti(L, -2, i);
}
return 1;
}

68
src/api/types/joints.c Normal file
View File

@ -0,0 +1,68 @@
#include "api/lovr.h"
#include "physics/physics.h"
int luax_pushjoint(lua_State* L, Joint* joint) {
switch (lovrJointGetType(joint)) {
case JOINT_BALL: luax_pushtype(L, BallJoint, joint); return 1;
default: return 0;
}
}
int l_lovrJointDestroy(lua_State* L) {
Joint* joint = luax_checktypeof(L, 1, Joint);
lovrJointDestroyData(joint);
return 0;
}
int l_lovrJointGetType(lua_State* L) {
Joint* joint = luax_checktypeof(L, 1, Joint);
luax_pushenum(L, &JointTypes, lovrJointGetType(joint));
return 1;
}
int l_lovrJointGetColliders(lua_State* L) {
Joint* joint = luax_checktype(L, 1, Joint);
Collider* a;
Collider* b;
lovrJointGetColliders(joint, &a, &b);
luax_pushtype(L, Collider, a);
luax_pushtype(L, Collider, b);
return 2;
}
int l_lovrJointGetUserData(lua_State* L) {
Joint* joint = luax_checktypeof(L, 1, Joint);
int ref = (int) lovrJointGetUserData(joint);
lua_rawgeti(L, LUA_REGISTRYINDEX, ref);
return 1;
}
int l_lovrJointSetUserData(lua_State* L) {
Joint* joint = luax_checktypeof(L, 1, Joint);
uint64_t ref = (int) lovrJointGetUserData(joint);
if (ref) {
luaL_unref(L, LUA_REGISTRYINDEX, ref);
}
if (lua_gettop(L) < 2) {
lua_pushnil(L);
}
lua_settop(L, 2);
ref = luaL_ref(L, LUA_REGISTRYINDEX);
lovrJointSetUserData(joint, (void*) ref);
return 0;
}
const luaL_Reg lovrJoint[] = {
{ "destroy", l_lovrJointDestroy },
{ "getType", l_lovrJointGetType },
{ "getColliders", l_lovrJointGetColliders },
{ "getUserData", l_lovrJointGetUserData },
{ "setUserData", l_lovrJointSetUserData },
{ NULL, NULL }
};
const luaL_Reg lovrBallJoint[] = {
{ NULL, NULL }
};

View File

@ -11,7 +11,8 @@ int l_lovrModelDraw(lua_State* L) {
int l_lovrModelGetTexture(lua_State* L) {
Model* model = luax_checktype(L, 1, Model);
luax_pushtype(L, Texture, lovrModelGetTexture(model));
Texture* texture = lovrModelGetTexture(model);
luax_pushtype(L, Texture, texture);
return 1;
}

View File

@ -7,6 +7,7 @@ int luax_pushshape(lua_State* L, Shape* shape) {
case SHAPE_BOX: luax_pushtype(L, BoxShape, shape); return 1;
case SHAPE_CAPSULE: luax_pushtype(L, CapsuleShape, shape); return 1;
case SHAPE_CYLINDER: luax_pushtype(L, CylinderShape, shape); return 1;
default: return 0;
}
}

View File

@ -163,12 +163,16 @@ Collider* lovrColliderCreate(World* world) {
collider->body = dBodyCreate(world->id);
collider->world = world;
dBodySetData(collider->body, collider);
vec_init(&collider->shapes);
vec_init(&collider->joints);
return collider;
}
void lovrColliderDestroy(const Ref* ref) {
Collider* collider = containerof(ref, Collider);
vec_deinit(&collider->shapes);
vec_deinit(&collider->joints);
lovrColliderDestroyData(collider);
free(collider);
}
@ -205,14 +209,27 @@ void lovrColliderRemoveShape(Collider* collider, Shape* shape) {
}
}
Shape* lovrColliderGetFirstShape(Collider* collider) {
dGeomID geom = dBodyGetFirstGeom(collider->body);
return geom ? dGeomGetData(geom) : NULL;
vec_void_t* lovrColliderGetShapes(Collider* collider) {
vec_clear(&collider->shapes);
for (dGeomID geom = dBodyGetFirstGeom(collider->body); geom; geom = dBodyGetNextGeom(geom)) {
Shape* shape = dGeomGetData(geom);
if (shape) {
vec_push(&collider->shapes, shape);
}
}
return &collider->shapes;
}
Shape* lovrColliderGetNextShape(Collider* collider, Shape* shape) {
dGeomID geom = dBodyGetNextGeom(shape->id);
return geom ? dGeomGetData(geom) : NULL;
vec_void_t* lovrColliderGetJoints(Collider* collider) {
vec_clear(&collider->joints);
int jointCount = dBodyGetNumJoints(collider->body);
for (int i = 0; i < jointCount; i++) {
Joint* joint = dJointGetData(dBodyGetJoint(collider->body, i));
if (joint) {
vec_push(&collider->joints, joint);
}
}
return &collider->joints;
}
void* lovrColliderGetUserData(Collider* collider) {
@ -675,3 +692,58 @@ float lovrCylinderShapeGetLength(CylinderShape* cylinder) {
void lovrCylinderShapeSetLength(CylinderShape* cylinder, float length) {
dGeomCylinderSetParams(cylinder->id, lovrCylinderShapeGetRadius(cylinder), length);
}
void lovrJointDestroy(const Ref* ref) {
Joint* joint = containerof(ref, Joint);
lovrJointDestroyData(joint);
free(joint);
}
void lovrJointDestroyData(Joint* joint) {
if (joint->id) {
dJointDestroy(joint->id);
joint->id = NULL;
}
}
JointType lovrJointGetType(Joint* joint) {
return joint->type;
}
void lovrJointGetColliders(Joint* joint, Collider** a, Collider** b) {
dBodyID bodyA = dJointGetBody(joint->id, 0);
dBodyID bodyB = dJointGetBody(joint->id, 1);
if (bodyA) {
*a = dBodyGetData(bodyA);
}
if (bodyB) {
*b = dBodyGetData(bodyB);
}
}
void* lovrJointGetUserData(Joint* joint) {
return joint->userdata;
}
void lovrJointSetUserData(Joint* joint, void* data) {
joint->userdata = data;
}
BallJoint* lovrBallJointCreate(Collider* a, Collider* b, float x, float y, float z) {
if (a->world != b->world) {
error("Joint bodies must exist in same World");
}
BallJoint* joint = lovrAlloc(sizeof(BallJoint), lovrJointDestroy);
if (!joint) return NULL;
joint->type = JOINT_BALL;
joint->id = dJointCreateBall(a->world->id, 0);
dJointSetData(joint->id, joint);
dJointAttach(joint->id, a->body, b->body);
dJointSetBallAnchor(joint->id, x, y, z);
return joint;
}

View File

@ -14,6 +14,10 @@ typedef enum {
SHAPE_CYLINDER
} ShapeType;
typedef enum {
JOINT_BALL,
} JointType;
typedef struct {
Ref ref;
dWorldID id;
@ -27,6 +31,8 @@ typedef struct {
dBodyID body;
World* world;
void* userdata;
vec_void_t shapes;
vec_void_t joints;
} Collider;
typedef struct {
@ -42,6 +48,15 @@ typedef Shape BoxShape;
typedef Shape CapsuleShape;
typedef Shape CylinderShape;
typedef struct {
Ref ref;
JointType type;
dJointID id;
void* userdata;
} Joint;
typedef Joint BallJoint;
typedef void (*CollisionResolver)(World* world, void* userdata);
void lovrPhysicsInit();
@ -69,8 +84,8 @@ void lovrColliderDestroyData(Collider* collider);
World* lovrColliderGetWorld(Collider* collider);
void lovrColliderAddShape(Collider* collider, Shape* shape);
void lovrColliderRemoveShape(Collider* collider, Shape* shape);
Shape* lovrColliderGetFirstShape(Collider* collider);
Shape* lovrColliderGetNextShape(Collider* collider, Shape* shape);
vec_void_t* lovrColliderGetShapes(Collider* collider);
vec_void_t* lovrColliderGetJoints(Collider* collider);
void* lovrColliderGetUserData(Collider* collider);
void lovrColliderSetUserData(Collider* collider, void* data);
int lovrColliderIsKinematic(Collider* collider);
@ -145,3 +160,12 @@ float lovrCylinderShapeGetRadius(CylinderShape* cylinder);
void lovrCylinderShapeSetRadius(CylinderShape* cylinder, float radius);
float lovrCylinderShapeGetLength(CylinderShape* cylinder);
void lovrCylinderShapeSetLength(CylinderShape* cylinder, float length);
void lovrJointDestroy(const Ref* ref);
void lovrJointDestroyData(Joint* joint);
JointType lovrJointGetType(Joint* joint);
void lovrJointGetColliders(Joint* joint, Collider** a, Collider** b);
void* lovrJointGetUserData(Joint* joint);
void lovrJointSetUserData(Joint* joint, void* data);
BallJoint* lovrBallJointCreate(Collider* a, Collider* b, float x, float y, float z);