summaryrefslogtreecommitdiff
path: root/src/ode
diff options
context:
space:
mode:
authorsanine <sanine.not@pm.me>2023-02-25 15:16:44 -0600
committersanine <sanine.not@pm.me>2023-02-25 15:16:44 -0600
commit4f0e0988eb457654f70cc2e96faca22db56234f3 (patch)
treed7e85bfb0a05e7984e9ca39497adafe8f4c7b3a5 /src/ode
parent2fa0047f4600ef95d32e864dd7c54e99e27265fe (diff)
bind ode heightfield and trimesh collider functions
Diffstat (limited to 'src/ode')
-rw-r--r--src/ode/geom.c379
-rw-r--r--src/ode/ode_bindings.h35
-rw-r--r--src/ode/setup.c24
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[] = {