From 50faaf10b296ebe3ca9af1cdf18f2b557b319be9 Mon Sep 17 00:00:00 2001 From: sanine Date: Sat, 25 Mar 2023 14:31:17 -0500 Subject: add the ability to store data in geoms --- src/ode/geom.c | 74 ++++++++++++++++++++++++++++++++++++++++++-------- src/ode/ode_bindings.h | 2 ++ src/ode/setup.c | 15 +++++++++- 3 files changed, 79 insertions(+), 12 deletions(-) diff --git a/src/ode/geom.c b/src/ode/geom.c index 085b06c..9700079 100644 --- a/src/ode/geom.c +++ b/src/ode/geom.c @@ -4,15 +4,43 @@ #include "ode_bindings.h" -void ode_push_geom(lua_State *L, dGeomID g) +struct geom_data_t { + lua_Integer self; + lua_Integer ref; +}; +struct geom_wrap_t { + dGeomID id; + struct geom_data_t data; +}; + + +void ode_create_geom(lua_State *L, dGeomID g) { - dGeomID *gu = lua_newuserdata(L, sizeof(dGeomID)); - *gu = g; + struct geom_wrap_t *wrap = lua_newuserdata(L, sizeof(struct geom_wrap_t)); + wrap->id = g; + if (g != NULL) { + lua_pushvalue(L, -1); + wrap->data.self = luaL_ref(L, LUA_REGISTRYINDEX); + wrap->data.ref = LUA_NOREF; + dGeomSetData(g, &(wrap->data)); + } luaL_getmetatable(L, ode_geom_tname); lua_setmetatable(L, -2); } +void ode_push_geom(lua_State *L, dGeomID g) +{ + if (g == NULL) { + lua_pushnil(L); + } + else { + struct geom_data_t *data = dGeomGetData(g); + lua_rawgeti(L, LUA_REGISTRYINDEX, data->self); + } +} + + void ode_push_space(lua_State *L, dSpaceID s) { dSpaceID *su = lua_newuserdata(L, sizeof(dSpaceID)); @@ -55,6 +83,30 @@ int dGeomDestroy_bind(lua_State *L) } +int dGeomSetData_bind(lua_State *L) +{ + dGeomID *g = luaL_checkudata(L, 1, ode_geom_tname); + luaL_checkany(L, 2); + const int val = 2; + + struct geom_data_t *data = dGeomGetData(*g); + luaL_unref(L, LUA_REGISTRYINDEX, data->ref); + lua_pushvalue(L, val); + data->ref = luaL_ref(L, LUA_REGISTRYINDEX); + + return 0; +} + + +int dGeomGetData_bind(lua_State *L) +{ + dGeomID *g = luaL_checkudata(L, 1, ode_geom_tname); + struct geom_data_t *data = dGeomGetData(*g); + lua_rawgeti(L, LUA_REGISTRYINDEX, data->ref); + return 1; +} + + int dGeomSetBody_bind(lua_State *L) { dGeomID *g = luaL_checkudata(L, 1, ode_geom_tname); @@ -612,7 +664,7 @@ int dCreateSphere_bind(lua_State *L) dSpaceID *space = luaL_checkudata(L, 1, ode_space_tname); dReal radius = luaL_checknumber(L, 2); dGeomID bind_result = dCreateSphere(*space, radius); - ode_push_geom(L, bind_result); + ode_create_geom(L, bind_result); return 1; } @@ -654,7 +706,7 @@ int dCreateBox_bind(lua_State *L) dReal ly = luaL_checknumber(L, 3); dReal lz = luaL_checknumber(L, 4); dGeomID bind_result = dCreateBox(*space, lx, ly, lz); - ode_push_geom(L, bind_result); + ode_create_geom(L, bind_result); return 1; } @@ -702,7 +754,7 @@ int dCreatePlane_bind(lua_State *L) dReal c = luaL_checknumber(L, 4); dReal d = luaL_checknumber(L, 5); dGeomID bind_result = dCreatePlane(*space, a, b, c, d); - ode_push_geom(L, bind_result); + ode_create_geom(L, bind_result); return 1; } @@ -750,7 +802,7 @@ int dCreateCapsule_bind(lua_State *L) dReal radius = luaL_checknumber(L, 2); dReal length = luaL_checknumber(L, 3); dGeomID bind_result = dCreateCapsule(*space, radius, length); - ode_push_geom(L, bind_result); + ode_create_geom(L, bind_result); return 1; } @@ -794,7 +846,7 @@ int dCreateCylinder_bind(lua_State *L) dReal radius = luaL_checknumber(L, 2); dReal length = luaL_checknumber(L, 3); dGeomID bind_result = dCreateCylinder(*space, radius, length); - ode_push_geom(L, bind_result); + ode_create_geom(L, bind_result); return 1; } @@ -825,7 +877,7 @@ int dCreateRay_bind(lua_State *L) dSpaceID *space = luaL_checkudata(L, 1, ode_space_tname); dReal length = luaL_checknumber(L, 2); dGeomID bind_result = dCreateRay(*space, length); - ode_push_geom(L, bind_result); + ode_create_geom(L, bind_result); return 1; } @@ -987,7 +1039,7 @@ int dCreateTriMesh_bind(lua_State *L) dTriArrayCallback * ArrayCallback = NULL; dTriRayCallback * RayCallback = NULL; dGeomID bind_result = dCreateTriMesh(*space, *Data, Callback, ArrayCallback, RayCallback); - ode_push_geom(L, bind_result); + ode_create_geom(L, bind_result); return 1; } @@ -1137,7 +1189,7 @@ int dCreateHeightfield_bind(lua_State *L) dHeightfieldDataID *data = luaL_checkudata(L, 2, ode_heightfielddata_tname); int bPlaceable = luaL_checkinteger(L, 3); dGeomID bind_result = dCreateHeightfield(*space, *data, bPlaceable); - ode_push_geom(L, bind_result); + ode_create_geom(L, bind_result); return 1; } diff --git a/src/ode/ode_bindings.h b/src/ode/ode_bindings.h index 3305b2a..7d3f518 100644 --- a/src/ode/ode_bindings.h +++ b/src/ode/ode_bindings.h @@ -319,6 +319,8 @@ void ode_push_space(lua_State *L, dSpaceID s); \ /* geom */ \ X("GeomDestroy", dGeomDestroy_bind) \ + X("GeomSetData", dGeomSetData_bind) \ + X("GeomGetData", dGeomGetData_bind) \ X("GeomSetBody", dGeomSetBody_bind) \ X("GeomGetBody", dGeomGetBody_bind) \ X("GeomSetPosition", dGeomSetPosition_bind) \ diff --git a/src/ode/setup.c b/src/ode/setup.c index 2b5b1e3..3655b1e 100644 --- a/src/ode/setup.c +++ b/src/ode/setup.c @@ -14,10 +14,23 @@ ODE_METATABLES #undef X +int generic_eq(lua_State *L) +{ + void **a = lua_touserdata(L, 1); + void **b = lua_touserdata(L, 2); + lua_pushboolean(L, *a == *b); + return 1; +} + + void setup_ode(lua_State *L, int honey_tbl) { /* setup metatables */ - #define X(name, mt) luaL_newmetatable(L, mt); lua_pop(L, 1); + #define X(name, mt) \ + luaL_newmetatable(L, mt); \ + lua_pushcfunction(L, generic_eq); \ + lua_setfield(L, -2, "__eq"); \ + lua_pop(L, 1); ODE_METATABLES #undef X -- cgit v1.2.1