From 4f0e0988eb457654f70cc2e96faca22db56234f3 Mon Sep 17 00:00:00 2001 From: sanine Date: Sat, 25 Feb 2023 15:16:44 -0600 Subject: bind ode heightfield and trimesh collider functions --- src/ode/geom.c | 379 ++++++++++++++++++++++++++-------------------- src/ode/ode_bindings.h | 35 +++-- src/ode/setup.c | 24 +-- util/generate-binding.lua | 3 +- 4 files changed, 242 insertions(+), 199 deletions(-) diff --git a/src/ode/geom.c b/src/ode/geom.c index b7694ad..085b06c 100644 --- a/src/ode/geom.c +++ b/src/ode/geom.c @@ -29,6 +29,24 @@ void ode_push_contactgeom(lua_State *L, dContactGeom cg) } +void ode_push_trimeshdata(lua_State *L, dTriMeshDataID d) +{ + dTriMeshDataID *du = lua_newuserdata(L, sizeof(dTriMeshDataID)); + *du = d; + luaL_getmetatable(L, ode_trimeshdata_tname); + lua_setmetatable(L, -2); +} + + +void ode_push_heightfielddata(lua_State *L, dHeightfieldDataID d) +{ + dHeightfieldDataID *du = lua_newuserdata(L, sizeof(dHeightfieldDataID)); + *du = d; + luaL_getmetatable(L, ode_heightfielddata_tname); + lua_setmetatable(L, -2); +} + + int dGeomDestroy_bind(lua_State *L) { dGeomID *g = luaL_checkudata(L, 1, ode_geom_tname); @@ -860,56 +878,71 @@ int dGeomRayGet_bind(lua_State *L) } -int dGeomRaySetParams_bind(lua_State *L) +int dGeomRaySetClosestHit_bind(lua_State *L) { dGeomID *ray = luaL_checkudata(L, 1, ode_geom_tname); - int FirstContact = luaL_checkinteger(L, 2); - int BackfaceCull = luaL_checkinteger(L, 3); - dGeomRaySetParams(*ray, FirstContact, BackfaceCull); + int ClosestHit = luaL_checkinteger(L, 2); + dGeomRaySetClosestHit(*ray, ClosestHit); return 0; } -int dGeomRayGetParams_bind(lua_State *L) +int dGeomRayGetClosestHit_bind(lua_State *L) { dGeomID *ray = luaL_checkudata(L, 1, ode_geom_tname); - int FirstContact, BackfaceCull; - dGeomRayGetParams(*ray, &FirstContact, &BackfaceCull); - lua_pushnumber(L, FirstContact); - lua_pushnumber(L, BackfaceCull); - return 2; + int bind_result = dGeomRayGetClosestHit(*ray); + lua_pushinteger(L, bind_result); + return 1; } -int dGeomRaySetClosestHit_bind(lua_State *L) +int dGeomRaySetFirstContact_bind(lua_State *L) { - dGeomID *ray = luaL_checkudata(L, 1, ode_geom_tname); - int ClosestHit = luaL_checkinteger(L, 2); - dGeomRaySetClosestHit(*ray, ClosestHit); + dGeomID *g = luaL_checkudata(L, 1, ode_geom_tname); + int first_contact = luaL_checkinteger(L, 2); + dGeomRaySetFirstContact(*g, first_contact); return 0; } -int dGeomRayGetClosestHit_bind(lua_State *L) +int dGeomRayGetFirstContact_bind(lua_State *L) { - dGeomID *ray = luaL_checkudata(L, 1, ode_geom_tname); - int bind_result = dGeomRayGetClosestHit(*ray); + dGeomID *g = luaL_checkudata(L, 1, ode_geom_tname); + int bind_result = dGeomRayGetFirstContact(*g); + lua_pushinteger(L, bind_result); + return 1; +} + + +int dGeomRaySetBackfaceCull_bind(lua_State *L) +{ + dGeomID *g = luaL_checkudata(L, 1, ode_geom_tname); + int backfaceCull = luaL_checkinteger(L, 2); + dGeomRaySetBackfaceCull(*g, backfaceCull); + return 0; +} + + +int dGeomRayGetBackfaceCull_bind(lua_State *L) +{ + dGeomID *g = luaL_checkudata(L, 1, ode_geom_tname); + int bind_result = dGeomRayGetBackfaceCull(*g); lua_pushinteger(L, bind_result); return 1; } -/*int dGeomTriMeshDataCreate_bind(lua_State *L) +int dGeomTriMeshDataCreate_bind(lua_State *L) { dTriMeshDataID bind_result = dGeomTriMeshDataCreate(); - /* push result / - return /* count /; + ode_push_trimeshdata(L, bind_result); + return 1; } int dGeomTriMeshDataDestroy_bind(lua_State *L) { - dTriMeshDataID g = get: dTriMeshDataID + dTriMeshDataID *g = luaL_checkudata(L, 1, ode_trimeshdata_tname); dGeomTriMeshDataDestroy(*g); return 0; } @@ -917,27 +950,31 @@ int dGeomTriMeshDataDestroy_bind(lua_State *L) int dGeomTriMeshDataBuild_bind(lua_State *L) { - dTriMeshDataID g = get: dTriMeshDataID - const void * Vertices = get: const void * - int VertexStride = luaL_checkinteger(L, 3); - int VertexCount = luaL_checkinteger(L, 4); - const void * Indices = get: const void * - int IndexCount = luaL_checkinteger(L, 6); - int TriStride = luaL_checkinteger(L, 7); - const void * Normals = get: const void * - dGeomTriMeshDataBuild(*g, Vertices, VertexStride, VertexCount, Indices, IndexCount, TriStride, Normals); - return 0; -} - + dTriMeshDataID *g = luaL_checkudata(L, 1, ode_trimeshdata_tname); + luaL_checktype(L, 2, LUA_TTABLE); + luaL_checktype(L, 3, LUA_TTABLE); + const int vertex_tbl = 2; + const int index_tbl = 3; + + int VertexStride = 3*sizeof(double); + int VertexCount = lua_objlen(L, vertex_tbl)/3; + double *Vertices = malloc(3 * VertexCount * sizeof(double)); + if (Vertices == NULL) { + return luaL_error(L, "failed to allocate %lu bytes for vertex buffer", VertexCount * sizeof(double)); + } + for (int i=0; iL; + lua_rawgeti(L, LUA_REGISTRYINDEX, d->ref); + lua_pushinteger(L, x); + lua_pushinteger(L, z); + lua_call(L, 2, 1); + dReal result = lua_tonumber(L, -1); + lua_pop(L, 1); + return result; +} +int dGeomHeightfieldDataBuildCallback_bind(lua_State *L) +{ + dHeightfieldDataID *d = luaL_checkudata(L, 1, ode_heightfielddata_tname); + luaL_checktype(L, 2, LUA_TFUNCTION); + lua_pushvalue(L, 2); + int ref = luaL_ref(L, LUA_REGISTRYINDEX); + struct hf_data_t userData = { L, ref }; + dHeightfieldGetHeight * pCallback = hf_callback; + dReal width = luaL_checknumber(L, 3); + dReal depth = luaL_checknumber(L, 4); + int widthSamples = luaL_checkinteger(L, 5); + int depthSamples = luaL_checkinteger(L, 6); + dReal scale = luaL_checknumber(L, 7); + dReal offset = luaL_checknumber(L, 8); + dReal thickness = luaL_checknumber(L, 9); + int bWrap = luaL_checkinteger(L, 10); + dGeomHeightfieldDataBuildCallback(*d, &userData, pCallback, width, depth, widthSamples, depthSamples, scale, offset, thickness, bWrap); + return 0; +} + + +int dGeomHeightfieldDataSetBounds_bind(lua_State *L) +{ + dHeightfieldDataID *d = luaL_checkudata(L, 1, ode_heightfielddata_tname); + dReal min_height = luaL_checknumber(L, 2); + dReal max_height = luaL_checknumber(L, 3); + dGeomHeightfieldDataSetBounds(*d, min_height, max_height); + return 0; +} + + +int dCreateHeightfield_bind(lua_State *L) +{ + dSpaceID *space = luaL_checkudata(L, 1, ode_space_tname); + 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); return 1; -}*/ - - -//int dGeomHeightfieldDataCreate_bind(lua_State *L) -//{ -// dHeightfieldDataID bind_result = dGeomHeightfieldDataCreate(); -// /* push result */ -// return /* count */; -//} -// -// -//int dGeomHeightfieldDataDestroy_bind(lua_State *L) -//{ -// dHeightfieldDataID d = get: dHeightfieldDataID -// dGeomHeightfieldDataDestroy(d); -// return 0; -//} -// -// -//int dGeomHeightfieldDataBuildDouble_bind(lua_State *L) -//{ -// dHeightfieldDataID d = get: dHeightfieldDataID -// const double * pHeightData = get: const double * -// int bCopyHeightData = luaL_checkinteger(L, 3); -// dReal width = luaL_checknumber(L, 4); -// dReal depth = luaL_checknumber(L, 5); -// int widthSamples = luaL_checkinteger(L, 6); -// int depthSamples = luaL_checkinteger(L, 7); -// dReal scale = luaL_checknumber(L, 8); -// dReal offset = luaL_checknumber(L, 9); -// dReal thickness = luaL_checknumber(L, 10); -// int bWrap = luaL_checkinteger(L, 11); -// dGeomHeightfieldDataBuildDouble(d, pHeightData, bCopyHeightData, width, depth, widthSamples, depthSamples, scale, offset, thickness, bWrap); -// return 0; -//} -// -// -//int dGeomHeightfieldDataBuildCallback_bind(lua_State *L) -//{ -// dHeightfieldDataID d = get: dHeightfieldDataID -// void * pUserData = get: void * -// dHeightfieldGetHeight * pCallback = get: dHeightfieldGetHeight * -// dReal width = luaL_checknumber(L, 4); -// dReal depth = luaL_checknumber(L, 5); -// int widthSamples = luaL_checkinteger(L, 6); -// int depthSamples = luaL_checkinteger(L, 7); -// dReal scale = luaL_checknumber(L, 8); -// dReal offset = luaL_checknumber(L, 9); -// dReal thickness = luaL_checknumber(L, 10); -// int bWrap = luaL_checkinteger(L, 11); -// dGeomHeightfieldDataBuildCallback(d, pUserData, pCallback, width, depth, widthSamples, depthSamples, scale, offset, thickness, bWrap); -// return 0; -//} -// -// -//int dGeomHeightfieldDataSetBounds_bind(lua_State *L) -//{ -// dHeightfieldDataID d = get: dHeightfieldDataID -// dReal min_height = luaL_checknumber(L, 2); -// dReal max_height = luaL_checknumber(L, 3); -// dGeomHeightfieldDataSetBounds(d, min_height, max_height); -// return 0; -//} -// -// -//int dCreateHeightfield_bind(lua_State *L) -//{ -// dSpaceID *space = luaL_checkudata(L, 1, ode_space_tname); -// dHeightfieldDataID data = get: dHeightfieldDataID -// int bPlaceable = luaL_checkinteger(L, 3); -// dGeomID *bind_result = dCreateHeightfield(*space, data, bPlaceable); -// /* push result */ -// return /* count */; -//} -// -// -//int dGeomHeightfieldSetHeightfieldData_bind(lua_State *L) -//{ -// dGeomID *g = luaL_checkudata(L, 1, ode_geom_tname); -// dHeightfieldDataID Data = get: dHeightfieldDataID -// dGeomHeightfieldSetHeightfieldData(*g, Data); -// return 0; -//} -// -// -//int dGeomHeightfieldGetHeightfieldData_bind(lua_State *L) -//{ -// dGeomID *g = luaL_checkudata(L, 1, ode_geom_tname); -// dHeightfieldDataID bind_result = dGeomHeightfieldGetHeightfieldData(*g); -// /* push result */ -// return /* count */; -//} +} + + +int dGeomHeightfieldSetHeightfieldData_bind(lua_State *L) +{ + dGeomID *g = luaL_checkudata(L, 1, ode_geom_tname); + dHeightfieldDataID *Data = luaL_checkudata(L, 1, ode_heightfielddata_tname); + dGeomHeightfieldSetHeightfieldData(*g, *Data); + return 0; +} +int dGeomHeightfieldGetHeightfieldData_bind(lua_State *L) +{ + dGeomID *g = luaL_checkudata(L, 1, ode_geom_tname); + dHeightfieldDataID bind_result = dGeomHeightfieldGetHeightfieldData(*g); + ode_push_heightfielddata(L, bind_result); + return 1; +} diff --git a/src/ode/ode_bindings.h b/src/ode/ode_bindings.h index 2102ab2..62c7bd9 100644 --- a/src/ode/ode_bindings.h +++ b/src/ode/ode_bindings.h @@ -4,15 +4,21 @@ #include -extern const char *ode_world_tname; -extern const char *ode_space_tname; -extern const char *ode_body_tname; -extern const char *ode_geom_tname; -extern const char *ode_mass_tname; -extern const char *ode_joint_group_tname; -extern const char *ode_joint_tname; -extern const char *ode_jointgroup_tname; -extern const char *ode_contact_tname; +#define ODE_METATABLES \ + X("ode.WordID", ode_world_tname) \ + X("ode.SpaceID", ode_space_tname) \ + X("ode.BodyID", ode_body_tname) \ + X("ode.GeomID", ode_geom_tname) \ + X("ode.Mass", ode_mass_tname) \ + X("ode.JointGroupID", ode_jointgroup_tname) \ + X("ode.JointID", ode_joint_tname) \ + X("ode.Contact", ode_contact_tname) \ + X("ode.TriMeshDataID", ode_trimeshdata_tname) \ + X("ode.HeightfieldDataID", ode_heightfielddata_tname) \ + +#define X(name, mt) extern const char *mt; +ODE_METATABLES +#undef X void ode_push_world(lua_State *L, dWorldID w); @@ -384,21 +390,18 @@ void ode_push_space(lua_State *L, dSpaceID s); X("GeomRayGetLength", dGeomRayGetLength_bind) \ X("GeomRaySet", dGeomRaySet_bind) \ X("GeomRayGet", dGeomRayGet_bind) \ - X("GeomRaySetParams", dGeomRaySetParams_bind) \ - X("GeomRayGetParams", dGeomRayGetParams_bind) \ X("GeomRaySetClosestHit", dGeomRaySetClosestHit_bind) \ X("GeomRayGetClosestHit", dGeomRayGetClosestHit_bind) \ - X("CreateConvex", dCreateConvex_bind) \ - X("GeomSetConvex", dGeomSetConvex_bind) \ + X("dGeomRaySetFirstContact", dGeomRaySetFirstContact_bind) \ + X("dGeomRayGetFirstContact", dGeomRayGetFirstContact_bind) \ + X("dGeomRaySetBackfaceCull", dGeomRaySetBackfaceCull_bind) \ + X("dGeomRayGetBackfaceCull", dGeomRayGetBackfaceCull_bind) \ X("GeomTriMeshDataCreate", dGeomTriMeshDataCreate_bind) \ X("GeomTriMeshDataDestroy", dGeomTriMeshDataDestroy_bind) \ X("GeomTriMeshDataBuild", dGeomTriMeshDataBuild_bind) \ - X("GeomTriMeshDataBuildSimple", dGeomTriMeshDataBuildSimple_bind) \ X("CreateTriMesh", dCreateTriMesh_bind) \ X("GeomTriMeshSetData", dGeomTriMeshSetData_bind) \ X("GeomTriMeshClearTCCache", dGeomTriMeshClearTCCache_bind) \ - X("GeomTriMeshGetTriangle", dGeomTriMeshGetTriangle_bind) \ - X("GeomTriMeshGetPoint", dGeomTriMeshGetPoint_bind) \ X("GeomTriMeshEnableTC", dGeomTriMeshEnableTC_bind) \ X("GeomTriMeshIsTCEnabled", dGeomTriMeshIsTCEnabled_bind) \ X("GeomHeightfieldDataCreate", dGeomHeightfieldDataCreate_bind) \ diff --git a/src/ode/setup.c b/src/ode/setup.c index 36e37c1..91e452c 100644 --- a/src/ode/setup.c +++ b/src/ode/setup.c @@ -9,29 +9,17 @@ int init_ode(lua_State *L); int close_ode(lua_State *L); - -#define NEW_METATABLE(name) luaL_newmetatable(L, name); lua_pop(L, 1); -const char *ode_world_tname = "ode.WorldID"; -const char *ode_space_tname = "ode.SpaceID"; -const char *ode_body_tname = "ode.BodyID"; -const char *ode_geom_tname = "ode.GeomID"; -const char *ode_mass_tname = "ode.Mass"; -const char *ode_joint_tname = "ode.JointID"; -const char *ode_jointgroup_tname = "ode.JointGroupID"; -const char *ode_contact_tname = "ode.Contact"; +#define X(name, mt) const char *mt = name; +ODE_METATABLES +#undef X void setup_ode(lua_State *L, int honey_tbl) { /* setup metatables */ - NEW_METATABLE(ode_world_tname); - NEW_METATABLE(ode_space_tname); - NEW_METATABLE(ode_body_tname); - NEW_METATABLE(ode_geom_tname); - NEW_METATABLE(ode_mass_tname); - NEW_METATABLE(ode_joint_tname); - NEW_METATABLE(ode_jointgroup_tname); - NEW_METATABLE(ode_contact_tname); + #define X(name, mt) luaL_newmetatable(L, mt); lua_pop(L, 1); + ODE_METATABLES + #undef X /* create main table */ struct honey_tbl_t ode[] = { diff --git a/util/generate-binding.lua b/util/generate-binding.lua index 870cbb4..7fa6dbe 100644 --- a/util/generate-binding.lua +++ b/util/generate-binding.lua @@ -69,6 +69,7 @@ function GetLuaType(ctype) -- numbers if string.match(ctype, "float$") then return "number" elseif string.match(ctype, "double$") then return "number" + elseif string.match(ctype, "Real$") then return "number" -- for ode bindings c; -- integers elseif string.match(ctype, "char$") then return "integer" elseif string.match(ctype, "int$") then return "integer" @@ -87,7 +88,7 @@ function PullArg(arg, index) local pull if ltype == "unknown" then - pull = string.format("/* get: %s */", arg.type) + pull = string.format("get: %s", arg.type) else pull = string.format("luaL_check%s(L, %d);", ltype, index) end -- cgit v1.2.1