1
0
Fork 0
mirror of https://github.com/bjornbytes/lovr.git synced 2024-07-11 16:33:35 +00:00
lovr/src/api/types/world.c

274 lines
8.4 KiB
C
Raw Normal View History

2017-12-10 20:40:37 +00:00
#include "api.h"
2017-05-16 05:02:08 +00:00
#include "physics/physics.h"
2017-10-31 08:14:09 +00:00
#include <stdbool.h>
2017-05-16 05:02:08 +00:00
2017-05-19 21:04:34 +00:00
static void collisionResolver(World* world, void* userdata) {
lua_State* L = userdata;
luaL_checktype(L, -1, LUA_TFUNCTION);
2018-07-25 03:10:30 +00:00
luax_pushobject(L, world);
2017-05-19 21:04:34 +00:00
lua_call(L, 1, 0);
}
static int nextOverlap(lua_State* L) {
World* world = luax_checktype(L, lua_upvalueindex(1), World);
Shape* a;
Shape* b;
if (lovrWorldGetNextOverlap(world, &a, &b)) {
2018-07-25 03:10:30 +00:00
luax_pushobject(L, a);
luax_pushobject(L, b);
2017-05-19 21:04:34 +00:00
return 2;
} else {
lua_pushnil(L);
return 1;
}
}
2017-05-25 00:40:02 +00:00
static void raycastCallback(Shape* shape, float x, float y, float z, float nx, float ny, float nz, void* userdata) {
lua_State* L = userdata;
luaL_checktype(L, -1, LUA_TFUNCTION);
2017-09-04 00:01:48 +00:00
lua_pushvalue(L, -1);
2018-07-25 03:10:30 +00:00
luax_pushobject(L, shape);
2017-05-25 00:40:02 +00:00
lua_pushnumber(L, x);
lua_pushnumber(L, y);
lua_pushnumber(L, z);
lua_pushnumber(L, nx);
lua_pushnumber(L, ny);
lua_pushnumber(L, nz);
lua_call(L, 7, 0);
}
2017-05-20 02:11:58 +00:00
int l_lovrWorldNewCollider(lua_State* L) {
World* world = luax_checktype(L, 1, World);
2017-06-10 21:17:59 +00:00
float x = luaL_optnumber(L, 2, 0);
float y = luaL_optnumber(L, 3, 0);
float z = luaL_optnumber(L, 4, 0);
Collider* collider = lovrColliderCreate(world, x, y, z);
2018-07-25 03:10:30 +00:00
luax_pushobject(L, collider);
2018-08-19 04:16:19 +00:00
lovrRelease(collider);
2017-05-20 02:11:58 +00:00
return 1;
}
int l_lovrWorldNewBoxCollider(lua_State* L) {
World* world = luax_checktype(L, 1, World);
2017-06-10 21:17:59 +00:00
float x = luaL_optnumber(L, 2, 0);
float y = luaL_optnumber(L, 3, 0);
float z = luaL_optnumber(L, 4, 0);
float sx = luaL_optnumber(L, 5, 1.f);
float sy = luaL_optnumber(L, 6, sx);
float sz = luaL_optnumber(L, 7, sx);
Collider* collider = lovrColliderCreate(world, x, y, z);
lovrColliderAddShape(collider, lovrBoxShapeCreate(sx, sy, sz));
2018-07-25 03:10:30 +00:00
luax_pushobject(L, collider);
2018-08-19 04:16:19 +00:00
lovrRelease(collider);
2017-05-20 02:11:58 +00:00
return 1;
}
int l_lovrWorldNewCapsuleCollider(lua_State* L) {
World* world = luax_checktype(L, 1, World);
2017-06-10 21:17:59 +00:00
float x = luaL_optnumber(L, 2, 0);
float y = luaL_optnumber(L, 3, 0);
float z = luaL_optnumber(L, 4, 0);
float radius = luaL_optnumber(L, 5, 1.f);
float length = luaL_optnumber(L, 6, 1.f);
Collider* collider = lovrColliderCreate(world, x, y, z);
2017-05-20 02:11:58 +00:00
lovrColliderAddShape(collider, lovrCapsuleShapeCreate(radius, length));
2018-07-25 03:10:30 +00:00
luax_pushobject(L, collider);
2018-08-19 04:16:19 +00:00
lovrRelease(collider);
2017-05-20 02:11:58 +00:00
return 1;
}
int l_lovrWorldNewCylinderCollider(lua_State* L) {
World* world = luax_checktype(L, 1, World);
2017-06-10 21:17:59 +00:00
float x = luaL_optnumber(L, 2, 0);
float y = luaL_optnumber(L, 3, 0);
float z = luaL_optnumber(L, 4, 0);
float radius = luaL_optnumber(L, 5, 1.f);
float length = luaL_optnumber(L, 6, 1.f);
Collider* collider = lovrColliderCreate(world, x, y, z);
2017-05-20 02:11:58 +00:00
lovrColliderAddShape(collider, lovrCylinderShapeCreate(radius, length));
2018-07-25 03:10:30 +00:00
luax_pushobject(L, collider);
2018-08-19 04:16:19 +00:00
lovrRelease(collider);
2017-05-20 02:11:58 +00:00
return 1;
}
int l_lovrWorldNewSphereCollider(lua_State* L) {
World* world = luax_checktype(L, 1, World);
2017-06-10 21:17:59 +00:00
float x = luaL_optnumber(L, 2, 0);
float y = luaL_optnumber(L, 3, 0);
float z = luaL_optnumber(L, 4, 0);
float radius = luaL_optnumber(L, 5, 1.f);
Collider* collider = lovrColliderCreate(world, x, y, z);
2017-05-20 02:11:58 +00:00
lovrColliderAddShape(collider, lovrSphereShapeCreate(radius));
2018-07-25 03:10:30 +00:00
luax_pushobject(L, collider);
2018-08-19 04:16:19 +00:00
lovrRelease(collider);
2017-05-20 02:11:58 +00:00
return 1;
}
2017-05-20 04:09:33 +00:00
int l_lovrWorldDestroy(lua_State* L) {
World* world = luax_checktype(L, 1, World);
lovrWorldDestroyData(world);
return 0;
}
int l_lovrWorldUpdate(lua_State* L) {
lua_settop(L, 3);
World* world = luax_checktype(L, 1, World);
float dt = luaL_checknumber(L, 2);
CollisionResolver resolver = lua_type(L, 3) == LUA_TFUNCTION ? collisionResolver : NULL;
lovrWorldUpdate(world, dt, resolver, L);
return 0;
}
int l_lovrWorldComputeOverlaps(lua_State* L) {
World* world = luax_checktype(L, 1, World);
lovrWorldComputeOverlaps(world);
return 0;
}
int l_lovrWorldOverlaps(lua_State* L) {
luax_checktype(L, 1, World);
lua_settop(L, 1);
lua_pushcclosure(L, nextOverlap, 1);
return 1;
}
int l_lovrWorldCollide(lua_State* L) {
World* world = luax_checktype(L, 1, World);
Shape* a = luax_checktype(L, 2, Shape);
Shape* b = luax_checktype(L, 3, Shape);
2017-05-25 00:39:12 +00:00
float friction = luaL_optnumber(L, 4, -1);
float restitution = luaL_optnumber(L, 5, -1);
lua_pushboolean(L, lovrWorldCollide(world, a, b, friction, restitution));
2017-05-20 04:09:33 +00:00
return 1;
}
2017-05-16 05:03:01 +00:00
int l_lovrWorldGetGravity(lua_State* L) {
World* world = luax_checktype(L, 1, World);
float x, y, z;
lovrWorldGetGravity(world, &x, &y, &z);
lua_pushnumber(L, x);
lua_pushnumber(L, y);
lua_pushnumber(L, z);
return 3;
}
int l_lovrWorldSetGravity(lua_State* L) {
World* world = luax_checktype(L, 1, World);
float x = luaL_checknumber(L, 2);
float y = luaL_checknumber(L, 3);
float z = luaL_checknumber(L, 4);
lovrWorldSetGravity(world, x, y, z);
return 0;
}
int l_lovrWorldGetLinearDamping(lua_State* L) {
World* world = luax_checktype(L, 1, World);
float damping, threshold;
lovrWorldGetLinearDamping(world, &damping, &threshold);
lua_pushnumber(L, damping);
lua_pushnumber(L, threshold);
return 2;
}
int l_lovrWorldSetLinearDamping(lua_State* L) {
World* world = luax_checktype(L, 1, World);
float damping = luaL_checknumber(L, 2);
float threshold = luaL_optnumber(L, 3, .01);
lovrWorldSetLinearDamping(world, damping, threshold);
return 0;
}
int l_lovrWorldGetAngularDamping(lua_State* L) {
World* world = luax_checktype(L, 1, World);
float damping, threshold;
lovrWorldGetAngularDamping(world, &damping, &threshold);
lua_pushnumber(L, damping);
lua_pushnumber(L, threshold);
return 2;
}
int l_lovrWorldSetAngularDamping(lua_State* L) {
World* world = luax_checktype(L, 1, World);
float damping = luaL_checknumber(L, 2);
float threshold = luaL_optnumber(L, 3, .01);
lovrWorldSetAngularDamping(world, damping, threshold);
return 0;
}
int l_lovrWorldIsSleepingAllowed(lua_State* L) {
World* world = luax_checktype(L, 1, World);
lua_pushboolean(L, lovrWorldIsSleepingAllowed(world));
return 1;
}
int l_lovrWorldSetSleepingAllowed(lua_State* L) {
World* world = luax_checktype(L, 1, World);
2017-10-31 08:14:09 +00:00
bool allowed = lua_toboolean(L, 2);
lovrWorldSetSleepingAllowed(world, allowed);
return 0;
}
2017-05-25 00:40:02 +00:00
int l_lovrWorldRaycast(lua_State* L) {
World* world = luax_checktype(L, 1, World);
float x1 = luaL_checknumber(L, 2);
float y1 = luaL_checknumber(L, 3);
float z1 = luaL_checknumber(L, 4);
float x2 = luaL_checknumber(L, 5);
float y2 = luaL_checknumber(L, 6);
float z2 = luaL_checknumber(L, 7);
luaL_checktype(L, 8, LUA_TFUNCTION);
lua_settop(L, 8);
lovrWorldRaycast(world, x1, y1, z1, x2, y2, z2, raycastCallback, L);
return 0;
}
2017-05-25 22:01:40 +00:00
int l_lovrWorldDisableCollisionBetween(lua_State* L) {
World* world = luax_checktype(L, 1, World);
const char* tag1 = luaL_checkstring(L, 2);
const char* tag2 = luaL_checkstring(L, 3);
lovrWorldDisableCollisionBetween(world, tag1, tag2);
return 0;
}
int l_lovrWorldEnableCollisionBetween(lua_State* L) {
World* world = luax_checktype(L, 1, World);
const char* tag1 = luaL_checkstring(L, 2);
const char* tag2 = luaL_checkstring(L, 3);
lovrWorldEnableCollisionBetween(world, tag1, tag2);
return 0;
}
int l_lovrWorldIsCollisionEnabledBetween(lua_State* L) {
World* world = luax_checktype(L, 1, World);
const char* tag1 = luaL_checkstring(L, 2);
const char* tag2 = luaL_checkstring(L, 3);
lua_pushboolean(L, lovrWorldIsCollisionEnabledBetween(world, tag1, tag2));
return 1;
}
2017-05-16 05:02:08 +00:00
const luaL_Reg lovrWorld[] = {
2017-05-20 02:11:58 +00:00
{ "newCollider", l_lovrWorldNewCollider },
{ "newBoxCollider", l_lovrWorldNewBoxCollider },
{ "newCapsuleCollider", l_lovrWorldNewCapsuleCollider },
{ "newCylinderCollider", l_lovrWorldNewCylinderCollider },
{ "newSphereCollider", l_lovrWorldNewSphereCollider },
2017-05-20 04:09:33 +00:00
{ "destroy", l_lovrWorldDestroy },
{ "update", l_lovrWorldUpdate },
{ "computeOverlaps", l_lovrWorldComputeOverlaps },
{ "overlaps", l_lovrWorldOverlaps },
{ "collide", l_lovrWorldCollide },
2017-05-16 05:03:01 +00:00
{ "getGravity", l_lovrWorldGetGravity },
{ "setGravity", l_lovrWorldSetGravity },
{ "getLinearDamping", l_lovrWorldGetLinearDamping },
{ "setLinearDamping", l_lovrWorldSetLinearDamping },
{ "getAngularDamping", l_lovrWorldGetAngularDamping },
{ "setAngularDamping", l_lovrWorldSetAngularDamping },
{ "isSleepingAllowed", l_lovrWorldIsSleepingAllowed },
{ "setSleepingAllowed", l_lovrWorldSetSleepingAllowed },
2017-05-25 00:40:02 +00:00
{ "raycast", l_lovrWorldRaycast },
2017-05-25 22:01:40 +00:00
{ "disableCollisionBetween", l_lovrWorldDisableCollisionBetween },
{ "enableCollisionBetween", l_lovrWorldEnableCollisionBetween },
{ "isCollisionEnabledBetween", l_lovrWorldIsCollisionEnabledBetween },
2017-05-16 05:02:08 +00:00
{ NULL, NULL }
};