mirror of https://github.com/bjornbytes/lovr.git
parent
19908a7d38
commit
f1a74c34c3
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 }
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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 }
|
||||
};
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue