diff options
author | sanine <sanine.not@pm.me> | 2023-02-25 15:16:44 -0600 |
---|---|---|
committer | sanine <sanine.not@pm.me> | 2023-02-25 15:16:44 -0600 |
commit | 4f0e0988eb457654f70cc2e96faca22db56234f3 (patch) | |
tree | d7e85bfb0a05e7984e9ca39497adafe8f4c7b3a5 /src/ode | |
parent | 2fa0047f4600ef95d32e864dd7c54e99e27265fe (diff) |
bind ode heightfield and trimesh collider functions
Diffstat (limited to 'src/ode')
-rw-r--r-- | src/ode/geom.c | 379 | ||||
-rw-r--r-- | src/ode/ode_bindings.h | 35 | ||||
-rw-r--r-- | src/ode/setup.c | 24 |
3 files changed, 240 insertions, 198 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; i<VertexCount; i++) { + lua_rawgeti(L, vertex_tbl, i+1); + Vertices[i] = lua_tonumber(L, -1); + lua_pop(L, 1); + } -int dGeomTriMeshDataBuildSimple_bind(lua_State *L) -{ - dTriMeshDataID g = get: dTriMeshDataID - const dVector3 * Vertices = get: const dVector3 * - int VertexCount = luaL_checkinteger(L, 3); - const int * Indices = get: const int * - int IndexCount = luaL_checkinteger(L, 5); - dGeomTriMeshDataBuildSimple(*g, Vertices, VertexCount, Indices, IndexCount); + int IndexCount = lua_objlen(L, index_tbl)/3; + int TriStride = 3*sizeof(unsigned int); + unsigned int *Indices = malloc(3 * IndexCount * sizeof(unsigned int)); + if (Indices == NULL) { + return luaL_error(L, "failed to allocate %lu bytes for index buffer", IndexCount * sizeof(unsigned int)); + } + dGeomTriMeshDataBuildDouble(*g, Vertices, VertexStride, VertexCount, Indices, IndexCount, TriStride); return 0; } @@ -945,21 +982,21 @@ int dGeomTriMeshDataBuildSimple_bind(lua_State *L) int dCreateTriMesh_bind(lua_State *L) { dSpaceID *space = luaL_checkudata(L, 1, ode_space_tname); - dTriMeshDataID Data = get: dTriMeshDataID - dTriCallback * Callback = get: dTriCallback * - dTriArrayCallback * ArrayCallback = get: dTriArrayCallback * - dTriRayCallback * RayCallback = get: dTriRayCallback * - dGeomID *bind_result = dCreateTriMesh(*space, Data, Callback, ArrayCallback, RayCallback); - /* push result / - return /* count /; + dTriMeshDataID *Data = luaL_checkudata(L, 2, ode_trimeshdata_tname); + dTriCallback * Callback = NULL; + dTriArrayCallback * ArrayCallback = NULL; + dTriRayCallback * RayCallback = NULL; + dGeomID bind_result = dCreateTriMesh(*space, *Data, Callback, ArrayCallback, RayCallback); + ode_push_geom(L, bind_result); + return 1; } int dGeomTriMeshSetData_bind(lua_State *L) { dGeomID *g = luaL_checkudata(L, 1, ode_geom_tname); - dTriMeshDataID Data = get: dTriMeshDataID - dGeomTriMeshSetData(*g, Data); + dTriMeshDataID *Data = luaL_checkudata(L, 2, ode_trimeshdata_tname); + dGeomTriMeshSetData(*g, *Data); return 0; } @@ -972,138 +1009,152 @@ int dGeomTriMeshClearTCCache_bind(lua_State *L) } -int dGeomTriMeshGetTriangle_bind(lua_State *L) +int dGeomTriMeshEnableTC_bind(lua_State *L) { dGeomID *g = luaL_checkudata(L, 1, ode_geom_tname); - int Index = luaL_checkinteger(L, 2); - dVector3 * v0 = get: dVector3 * - dVector3 * v1 = get: dVector3 * - dVector3 * v2 = get: dVector3 * - dGeomTriMeshGetTriangle(*g, Index, v0, v1, v2); + int geomClass = luaL_checkinteger(L, 2); + int enable = luaL_checkinteger(L, 3); + dGeomTriMeshEnableTC(*g, geomClass, enable); return 0; } -int dGeomTriMeshGetPoint_bind(lua_State *L) +int dGeomTriMeshIsTCEnabled_bind(lua_State *L) { dGeomID *g = luaL_checkudata(L, 1, ode_geom_tname); - int Index = luaL_checkinteger(L, 2); - dReal u = luaL_checknumber(L, 3); - dReal v = luaL_checknumber(L, 4); - dVector3 Out = get: dVector3 - dGeomTriMeshGetPoint(*g, Index, u, v, Out); + int geomClass = luaL_checkinteger(L, 2); + int bind_result = dGeomTriMeshIsTCEnabled(*g, geomClass); + lua_pushinteger(L, bind_result); + return 1; +} + + +int dGeomHeightfieldDataCreate_bind(lua_State *L) +{ + dHeightfieldDataID bind_result = dGeomHeightfieldDataCreate(); + ode_push_heightfielddata(L, bind_result); + return 1; +} + + +int dGeomHeightfieldDataDestroy_bind(lua_State *L) +{ + dHeightfieldDataID *d = luaL_checkudata(L, 1, ode_heightfielddata_tname); + dGeomHeightfieldDataDestroy(*d); return 0; } -int dGeomTriMeshEnableTC_bind(lua_State *L) +int dGeomHeightfieldDataBuildDouble_bind(lua_State *L) { - dGeomID *g = luaL_checkudata(L, 1, ode_geom_tname); - int geomClass = luaL_checkinteger(L, 2); - int enable = luaL_checkinteger(L, 3); - dGeomTriMeshEnableTC(*g, geomClass, enable); + dHeightfieldDataID *d = luaL_checkudata(L, 1, ode_heightfielddata_tname); + luaL_checktype(L, 2, LUA_TTABLE); + int data_tbl = 2; + dReal width = luaL_checknumber(L, 3); + dReal depth = luaL_checknumber(L, 4); + int widthSamples = luaL_checkinteger(L, 5); + int depthSamples = luaL_checkinteger(L, 6); + size_t height_size = widthSamples * depthSamples * sizeof(double); + double * pHeightData = malloc(height_size); + if (pHeightData == NULL) { + return luaL_error(L, "failed to allocate %lu bytes for pHeightData buffer", height_size); + } + + /* read data_tbl into pHeightData */ + for (int y=0; y<depthSamples; y++) { + for (int x=0; x<widthSamples; x++) { + int index = x + (depthSamples * y); + lua_rawgeti(L, data_tbl, index+1); + pHeightData[index] = lua_tonumber(L, -1); + lua_pop(L, 1); + } + } + + dReal scale = luaL_checknumber(L, 7); + dReal offset = luaL_checknumber(L, 8); + dReal thickness = luaL_checknumber(L, 9); + int bWrap = luaL_checkinteger(L, 10); + dGeomHeightfieldDataBuildDouble( + *d, + pHeightData, 1, + width, depth, widthSamples, depthSamples, + scale, offset, thickness, bWrap + ); return 0; } -int dGeomTriMeshIsTCEnabled_bind(lua_State *L) +struct hf_data_t { + lua_State *L; + int ref; +}; +static dReal hf_callback(void *userdata, int x, int z) { - dGeomID *g = luaL_checkudata(L, 1, ode_geom_tname); - int geomClass = luaL_checkinteger(L, 2); - int bind_result = dGeomTriMeshIsTCEnabled(*g, geomClass); - lua_pushinteger(L, bind_result); + struct hf_data_t *d = userdata; + lua_State *L = d->L; + 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 <lua.h> -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[] = { |