summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsanine <sanine.not@pm.me>2023-03-22 23:06:26 -0500
committersanine <sanine.not@pm.me>2023-03-22 23:06:26 -0500
commitdc8f29206201fcc977443ce9c6138c2f3129c1c8 (patch)
treed2acf572e965f3fdabf4fdb02ee0779ddacfb846
parent78eb15d59190c079b1edb405eeae6696724f1b2e (diff)
re-implement bouncing ball
-rw-r--r--src/ode/CMakeLists.txt1
-rw-r--r--src/ode/bind15
-rw-r--r--src/ode/body.c11
-rw-r--r--src/ode/joint.c84
-rw-r--r--src/ode/mass.c192
-rw-r--r--src/ode/ode_bindings.h42
-rw-r--r--src/ode/setup.c4
-rw-r--r--src/ode/world.c4
-rw-r--r--src/options/options.c6
-rw-r--r--src/util/util.c8
-rw-r--r--src/util/util.h2
11 files changed, 323 insertions, 46 deletions
diff --git a/src/ode/CMakeLists.txt b/src/ode/CMakeLists.txt
index f11573f..1538d1d 100644
--- a/src/ode/CMakeLists.txt
+++ b/src/ode/CMakeLists.txt
@@ -6,6 +6,7 @@ target_sources(honey PUBLIC
${CMAKE_CURRENT_LIST_DIR}/body.c
${CMAKE_CURRENT_LIST_DIR}/joint.c
${CMAKE_CURRENT_LIST_DIR}/geom.c
+ ${CMAKE_CURRENT_LIST_DIR}/mass.c
)
diff --git a/src/ode/bind b/src/ode/bind
new file mode 100644
index 0000000..1c28b65
--- /dev/null
+++ b/src/ode/bind
@@ -0,0 +1,15 @@
+void dMassSetZero (dMass *m);
+void dMassSetParameters (dMass *m, dReal themass, dReal cgx, dReal cgy, dReal cgz, dReal I11, dReal I22, dReal I33, dReal I12, dReal I13, dReal I23);
+void dMassSetSphere (dMass *m, dReal density, dReal radius);
+void dMassSetSphereTotal (dMass *m, dReal total_mass, dReal radius);
+void dMassSetCapsule (dMass *m, dReal density, int direction, dReal radius, dReal length);
+void dMassSetCapsuleTotal (dMass *m, dReal total_mass, int direction, dReal radius, dReal length);
+void dMassSetCylinder (dMass *m, dReal density, int direction, dReal radius, dReal length);
+void dMassSetCylinderTotal (dMass *m, dReal total_mass, int direction, dReal radius, dReal length);
+void dMassSetBox (dMass *m, dReal density, dReal lx, dReal ly, dReal lz);
+void dMassSetBoxTotal (dMass *m, dReal total_mass, dReal lx, dReal ly, dReal lz);
+void dMassSetTrimesh (dMass *m, dReal density, dGeomID g)
+void dMassAdjust (dMass *m, dReal newmass);
+void dMassTranslate (dMass *m, dReal x, dReal y, dReal z);
+void dMassRotate (dMass *m, const dMatrix3 R);
+void dMassAdd (dMass *ma, const dMass *mb);
diff --git a/src/ode/body.c b/src/ode/body.c
index f543b34..1284bb0 100644
--- a/src/ode/body.c
+++ b/src/ode/body.c
@@ -19,9 +19,11 @@ void ode_push_body(lua_State *L, dBodyID bb)
{
struct body_t *b = lua_newuserdata(L, sizeof(struct body_t));
b->id = bb;
- b->data.L = L;
- b->data.callback_ref = LUA_NOREF;
- dBodySetData(b->id, &(b->data));
+ if (bb != 0) {
+ b->data.L = L;
+ b->data.callback_ref = LUA_NOREF;
+ dBodySetData(b->id, &(b->data));
+ }
luaL_getmetatable(L, ode_body_tname);
lua_setmetatable(L, -2);
}
@@ -140,7 +142,8 @@ int dBodyGetQuaternion_bind(lua_State *L)
lua_pushnumber(L, bind_result[0]);
lua_pushnumber(L, bind_result[1]);
lua_pushnumber(L, bind_result[2]);
- return 3;
+ lua_pushnumber(L, bind_result[3]);
+ return 4;
}
diff --git a/src/ode/joint.c b/src/ode/joint.c
index 6fa79b4..7ff4c22 100644
--- a/src/ode/joint.c
+++ b/src/ode/joint.c
@@ -56,7 +56,7 @@ static int get_field(lua_State *L, int tbl, const char *key, int type)
{
lua_getfield(L, tbl, key);
int actual_type = lua_type(L, -1);
- if (actual_type != type) {
+ if (actual_type != type && actual_type != LUA_TNIL) {
luaL_error(L,
"field \"%s\" must have type %s but is %s instead",
key, lua_typename(L, type), lua_typename(L, actual_type)
@@ -67,49 +67,49 @@ static int get_field(lua_State *L, int tbl, const char *key, int type)
static int parse_surface_params(lua_State *L, struct dSurfaceParameters *surface, int tbl)
{
get_field(L, tbl, "mode", LUA_TNUMBER);
- surface->mode = lua_tointeger(L, -1);
+ if (!lua_isnil(L, -1)) surface->mode = lua_tointeger(L, -1);
get_field(L, tbl, "mu", LUA_TNUMBER);
- surface->mu = lua_tointeger(L, -1);
+ if (!lua_isnil(L, -1)) surface->mu = lua_tointeger(L, -1);
get_field(L, tbl, "mu2", LUA_TNUMBER);
- surface->mu2 = lua_tointeger(L, -1);
+ if (!lua_isnil(L, -1)) surface->mu2 = lua_tointeger(L, -1);
get_field(L, tbl, "rho", LUA_TNUMBER);
- surface->rho = lua_tointeger(L, -1);
+ if (!lua_isnil(L, -1)) surface->rho = lua_tointeger(L, -1);
get_field(L, tbl, "rho2", LUA_TNUMBER);
- surface->rho2 = lua_tointeger(L, -1);
+ if (!lua_isnil(L, -1)) surface->rho2 = lua_tointeger(L, -1);
get_field(L, tbl, "rhoN", LUA_TNUMBER);
- surface->rhoN = lua_tointeger(L, -1);
+ if (!lua_isnil(L, -1)) surface->rhoN = lua_tointeger(L, -1);
get_field(L, tbl, "bounce", LUA_TNUMBER);
- surface->bounce = lua_tointeger(L, -1);
+ if (!lua_isnil(L, -1)) surface->bounce = lua_tointeger(L, -1);
get_field(L, tbl, "bounce_vel", LUA_TNUMBER);
- surface->bounce_vel = lua_tointeger(L, -1);
+ if (!lua_isnil(L, -1)) surface->bounce_vel = lua_tointeger(L, -1);
get_field(L, tbl, "soft_erp", LUA_TNUMBER);
- surface->soft_erp = lua_tointeger(L, -1);
+ if (!lua_isnil(L, -1)) surface->soft_erp = lua_tointeger(L, -1);
get_field(L, tbl, "soft_cfm", LUA_TNUMBER);
- surface->soft_cfm = lua_tointeger(L, -1);
+ if (!lua_isnil(L, -1)) surface->soft_cfm = lua_tointeger(L, -1);
get_field(L, tbl, "motion1", LUA_TNUMBER);
- surface->motion1 = lua_tointeger(L, -1);
+ if (!lua_isnil(L, -1)) surface->motion1 = lua_tointeger(L, -1);
get_field(L, tbl, "motion2", LUA_TNUMBER);
- surface->motion2 = lua_tointeger(L, -1);
+ if (!lua_isnil(L, -1)) surface->motion2 = lua_tointeger(L, -1);
get_field(L, tbl, "motionN", LUA_TNUMBER);
- surface->motionN = lua_tointeger(L, -1);
+ if (!lua_isnil(L, -1)) surface->motionN = lua_tointeger(L, -1);
get_field(L, tbl, "slip1", LUA_TNUMBER);
- surface->slip1 = lua_tointeger(L, -1);
+ if (!lua_isnil(L, -1)) surface->slip1 = lua_tointeger(L, -1);
get_field(L, tbl, "slip2", LUA_TNUMBER);
- surface->slip2 = lua_tointeger(L, -1);
+ if (!lua_isnil(L, -1)) surface->slip2 = lua_tointeger(L, -1);
lua_pop(L, 15);
}
@@ -121,30 +121,50 @@ static int parse_contact_tbl(lua_State *L, dContact *contact, int tbl)
parse_surface_params(L, &(contact->surface), surface_tbl);
lua_pop(L, 1);
- get_field(L, tbl, "geom", LUA_TUSERDATA);
- dContactGeom *g = lua_touserdata(L, -1);
- contact->geom = *g;
- lua_pop(L, 1);
+ //get_field(L, tbl, "geom", LUA_TUSERDATA);
+ //dContactGeom *g = lua_touserdata(L, -1);
+ //contact->geom = *g;
+ //lua_pop(L, 1);
get_field(L, tbl, "fdir1", LUA_TTABLE);
- int fdir_tbl = lua_gettop(L);
- lua_rawgeti(L, fdir_tbl, 1);
- contact->fdir1[0] = lua_tonumber(L, -1);
- lua_rawgeti(L, fdir_tbl, 1);
- contact->fdir1[1] = lua_tonumber(L, -1);
- lua_rawgeti(L, fdir_tbl, 1);
- contact->fdir1[2] = lua_tonumber(L, -1);
- lua_pop(L, 4);
+ if (!lua_isnil(L, -1)) {
+ int fdir_tbl = lua_gettop(L);
+ lua_rawgeti(L, fdir_tbl, 1);
+ contact->fdir1[0] = lua_tonumber(L, -1);
+ lua_rawgeti(L, fdir_tbl, 1);
+ contact->fdir1[1] = lua_tonumber(L, -1);
+ lua_rawgeti(L, fdir_tbl, 1);
+ contact->fdir1[2] = lua_tonumber(L, -1);
+ lua_pop(L, 3);
+ }
+ lua_pop(L, 1);
+}
+
+
+int CreateContact_bind(lua_State *L)
+{
+ luaL_checktype(L, 1, LUA_TTABLE);
+ dContact *contact = lua_newuserdata(L, sizeof(dContact));
+ parse_contact_tbl(L, contact, 1);
+ return 1;
}
+
+int ContactSetGeom_bind(lua_State *L)
+{
+ dContact *contact = lua_touserdata(L, 1);
+ dContactGeom *geom = lua_touserdata(L, 2);
+ contact->geom = *geom;
+ return 0;
+}
+
+
int dJointCreateContact_bind(lua_State *L)
{
dWorldID *w = luaL_checkudata(L, 1, ode_world_tname);
dJointGroupID *g = luaL_checkudata(L, 2, ode_jointgroup_tname);
- luaL_checktype(L, 3, LUA_TTABLE);
- dContact contact;
- parse_contact_tbl(L, &contact, 3);
- dJointID bind_result = dJointCreateContact(*w, *g, &contact);
+ dContact *contact = lua_touserdata(L, 3);
+ dJointID bind_result = dJointCreateContact(*w, *g, contact);
ode_push_joint(L, bind_result);
return 1;
}
diff --git a/src/ode/mass.c b/src/ode/mass.c
new file mode 100644
index 0000000..fb90d65
--- /dev/null
+++ b/src/ode/mass.c
@@ -0,0 +1,192 @@
+#include <lua.h>
+#include <lauxlib.h>
+#include <ode/ode.h>
+#include "ode_bindings.h"
+
+
+int MassCreate_bind(lua_State *L)
+{
+ dMass *m = lua_newuserdata(L, sizeof(dMass));
+ luaL_getmetatable(L, ode_mass_tname);
+ lua_setmetatable(L, -2);
+ return 1;
+}
+
+
+int dMassSetZero_bind(lua_State *L)
+{
+ dMass * m = luaL_checkudata(L, 1, ode_mass_tname);
+ dMassSetZero(m);
+ return 0;
+}
+
+
+int dMassSetParameters_bind(lua_State *L)
+{
+ dMass * m = luaL_checkudata(L, 1, ode_mass_tname);
+ dReal themass = luaL_checknumber(L, 2);
+ dReal cgx = luaL_checknumber(L, 3);
+ dReal cgy = luaL_checknumber(L, 4);
+ dReal cgz = luaL_checknumber(L, 5);
+ dReal I11 = luaL_checknumber(L, 6);
+ dReal I22 = luaL_checknumber(L, 7);
+ dReal I33 = luaL_checknumber(L, 8);
+ dReal I12 = luaL_checknumber(L, 9);
+ dReal I13 = luaL_checknumber(L, 10);
+ dReal I23 = luaL_checknumber(L, 11);
+ dMassSetParameters(m, themass, cgx, cgy, cgz, I11, I22, I33, I12, I13, I23);
+ return 0;
+}
+
+
+int dMassSetSphere_bind(lua_State *L)
+{
+ dMass * m = luaL_checkudata(L, 1, ode_mass_tname);
+ dReal density = luaL_checknumber(L, 2);
+ dReal radius = luaL_checknumber(L, 3);
+ dMassSetSphere(m, density, radius);
+ return 0;
+}
+
+
+int dMassSetSphereTotal_bind(lua_State *L)
+{
+ dMass * m = luaL_checkudata(L, 1, ode_mass_tname);
+ dReal total_mass = luaL_checknumber(L, 2);
+ dReal radius = luaL_checknumber(L, 3);
+ dMassSetSphereTotal(m, total_mass, radius);
+ return 0;
+}
+
+
+int dMassSetCapsule_bind(lua_State *L)
+{
+ dMass * m = luaL_checkudata(L, 1, ode_mass_tname);
+ dReal density = luaL_checknumber(L, 2);
+ int direction = luaL_checkinteger(L, 3);
+ dReal radius = luaL_checknumber(L, 4);
+ dReal length = luaL_checknumber(L, 5);
+ dMassSetCapsule(m, density, direction, radius, length);
+ return 0;
+}
+
+
+int dMassSetCapsuleTotal_bind(lua_State *L)
+{
+ dMass * m = luaL_checkudata(L, 1, ode_mass_tname);
+ dReal total_mass = luaL_checknumber(L, 2);
+ int direction = luaL_checkinteger(L, 3);
+ dReal radius = luaL_checknumber(L, 4);
+ dReal length = luaL_checknumber(L, 5);
+ dMassSetCapsuleTotal(m, total_mass, direction, radius, length);
+ return 0;
+}
+
+
+int dMassSetCylinder_bind(lua_State *L)
+{
+ dMass * m = luaL_checkudata(L, 1, ode_mass_tname);
+ dReal density = luaL_checknumber(L, 2);
+ int direction = luaL_checkinteger(L, 3);
+ dReal radius = luaL_checknumber(L, 4);
+ dReal length = luaL_checknumber(L, 5);
+ dMassSetCylinder(m, density, direction, radius, length);
+ return 0;
+}
+
+
+int dMassSetCylinderTotal_bind(lua_State *L)
+{
+ dMass * m = luaL_checkudata(L, 1, ode_mass_tname);
+ dReal total_mass = luaL_checknumber(L, 2);
+ int direction = luaL_checkinteger(L, 3);
+ dReal radius = luaL_checknumber(L, 4);
+ dReal length = luaL_checknumber(L, 5);
+ dMassSetCylinderTotal(m, total_mass, direction, radius, length);
+ return 0;
+}
+
+
+int dMassSetBox_bind(lua_State *L)
+{
+ dMass * m = luaL_checkudata(L, 1, ode_mass_tname);
+ dReal density = luaL_checknumber(L, 2);
+ dReal lx = luaL_checknumber(L, 3);
+ dReal ly = luaL_checknumber(L, 4);
+ dReal lz = luaL_checknumber(L, 5);
+ dMassSetBox(m, density, lx, ly, lz);
+ return 0;
+}
+
+
+int dMassSetBoxTotal_bind(lua_State *L)
+{
+ dMass * m = luaL_checkudata(L, 1, ode_mass_tname);
+ dReal total_mass = luaL_checknumber(L, 2);
+ dReal lx = luaL_checknumber(L, 3);
+ dReal ly = luaL_checknumber(L, 4);
+ dReal lz = luaL_checknumber(L, 5);
+ dMassSetBoxTotal(m, total_mass, lx, ly, lz);
+ return 0;
+}
+
+
+int dMassSetTrimesh_bind(lua_State *L)
+{
+ dMass * m = luaL_checkudata(L, 1, ode_mass_tname);
+ dReal density = luaL_checknumber(L, 2);
+ dGeomID g = luaL_checkudata(L, 3, ode_geom_tname);
+ dMassSetTrimesh(m, density, g);
+ return 0;
+}
+
+
+int dMassAdjust_bind(lua_State *L)
+{
+ dMass * m = luaL_checkudata(L, 1, ode_mass_tname);
+ dReal newmass = luaL_checknumber(L, 2);
+ dMassAdjust(m, newmass);
+ return 0;
+}
+
+
+int dMassTranslate_bind(lua_State *L)
+{
+ dMass * m = luaL_checkudata(L, 1, ode_mass_tname);
+ dReal x = luaL_checknumber(L, 2);
+ dReal y = luaL_checknumber(L, 3);
+ dReal z = luaL_checknumber(L, 4);
+ dMassTranslate(m, x, y, z);
+ return 0;
+}
+
+
+int dMassRotate_bind(lua_State *L)
+{
+ dMass * m = luaL_checkudata(L, 1, ode_mass_tname);
+ dMatrix3 R;
+ R[0] = luaL_checknumber(L, 2);
+ R[1] = luaL_checknumber(L, 3);
+ R[2] = luaL_checknumber(L, 4);
+
+ R[4] = luaL_checknumber(L, 5);
+ R[5] = luaL_checknumber(L, 6);
+ R[6] = luaL_checknumber(L, 7);
+
+ R[8] = luaL_checknumber(L, 8);
+ R[9] = luaL_checknumber(L, 9);
+ R[10] = luaL_checknumber(L, 10);
+ dMassRotate(m, R);
+ return 0;
+}
+
+
+int dMassAdd_bind(lua_State *L)
+{
+ dMass * ma = luaL_checkudata(L, 1, ode_mass_tname);
+ const dMass * mb = luaL_checkudata(L, 2, ode_mass_tname);
+ dMassAdd(ma, mb);
+ return 0;
+}
+
+
diff --git a/src/ode/ode_bindings.h b/src/ode/ode_bindings.h
index 62c7bd9..3305b2a 100644
--- a/src/ode/ode_bindings.h
+++ b/src/ode/ode_bindings.h
@@ -412,12 +412,50 @@ void ode_push_space(lua_State *L, dSpaceID s);
X("CreateHeightfield", dCreateHeightfield_bind) \
X("GeomHeightfieldSetHeightfieldData", dGeomHeightfieldSetHeightfieldData_bind) \
X("GeomHeightfieldGetHeightfieldData", dGeomHeightfieldGetHeightfieldData_bind) \
-
-
+ X("CreateContact", CreateContact_bind) \
+ X("ContactSetGeom", ContactSetGeom_bind) \
+ /* mass */ \
+ X("MassCreate", MassCreate_bind) \
+ X("MassSetZero", dMassSetZero_bind) \
+ X("MassSetParameters", dMassSetParameters_bind) \
+ X("MassSetSphere", dMassSetSphere_bind) \
+ X("MassSetSphereTotal", dMassSetSphereTotal_bind) \
+ X("MassSetCapsule", dMassSetCapsule_bind) \
+ X("MassSetCapsuleTotal", dMassSetCapsuleTotal_bind) \
+ X("MassSetCylinder", dMassSetCylinder_bind) \
+ X("MassSetCylinderTotal", dMassSetCylinderTotal_bind) \
+ X("MassSetBox", dMassSetBox_bind) \
+ X("MassSetBoxTotal", dMassSetBoxTotal_bind) \
+ X("MassSetTrimesh", dMassSetTrimesh_bind) \
+ X("MassAdjust", dMassAdjust_bind) \
+ X("MassTranslate", dMassTranslate_bind) \
+ X("MassRotate", dMassRotate_bind) \
+ X("MassAdd", dMassAdd_bind) \
#define X(name, func) int func(lua_State *L);
ODE_FUNCTIONS
#undef X
+
+
+#define ODE_ENUMS \
+ /* contact modes */ \
+ X("ContactMu2", dContactMu2) \
+ X("ContactFDir1", dContactFDir1) \
+ X("ContactBounce", dContactBounce) \
+ X("ContactSoftERP", dContactSoftERP) \
+ X("ContactSoftCFM", dContactSoftCFM) \
+ X("ContactMotion1", dContactMotion1) \
+ X("ContactMotion2", dContactMotion2) \
+ X("ContactMotionN", dContactMotionN) \
+ X("ContactSlip1", dContactSlip1) \
+ X("ContactSlip2", dContactSlip2) \
+ X("ContactRolling", dContactRolling) \
+ X("ContactApprox1_1", dContactApprox1_1) \
+ X("ContactApprox1_2", dContactApprox1_2) \
+ X("ContactApprox1_N", dContactApprox1_N) \
+ X("ContactApprox1", dContactApprox1) \
+
+
#endif
diff --git a/src/ode/setup.c b/src/ode/setup.c
index 91e452c..2b5b1e3 100644
--- a/src/ode/setup.c
+++ b/src/ode/setup.c
@@ -28,6 +28,10 @@ void setup_ode(lua_State *L, int honey_tbl)
#define X(name, func) H_FUNC(name, func),
ODE_FUNCTIONS
#undef X
+ #define X(name, value) H_INT(name, value),
+ ODE_ENUMS
+ #undef X
+ H_NUM("Infinity", dInfinity),
H_END
};
create_table(L, ode);
diff --git a/src/ode/world.c b/src/ode/world.c
index 69b5a92..a38eb30 100644
--- a/src/ode/world.c
+++ b/src/ode/world.c
@@ -15,7 +15,7 @@ void ode_push_world(lua_State *L, dWorldID w)
int dWorldCreate_bind(lua_State *L)
{
- dWorldID w = lua_newuserdata(L, sizeof(dWorldID));
+ dWorldID w = dWorldCreate();
ode_push_world(L, w);
return 1;
}
@@ -206,7 +206,7 @@ int dWorldStep_bind(lua_State *L)
int dWorldQuickStep_bind(lua_State *L)
{
dWorldID *w = luaL_checkudata(L, 1, ode_world_tname);
- dReal stepsize = luaL_checkinteger(L, 2);
+ dReal stepsize = luaL_checknumber(L, 2);
dWorldQuickStep(*w, stepsize);
return 0;
}
diff --git a/src/options/options.c b/src/options/options.c
index 7ac35c7..cf2ae49 100644
--- a/src/options/options.c
+++ b/src/options/options.c
@@ -37,12 +37,6 @@ void print_help(char *program_name)
enum outcomes_t parse_options(struct honey_options *options, int argc, char **argv)
{
- /* check if we even need to parse at all */
- if (argc == 1) {
- print_help(argv[0]);
- return EXIT_SUCCESS;
- }
-
/* default values */
options->script_file = "main.lua";
diff --git a/src/util/util.c b/src/util/util.c
index 564ffd4..0e71f22 100644
--- a/src/util/util.c
+++ b/src/util/util.c
@@ -16,6 +16,14 @@ void create_table(lua_State *L, struct honey_tbl_t *tbl)
lua_pushcfunction(L, pair->value.function);
lua_setfield(L, t, pair->key);
}
+ else if (pair->type == LUA_TSTRING) {
+ lua_pushstring(L, pair->value.string);
+ lua_setfield(L, t, pair->key);
+ }
+ else if (pair->type == LUA_TNUMBER) {
+ lua_pushnumber(L, pair->value.number);
+ lua_setfield(L, t, pair->key);
+ }
else {
/* bad type, ignore */
}
diff --git a/src/util/util.h b/src/util/util.h
index 293397c..c73ba54 100644
--- a/src/util/util.h
+++ b/src/util/util.h
@@ -9,6 +9,7 @@ struct honey_tbl_t {
int type;
union {
lua_Integer integer;
+ lua_Number number;
lua_CFunction function;
const char *string;
} value;
@@ -18,6 +19,7 @@ struct honey_tbl_t {
#define H_ENUM(v) { .key=#v, .type=LUA_TNUMBER, .value.integer=v }
#define H_FUNC(k, v) { .key=k, .type=LUA_TFUNCTION, .value.function=v }
#define H_STR(k, v) { .key=k, .type=LUA_TSTRING, .value.string=v }
+#define H_NUM(k, v) { .key=k, .type=LUA_TNUMBER, .value.number=v }
#define H_END { .key=NULL, .type=LUA_TNIL, .value.integer=0 }