2017-12-10 20:40:37 +00:00
|
|
|
#include "api.h"
|
2017-05-16 04:59:53 +00:00
|
|
|
#include "physics/physics.h"
|
2022-03-22 07:13:21 +00:00
|
|
|
#include "util.h"
|
2017-05-16 04:59:53 +00:00
|
|
|
|
2020-09-28 00:13:00 +00:00
|
|
|
StringEntry lovrShapeType[] = {
|
2020-02-17 02:31:02 +00:00
|
|
|
[SHAPE_SPHERE] = ENTRY("sphere"),
|
|
|
|
[SHAPE_BOX] = ENTRY("box"),
|
|
|
|
[SHAPE_CAPSULE] = ENTRY("capsule"),
|
|
|
|
[SHAPE_CYLINDER] = ENTRY("cylinder"),
|
2024-04-09 20:01:30 +00:00
|
|
|
[SHAPE_CONVEX] = ENTRY("convex"),
|
2020-09-13 10:34:36 +00:00
|
|
|
[SHAPE_MESH] = ENTRY("mesh"),
|
2022-08-12 05:04:59 +00:00
|
|
|
[SHAPE_TERRAIN] = ENTRY("terrain"),
|
2024-04-03 22:03:46 +00:00
|
|
|
[SHAPE_COMPOUND] = ENTRY("compound"),
|
2020-02-17 02:31:02 +00:00
|
|
|
{ 0 }
|
2018-07-05 03:11:52 +00:00
|
|
|
};
|
|
|
|
|
2020-09-28 00:13:00 +00:00
|
|
|
StringEntry lovrJointType[] = {
|
2020-02-17 02:31:02 +00:00
|
|
|
[JOINT_BALL] = ENTRY("ball"),
|
|
|
|
[JOINT_DISTANCE] = ENTRY("distance"),
|
|
|
|
[JOINT_HINGE] = ENTRY("hinge"),
|
|
|
|
[JOINT_SLIDER] = ENTRY("slider"),
|
|
|
|
{ 0 }
|
2018-07-05 03:11:52 +00:00
|
|
|
};
|
2017-05-16 18:17:01 +00:00
|
|
|
|
2018-09-27 01:27:38 +00:00
|
|
|
static int l_lovrPhysicsNewWorld(lua_State* L) {
|
2024-04-05 20:23:17 +00:00
|
|
|
WorldInfo info = {
|
|
|
|
.maxColliders = 65536,
|
|
|
|
.maxColliderPairs = 65536,
|
|
|
|
.maxContacts = 16384,
|
2024-04-08 03:27:10 +00:00
|
|
|
.allowSleep = true
|
2024-04-05 20:23:17 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
if (lua_istable(L, 1)) {
|
|
|
|
lua_getfield(L, 1, "maxColliders");
|
|
|
|
if (!lua_isnil(L, -1)) info.maxColliders = luax_checku32(L, -1);
|
|
|
|
lua_pop(L, 1);
|
|
|
|
|
|
|
|
lua_getfield(L, 1, "maxColliderPairs");
|
|
|
|
if (!lua_isnil(L, -1)) info.maxColliderPairs = luax_checku32(L, -1);
|
|
|
|
lua_pop(L, 1);
|
|
|
|
|
|
|
|
lua_getfield(L, 1, "maxContacts");
|
|
|
|
if (!lua_isnil(L, -1)) info.maxContacts = luax_checku32(L, -1);
|
|
|
|
lua_pop(L, 1);
|
|
|
|
|
|
|
|
lua_getfield(L, 1, "allowSleep");
|
|
|
|
if (!lua_isnil(L, -1)) info.allowSleep = lua_toboolean(L, -1);
|
|
|
|
lua_pop(L, 1);
|
|
|
|
|
|
|
|
lua_getfield(L, 1, "tags");
|
|
|
|
if (!lua_isnil(L, -1)) {
|
|
|
|
lovrCheck(lua_istable(L, -1), "World tag list should be a table");
|
|
|
|
lovrCheck(info.tagCount <= MAX_TAGS, "Max number of world tags is %d", MAX_TAGS);
|
|
|
|
info.tagCount = luax_len(L, 5);
|
|
|
|
for (uint32_t i = 0; i < info.tagCount; i++) {
|
|
|
|
lua_rawgeti(L, -1, (int) i + 1);
|
|
|
|
if (lua_isstring(L, -1)) {
|
|
|
|
info.tags[i] = lua_tostring(L, -1);
|
|
|
|
} else {
|
|
|
|
return luaL_error(L, "World tags must be a table of strings");
|
|
|
|
}
|
|
|
|
lua_pop(L, 1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
lua_pop(L, 1);
|
|
|
|
} else { // Deprecated
|
|
|
|
info.allowSleep = lua_gettop(L) < 4 || lua_toboolean(L, 4);
|
|
|
|
if (lua_type(L, 5) == LUA_TTABLE) {
|
|
|
|
info.tagCount = luax_len(L, 5);
|
|
|
|
lovrCheck(info.tagCount <= MAX_TAGS, "Max number of world tags is %d", MAX_TAGS);
|
|
|
|
for (uint32_t i = 0; i < info.tagCount; i++) {
|
|
|
|
lua_rawgeti(L, -1, (int) i + 1);
|
|
|
|
if (lua_isstring(L, -1)) {
|
|
|
|
info.tags[i] = lua_tostring(L, -1);
|
|
|
|
} else {
|
|
|
|
return luaL_error(L, "World tags must be a table of strings");
|
|
|
|
}
|
|
|
|
lua_pop(L, 1);
|
2017-05-25 22:01:40 +00:00
|
|
|
}
|
2024-04-05 20:23:17 +00:00
|
|
|
} else {
|
|
|
|
info.tagCount = 0;
|
2017-05-25 22:01:40 +00:00
|
|
|
}
|
|
|
|
}
|
2024-04-05 20:23:17 +00:00
|
|
|
|
|
|
|
World* world = lovrWorldCreate(&info);
|
2024-04-08 03:27:10 +00:00
|
|
|
|
|
|
|
if (!lua_istable(L, 1)) {
|
|
|
|
float gravity[3];
|
|
|
|
gravity[0] = luax_optfloat(L, 1, 0.f);
|
|
|
|
gravity[1] = luax_optfloat(L, 2, -9.81f);
|
|
|
|
gravity[2] = luax_optfloat(L, 3, 0.f);
|
|
|
|
lovrWorldSetGravity(world, gravity);
|
|
|
|
}
|
|
|
|
|
2019-06-02 07:20:10 +00:00
|
|
|
luax_pushtype(L, World, world);
|
2021-02-09 00:52:26 +00:00
|
|
|
lovrRelease(world, lovrWorldDestroy);
|
2017-05-16 05:02:08 +00:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2018-09-27 01:27:38 +00:00
|
|
|
static int l_lovrPhysicsNewBallJoint(lua_State* L) {
|
2017-05-25 00:38:03 +00:00
|
|
|
Collider* a = luax_checktype(L, 1, Collider);
|
|
|
|
Collider* b = luax_checktype(L, 2, Collider);
|
2023-07-11 00:51:24 +00:00
|
|
|
float anchor[3];
|
2020-05-07 17:07:33 +00:00
|
|
|
luax_readvec3(L, 3, anchor, NULL);
|
2023-07-11 00:51:24 +00:00
|
|
|
BallJoint* joint = lovrBallJointCreate(a, b, anchor);
|
2019-06-02 07:20:10 +00:00
|
|
|
luax_pushtype(L, BallJoint, joint);
|
2021-02-09 00:52:26 +00:00
|
|
|
lovrRelease(joint, lovrJointDestroy);
|
2017-05-16 21:21:10 +00:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2018-09-27 01:27:38 +00:00
|
|
|
static int l_lovrPhysicsNewBoxShape(lua_State* L) {
|
2022-11-10 04:53:42 +00:00
|
|
|
BoxShape* box = luax_newboxshape(L, 1);
|
2019-06-02 07:20:10 +00:00
|
|
|
luax_pushtype(L, BoxShape, box);
|
2021-02-09 00:52:26 +00:00
|
|
|
lovrRelease(box, lovrShapeDestroy);
|
2017-05-16 21:37:05 +00:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2018-09-27 01:27:38 +00:00
|
|
|
static int l_lovrPhysicsNewCapsuleShape(lua_State* L) {
|
2022-11-10 04:53:42 +00:00
|
|
|
CapsuleShape* capsule = luax_newcapsuleshape(L, 1);
|
2019-06-02 07:20:10 +00:00
|
|
|
luax_pushtype(L, CapsuleShape, capsule);
|
2021-02-09 00:52:26 +00:00
|
|
|
lovrRelease(capsule, lovrShapeDestroy);
|
2017-05-16 21:52:41 +00:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2024-04-09 20:01:30 +00:00
|
|
|
static int l_lovrPhysicsNewConvexShape(lua_State* L) {
|
|
|
|
ConvexShape* convex = luax_newconvexshape(L, 1);
|
|
|
|
luax_pushtype(L, ConvexShape, convex);
|
|
|
|
lovrRelease(convex, lovrShapeDestroy);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2018-09-27 01:27:38 +00:00
|
|
|
static int l_lovrPhysicsNewCylinderShape(lua_State* L) {
|
2022-11-10 04:53:42 +00:00
|
|
|
CylinderShape* cylinder = luax_newcylindershape(L, 1);
|
2019-06-02 07:20:10 +00:00
|
|
|
luax_pushtype(L, CylinderShape, cylinder);
|
2021-02-09 00:52:26 +00:00
|
|
|
lovrRelease(cylinder, lovrShapeDestroy);
|
2017-05-25 00:38:03 +00:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2018-09-27 01:27:38 +00:00
|
|
|
static int l_lovrPhysicsNewDistanceJoint(lua_State* L) {
|
2017-06-10 22:13:19 +00:00
|
|
|
Collider* a = luax_checktype(L, 1, Collider);
|
|
|
|
Collider* b = luax_checktype(L, 2, Collider);
|
2023-07-11 00:51:24 +00:00
|
|
|
float anchor1[3], anchor2[3];
|
2020-05-07 17:07:33 +00:00
|
|
|
int index = luax_readvec3(L, 3, anchor1, NULL);
|
|
|
|
luax_readvec3(L, index, anchor2, NULL);
|
2023-07-11 00:51:24 +00:00
|
|
|
DistanceJoint* joint = lovrDistanceJointCreate(a, b, anchor1, anchor2);
|
2019-06-02 07:20:10 +00:00
|
|
|
luax_pushtype(L, DistanceJoint, joint);
|
2021-02-09 00:52:26 +00:00
|
|
|
lovrRelease(joint, lovrJointDestroy);
|
2017-06-10 22:13:19 +00:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2018-09-27 01:27:38 +00:00
|
|
|
static int l_lovrPhysicsNewHingeJoint(lua_State* L) {
|
2017-05-25 06:51:27 +00:00
|
|
|
Collider* a = luax_checktype(L, 1, Collider);
|
|
|
|
Collider* b = luax_checktype(L, 2, Collider);
|
2023-07-11 00:51:24 +00:00
|
|
|
float anchor[3], axis[3];
|
2020-05-07 17:07:33 +00:00
|
|
|
int index = luax_readvec3(L, 3, anchor, NULL);
|
|
|
|
luax_readvec3(L, index, axis, NULL);
|
2023-07-11 00:51:24 +00:00
|
|
|
HingeJoint* joint = lovrHingeJointCreate(a, b, anchor, axis);
|
2019-06-02 07:20:10 +00:00
|
|
|
luax_pushtype(L, HingeJoint, joint);
|
2021-02-09 00:52:26 +00:00
|
|
|
lovrRelease(joint, lovrJointDestroy);
|
2017-05-25 06:51:27 +00:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2022-11-10 04:53:42 +00:00
|
|
|
static int l_lovrPhysicsNewMeshShape(lua_State* L) {
|
|
|
|
MeshShape* mesh = luax_newmeshshape(L, 1);
|
|
|
|
luax_pushtype(L, MeshShape, mesh);
|
|
|
|
lovrRelease(mesh, lovrShapeDestroy);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2018-09-27 01:27:38 +00:00
|
|
|
static int l_lovrPhysicsNewSliderJoint(lua_State* L) {
|
2017-05-25 07:48:02 +00:00
|
|
|
Collider* a = luax_checktype(L, 1, Collider);
|
|
|
|
Collider* b = luax_checktype(L, 2, Collider);
|
2023-07-11 00:51:24 +00:00
|
|
|
float axis[3];
|
2020-05-07 17:07:33 +00:00
|
|
|
luax_readvec3(L, 3, axis, NULL);
|
2023-07-11 00:51:24 +00:00
|
|
|
SliderJoint* joint = lovrSliderJointCreate(a, b, axis);
|
2019-06-02 07:20:10 +00:00
|
|
|
luax_pushtype(L, SliderJoint, joint);
|
2021-02-09 00:52:26 +00:00
|
|
|
lovrRelease(joint, lovrJointDestroy);
|
2017-05-25 07:48:02 +00:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2018-09-27 01:27:38 +00:00
|
|
|
static int l_lovrPhysicsNewSphereShape(lua_State* L) {
|
2022-11-10 04:53:42 +00:00
|
|
|
SphereShape* sphere = luax_newsphereshape(L, 1);
|
2019-06-02 07:20:10 +00:00
|
|
|
luax_pushtype(L, SphereShape, sphere);
|
2021-02-09 00:52:26 +00:00
|
|
|
lovrRelease(sphere, lovrShapeDestroy);
|
2017-05-16 21:56:20 +00:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2022-11-10 04:53:42 +00:00
|
|
|
static int l_lovrPhysicsNewTerrainShape(lua_State* L) {
|
|
|
|
TerrainShape* terrain = luax_newterrainshape(L, 1);
|
|
|
|
luax_pushtype(L, TerrainShape, terrain);
|
|
|
|
lovrRelease(terrain, lovrShapeDestroy);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2024-04-03 22:03:46 +00:00
|
|
|
static int l_lovrPhysicsNewCompoundShape(lua_State* L) {
|
|
|
|
CompoundShape* shape = luax_newcompoundshape(L, 1);
|
|
|
|
luax_pushtype(L, CompoundShape, shape);
|
|
|
|
lovrRelease(shape, lovrShapeDestroy);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2018-09-27 01:27:38 +00:00
|
|
|
static const luaL_Reg lovrPhysics[] = {
|
2017-05-16 05:02:08 +00:00
|
|
|
{ "newWorld", l_lovrPhysicsNewWorld },
|
2017-05-25 00:38:03 +00:00
|
|
|
{ "newBallJoint", l_lovrPhysicsNewBallJoint },
|
2017-05-16 21:37:05 +00:00
|
|
|
{ "newBoxShape", l_lovrPhysicsNewBoxShape },
|
2017-05-16 21:52:41 +00:00
|
|
|
{ "newCapsuleShape", l_lovrPhysicsNewCapsuleShape },
|
2024-04-09 20:01:30 +00:00
|
|
|
{ "newConvexShape", l_lovrPhysicsNewConvexShape },
|
2017-05-16 21:56:20 +00:00
|
|
|
{ "newCylinderShape", l_lovrPhysicsNewCylinderShape },
|
2017-06-10 22:13:19 +00:00
|
|
|
{ "newDistanceJoint", l_lovrPhysicsNewDistanceJoint },
|
2017-05-25 06:51:27 +00:00
|
|
|
{ "newHingeJoint", l_lovrPhysicsNewHingeJoint },
|
2022-11-10 04:53:42 +00:00
|
|
|
{ "newMeshShape", l_lovrPhysicsNewMeshShape },
|
2017-05-25 07:48:02 +00:00
|
|
|
{ "newSliderJoint", l_lovrPhysicsNewSliderJoint },
|
2017-05-25 00:38:03 +00:00
|
|
|
{ "newSphereShape", l_lovrPhysicsNewSphereShape },
|
2022-11-10 04:53:42 +00:00
|
|
|
{ "newTerrainShape", l_lovrPhysicsNewTerrainShape },
|
2024-04-03 22:03:46 +00:00
|
|
|
{ "newCompoundShape", l_lovrPhysicsNewCompoundShape },
|
2017-05-16 04:59:53 +00:00
|
|
|
{ NULL, NULL }
|
|
|
|
};
|
2018-09-27 01:27:38 +00:00
|
|
|
|
2021-03-16 00:54:27 +00:00
|
|
|
extern const luaL_Reg lovrWorld[];
|
|
|
|
extern const luaL_Reg lovrCollider[];
|
|
|
|
extern const luaL_Reg lovrBallJoint[];
|
|
|
|
extern const luaL_Reg lovrDistanceJoint[];
|
|
|
|
extern const luaL_Reg lovrHingeJoint[];
|
|
|
|
extern const luaL_Reg lovrSliderJoint[];
|
|
|
|
extern const luaL_Reg lovrSphereShape[];
|
|
|
|
extern const luaL_Reg lovrBoxShape[];
|
|
|
|
extern const luaL_Reg lovrCapsuleShape[];
|
|
|
|
extern const luaL_Reg lovrCylinderShape[];
|
2024-04-09 20:01:30 +00:00
|
|
|
extern const luaL_Reg lovrConvexShape[];
|
2021-03-16 00:54:27 +00:00
|
|
|
extern const luaL_Reg lovrMeshShape[];
|
2022-11-10 04:53:42 +00:00
|
|
|
extern const luaL_Reg lovrTerrainShape[];
|
2024-04-03 22:03:46 +00:00
|
|
|
extern const luaL_Reg lovrCompoundShape[];
|
2021-03-16 00:54:27 +00:00
|
|
|
|
2019-08-26 22:53:10 +00:00
|
|
|
int luaopen_lovr_physics(lua_State* L) {
|
2018-09-27 01:27:38 +00:00
|
|
|
lua_newtable(L);
|
2020-08-19 19:12:06 +00:00
|
|
|
luax_register(L, lovrPhysics);
|
2019-04-05 10:48:36 +00:00
|
|
|
luax_registertype(L, World);
|
|
|
|
luax_registertype(L, Collider);
|
2019-06-02 07:20:10 +00:00
|
|
|
luax_registertype(L, BallJoint);
|
|
|
|
luax_registertype(L, DistanceJoint);
|
|
|
|
luax_registertype(L, HingeJoint);
|
|
|
|
luax_registertype(L, SliderJoint);
|
|
|
|
luax_registertype(L, SphereShape);
|
|
|
|
luax_registertype(L, BoxShape);
|
|
|
|
luax_registertype(L, CapsuleShape);
|
|
|
|
luax_registertype(L, CylinderShape);
|
2024-04-09 20:01:30 +00:00
|
|
|
luax_registertype(L, ConvexShape);
|
2020-09-13 10:34:36 +00:00
|
|
|
luax_registertype(L, MeshShape);
|
2022-11-10 04:53:42 +00:00
|
|
|
luax_registertype(L, TerrainShape);
|
2024-04-03 22:03:46 +00:00
|
|
|
luax_registertype(L, CompoundShape);
|
2023-11-24 01:07:44 +00:00
|
|
|
lovrPhysicsInit();
|
|
|
|
luax_atexit(L, lovrPhysicsDestroy);
|
2018-09-27 01:27:38 +00:00
|
|
|
return 1;
|
|
|
|
}
|