mirror of https://github.com/bjornbytes/lovr.git
Compare commits
31 Commits
f4d1161a3d
...
5df8405af3
Author | SHA1 | Date |
---|---|---|
bjorn | 5df8405af3 | |
bjorn | 2952ed764d | |
bjorn | 985ba6bd13 | |
bjorn | 15649802c8 | |
Bjorn | e3b42fe24b | |
bjorn | 060e72c525 | |
bjorn | 47dec01772 | |
bjorn | 582ee1625f | |
bjorn | e36374c4cf | |
bjorn | 98601b3425 | |
bjorn | 2ac0d6946e | |
bjorn | b589cec975 | |
bjorn | 8bdab9f2d4 | |
bjorn | 5751068728 | |
bjorn | 481a9dafa2 | |
bjorn | 95cc6c2753 | |
bjorn | f35cda7db8 | |
bjorn | 907d89c913 | |
bjorn | ff0f39fc7b | |
bjorn | b809db1d83 | |
bjorn | 051266f8ea | |
bjorn | 930e713079 | |
bjorn | 4f26182595 | |
bjorn | 8cbdda00f3 | |
bjorn | 10f965d69e | |
bjorn | a7bf4ca2a4 | |
bjorn | c27694fd8e | |
bjorn | b3e9e55b8a | |
bjorn | 6f0b6391df | |
bjorn | ce58619094 | |
bjorn | 9b6f58ac1e |
|
@ -1 +1 @@
|
|||
Subproject commit 29fe07e8088279c47d7108107856ec3c826d1817
|
||||
Subproject commit 2cda386d71174bec355888539679f7a4f7be1c2a
|
|
@ -203,4 +203,5 @@ struct Shape* luax_newcapsuleshape(lua_State* L, int index);
|
|||
struct Shape* luax_newcylindershape(lua_State* L, int index);
|
||||
struct Shape* luax_newmeshshape(lua_State* L, int index);
|
||||
struct Shape* luax_newterrainshape(lua_State* L, int index);
|
||||
struct Shape* luax_newcompoundshape(lua_State* L, int index);
|
||||
#endif
|
||||
|
|
|
@ -9,6 +9,7 @@ StringEntry lovrShapeType[] = {
|
|||
[SHAPE_CYLINDER] = ENTRY("cylinder"),
|
||||
[SHAPE_MESH] = ENTRY("mesh"),
|
||||
[SHAPE_TERRAIN] = ENTRY("terrain"),
|
||||
[SHAPE_COMPOUND] = ENTRY("compound"),
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
|
@ -25,8 +26,7 @@ static int l_lovrPhysicsNewWorld(lua_State* L) {
|
|||
.maxColliders = 65536,
|
||||
.maxColliderPairs = 65536,
|
||||
.maxContacts = 16384,
|
||||
.allowSleep = true,
|
||||
.gravity = { 0.f, -9.81f, 0.f }
|
||||
.allowSleep = true
|
||||
};
|
||||
|
||||
if (lua_istable(L, 1)) {
|
||||
|
@ -63,9 +63,6 @@ static int l_lovrPhysicsNewWorld(lua_State* L) {
|
|||
}
|
||||
lua_pop(L, 1);
|
||||
} else { // Deprecated
|
||||
info.gravity[0] = luax_optfloat(L, 1, 0.f);
|
||||
info.gravity[1] = luax_optfloat(L, 2, -9.81f);
|
||||
info.gravity[2] = luax_optfloat(L, 3, 0.f);
|
||||
info.allowSleep = lua_gettop(L) < 4 || lua_toboolean(L, 4);
|
||||
if (lua_type(L, 5) == LUA_TTABLE) {
|
||||
info.tagCount = luax_len(L, 5);
|
||||
|
@ -85,6 +82,15 @@ static int l_lovrPhysicsNewWorld(lua_State* L) {
|
|||
}
|
||||
|
||||
World* world = lovrWorldCreate(&info);
|
||||
|
||||
if (!lua_istable(L, 1)) {
|
||||
float gravity[3];
|
||||
gravity[0] = luax_optfloat(L, 1, 0.f);
|
||||
gravity[1] = luax_optfloat(L, 2, -9.81f);
|
||||
gravity[2] = luax_optfloat(L, 3, 0.f);
|
||||
lovrWorldSetGravity(world, gravity);
|
||||
}
|
||||
|
||||
luax_pushtype(L, World, world);
|
||||
lovrRelease(world, lovrWorldDestroy);
|
||||
return 1;
|
||||
|
@ -178,6 +184,13 @@ static int l_lovrPhysicsNewTerrainShape(lua_State* L) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
static int l_lovrPhysicsNewCompoundShape(lua_State* L) {
|
||||
CompoundShape* shape = luax_newcompoundshape(L, 1);
|
||||
luax_pushtype(L, CompoundShape, shape);
|
||||
lovrRelease(shape, lovrShapeDestroy);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static const luaL_Reg lovrPhysics[] = {
|
||||
{ "newWorld", l_lovrPhysicsNewWorld },
|
||||
{ "newBallJoint", l_lovrPhysicsNewBallJoint },
|
||||
|
@ -190,6 +203,7 @@ static const luaL_Reg lovrPhysics[] = {
|
|||
{ "newSliderJoint", l_lovrPhysicsNewSliderJoint },
|
||||
{ "newSphereShape", l_lovrPhysicsNewSphereShape },
|
||||
{ "newTerrainShape", l_lovrPhysicsNewTerrainShape },
|
||||
{ "newCompoundShape", l_lovrPhysicsNewCompoundShape },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
|
@ -205,6 +219,7 @@ extern const luaL_Reg lovrCapsuleShape[];
|
|||
extern const luaL_Reg lovrCylinderShape[];
|
||||
extern const luaL_Reg lovrMeshShape[];
|
||||
extern const luaL_Reg lovrTerrainShape[];
|
||||
extern const luaL_Reg lovrCompoundShape[];
|
||||
|
||||
int luaopen_lovr_physics(lua_State* L) {
|
||||
lua_newtable(L);
|
||||
|
@ -221,6 +236,7 @@ int luaopen_lovr_physics(lua_State* L) {
|
|||
luax_registertype(L, CylinderShape);
|
||||
luax_registertype(L, MeshShape);
|
||||
luax_registertype(L, TerrainShape);
|
||||
luax_registertype(L, CompoundShape);
|
||||
lovrPhysicsInit();
|
||||
luax_atexit(L, lovrPhysicsDestroy);
|
||||
return 1;
|
||||
|
|
|
@ -17,6 +17,20 @@ static int l_lovrColliderIsDestroyed(lua_State* L) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
static int l_lovrColliderIsEnabled(lua_State* L) {
|
||||
Collider* collider = luax_checktype(L, 1, Collider);
|
||||
bool enabled = lovrColliderIsEnabled(collider);
|
||||
lua_pushboolean(L, enabled);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int l_lovrColliderSetEnabled(lua_State* L) {
|
||||
Collider* collider = luax_checktype(L, 1, Collider);
|
||||
bool enable = lua_toboolean(L, 2);
|
||||
lovrColliderSetEnabled(collider, enable);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int l_lovrColliderGetWorld(lua_State* L) {
|
||||
Collider* collider = luax_checktype(L, 1, Collider);
|
||||
World* world = lovrColliderGetWorld(collider);
|
||||
|
@ -24,40 +38,59 @@ static int l_lovrColliderGetWorld(lua_State* L) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
static int l_lovrColliderAddShape(lua_State* L) {
|
||||
static int l_lovrColliderGetShape(lua_State* L) {
|
||||
Collider* collider = luax_checktype(L, 1, Collider);
|
||||
Shape* shape = luax_checkshape(L, 2);
|
||||
lovrColliderAddShape(collider, shape);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int l_lovrColliderRemoveShape(lua_State* L) {
|
||||
Collider* collider = luax_checktype(L, 1, Collider);
|
||||
Shape* shape = luax_checkshape(L, 2);
|
||||
lovrColliderRemoveShape(collider, shape);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int l_lovrColliderGetShapes(lua_State* L) {
|
||||
Collider* collider = luax_checktype(L, 1, Collider);
|
||||
size_t count;
|
||||
Shape** shapes = lovrColliderGetShapes(collider, &count);
|
||||
lua_createtable(L, (int) count, 0);
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
luax_pushshape(L, shapes[i]);
|
||||
lua_rawseti(L, -2, (int) i + 1);
|
||||
uint32_t child = lua_gettop(L) == 1 ? ~0u : luax_checku32(L, 2) - 1;
|
||||
Shape* shape = lovrColliderGetShape(collider, child);
|
||||
if (shape) {
|
||||
luax_pushshape(L, shape);
|
||||
} else {
|
||||
lua_pushnil(L);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int l_lovrColliderSetShape(lua_State* L) {
|
||||
Collider* collider = luax_checktype(L, 1, Collider);
|
||||
Shape* shape = lua_isnoneornil(L, 2) ? NULL : luax_checkshape(L, 2);
|
||||
lovrColliderSetShape(collider, shape);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int l_lovrColliderGetShapeOffset(lua_State* L) {
|
||||
Collider* collider = luax_checktype(L, 1, Collider);
|
||||
float position[3], orientation[4], angle, ax, ay, az;
|
||||
lovrColliderGetShapeOffset(collider, position, orientation);
|
||||
quat_getAngleAxis(orientation, &angle, &ax, &ay, &az);
|
||||
lua_pushnumber(L, position[0]);
|
||||
lua_pushnumber(L, position[1]);
|
||||
lua_pushnumber(L, position[2]);
|
||||
lua_pushnumber(L, angle);
|
||||
lua_pushnumber(L, ax);
|
||||
lua_pushnumber(L, ay);
|
||||
lua_pushnumber(L, az);
|
||||
return 7;
|
||||
}
|
||||
|
||||
static int l_lovrColliderSetShapeOffset(lua_State* L) {
|
||||
Collider* collider = luax_checktype(L, 1, Collider);
|
||||
int index = 2;
|
||||
float position[3], orientation[4];
|
||||
index = luax_readvec3(L, index, position, NULL);
|
||||
index = luax_readquat(L, index, orientation, NULL);
|
||||
lovrColliderSetShapeOffset(collider, position, orientation);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int l_lovrColliderGetJoints(lua_State* L) {
|
||||
Collider* collider = luax_checktype(L, 1, Collider);
|
||||
size_t count;
|
||||
Joint** joints = lovrColliderGetJoints(collider, &count);
|
||||
lua_createtable(L, (int) count, 0);
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
luax_pushjoint(L, joints[i]);
|
||||
lua_rawseti(L, -2, (int) i + 1);
|
||||
lua_newtable(L);
|
||||
int index = 1;
|
||||
void* private;
|
||||
Joint* joint = NULL;
|
||||
while ((joint = lovrColliderEnumerateJoints(collider, joint, &private)) != NULL) {
|
||||
luax_pushjoint(L, joint);
|
||||
lua_rawseti(L, -2, index++);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
@ -110,6 +143,19 @@ static int l_lovrColliderSetKinematic(lua_State* L) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int l_lovrColliderIsSensor(lua_State* L) {
|
||||
Collider* collider = luax_checktype(L, 1, Collider);
|
||||
lua_pushboolean(L, lovrColliderIsSensor(collider));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int l_lovrColliderSetSensor(lua_State* L) {
|
||||
Collider* collider = luax_checktype(L, 1, Collider);
|
||||
bool sensor = lua_toboolean(L, 2);
|
||||
lovrColliderSetSensor(collider, sensor);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int l_lovrColliderIsContinuous(lua_State* L) {
|
||||
Collider* collider = luax_checktype(L, 1, Collider);
|
||||
bool continuous = lovrColliderIsContinuous(collider);
|
||||
|
@ -179,12 +225,11 @@ static int l_lovrColliderSetMass(lua_State* L) {
|
|||
|
||||
static int l_lovrColliderGetMassData(lua_State* L) {
|
||||
Collider* collider = luax_checktype(L, 1, Collider);
|
||||
float cx, cy, cz, mass;
|
||||
float inertia[6];
|
||||
lovrColliderGetMassData(collider, &cx, &cy, &cz, &mass, inertia);
|
||||
lua_pushnumber(L, cx);
|
||||
lua_pushnumber(L, cy);
|
||||
lua_pushnumber(L, cz);
|
||||
float centerOfMass[3], mass, inertia[6];
|
||||
lovrColliderGetMassData(collider, centerOfMass, &mass, inertia);
|
||||
lua_pushnumber(L, centerOfMass[0]);
|
||||
lua_pushnumber(L, centerOfMass[1]);
|
||||
lua_pushnumber(L, centerOfMass[2]);
|
||||
lua_pushnumber(L, mass);
|
||||
lua_newtable(L);
|
||||
for (int i = 0; i < 6; i++) {
|
||||
|
@ -196,14 +241,13 @@ static int l_lovrColliderGetMassData(lua_State* L) {
|
|||
|
||||
static int l_lovrColliderSetMassData(lua_State* L) {
|
||||
Collider* collider = luax_checktype(L, 1, Collider);
|
||||
float cx = luax_checkfloat(L, 2);
|
||||
float cy = luax_checkfloat(L, 3);
|
||||
float cz = luax_checkfloat(L, 4);
|
||||
float mass = luax_checkfloat(L, 5);
|
||||
float centerOfMass[3];
|
||||
int index = luax_readvec3(L, 2, centerOfMass, NULL);
|
||||
float mass = luax_checkfloat(L, index++);
|
||||
float inertia[6];
|
||||
if (lua_istable(L, 6) && luax_len(L, 6) >= 6) {
|
||||
if (lua_istable(L, index) && luax_len(L, index) >= 6) {
|
||||
for (int i = 0; i < 6; i++) {
|
||||
lua_rawgeti(L, 6, i + 1);
|
||||
lua_rawgeti(L, index, i + 1);
|
||||
if (!lua_isnumber(L, -1)) {
|
||||
return luaL_argerror(L, 6, "Expected 6 numbers or a table with 6 numbers");
|
||||
}
|
||||
|
@ -212,25 +256,25 @@ static int l_lovrColliderSetMassData(lua_State* L) {
|
|||
lua_pop(L, 1);
|
||||
}
|
||||
} else {
|
||||
for (int i = 6; i < 12; i++) {
|
||||
for (int i = index; i < index + 6; i++) {
|
||||
if (lua_isnumber(L, i)) {
|
||||
inertia[i - 6] = lua_tonumber(L, i);
|
||||
inertia[i - index] = lua_tonumber(L, i);
|
||||
} else {
|
||||
return luaL_argerror(L, i, "Expected 6 numbers or a table with 6 numbers");
|
||||
}
|
||||
}
|
||||
}
|
||||
lovrColliderSetMassData(collider, cx, cy, cz, mass, inertia);
|
||||
lovrColliderSetMassData(collider, centerOfMass, mass, inertia);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int l_lovrColliderGetPosition(lua_State* L) {
|
||||
Collider* collider = luax_checktype(L, 1, Collider);
|
||||
float x, y, z;
|
||||
lovrColliderGetPosition(collider, &x, &y, &z);
|
||||
lua_pushnumber(L, x);
|
||||
lua_pushnumber(L, y);
|
||||
lua_pushnumber(L, z);
|
||||
float position[3];
|
||||
lovrColliderGetPosition(collider, position);
|
||||
lua_pushnumber(L, position[0]);
|
||||
lua_pushnumber(L, position[1]);
|
||||
lua_pushnumber(L, position[2]);
|
||||
return 3;
|
||||
}
|
||||
|
||||
|
@ -238,13 +282,13 @@ static int l_lovrColliderSetPosition(lua_State* L) {
|
|||
Collider* collider = luax_checktype(L, 1, Collider);
|
||||
float position[3];
|
||||
luax_readvec3(L, 2, position, NULL);
|
||||
lovrColliderSetPosition(collider, position[0], position[1], position[2]);
|
||||
lovrColliderSetPosition(collider, position);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int l_lovrColliderGetOrientation(lua_State* L) {
|
||||
Collider* collider = luax_checktype(L, 1, Collider);
|
||||
float angle, x, y, z, orientation[4];
|
||||
float orientation[4], angle, x, y, z;
|
||||
lovrColliderGetOrientation(collider, orientation);
|
||||
quat_getAngleAxis(orientation, &angle, &x, &y, &z);
|
||||
lua_pushnumber(L, angle);
|
||||
|
@ -264,13 +308,13 @@ static int l_lovrColliderSetOrientation(lua_State* L) {
|
|||
|
||||
static int l_lovrColliderGetPose(lua_State* L) {
|
||||
Collider* collider = luax_checktype(L, 1, Collider);
|
||||
float x, y, z, angle, ax, ay, az, orientation[4];
|
||||
lovrColliderGetPosition(collider, &x, &y, &z);
|
||||
float position[3], orientation[4], angle, ax, ay, az;
|
||||
lovrColliderGetPosition(collider, position);
|
||||
lovrColliderGetOrientation(collider, orientation);
|
||||
quat_getAngleAxis(orientation, &angle, &ax, &ay, &az);
|
||||
lua_pushnumber(L, x);
|
||||
lua_pushnumber(L, y);
|
||||
lua_pushnumber(L, z);
|
||||
lua_pushnumber(L, position[0]);
|
||||
lua_pushnumber(L, position[1]);
|
||||
lua_pushnumber(L, position[2]);
|
||||
lua_pushnumber(L, angle);
|
||||
lua_pushnumber(L, ax);
|
||||
lua_pushnumber(L, ay);
|
||||
|
@ -283,18 +327,18 @@ static int l_lovrColliderSetPose(lua_State* L) {
|
|||
float position[3], orientation[4];
|
||||
int index = luax_readvec3(L, 2, position, NULL);
|
||||
luax_readquat(L, index, orientation, NULL);
|
||||
lovrColliderSetPosition(collider, position[0], position[1], position[2]);
|
||||
lovrColliderSetPosition(collider, position);
|
||||
lovrColliderSetOrientation(collider, orientation);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int l_lovrColliderGetLinearVelocity(lua_State* L) {
|
||||
Collider* collider = luax_checktype(L, 1, Collider);
|
||||
float x, y, z;
|
||||
lovrColliderGetLinearVelocity(collider, &x, &y, &z);
|
||||
lua_pushnumber(L, x);
|
||||
lua_pushnumber(L, y);
|
||||
lua_pushnumber(L, z);
|
||||
float velocity[3];
|
||||
lovrColliderGetLinearVelocity(collider, velocity);
|
||||
lua_pushnumber(L, velocity[0]);
|
||||
lua_pushnumber(L, velocity[1]);
|
||||
lua_pushnumber(L, velocity[2]);
|
||||
return 3;
|
||||
}
|
||||
|
||||
|
@ -302,17 +346,17 @@ static int l_lovrColliderSetLinearVelocity(lua_State* L) {
|
|||
Collider* collider = luax_checktype(L, 1, Collider);
|
||||
float velocity[3];
|
||||
luax_readvec3(L, 2, velocity, NULL);
|
||||
lovrColliderSetLinearVelocity(collider, velocity[0], velocity[1], velocity[2]);
|
||||
lovrColliderSetLinearVelocity(collider, velocity);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int l_lovrColliderGetAngularVelocity(lua_State* L) {
|
||||
Collider* collider = luax_checktype(L, 1, Collider);
|
||||
float x, y, z;
|
||||
lovrColliderGetAngularVelocity(collider, &x, &y, &z);
|
||||
lua_pushnumber(L, x);
|
||||
lua_pushnumber(L, y);
|
||||
lua_pushnumber(L, z);
|
||||
float velocity[3];
|
||||
lovrColliderGetAngularVelocity(collider, velocity);
|
||||
lua_pushnumber(L, velocity[0]);
|
||||
lua_pushnumber(L, velocity[1]);
|
||||
lua_pushnumber(L, velocity[2]);
|
||||
return 3;
|
||||
}
|
||||
|
||||
|
@ -320,7 +364,7 @@ static int l_lovrColliderSetAngularVelocity(lua_State* L) {
|
|||
Collider* collider = luax_checktype(L, 1, Collider);
|
||||
float velocity[3];
|
||||
luax_readvec3(L, 2, velocity, NULL);
|
||||
lovrColliderSetAngularVelocity(collider, velocity[0], velocity[1], velocity[2]);
|
||||
lovrColliderSetAngularVelocity(collider, velocity);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -366,10 +410,9 @@ static int l_lovrColliderApplyForce(lua_State* L) {
|
|||
if (lua_gettop(L) >= index) {
|
||||
float position[3];
|
||||
luax_readvec3(L, index, position, NULL);
|
||||
lovrColliderApplyForceAtPosition(collider, force[0], force[1], force[2],
|
||||
position[0], position[1], position[2]);
|
||||
lovrColliderApplyForceAtPosition(collider, force, position);
|
||||
} else {
|
||||
lovrColliderApplyForce(collider, force[0], force[1], force[2]);
|
||||
lovrColliderApplyForce(collider, force);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -377,9 +420,9 @@ static int l_lovrColliderApplyForce(lua_State* L) {
|
|||
|
||||
static int l_lovrColliderApplyTorque(lua_State* L) {
|
||||
Collider* collider = luax_checktype(L, 1, Collider);
|
||||
float force[3];
|
||||
luax_readvec3(L, 2, force, NULL);
|
||||
lovrColliderApplyTorque(collider, force[0], force[1], force[2]);
|
||||
float torque[3];
|
||||
luax_readvec3(L, 2, torque, NULL);
|
||||
lovrColliderApplyTorque(collider, torque);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -407,83 +450,77 @@ static int l_lovrColliderApplyAngularImpulse(lua_State* L) {
|
|||
|
||||
static int l_lovrColliderGetLocalCenter(lua_State* L) {
|
||||
Collider* collider = luax_checktype(L, 1, Collider);
|
||||
float x, y, z;
|
||||
lovrColliderGetLocalCenter(collider, &x, &y, &z);
|
||||
lua_pushnumber(L, x);
|
||||
lua_pushnumber(L, y);
|
||||
lua_pushnumber(L, z);
|
||||
float center[3];
|
||||
lovrColliderGetLocalCenter(collider, center);
|
||||
lua_pushnumber(L, center[0]);
|
||||
lua_pushnumber(L, center[1]);
|
||||
lua_pushnumber(L, center[2]);
|
||||
return 3;
|
||||
}
|
||||
|
||||
static int l_lovrColliderGetLocalPoint(lua_State* L) {
|
||||
Collider* collider = luax_checktype(L, 1, Collider);
|
||||
float world[3];
|
||||
float world[3], local[3];
|
||||
luax_readvec3(L, 2, world, NULL);
|
||||
float x, y, z;
|
||||
lovrColliderGetLocalPoint(collider, world[0], world[1], world[2], &x, &y, &z);
|
||||
lua_pushnumber(L, x);
|
||||
lua_pushnumber(L, y);
|
||||
lua_pushnumber(L, z);
|
||||
lovrColliderGetLocalPoint(collider, world, local);
|
||||
lua_pushnumber(L, local[0]);
|
||||
lua_pushnumber(L, local[1]);
|
||||
lua_pushnumber(L, local[2]);
|
||||
return 3;
|
||||
}
|
||||
|
||||
static int l_lovrColliderGetWorldPoint(lua_State* L) {
|
||||
Collider* collider = luax_checktype(L, 1, Collider);
|
||||
float local[3];
|
||||
float local[3], world[3];
|
||||
luax_readvec3(L, 2, local, NULL);
|
||||
float wx, wy, wz;
|
||||
lovrColliderGetWorldPoint(collider, local[0], local[1], local[2], &wx, &wy, &wz);
|
||||
lua_pushnumber(L, wx);
|
||||
lua_pushnumber(L, wy);
|
||||
lua_pushnumber(L, wz);
|
||||
lovrColliderGetWorldPoint(collider, local, world);
|
||||
lua_pushnumber(L, world[0]);
|
||||
lua_pushnumber(L, world[1]);
|
||||
lua_pushnumber(L, world[2]);
|
||||
return 3;
|
||||
}
|
||||
|
||||
static int l_lovrColliderGetLocalVector(lua_State* L) {
|
||||
Collider* collider = luax_checktype(L, 1, Collider);
|
||||
float world[3];
|
||||
float world[3], local[3];
|
||||
luax_readvec3(L, 2, world, NULL);
|
||||
float x, y, z;
|
||||
lovrColliderGetLocalVector(collider, world[0], world[1], world[2], &x, &y, &z);
|
||||
lua_pushnumber(L, x);
|
||||
lua_pushnumber(L, y);
|
||||
lua_pushnumber(L, z);
|
||||
lovrColliderGetLocalVector(collider, world, local);
|
||||
lua_pushnumber(L, local[0]);
|
||||
lua_pushnumber(L, local[1]);
|
||||
lua_pushnumber(L, local[2]);
|
||||
return 3;
|
||||
}
|
||||
|
||||
static int l_lovrColliderGetWorldVector(lua_State* L) {
|
||||
Collider* collider = luax_checktype(L, 1, Collider);
|
||||
float local[3];
|
||||
float local[3], world[3];
|
||||
luax_readvec3(L, 2, local, NULL);
|
||||
float wx, wy, wz;
|
||||
lovrColliderGetWorldVector(collider, local[0], local[1], local[2], &wx, &wy, &wz);
|
||||
lua_pushnumber(L, wx);
|
||||
lua_pushnumber(L, wy);
|
||||
lua_pushnumber(L, wz);
|
||||
lovrColliderGetWorldVector(collider, local, world);
|
||||
lua_pushnumber(L, world[0]);
|
||||
lua_pushnumber(L, world[1]);
|
||||
lua_pushnumber(L, world[2]);
|
||||
return 3;
|
||||
}
|
||||
|
||||
static int l_lovrColliderGetLinearVelocityFromLocalPoint(lua_State* L) {
|
||||
Collider* collider = luax_checktype(L, 1, Collider);
|
||||
float local[3];
|
||||
luax_readvec3(L, 2, local, NULL);
|
||||
float vx, vy, vz;
|
||||
lovrColliderGetLinearVelocityFromLocalPoint(collider, local[0], local[1], local[2], &vx, &vy, &vz);
|
||||
lua_pushnumber(L, vx);
|
||||
lua_pushnumber(L, vy);
|
||||
lua_pushnumber(L, vz);
|
||||
float point[3], velocity[3];
|
||||
luax_readvec3(L, 2, point, NULL);
|
||||
lovrColliderGetLinearVelocityFromLocalPoint(collider, point, velocity);
|
||||
lua_pushnumber(L, velocity[0]);
|
||||
lua_pushnumber(L, velocity[1]);
|
||||
lua_pushnumber(L, velocity[2]);
|
||||
return 3;
|
||||
}
|
||||
|
||||
static int l_lovrColliderGetLinearVelocityFromWorldPoint(lua_State* L) {
|
||||
Collider* collider = luax_checktype(L, 1, Collider);
|
||||
float world[3];
|
||||
luax_readvec3(L, 2, world, NULL);
|
||||
float vx, vy, vz;
|
||||
lovrColliderGetLinearVelocityFromWorldPoint(collider, world[0], world[1], world[2], &vx, &vy, &vz);
|
||||
lua_pushnumber(L, vx);
|
||||
lua_pushnumber(L, vy);
|
||||
lua_pushnumber(L, vz);
|
||||
float point[3], velocity[3];
|
||||
luax_readvec3(L, 2, point, NULL);
|
||||
lovrColliderGetLinearVelocityFromWorldPoint(collider, point, velocity);
|
||||
lua_pushnumber(L, velocity[0]);
|
||||
lua_pushnumber(L, velocity[1]);
|
||||
lua_pushnumber(L, velocity[2]);
|
||||
return 3;
|
||||
}
|
||||
|
||||
|
@ -544,6 +581,16 @@ static int l_lovrColliderSetTag(lua_State* L) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
// Deprecated
|
||||
static int l_lovrColliderGetShapes(lua_State* L) {
|
||||
Collider* collider = luax_checktype(L, 1, Collider);
|
||||
Shape* shape = lovrColliderGetShape(collider, ~0u);
|
||||
lua_createtable(L, 1, 0);
|
||||
luax_pushshape(L, shape);
|
||||
lua_rawseti(L, -2, 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Deprecated
|
||||
static int l_lovrColliderIsGravityIgnored(lua_State* L) {
|
||||
Collider* collider = luax_checktype(L, 1, Collider);
|
||||
|
@ -562,15 +609,20 @@ static int l_lovrColliderSetGravityIgnored(lua_State* L) {
|
|||
const luaL_Reg lovrCollider[] = {
|
||||
{ "destroy", l_lovrColliderDestroy },
|
||||
{ "isDestroyed", l_lovrColliderIsDestroyed },
|
||||
{ "isEnabled", l_lovrColliderIsEnabled },
|
||||
{ "setEnabled", l_lovrColliderSetEnabled },
|
||||
{ "getWorld", l_lovrColliderGetWorld },
|
||||
{ "addShape", l_lovrColliderAddShape },
|
||||
{ "removeShape", l_lovrColliderRemoveShape },
|
||||
{ "getShapes", l_lovrColliderGetShapes },
|
||||
{ "getShape", l_lovrColliderGetShape },
|
||||
{ "setShape", l_lovrColliderSetShape },
|
||||
{ "getShapeOffset", l_lovrColliderGetShapeOffset },
|
||||
{ "setShapeOffset", l_lovrColliderSetShapeOffset },
|
||||
{ "getJoints", l_lovrColliderGetJoints },
|
||||
{ "getUserData", l_lovrColliderGetUserData },
|
||||
{ "setUserData", l_lovrColliderSetUserData },
|
||||
{ "isKinematic", l_lovrColliderIsKinematic },
|
||||
{ "setKinematic", l_lovrColliderSetKinematic },
|
||||
{ "isSensor", l_lovrColliderIsSensor },
|
||||
{ "setSensor", l_lovrColliderSetSensor },
|
||||
{ "isContinuous", l_lovrColliderIsContinuous },
|
||||
{ "setContinuous", l_lovrColliderSetContinuous },
|
||||
{ "getGravityScale", l_lovrColliderGetGravityScale },
|
||||
|
@ -617,6 +669,7 @@ const luaL_Reg lovrCollider[] = {
|
|||
{ "setTag", l_lovrColliderSetTag },
|
||||
|
||||
// Deprecated
|
||||
{ "getShapes", l_lovrColliderGetShapes },
|
||||
{ "isGravityIgnored", l_lovrColliderIsGravityIgnored },
|
||||
{ "setGravityIgnored", l_lovrColliderSetGravityIgnored },
|
||||
|
||||
|
|
|
@ -41,6 +41,13 @@ static int l_lovrJointDestroy(lua_State* L) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int l_lovrJointIsDestroyed(lua_State* L) {
|
||||
Joint* joint = luax_checkjoint(L, 1);
|
||||
bool destroyed = lovrJointIsDestroyed(joint);
|
||||
lua_pushboolean(L, destroyed);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int l_lovrJointGetType(lua_State* L) {
|
||||
Joint* joint = luax_checkjoint(L, 1);
|
||||
luax_pushenum(L, JointType, lovrJointGetType(joint));
|
||||
|
@ -107,6 +114,7 @@ static int l_lovrJointSetEnabled(lua_State* L) {
|
|||
|
||||
#define lovrJoint \
|
||||
{ "destroy", l_lovrJointDestroy }, \
|
||||
{ "isDestroyed", l_lovrJointIsDestroyed }, \
|
||||
{ "getType", l_lovrJointGetType }, \
|
||||
{ "getColliders", l_lovrJointGetColliders }, \
|
||||
{ "getUserData", l_lovrJointGetUserData }, \
|
||||
|
|
|
@ -14,6 +14,7 @@ void luax_pushshape(lua_State* L, Shape* shape) {
|
|||
case SHAPE_CYLINDER: luax_pushtype(L, CylinderShape, shape); break;
|
||||
case SHAPE_MESH: luax_pushtype(L, MeshShape, shape); break;
|
||||
case SHAPE_TERRAIN: luax_pushtype(L, TerrainShape, shape); break;
|
||||
case SHAPE_COMPOUND: luax_pushtype(L, CompoundShape, shape); break;
|
||||
default: lovrUnreachable();
|
||||
}
|
||||
}
|
||||
|
@ -28,7 +29,8 @@ Shape* luax_checkshape(lua_State* L, int index) {
|
|||
hash64("CapsuleShape", strlen("CapsuleShape")),
|
||||
hash64("CylinderShape", strlen("CylinderShape")),
|
||||
hash64("MeshShape", strlen("MeshShape")),
|
||||
hash64("TerrainShape", strlen("TerrainShape"))
|
||||
hash64("TerrainShape", strlen("TerrainShape")),
|
||||
hash64("CompoundShape", strlen("CompoundShape"))
|
||||
};
|
||||
|
||||
for (size_t i = 0; i < COUNTOF(hashes); i++) {
|
||||
|
@ -50,7 +52,7 @@ Shape* luax_newsphereshape(lua_State* L, int index) {
|
|||
Shape* luax_newboxshape(lua_State* L, int index) {
|
||||
float size[3];
|
||||
luax_readscale(L, index, size, 3, NULL);
|
||||
return lovrBoxShapeCreate(size[0], size[1], size[2]);
|
||||
return lovrBoxShapeCreate(size);
|
||||
}
|
||||
|
||||
Shape* luax_newcapsuleshape(lua_State* L, int index) {
|
||||
|
@ -135,6 +137,85 @@ Shape* luax_newterrainshape(lua_State* L, int index) {
|
|||
}
|
||||
}
|
||||
|
||||
Shape* luax_newcompoundshape(lua_State* L, int index) {
|
||||
if (lua_isnoneornil(L, index)) {
|
||||
return lovrCompoundShapeCreate(NULL, NULL, NULL, 0, false);
|
||||
}
|
||||
|
||||
luaL_checktype(L, index, LUA_TTABLE);
|
||||
int length = luax_len(L, index);
|
||||
|
||||
uint32_t defer = lovrDeferPush();
|
||||
Shape** shapes = lovrMalloc(length * sizeof(Shape*));
|
||||
float* positions = lovrMalloc(length * 3 * sizeof(float));
|
||||
float* orientations = lovrMalloc(length * 4 * sizeof(float));
|
||||
lovrDefer(lovrFree, shapes);
|
||||
lovrDefer(lovrFree, positions);
|
||||
lovrDefer(lovrFree, orientations);
|
||||
|
||||
for (int i = 0; i < length; i++) {
|
||||
lua_rawgeti(L, index, i + 1);
|
||||
lovrCheck(lua_istable(L, -1), "Expected table of tables for compound shape");
|
||||
|
||||
lua_rawgeti(L, -1, 1);
|
||||
shapes[i] = luax_checkshape(L, -1);
|
||||
lua_pop(L, 1);
|
||||
|
||||
int index = 2;
|
||||
lua_rawgeti(L, -1, index);
|
||||
switch (lua_type(L, -1)) {
|
||||
case LUA_TNIL:
|
||||
vec3_set(&positions[3 * i], 0.f, 0.f, 0.f);
|
||||
lua_pop(L, 1);
|
||||
break;
|
||||
case LUA_TNUMBER:
|
||||
lua_rawgeti(L, -2, index + 1);
|
||||
lua_rawgeti(L, -3, index + 2);
|
||||
vec3_set(&positions[3 * i], luax_tofloat(L, -3), luax_tofloat(L, -2), luax_tofloat(L, -1));
|
||||
lua_pop(L, 3);
|
||||
index += 3;
|
||||
break;
|
||||
default: {
|
||||
float* v = luax_checkvector(L, -1, V_VEC3, "nil, number, or vec3");
|
||||
vec3_init(&positions[3 * i], v);
|
||||
lua_pop(L, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
lua_rawgeti(L, -1, index);
|
||||
switch (lua_type(L, -1)) {
|
||||
case LUA_TNIL:
|
||||
quat_identity(&orientations[4 * i]);
|
||||
lua_pop(L, 1);
|
||||
break;
|
||||
case LUA_TNUMBER:
|
||||
lua_rawgeti(L, -2, index);
|
||||
lua_rawgeti(L, -3, index);
|
||||
lua_rawgeti(L, -4, index);
|
||||
quat_set(&orientations[4 * i], luax_tofloat(L, -4), luax_tofloat(L, -3), luax_tofloat(L, -2), luax_tofloat(L, -1));
|
||||
lua_pop(L, 4);
|
||||
break;
|
||||
default: {
|
||||
float* q = luax_checkvector(L, -1, V_QUAT, "nil, number, or quat");
|
||||
quat_init(&positions[4 * i], q);
|
||||
lua_pop(L, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
|
||||
lua_getfield(L, index, "freeze");
|
||||
bool freeze = lua_toboolean(L, -1);
|
||||
lua_pop(L, 1);
|
||||
|
||||
CompoundShape* shape = lovrCompoundShapeCreate(shapes, positions, orientations, length, freeze);
|
||||
lovrDeferPop(defer);
|
||||
return shape;
|
||||
}
|
||||
|
||||
static int l_lovrShapeDestroy(lua_State* L) {
|
||||
Shape* shape = luax_checkshape(L, 1);
|
||||
lovrShapeDestroyData(shape);
|
||||
|
@ -147,38 +228,6 @@ static int l_lovrShapeGetType(lua_State* L) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
static int l_lovrShapeGetCollider(lua_State* L) {
|
||||
Shape* shape = luax_checkshape(L, 1);
|
||||
luax_pushtype(L, Collider, lovrShapeGetCollider(shape));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int l_lovrShapeIsEnabled(lua_State* L) {
|
||||
Shape* shape = luax_checkshape(L, 1);
|
||||
lua_pushboolean(L, lovrShapeIsEnabled(shape));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int l_lovrShapeSetEnabled(lua_State* L) {
|
||||
Shape* shape = luax_checkshape(L, 1);
|
||||
bool enabled = lua_toboolean(L, 2);
|
||||
lovrShapeSetEnabled(shape, enabled);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int l_lovrShapeIsSensor(lua_State* L) {
|
||||
Shape* shape = luax_checkshape(L, 1);
|
||||
lua_pushboolean(L, lovrShapeIsSensor(shape));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int l_lovrShapeSetSensor(lua_State* L) {
|
||||
Shape* shape = luax_checkshape(L, 1);
|
||||
bool sensor = lua_toboolean(L, 2);
|
||||
lovrShapeSetSensor(shape, sensor);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void luax_pushshapestash(lua_State* L) {
|
||||
lua_getfield(L, LUA_REGISTRYINDEX, "_lovrshapestash");
|
||||
|
||||
|
@ -214,83 +263,14 @@ static int l_lovrShapeSetUserData(lua_State* L) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int l_lovrShapeGetPosition(lua_State* L) {
|
||||
Shape* shape = luax_checkshape(L, 1);
|
||||
float x, y, z;
|
||||
lovrShapeGetPosition(shape, &x, &y, &z);
|
||||
lua_pushnumber(L, x);
|
||||
lua_pushnumber(L, y);
|
||||
lua_pushnumber(L, z);
|
||||
return 3;
|
||||
}
|
||||
|
||||
static int l_lovrShapeSetPosition(lua_State* L) {
|
||||
Shape* shape = luax_checkshape(L, 1);
|
||||
lovrCheck(lovrShapeGetCollider(shape) != NULL, "Shape must be attached to collider");
|
||||
float position[3];
|
||||
luax_readvec3(L, 2, position, NULL);
|
||||
lovrShapeSetPosition(shape, position[0], position[1], position[2]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int l_lovrShapeGetOrientation(lua_State* L) {
|
||||
Shape* shape = luax_checkshape(L, 1);
|
||||
float angle, x, y, z, orientation[4];
|
||||
lovrShapeGetOrientation(shape, orientation);
|
||||
quat_getAngleAxis(orientation, &angle, &x, &y, &z);
|
||||
lua_pushnumber(L, angle);
|
||||
lua_pushnumber(L, x);
|
||||
lua_pushnumber(L, y);
|
||||
lua_pushnumber(L, z);
|
||||
return 4;
|
||||
}
|
||||
|
||||
static int l_lovrShapeSetOrientation(lua_State* L) {
|
||||
Shape* shape = luax_checkshape(L, 1);
|
||||
lovrCheck(lovrShapeGetCollider(shape) != NULL, "Shape must be attached to collider");
|
||||
float orientation[4];
|
||||
luax_readquat(L, 2, orientation, NULL);
|
||||
lovrShapeSetOrientation(shape, orientation);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int l_lovrShapeGetPose(lua_State* L) {
|
||||
Shape* shape = luax_checkshape(L, 1);
|
||||
float x, y, z;
|
||||
lovrShapeGetPosition(shape, &x, &y, &z);
|
||||
float angle, ax, ay, az, orientation[4];
|
||||
lovrShapeGetOrientation(shape, orientation);
|
||||
quat_getAngleAxis(orientation, &angle, &ax, &ay, &az);
|
||||
lua_pushnumber(L, x);
|
||||
lua_pushnumber(L, y);
|
||||
lua_pushnumber(L, z);
|
||||
lua_pushnumber(L, angle);
|
||||
lua_pushnumber(L, ax);
|
||||
lua_pushnumber(L, ay);
|
||||
lua_pushnumber(L, az);
|
||||
return 7;
|
||||
}
|
||||
|
||||
static int l_lovrShapeSetPose(lua_State* L) {
|
||||
Shape* shape = luax_checkshape(L, 1);
|
||||
lovrCheck(lovrShapeGetCollider(shape) != NULL, "Shape must be attached to collider");
|
||||
float position[3], orientation[4];
|
||||
int index = luax_readvec3(L, 2, position, NULL);
|
||||
luax_readquat(L, index, orientation, NULL);
|
||||
lovrShapeSetPosition(shape, position[0], position[1], position[2]);
|
||||
lovrShapeSetOrientation(shape, orientation);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int l_lovrShapeGetMass(lua_State* L) {
|
||||
Shape* shape = luax_checkshape(L, 1);
|
||||
float density = luax_checkfloat(L, 2);
|
||||
float cx, cy, cz, mass;
|
||||
float inertia[6];
|
||||
lovrShapeGetMass(shape, density, &cx, &cy, &cz, &mass, inertia);
|
||||
lua_pushnumber(L, cx);
|
||||
lua_pushnumber(L, cy);
|
||||
lua_pushnumber(L, cz);
|
||||
float centerOfMass[3], mass, inertia[6];
|
||||
lovrShapeGetMass(shape, density, centerOfMass, &mass, inertia);
|
||||
lua_pushnumber(L, centerOfMass[0]);
|
||||
lua_pushnumber(L, centerOfMass[1]);
|
||||
lua_pushnumber(L, centerOfMass[2]);
|
||||
lua_pushnumber(L, mass);
|
||||
lua_newtable(L);
|
||||
for (int i = 0; i < 6; i++) {
|
||||
|
@ -302,8 +282,15 @@ static int l_lovrShapeGetMass(lua_State* L) {
|
|||
|
||||
static int l_lovrShapeGetAABB(lua_State* L) {
|
||||
Shape* shape = luax_checkshape(L, 1);
|
||||
float aabb[6];
|
||||
lovrShapeGetAABB(shape, aabb);
|
||||
float position[3], orientation[4], aabb[6];
|
||||
if (lua_gettop(L) >= 2) {
|
||||
int index = 2;
|
||||
index = luax_readvec3(L, index, position, NULL);
|
||||
index = luax_readquat(L, index, orientation, NULL);
|
||||
lovrShapeGetAABB(shape, position, orientation, aabb);
|
||||
} else {
|
||||
lovrShapeGetAABB(shape, NULL, NULL, aabb);
|
||||
}
|
||||
for (int i = 0; i < 6; i++) {
|
||||
lua_pushnumber(L, aabb[i]);
|
||||
}
|
||||
|
@ -313,19 +300,8 @@ static int l_lovrShapeGetAABB(lua_State* L) {
|
|||
#define lovrShape \
|
||||
{ "destroy", l_lovrShapeDestroy }, \
|
||||
{ "getType", l_lovrShapeGetType }, \
|
||||
{ "getCollider", l_lovrShapeGetCollider }, \
|
||||
{ "isEnabled", l_lovrShapeIsEnabled }, \
|
||||
{ "setEnabled", l_lovrShapeSetEnabled }, \
|
||||
{ "isSensor", l_lovrShapeIsSensor }, \
|
||||
{ "setSensor", l_lovrShapeSetSensor }, \
|
||||
{ "getUserData", l_lovrShapeGetUserData }, \
|
||||
{ "setUserData", l_lovrShapeSetUserData }, \
|
||||
{ "getPosition", l_lovrShapeGetPosition }, \
|
||||
{ "setPosition", l_lovrShapeSetPosition }, \
|
||||
{ "getOrientation", l_lovrShapeGetOrientation }, \
|
||||
{ "setOrientation", l_lovrShapeSetOrientation }, \
|
||||
{ "getPose", l_lovrShapeGetPose }, \
|
||||
{ "setPose", l_lovrShapeSetPose }, \
|
||||
{ "getMass", l_lovrShapeGetMass }, \
|
||||
{ "getAABB", l_lovrShapeGetAABB }
|
||||
|
||||
|
@ -335,42 +311,25 @@ static int l_lovrSphereShapeGetRadius(lua_State* L) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
static int l_lovrSphereShapeSetRadius(lua_State* L) {
|
||||
SphereShape* sphere = luax_checktype(L, 1, SphereShape);
|
||||
float radius = luax_checkfloat(L, 2);
|
||||
lovrSphereShapeSetRadius(sphere, radius);
|
||||
return 0;
|
||||
}
|
||||
|
||||
const luaL_Reg lovrSphereShape[] = {
|
||||
lovrShape,
|
||||
{ "getRadius", l_lovrSphereShapeGetRadius },
|
||||
{ "setRadius", l_lovrSphereShapeSetRadius },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
static int l_lovrBoxShapeGetDimensions(lua_State* L) {
|
||||
BoxShape* box = luax_checktype(L, 1, BoxShape);
|
||||
float w, h, d;
|
||||
lovrBoxShapeGetDimensions(box, &w, &h, &d);
|
||||
lua_pushnumber(L, w);
|
||||
lua_pushnumber(L, h);
|
||||
lua_pushnumber(L, d);
|
||||
float dimensions[3];
|
||||
lovrBoxShapeGetDimensions(box, dimensions);
|
||||
lua_pushnumber(L, dimensions[0]);
|
||||
lua_pushnumber(L, dimensions[1]);
|
||||
lua_pushnumber(L, dimensions[2]);
|
||||
return 3;
|
||||
}
|
||||
|
||||
static int l_lovrBoxShapeSetDimensions(lua_State* L) {
|
||||
BoxShape* box = luax_checktype(L, 1, BoxShape);
|
||||
float size[3];
|
||||
luax_readscale(L, 2, size, 3, NULL);
|
||||
lovrBoxShapeSetDimensions(box, size[0], size[1], size[2]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
const luaL_Reg lovrBoxShape[] = {
|
||||
lovrShape,
|
||||
{ "getDimensions", l_lovrBoxShapeGetDimensions },
|
||||
{ "setDimensions", l_lovrBoxShapeSetDimensions },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
|
@ -380,32 +339,16 @@ static int l_lovrCapsuleShapeGetRadius(lua_State* L) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
static int l_lovrCapsuleShapeSetRadius(lua_State* L) {
|
||||
CapsuleShape* capsule = luax_checktype(L, 1, CapsuleShape);
|
||||
float radius = luax_checkfloat(L, 2);
|
||||
lovrCapsuleShapeSetRadius(capsule, radius);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int l_lovrCapsuleShapeGetLength(lua_State* L) {
|
||||
CapsuleShape* capsule = luax_checktype(L, 1, CapsuleShape);
|
||||
lua_pushnumber(L, lovrCapsuleShapeGetLength(capsule));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int l_lovrCapsuleShapeSetLength(lua_State* L) {
|
||||
CapsuleShape* capsule = luax_checktype(L, 1, CapsuleShape);
|
||||
float length = luax_checkfloat(L, 2);
|
||||
lovrCapsuleShapeSetLength(capsule, length);
|
||||
return 0;
|
||||
}
|
||||
|
||||
const luaL_Reg lovrCapsuleShape[] = {
|
||||
lovrShape,
|
||||
{ "getRadius", l_lovrCapsuleShapeGetRadius },
|
||||
{ "setRadius", l_lovrCapsuleShapeSetRadius },
|
||||
{ "getLength", l_lovrCapsuleShapeGetLength },
|
||||
{ "setLength", l_lovrCapsuleShapeSetLength },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
|
@ -415,32 +358,16 @@ static int l_lovrCylinderShapeGetRadius(lua_State* L) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
static int l_lovrCylinderShapeSetRadius(lua_State* L) {
|
||||
CylinderShape* cylinder = luax_checktype(L, 1, CylinderShape);
|
||||
float radius = luax_checkfloat(L, 2);
|
||||
lovrCylinderShapeSetRadius(cylinder, radius);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int l_lovrCylinderShapeGetLength(lua_State* L) {
|
||||
CylinderShape* cylinder = luax_checktype(L, 1, CylinderShape);
|
||||
lua_pushnumber(L, lovrCylinderShapeGetLength(cylinder));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int l_lovrCylinderShapeSetLength(lua_State* L) {
|
||||
CylinderShape* cylinder = luax_checktype(L, 1, CylinderShape);
|
||||
float length = luax_checkfloat(L, 2);
|
||||
lovrCylinderShapeSetLength(cylinder, length);
|
||||
return 0;
|
||||
}
|
||||
|
||||
const luaL_Reg lovrCylinderShape[] = {
|
||||
lovrShape,
|
||||
{ "getRadius", l_lovrCylinderShapeGetRadius },
|
||||
{ "setRadius", l_lovrCylinderShapeSetRadius },
|
||||
{ "getLength", l_lovrCylinderShapeGetLength },
|
||||
{ "setLength", l_lovrCylinderShapeSetLength },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
|
@ -453,3 +380,109 @@ const luaL_Reg lovrTerrainShape[] = {
|
|||
lovrShape,
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
static int l_lovrCompoundShapeIsFrozen(lua_State* L) {
|
||||
CompoundShape* shape = luax_checktype(L, 1, CompoundShape);
|
||||
bool frozen = lovrCompoundShapeIsFrozen(shape);
|
||||
lua_pushboolean(L, frozen);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int l_lovrCompoundShapeAddChild(lua_State* L) {
|
||||
CompoundShape* shape = luax_checktype(L, 1, CompoundShape);
|
||||
Shape* child = luax_checkshape(L, 2);
|
||||
float position[3], orientation[4];
|
||||
int index = 3;
|
||||
index = luax_readvec3(L, index, position, NULL);
|
||||
index = luax_readquat(L, index, orientation, NULL);
|
||||
lovrCompoundShapeAddChild(shape, child, position, orientation);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int l_lovrCompoundShapeReplaceChild(lua_State* L) {
|
||||
CompoundShape* shape = luax_checktype(L, 1, CompoundShape);
|
||||
uint32_t index = luax_checku32(L, 2) - 1;
|
||||
Shape* child = luax_checkshape(L, 3);
|
||||
float position[3], orientation[4];
|
||||
int i = 4;
|
||||
i = luax_readvec3(L, i, position, NULL);
|
||||
i = luax_readquat(L, i, orientation, NULL);
|
||||
lovrCompoundShapeReplaceChild(shape, index, child, position, orientation);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int l_lovrCompoundShapeRemoveChild(lua_State* L) {
|
||||
CompoundShape* shape = luax_checktype(L, 1, CompoundShape);
|
||||
uint32_t index = luax_checku32(L, 2) - 1;
|
||||
lovrCompoundShapeRemoveChild(shape, index);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int l_lovrCompoundShapeGetChild(lua_State* L) {
|
||||
CompoundShape* shape = luax_checktype(L, 1, CompoundShape);
|
||||
uint32_t index = luax_checku32(L, 2) - 1;
|
||||
Shape* child = lovrCompoundShapeGetChild(shape, index);
|
||||
luax_pushshape(L, child);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int l_lovrCompoundShapeGetChildren(lua_State* L) {
|
||||
CompoundShape* shape = luax_checktype(L, 1, CompoundShape);
|
||||
int count = (int) lovrCompoundShapeGetChildCount(shape);
|
||||
lua_createtable(L, count, 0);
|
||||
for (int i = 0; i < count; i++) {
|
||||
Shape* child = lovrCompoundShapeGetChild(shape, (uint32_t) i);
|
||||
luax_pushshape(L, child);
|
||||
lua_rawseti(L, -2, i + 1);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int l_lovrCompoundShapeGetChildCount(lua_State* L) {
|
||||
CompoundShape* shape = luax_checktype(L, 1, CompoundShape);
|
||||
uint32_t count = lovrCompoundShapeGetChildCount(shape);
|
||||
lua_pushinteger(L, count);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int l_lovrCompoundShapeGetChildOffset(lua_State* L) {
|
||||
CompoundShape* shape = luax_checktype(L, 1, CompoundShape);
|
||||
uint32_t index = luax_checku32(L, 2) - 1;
|
||||
float position[3], orientation[4], angle, ax, ay, az;
|
||||
lovrCompoundShapeGetChildOffset(shape, index, position, orientation);
|
||||
quat_getAngleAxis(orientation, &angle, &ax, &ay, &az);
|
||||
lua_pushnumber(L, position[0]);
|
||||
lua_pushnumber(L, position[1]);
|
||||
lua_pushnumber(L, position[2]);
|
||||
lua_pushnumber(L, angle);
|
||||
lua_pushnumber(L, ax);
|
||||
lua_pushnumber(L, ay);
|
||||
lua_pushnumber(L, az);
|
||||
return 7;
|
||||
}
|
||||
|
||||
static int l_lovrCompoundShapeSetChildOffset(lua_State* L) {
|
||||
CompoundShape* shape = luax_checktype(L, 1, CompoundShape);
|
||||
uint32_t index = luax_checku32(L, 2) - 1;
|
||||
float position[3], orientation[4];
|
||||
int i = 3;
|
||||
i = luax_readvec3(L, i, position, NULL);
|
||||
i = luax_readquat(L, i, orientation, NULL);
|
||||
lovrCompoundShapeSetChildOffset(shape, index, position, orientation);
|
||||
return 0;
|
||||
}
|
||||
|
||||
const luaL_Reg lovrCompoundShape[] = {
|
||||
lovrShape,
|
||||
{ "isFrozen", l_lovrCompoundShapeIsFrozen },
|
||||
{ "addChild", l_lovrCompoundShapeAddChild },
|
||||
{ "replaceChild", l_lovrCompoundShapeReplaceChild },
|
||||
{ "removeChild", l_lovrCompoundShapeRemoveChild },
|
||||
{ "getChild", l_lovrCompoundShapeGetChild },
|
||||
{ "getChildren", l_lovrCompoundShapeGetChildren },
|
||||
{ "getChildCount", l_lovrCompoundShapeGetChildCount },
|
||||
{ "getChildOffset", l_lovrCompoundShapeGetChildOffset },
|
||||
{ "setChildOffset", l_lovrCompoundShapeSetChildOffset },
|
||||
{ "__len", l_lovrCompoundShapeGetChildCount }, // :)
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
|
|
@ -27,17 +27,18 @@ static int nextOverlap(lua_State* L) {
|
|||
}
|
||||
}
|
||||
|
||||
static bool raycastCallback(Shape* shape, float x, float y, float z, float nx, float ny, float nz, void* userdata) {
|
||||
static bool raycastCallback(Collider* collider, float position[3], float normal[3], uint32_t shape, void* userdata) {
|
||||
lua_State* L = userdata;
|
||||
lua_pushvalue(L, -1);
|
||||
luax_pushshape(L, shape);
|
||||
lua_pushnumber(L, x);
|
||||
lua_pushnumber(L, y);
|
||||
lua_pushnumber(L, z);
|
||||
lua_pushnumber(L, nx);
|
||||
lua_pushnumber(L, ny);
|
||||
lua_pushnumber(L, nz);
|
||||
lua_call(L, 7, 1);
|
||||
luax_pushtype(L, Collider, collider);
|
||||
lua_pushnumber(L, position[0]);
|
||||
lua_pushnumber(L, position[1]);
|
||||
lua_pushnumber(L, position[2]);
|
||||
lua_pushnumber(L, normal[0]);
|
||||
lua_pushnumber(L, normal[1]);
|
||||
lua_pushnumber(L, normal[2]);
|
||||
lua_pushinteger(L, shape + 1);
|
||||
lua_call(L, 8, 1);
|
||||
bool shouldStop = lua_type(L, -1) == LUA_TBOOLEAN && !lua_toboolean(L, -1);
|
||||
lua_pop(L, 1);
|
||||
return shouldStop;
|
||||
|
@ -45,53 +46,55 @@ static bool raycastCallback(Shape* shape, float x, float y, float z, float nx, f
|
|||
|
||||
typedef struct {
|
||||
const char* tag;
|
||||
Shape* shape;
|
||||
Collider* collider;
|
||||
uint32_t shape;
|
||||
float distance;
|
||||
float origin[3];
|
||||
float position[3];
|
||||
float normal[3];
|
||||
} RaycastData;
|
||||
|
||||
static bool raycastAnyCallback(Shape* shape, float x, float y, float z, float nx, float ny, float nz, void* userdata) {
|
||||
static bool raycastAnyCallback(Collider* collider, float position[3], float normal[3], uint32_t shape, void* userdata) {
|
||||
RaycastData* data = userdata;
|
||||
if (data->tag) {
|
||||
const char* tag = lovrColliderGetTag(lovrShapeGetCollider(shape));
|
||||
const char* tag = lovrColliderGetTag(collider);
|
||||
if (!tag || strcmp(tag, data->tag)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
data->collider = collider;
|
||||
data->shape = shape;
|
||||
vec3_set(data->position, x, y, z);
|
||||
vec3_set(data->normal, nx, ny, nz);
|
||||
vec3_init(data->position, position);
|
||||
vec3_init(data->normal, normal);
|
||||
data->distance = vec3_distance(data->origin, data->position);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool raycastClosestCallback(Shape* shape, float x, float y, float z, float nx, float ny, float nz, void* userdata) {
|
||||
static bool raycastClosestCallback(Collider* collider, float position[3], float normal[3], uint32_t shape, void* userdata) {
|
||||
RaycastData* data = userdata;
|
||||
if (data->tag) {
|
||||
const char* tag = lovrColliderGetTag(lovrShapeGetCollider(shape));
|
||||
const char* tag = lovrColliderGetTag(collider);
|
||||
if (!tag || strcmp(tag, data->tag)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
float position[3];
|
||||
vec3_set(position, x, y, z);
|
||||
float distance = vec3_distance(data->origin, position);
|
||||
if (distance < data->distance) {
|
||||
vec3_init(data->position, position);
|
||||
vec3_set(data->normal, nx, ny, nz);
|
||||
vec3_init(data->normal, normal);
|
||||
data->distance = distance;
|
||||
data->collider = collider;
|
||||
data->shape = shape;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool queryCallback(Shape* shape, void* userdata) {
|
||||
static bool queryCallback(Collider* collider, uint32_t shape, void* userdata) {
|
||||
lua_State* L = userdata;
|
||||
lua_pushvalue(L, -1);
|
||||
luax_pushshape(L, shape);
|
||||
lua_call(L, 1, 1);
|
||||
luax_pushtype(L, Collider, collider);
|
||||
lua_pushinteger(L, shape + 1);
|
||||
lua_call(L, 2, 1);
|
||||
bool shouldStop = lua_type(L, -1) == LUA_TBOOLEAN && !lua_toboolean(L, -1);
|
||||
lua_pop(L, 1);
|
||||
return shouldStop;
|
||||
|
@ -99,9 +102,10 @@ static bool queryCallback(Shape* shape, void* userdata) {
|
|||
|
||||
static int l_lovrWorldNewCollider(lua_State* L) {
|
||||
World* world = luax_checktype(L, 1, World);
|
||||
Shape* shape = luax_totype(L, 2, Shape);
|
||||
float position[3];
|
||||
luax_readvec3(L, 2, position, NULL);
|
||||
Collider* collider = lovrColliderCreate(world, position[0], position[1], position[2]);
|
||||
luax_readvec3(L, 2 + !!shape, position, NULL);
|
||||
Collider* collider = lovrColliderCreate(world, shape, position);
|
||||
luax_pushtype(L, Collider, collider);
|
||||
lovrRelease(collider, lovrColliderDestroy);
|
||||
return 1;
|
||||
|
@ -111,9 +115,8 @@ static int l_lovrWorldNewBoxCollider(lua_State* L) {
|
|||
World* world = luax_checktype(L, 1, World);
|
||||
float position[3];
|
||||
int index = luax_readvec3(L, 2, position, NULL);
|
||||
Collider* collider = lovrColliderCreate(world, position[0], position[1], position[2]);
|
||||
BoxShape* shape = luax_newboxshape(L, index);
|
||||
lovrColliderAddShape(collider, shape);
|
||||
Collider* collider = lovrColliderCreate(world, shape, position);
|
||||
lovrColliderInitInertia(collider, shape);
|
||||
luax_pushtype(L, Collider, collider);
|
||||
lovrRelease(collider, lovrColliderDestroy);
|
||||
|
@ -125,9 +128,8 @@ static int l_lovrWorldNewCapsuleCollider(lua_State* L) {
|
|||
World* world = luax_checktype(L, 1, World);
|
||||
float position[3];
|
||||
int index = luax_readvec3(L, 2, position, NULL);
|
||||
Collider* collider = lovrColliderCreate(world, position[0], position[1], position[2]);
|
||||
CapsuleShape* shape = luax_newcapsuleshape(L, index);
|
||||
lovrColliderAddShape(collider, shape);
|
||||
Collider* collider = lovrColliderCreate(world, shape, position);
|
||||
lovrColliderInitInertia(collider, shape);
|
||||
luax_pushtype(L, Collider, collider);
|
||||
lovrRelease(collider, lovrColliderDestroy);
|
||||
|
@ -139,9 +141,8 @@ static int l_lovrWorldNewCylinderCollider(lua_State* L) {
|
|||
World* world = luax_checktype(L, 1, World);
|
||||
float position[3];
|
||||
int index = luax_readvec3(L, 2, position, NULL);
|
||||
Collider* collider = lovrColliderCreate(world, position[0], position[1], position[2]);
|
||||
CylinderShape* shape = luax_newcylindershape(L, index);
|
||||
lovrColliderAddShape(collider, shape);
|
||||
Collider* collider = lovrColliderCreate(world, shape, position);
|
||||
lovrColliderInitInertia(collider, shape);
|
||||
luax_pushtype(L, Collider, collider);
|
||||
lovrRelease(collider, lovrColliderDestroy);
|
||||
|
@ -153,9 +154,8 @@ static int l_lovrWorldNewSphereCollider(lua_State* L) {
|
|||
World* world = luax_checktype(L, 1, World);
|
||||
float position[3];
|
||||
int index = luax_readvec3(L, 2, position, NULL);
|
||||
Collider* collider = lovrColliderCreate(world, position[0], position[1], position[2]);
|
||||
SphereShape* shape = luax_newsphereshape(L, index);
|
||||
lovrColliderAddShape(collider, shape);
|
||||
Collider* collider = lovrColliderCreate(world, shape, position);
|
||||
lovrColliderInitInertia(collider, shape);
|
||||
luax_pushtype(L, Collider, collider);
|
||||
lovrRelease(collider, lovrColliderDestroy);
|
||||
|
@ -165,9 +165,9 @@ static int l_lovrWorldNewSphereCollider(lua_State* L) {
|
|||
|
||||
static int l_lovrWorldNewMeshCollider(lua_State* L) {
|
||||
World* world = luax_checktype(L, 1, World);
|
||||
Collider* collider = lovrColliderCreate(world, 0.f, 0.f, 0.f);
|
||||
MeshShape* shape = luax_newmeshshape(L, 2);
|
||||
lovrColliderAddShape(collider, shape);
|
||||
float position[3] = { 0.f, 0.f, 0.f };
|
||||
Collider* collider = lovrColliderCreate(world, shape, position);
|
||||
lovrColliderInitInertia(collider, shape);
|
||||
luax_pushtype(L, Collider, collider);
|
||||
lovrRelease(collider, lovrColliderDestroy);
|
||||
|
@ -177,9 +177,9 @@ static int l_lovrWorldNewMeshCollider(lua_State* L) {
|
|||
|
||||
static int l_lovrWorldNewTerrainCollider(lua_State* L) {
|
||||
World* world = luax_checktype(L, 1, World);
|
||||
Collider* collider = lovrColliderCreate(world, 0.f, 0.f, 0.f);
|
||||
TerrainShape* shape = luax_newterrainshape(L, 2);
|
||||
lovrColliderAddShape(collider, shape);
|
||||
float position[3] = { 0.f, 0.f, 0.f };
|
||||
Collider* collider = lovrColliderCreate(world, shape, position);
|
||||
lovrColliderSetKinematic(collider, true);
|
||||
luax_pushtype(L, Collider, collider);
|
||||
lovrRelease(collider, lovrColliderDestroy);
|
||||
|
@ -187,25 +187,10 @@ static int l_lovrWorldNewTerrainCollider(lua_State* L) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
static int l_lovrWorldGetColliders(lua_State* L) {
|
||||
static int l_lovrWorldDestroy(lua_State* L) {
|
||||
World* world = luax_checktype(L, 1, World);
|
||||
|
||||
if (lua_istable(L, 2)) {
|
||||
lua_settop(L, 2);
|
||||
} else {
|
||||
lua_newtable(L);
|
||||
}
|
||||
|
||||
Collider* collider = lovrWorldGetFirstCollider(world);
|
||||
int index = 1;
|
||||
|
||||
while (collider) {
|
||||
luax_pushtype(L, Collider, collider);
|
||||
lua_rawseti(L, -2, index++);
|
||||
collider = lovrColliderGetNext(collider);
|
||||
}
|
||||
|
||||
return 1;
|
||||
lovrWorldDestroyData(world);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int l_lovrWorldGetTags(lua_State* L) {
|
||||
|
@ -221,10 +206,42 @@ static int l_lovrWorldGetTags(lua_State* L) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
static int l_lovrWorldDestroy(lua_State* L) {
|
||||
static int l_lovrWorldGetColliders(lua_State* L) {
|
||||
World* world = luax_checktype(L, 1, World);
|
||||
lovrWorldDestroyData(world);
|
||||
return 0;
|
||||
lua_createtable(L, (int) lovrWorldGetColliderCount(world), 0);
|
||||
Collider* collider = NULL;
|
||||
int index = 1;
|
||||
while ((collider = lovrWorldEnumerateColliders(world, collider)) != NULL) {
|
||||
luax_pushtype(L, Collider, collider);
|
||||
lua_rawseti(L, -2, index++);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int l_lovrWorldGetColliderCount(lua_State* L) {
|
||||
World* world = luax_checktype(L, 1, World);
|
||||
uint32_t count = lovrWorldGetColliderCount(world);
|
||||
lua_pushinteger(L, count);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int l_lovrWorldGetJoints(lua_State* L) {
|
||||
World* world = luax_checktype(L, 1, World);
|
||||
lua_createtable(L, (int) lovrWorldGetJointCount(world), 0);
|
||||
Joint* joint = NULL;
|
||||
int index = 1;
|
||||
while ((joint = lovrWorldEnumerateJoints(world, joint)) != NULL) {
|
||||
luax_pushjoint(L, joint);
|
||||
lua_rawseti(L, -2, index++);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int l_lovrWorldGetJointCount(lua_State* L) {
|
||||
World* world = luax_checktype(L, 1, World);
|
||||
uint32_t count = lovrWorldGetJointCount(world);
|
||||
lua_pushinteger(L, count);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int l_lovrWorldUpdate(lua_State* L) {
|
||||
|
@ -296,7 +313,7 @@ static int l_lovrWorldRaycast(lua_State* L) {
|
|||
index = luax_readvec3(L, index, end, NULL);
|
||||
luaL_checktype(L, index, LUA_TFUNCTION);
|
||||
lua_settop(L, index);
|
||||
lovrWorldRaycast(world, start[0], start[1], start[2], end[0], end[1], end[2], raycastCallback, L);
|
||||
lovrWorldRaycast(world, start, end, raycastCallback, L);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -308,16 +325,17 @@ static int l_lovrWorldRaycastAny(lua_State* L) {
|
|||
index = luax_readvec3(L, index, end, NULL);
|
||||
RaycastData data = { 0 };
|
||||
data.tag = lua_tostring(L, index);
|
||||
lovrWorldRaycast(world, start[0], start[1], start[2], end[0], end[1], end[2], raycastAnyCallback, &data);
|
||||
if (data.shape) {
|
||||
luax_pushshape(L, data.shape);
|
||||
lovrWorldRaycast(world, start, end, raycastAnyCallback, &data);
|
||||
if (data.collider) {
|
||||
luax_pushtype(L, Collider, data.collider);
|
||||
lua_pushnumber(L, data.position[0]);
|
||||
lua_pushnumber(L, data.position[1]);
|
||||
lua_pushnumber(L, data.position[2]);
|
||||
lua_pushnumber(L, data.normal[0]);
|
||||
lua_pushnumber(L, data.normal[1]);
|
||||
lua_pushnumber(L, data.normal[2]);
|
||||
return 7;
|
||||
lua_pushinteger(L, data.shape + 1);
|
||||
return 8;
|
||||
} else {
|
||||
lua_pushnil(L);
|
||||
return 1;
|
||||
|
@ -332,16 +350,17 @@ static int l_lovrWorldRaycastClosest(lua_State* L) {
|
|||
index = luax_readvec3(L, index, end, NULL);
|
||||
RaycastData data = { .distance = FLT_MAX };
|
||||
data.tag = lua_tostring(L, index);
|
||||
lovrWorldRaycast(world, start[0], start[1], start[2], end[0], end[1], end[2], raycastClosestCallback, &data);
|
||||
lovrWorldRaycast(world, start, end, raycastClosestCallback, &data);
|
||||
if (data.shape) {
|
||||
luax_pushshape(L, data.shape);
|
||||
luax_pushtype(L, Collider, data.collider);
|
||||
lua_pushnumber(L, data.position[0]);
|
||||
lua_pushnumber(L, data.position[1]);
|
||||
lua_pushnumber(L, data.position[2]);
|
||||
lua_pushnumber(L, data.normal[0]);
|
||||
lua_pushnumber(L, data.normal[1]);
|
||||
lua_pushnumber(L, data.normal[2]);
|
||||
return 7;
|
||||
lua_pushinteger(L, data.shape + 1);
|
||||
return 8;
|
||||
} else {
|
||||
lua_pushnil(L);
|
||||
return 1;
|
||||
|
@ -514,9 +533,12 @@ const luaL_Reg lovrWorld[] = {
|
|||
{ "newSphereCollider", l_lovrWorldNewSphereCollider },
|
||||
{ "newMeshCollider", l_lovrWorldNewMeshCollider },
|
||||
{ "newTerrainCollider", l_lovrWorldNewTerrainCollider },
|
||||
{ "getColliders", l_lovrWorldGetColliders },
|
||||
{ "getTags", l_lovrWorldGetTags },
|
||||
{ "destroy", l_lovrWorldDestroy },
|
||||
{ "getTags", l_lovrWorldGetTags },
|
||||
{ "getColliderCount", l_lovrWorldGetColliderCount },
|
||||
{ "getJointCount", l_lovrWorldGetJointCount },
|
||||
{ "getColliders", l_lovrWorldGetColliders },
|
||||
{ "getJoints", l_lovrWorldGetJoints },
|
||||
{ "update", l_lovrWorldUpdate },
|
||||
{ "computeOverlaps", l_lovrWorldComputeOverlaps },
|
||||
{ "overlaps", l_lovrWorldOverlaps },
|
||||
|
|
|
@ -19,6 +19,7 @@ typedef Shape CapsuleShape;
|
|||
typedef Shape CylinderShape;
|
||||
typedef Shape MeshShape;
|
||||
typedef Shape TerrainShape;
|
||||
typedef Shape CompoundShape;
|
||||
|
||||
typedef Joint BallJoint;
|
||||
typedef Joint DistanceJoint;
|
||||
|
@ -26,8 +27,8 @@ typedef Joint HingeJoint;
|
|||
typedef Joint SliderJoint;
|
||||
|
||||
typedef void (*CollisionResolver)(World* world, void* userdata);
|
||||
typedef bool (*RaycastCallback)(Shape* shape, float x, float y, float z, float nx, float ny, float nz, void* userdata);
|
||||
typedef bool (*QueryCallback)(Shape* shape, void* userdata);
|
||||
typedef bool (*RaycastCallback)(Collider* collider, float position[3], float normal[3], uint32_t child, void* userdata);
|
||||
typedef bool (*QueryCallback)(Collider* collider, uint32_t child, void* userdata);
|
||||
|
||||
bool lovrPhysicsInit(void);
|
||||
void lovrPhysicsDestroy(void);
|
||||
|
@ -47,21 +48,23 @@ typedef struct {
|
|||
bool allowSleep;
|
||||
const char* tags[MAX_TAGS];
|
||||
uint32_t tagCount;
|
||||
float gravity[3]; // Deprecated
|
||||
} WorldInfo;
|
||||
|
||||
World* lovrWorldCreate(WorldInfo* info);
|
||||
void lovrWorldDestroy(void* ref);
|
||||
void lovrWorldDestroyData(World* world);
|
||||
uint32_t lovrWorldGetColliderCount(World* world);
|
||||
uint32_t lovrWorldGetJointCount(World* world);
|
||||
Collider* lovrWorldEnumerateColliders(World* world, Collider* collider);
|
||||
Joint* lovrWorldEnumerateJoints(World* world, Joint* joint);
|
||||
void lovrWorldUpdate(World* world, float dt, CollisionResolver resolver, void* userdata);
|
||||
void lovrWorldComputeOverlaps(World* world);
|
||||
int lovrWorldGetNextOverlap(World* world, Shape** a, Shape** b);
|
||||
int lovrWorldCollide(World* world, Shape* a, Shape* b, float friction, float restitution);
|
||||
void lovrWorldGetContacts(World* world, Shape* a, Shape* b, Contact contacts[MAX_CONTACTS], uint32_t* count);
|
||||
void lovrWorldRaycast(World* world, float x1, float y1, float z1, float x2, float y2, float z2, RaycastCallback callback, void* userdata);
|
||||
void lovrWorldRaycast(World* world, float start[3], float end[3], RaycastCallback callback, void* userdata);
|
||||
bool lovrWorldQueryBox(World* world, float position[3], float size[3], QueryCallback callback, void* userdata);
|
||||
bool lovrWorldQuerySphere(World* world, float position[3], float radius, QueryCallback callback, void* userdata);
|
||||
Collider* lovrWorldGetFirstCollider(World* world);
|
||||
void lovrWorldGetGravity(World* world, float gravity[3]);
|
||||
void lovrWorldSetGravity(World* world, float gravity[3]);
|
||||
const char* lovrWorldGetTagName(World* world, uint32_t tag);
|
||||
|
@ -85,17 +88,19 @@ void lovrWorldSetSleepingAllowed(World* world, bool allowed);
|
|||
|
||||
// Collider
|
||||
|
||||
Collider* lovrColliderCreate(World* world, float x, float y, float z);
|
||||
Collider* lovrColliderCreate(World* world, Shape* shape, float position[3]);
|
||||
void lovrColliderDestroy(void* ref);
|
||||
void lovrColliderDestroyData(Collider* collider);
|
||||
bool lovrColliderIsDestroyed(Collider* collider);
|
||||
bool lovrColliderIsEnabled(Collider* collider);
|
||||
void lovrColliderSetEnabled(Collider* collider, bool enable);
|
||||
void lovrColliderInitInertia(Collider* collider, Shape* shape);
|
||||
World* lovrColliderGetWorld(Collider* collider);
|
||||
Collider* lovrColliderGetNext(Collider* collider);
|
||||
void lovrColliderAddShape(Collider* collider, Shape* shape);
|
||||
void lovrColliderRemoveShape(Collider* collider, Shape* shape);
|
||||
Shape** lovrColliderGetShapes(Collider* collider, size_t* count);
|
||||
Joint** lovrColliderGetJoints(Collider* collider, size_t* count);
|
||||
Shape* lovrColliderGetShape(Collider* collider, uint32_t child);
|
||||
void lovrColliderSetShape(Collider* collider, Shape* shape);
|
||||
void lovrColliderGetShapeOffset(Collider* collider, float position[3], float orientation[4]);
|
||||
void lovrColliderSetShapeOffset(Collider* collider, float position[3], float orientation[4]);
|
||||
Joint* lovrColliderEnumerateJoints(Collider* collider, Joint* joint, void** private);
|
||||
const char* lovrColliderGetTag(Collider* collider);
|
||||
bool lovrColliderSetTag(Collider* collider, const char* tag);
|
||||
float lovrColliderGetFriction(Collider* collider);
|
||||
|
@ -104,6 +109,8 @@ float lovrColliderGetRestitution(Collider* collider);
|
|||
void lovrColliderSetRestitution(Collider* collider, float restitution);
|
||||
bool lovrColliderIsKinematic(Collider* collider);
|
||||
void lovrColliderSetKinematic(Collider* collider, bool kinematic);
|
||||
bool lovrColliderIsSensor(Collider* collider);
|
||||
void lovrColliderSetSensor(Collider* collider, bool sensor);
|
||||
bool lovrColliderIsContinuous(Collider* collider);
|
||||
void lovrColliderSetContinuous(Collider* collider, bool continuous);
|
||||
float lovrColliderGetGravityScale(Collider* collider);
|
||||
|
@ -114,33 +121,33 @@ bool lovrColliderIsAwake(Collider* collider);
|
|||
void lovrColliderSetAwake(Collider* collider, bool awake);
|
||||
float lovrColliderGetMass(Collider* collider);
|
||||
void lovrColliderSetMass(Collider* collider, float mass);
|
||||
void lovrColliderGetMassData(Collider* collider, float* cx, float* cy, float* cz, float* mass, float inertia[6]);
|
||||
void lovrColliderSetMassData(Collider* collider, float cx, float cy, float cz, float mass, float inertia[6]);
|
||||
void lovrColliderGetPosition(Collider* collider, float* x, float* y, float* z);
|
||||
void lovrColliderSetPosition(Collider* collider, float x, float y, float z);
|
||||
void lovrColliderGetOrientation(Collider* collider, float* orientation);
|
||||
void lovrColliderSetOrientation(Collider* collider, float* orientation);
|
||||
void lovrColliderGetLinearVelocity(Collider* collider, float* x, float* y, float* z);
|
||||
void lovrColliderSetLinearVelocity(Collider* collider, float x, float y, float z);
|
||||
void lovrColliderGetAngularVelocity(Collider* collider, float* x, float* y, float* z);
|
||||
void lovrColliderSetAngularVelocity(Collider* collider, float x, float y, float z);
|
||||
void lovrColliderGetMassData(Collider* collider, float centerOfMass[3], float* mass, float inertia[6]);
|
||||
void lovrColliderSetMassData(Collider* collider, float centerOfMass[3], float mass, float inertia[6]);
|
||||
void lovrColliderGetPosition(Collider* collider, float position[3]);
|
||||
void lovrColliderSetPosition(Collider* collider, float position[3]);
|
||||
void lovrColliderGetOrientation(Collider* collider, float orientation[4]);
|
||||
void lovrColliderSetOrientation(Collider* collider, float orientation[4]);
|
||||
void lovrColliderGetLinearVelocity(Collider* collider, float velocity[3]);
|
||||
void lovrColliderSetLinearVelocity(Collider* collider, float velocity[3]);
|
||||
void lovrColliderGetAngularVelocity(Collider* collider, float velocity[3]);
|
||||
void lovrColliderSetAngularVelocity(Collider* collider, float velocity[3]);
|
||||
void lovrColliderGetLinearDamping(Collider* collider, float* damping, float* threshold);
|
||||
void lovrColliderSetLinearDamping(Collider* collider, float damping, float threshold);
|
||||
void lovrColliderGetAngularDamping(Collider* collider, float* damping, float* threshold);
|
||||
void lovrColliderSetAngularDamping(Collider* collider, float damping, float threshold);
|
||||
void lovrColliderApplyForce(Collider* collider, float x, float y, float z);
|
||||
void lovrColliderApplyForceAtPosition(Collider* collider, float x, float y, float z, float cx, float cy, float cz);
|
||||
void lovrColliderApplyTorque(Collider* collider, float x, float y, float z);
|
||||
void lovrColliderApplyForce(Collider* collider, float force[3]);
|
||||
void lovrColliderApplyForceAtPosition(Collider* collider, float force[3], float position[3]);
|
||||
void lovrColliderApplyTorque(Collider* collider, float torque[3]);
|
||||
void lovrColliderApplyLinearImpulse(Collider* collider, float impulse[3]);
|
||||
void lovrColliderApplyLinearImpulseAtPosition(Collider* collider, float impulse[3], float position[3]);
|
||||
void lovrColliderApplyAngularImpulse(Collider* collider, float impulse[3]);
|
||||
void lovrColliderGetLocalCenter(Collider* collider, float* x, float* y, float* z);
|
||||
void lovrColliderGetLocalPoint(Collider* collider, float wx, float wy, float wz, float* x, float* y, float* z);
|
||||
void lovrColliderGetWorldPoint(Collider* collider, float x, float y, float z, float* wx, float* wy, float* wz);
|
||||
void lovrColliderGetLocalVector(Collider* collider, float wx, float wy, float wz, float* x, float* y, float* z);
|
||||
void lovrColliderGetWorldVector(Collider* collider, float x, float y, float z, float* wx, float* wy, float* wz);
|
||||
void lovrColliderGetLinearVelocityFromLocalPoint(Collider* collider, float x, float y, float z, float* vx, float* vy, float* vz);
|
||||
void lovrColliderGetLinearVelocityFromWorldPoint(Collider* collider, float wx, float wy, float wz, float* vx, float* vy, float* vz);
|
||||
void lovrColliderGetLocalCenter(Collider* collider, float center[3]);
|
||||
void lovrColliderGetLocalPoint(Collider* collider, float world[3], float local[3]);
|
||||
void lovrColliderGetWorldPoint(Collider* collider, float local[3], float world[3]);
|
||||
void lovrColliderGetLocalVector(Collider* collider, float world[3], float local[3]);
|
||||
void lovrColliderGetWorldVector(Collider* collider, float local[3], float world[3]);
|
||||
void lovrColliderGetLinearVelocityFromLocalPoint(Collider* collider, float point[3], float velocity[3]);
|
||||
void lovrColliderGetLinearVelocityFromWorldPoint(Collider* collider, float point[3], float velocity[3]);
|
||||
void lovrColliderGetAABB(Collider* collider, float aabb[6]);
|
||||
|
||||
// Shapes
|
||||
|
@ -151,48 +158,44 @@ typedef enum {
|
|||
SHAPE_CAPSULE,
|
||||
SHAPE_CYLINDER,
|
||||
SHAPE_MESH,
|
||||
SHAPE_TERRAIN
|
||||
SHAPE_TERRAIN,
|
||||
SHAPE_COMPOUND
|
||||
} ShapeType;
|
||||
|
||||
void lovrShapeDestroy(void* ref);
|
||||
void lovrShapeDestroyData(Shape* shape);
|
||||
ShapeType lovrShapeGetType(Shape* shape);
|
||||
Collider* lovrShapeGetCollider(Shape* shape);
|
||||
bool lovrShapeIsEnabled(Shape* shape);
|
||||
void lovrShapeSetEnabled(Shape* shape, bool enabled);
|
||||
bool lovrShapeIsSensor(Shape* shape);
|
||||
void lovrShapeSetSensor(Shape* shape, bool sensor);
|
||||
void lovrShapeGetPosition(Shape* shape, float* x, float* y, float* z);
|
||||
void lovrShapeSetPosition(Shape* shape, float x, float y, float z);
|
||||
void lovrShapeGetOrientation(Shape* shape, float* orientation);
|
||||
void lovrShapeSetOrientation(Shape* shape, float* orientation);
|
||||
void lovrShapeGetMass(Shape* shape, float density, float* cx, float* cy, float* cz, float* mass, float inertia[6]);
|
||||
void lovrShapeGetAABB(Shape* shape, float aabb[6]);
|
||||
void lovrShapeGetMass(Shape* shape, float density, float centerOfMass[3], float* mass, float inertia[6]);
|
||||
void lovrShapeGetAABB(Shape* shape, float position[3], float orientation[4], float aabb[6]);
|
||||
|
||||
SphereShape* lovrSphereShapeCreate(float radius);
|
||||
float lovrSphereShapeGetRadius(SphereShape* sphere);
|
||||
void lovrSphereShapeSetRadius(SphereShape* sphere, float radius);
|
||||
|
||||
BoxShape* lovrBoxShapeCreate(float w, float h, float d);
|
||||
void lovrBoxShapeGetDimensions(BoxShape* box, float* w, float* h, float* d);
|
||||
void lovrBoxShapeSetDimensions(BoxShape* box, float w, float h, float d);
|
||||
BoxShape* lovrBoxShapeCreate(float dimensions[3]);
|
||||
void lovrBoxShapeGetDimensions(BoxShape* box, float dimensions[3]);
|
||||
|
||||
CapsuleShape* lovrCapsuleShapeCreate(float radius, float length);
|
||||
float lovrCapsuleShapeGetRadius(CapsuleShape* capsule);
|
||||
void lovrCapsuleShapeSetRadius(CapsuleShape* capsule, float radius);
|
||||
float lovrCapsuleShapeGetLength(CapsuleShape* capsule);
|
||||
void lovrCapsuleShapeSetLength(CapsuleShape* capsule, float length);
|
||||
|
||||
CylinderShape* lovrCylinderShapeCreate(float radius, float length);
|
||||
float lovrCylinderShapeGetRadius(CylinderShape* cylinder);
|
||||
void lovrCylinderShapeSetRadius(CylinderShape* cylinder, float radius);
|
||||
float lovrCylinderShapeGetLength(CylinderShape* cylinder);
|
||||
void lovrCylinderShapeSetLength(CylinderShape* cylinder, float length);
|
||||
|
||||
MeshShape* lovrMeshShapeCreate(int vertexCount, float vertices[], int indexCount, uint32_t indices[]);
|
||||
|
||||
TerrainShape* lovrTerrainShapeCreate(float* vertices, uint32_t n, float scaleXZ, float scaleY);
|
||||
|
||||
CompoundShape* lovrCompoundShapeCreate(Shape** shapes, float* positions, float* orientations, uint32_t count, bool freeze);
|
||||
bool lovrCompoundShapeIsFrozen(CompoundShape* shape);
|
||||
void lovrCompoundShapeAddChild(CompoundShape* shape, Shape* child, float position[3], float orientation[4]);
|
||||
void lovrCompoundShapeReplaceChild(CompoundShape* shape, uint32_t index, Shape* child, float position[3], float orientation[4]);
|
||||
void lovrCompoundShapeRemoveChild(CompoundShape* shape, uint32_t index);
|
||||
Shape* lovrCompoundShapeGetChild(CompoundShape* shape, uint32_t index);
|
||||
uint32_t lovrCompoundShapeGetChildCount(CompoundShape* shape);
|
||||
void lovrCompoundShapeGetChildOffset(CompoundShape* shape, uint32_t index, float position[3], float orientation[4]);
|
||||
void lovrCompoundShapeSetChildOffset(CompoundShape* shape, uint32_t index, float position[3], float orientation[4]);
|
||||
|
||||
// These tokens need to exist for Lua bindings
|
||||
#define lovrSphereShapeDestroy lovrShapeDestroy
|
||||
#define lovrBoxShapeDestroy lovrShapeDestroy
|
||||
|
@ -200,6 +203,7 @@ TerrainShape* lovrTerrainShapeCreate(float* vertices, uint32_t n, float scaleXZ,
|
|||
#define lovrCylinderShapeDestroy lovrShapeDestroy
|
||||
#define lovrMeshShapeDestroy lovrShapeDestroy
|
||||
#define lovrTerrainShapeDestroy lovrShapeDestroy
|
||||
#define lovrCompoundShapeDestroy lovrShapeDestroy
|
||||
|
||||
// Joints
|
||||
|
||||
|
@ -212,6 +216,7 @@ typedef enum {
|
|||
|
||||
void lovrJointDestroy(void* ref);
|
||||
void lovrJointDestroyData(Joint* joint);
|
||||
bool lovrJointIsDestroyed(Joint* joint);
|
||||
JointType lovrJointGetType(Joint* joint);
|
||||
float lovrJointGetCFM(Joint* joint);
|
||||
void lovrJointSetCFM(Joint* joint, float cfm);
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,4 +1,5 @@
|
|||
#include "physics.h"
|
||||
#include "core/maf.h"
|
||||
#include "util.h"
|
||||
#include <ode/ode.h>
|
||||
#include <stdatomic.h>
|
||||
|
@ -22,10 +23,11 @@ struct Collider {
|
|||
Collider* prev;
|
||||
Collider* next;
|
||||
uint32_t tag;
|
||||
arr_t(Shape*) shapes;
|
||||
Shape* shape;
|
||||
arr_t(Joint*) joints;
|
||||
float friction;
|
||||
float restitution;
|
||||
bool sensor;
|
||||
};
|
||||
|
||||
struct Shape {
|
||||
|
@ -35,7 +37,6 @@ struct Shape {
|
|||
Collider* collider;
|
||||
void* vertices;
|
||||
void* indices;
|
||||
bool sensor;
|
||||
};
|
||||
|
||||
struct Joint {
|
||||
|
@ -66,8 +67,9 @@ static void raycastCallback(void* d, dGeomID a, dGeomID b) {
|
|||
RaycastCallback callback = data->callback;
|
||||
void* userdata = data->userdata;
|
||||
Shape* shape = dGeomGetData(b);
|
||||
Collider* collider = dBodyGetData(dGeomGetBody(b));
|
||||
|
||||
if (!shape) {
|
||||
if (!shape || !collider) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -75,9 +77,7 @@ static void raycastCallback(void* d, dGeomID a, dGeomID b) {
|
|||
int count = dCollide(a, b, MAX_CONTACTS, &contact->geom, sizeof(dContact));
|
||||
for (int i = 0; i < count; i++) {
|
||||
dContactGeom g = contact[i].geom;
|
||||
data->shouldStop = callback(
|
||||
shape, g.pos[0], g.pos[1], g.pos[2], g.normal[0], g.normal[1], g.normal[2], userdata
|
||||
);
|
||||
data->shouldStop = callback(collider, g.pos, g.normal, 0, userdata);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -93,14 +93,15 @@ static void queryCallback(void* d, dGeomID a, dGeomID b) {
|
|||
if (data->shouldStop) return;
|
||||
|
||||
Shape* shape = dGeomGetData(b);
|
||||
if (!shape) {
|
||||
Collider* collider = dBodyGetData(dGeomGetBody(b));
|
||||
if (!shape || !collider) {
|
||||
return;
|
||||
}
|
||||
|
||||
dContactGeom contact;
|
||||
if (dCollide(a, b, 1 | CONTACTS_UNIMPORTANT, &contact, sizeof(contact))) {
|
||||
if (data->callback) {
|
||||
data->shouldStop = data->callback(shape, data->userdata);
|
||||
data->shouldStop = data->callback(collider, 0, data->userdata);
|
||||
} else {
|
||||
data->shouldStop = true;
|
||||
}
|
||||
|
@ -162,7 +163,6 @@ World* lovrWorldCreate(WorldInfo* info) {
|
|||
dHashSpaceSetLevels(world->space, -4, 8);
|
||||
world->contactGroup = dJointGroupCreate(0);
|
||||
arr_init(&world->overlaps);
|
||||
lovrWorldSetGravity(world, info->gravity);
|
||||
lovrWorldSetSleepingAllowed(world, info->allowSleep);
|
||||
for (uint32_t i = 0; i < info->tagCount; i++) {
|
||||
size_t size = strlen(info->tags[i]) + 1;
|
||||
|
@ -206,6 +206,28 @@ void lovrWorldDestroyData(World* world) {
|
|||
}
|
||||
}
|
||||
|
||||
uint32_t lovrWorldGetColliderCount(World* world) {
|
||||
Collider* collider = world->head;
|
||||
uint32_t count = 0;
|
||||
while (collider) {
|
||||
collider = collider->next;
|
||||
count++;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
uint32_t lovrWorldGetJointCount(World* world) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
Collider* lovrWorldEnumerateColliders(World* world, Collider* collider) {
|
||||
return collider ? collider->next : world->head;
|
||||
}
|
||||
|
||||
Joint* lovrWorldEnumerateJoints(World* world, Joint* joint) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void lovrWorldUpdate(World* world, float dt, CollisionResolver resolver, void* userdata) {
|
||||
if (resolver) {
|
||||
resolver(world, userdata);
|
||||
|
@ -279,7 +301,7 @@ int lovrWorldCollide(World* world, Shape* a, Shape* b, float friction, float res
|
|||
|
||||
int contactCount = dCollide(a->id, b->id, MAX_CONTACTS, &contacts[0].geom, sizeof(dContact));
|
||||
|
||||
if (!a->sensor && !b->sensor) {
|
||||
if (!colliderA->sensor && !colliderB->sensor) {
|
||||
for (int c = 0; c < contactCount; c++) {
|
||||
dJointID joint = dJointCreateContact(world->id, world->contactGroup, &contacts[c]);
|
||||
dJointAttach(joint, colliderA->body, colliderB->body);
|
||||
|
@ -305,14 +327,14 @@ void lovrWorldGetContacts(World* world, Shape* a, Shape* b, Contact contacts[MAX
|
|||
}
|
||||
}
|
||||
|
||||
void lovrWorldRaycast(World* world, float x1, float y1, float z1, float x2, float y2, float z2, RaycastCallback callback, void* userdata) {
|
||||
void lovrWorldRaycast(World* world, float start[3], float end[3], RaycastCallback callback, void* userdata) {
|
||||
RaycastData data = { .callback = callback, .userdata = userdata, .shouldStop = false };
|
||||
float dx = x2 - x1;
|
||||
float dy = y2 - y1;
|
||||
float dz = z2 - z1;
|
||||
float dx = start[0] - end[0];
|
||||
float dy = start[1] - end[1];
|
||||
float dz = start[2] - end[2];
|
||||
float length = sqrtf(dx * dx + dy * dy + dz * dz);
|
||||
dGeomID ray = dCreateRay(world->space, length);
|
||||
dGeomRaySet(ray, x1, y1, z1, dx, dy, dz);
|
||||
dGeomRaySet(ray, start[0], start[1], start[2], end[0], end[1], end[2]);
|
||||
dSpaceCollide2(ray, (dGeomID) world->space, &data, raycastCallback);
|
||||
dGeomDestroy(ray);
|
||||
}
|
||||
|
@ -335,10 +357,6 @@ bool lovrWorldQuerySphere(World* world, float position[3], float radius, QueryCa
|
|||
return data.called;
|
||||
}
|
||||
|
||||
Collider* lovrWorldGetFirstCollider(World* world) {
|
||||
return world->head;
|
||||
}
|
||||
|
||||
void lovrWorldGetGravity(World* world, float gravity[3]) {
|
||||
dReal g[4];
|
||||
dWorldGetGravity(world->id, g);
|
||||
|
@ -436,7 +454,7 @@ bool lovrWorldIsCollisionEnabledBetween(World* world, const char* tag1, const ch
|
|||
return (world->masks[i] & (1 << j)) && (world->masks[j] & (1 << i));
|
||||
}
|
||||
|
||||
Collider* lovrColliderCreate(World* world, float x, float y, float z) {
|
||||
Collider* lovrColliderCreate(World* world, Shape* shape, float position[3]) {
|
||||
Collider* collider = lovrCalloc(sizeof(Collider));
|
||||
collider->ref = 1;
|
||||
collider->body = dBodyCreate(world->id);
|
||||
|
@ -445,10 +463,10 @@ Collider* lovrColliderCreate(World* world, float x, float y, float z) {
|
|||
collider->restitution = 0;
|
||||
collider->tag = NO_TAG;
|
||||
dBodySetData(collider->body, collider);
|
||||
arr_init(&collider->shapes);
|
||||
arr_init(&collider->joints);
|
||||
|
||||
lovrColliderSetPosition(collider, x, y, z);
|
||||
lovrColliderSetShape(collider, shape);
|
||||
lovrColliderSetPosition(collider, position);
|
||||
|
||||
// Adjust the world's collider list
|
||||
if (!collider->world->head) {
|
||||
|
@ -467,7 +485,6 @@ Collider* lovrColliderCreate(World* world, float x, float y, float z) {
|
|||
void lovrColliderDestroy(void* ref) {
|
||||
Collider* collider = ref;
|
||||
lovrColliderDestroyData(collider);
|
||||
arr_free(&collider->shapes);
|
||||
arr_free(&collider->joints);
|
||||
lovrFree(collider);
|
||||
}
|
||||
|
@ -477,14 +494,10 @@ void lovrColliderDestroyData(Collider* collider) {
|
|||
return;
|
||||
}
|
||||
|
||||
size_t count;
|
||||
lovrColliderSetShape(collider, NULL);
|
||||
|
||||
Shape** shapes = lovrColliderGetShapes(collider, &count);
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
lovrColliderRemoveShape(collider, shapes[i]);
|
||||
}
|
||||
|
||||
Joint** joints = lovrColliderGetJoints(collider, &count);
|
||||
Joint** joints = collider->joints.data;
|
||||
size_t count = collider->joints.length;
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
lovrRelease(joints[i], lovrJointDestroy);
|
||||
}
|
||||
|
@ -505,12 +518,20 @@ bool lovrColliderIsDestroyed(Collider* collider) {
|
|||
return !collider->body;
|
||||
}
|
||||
|
||||
bool lovrColliderIsEnabled(Collider* collider) {
|
||||
return true;
|
||||
}
|
||||
|
||||
void lovrColliderSetEnabled(Collider* collider, bool enable) {
|
||||
//
|
||||
}
|
||||
|
||||
void lovrColliderInitInertia(Collider* collider, Shape* shape) {
|
||||
// compute inertia matrix for default density
|
||||
const float density = 1.0f;
|
||||
float cx, cy, cz, mass, inertia[6];
|
||||
lovrShapeGetMass(shape, density, &cx, &cy, &cz, &mass, inertia);
|
||||
lovrColliderSetMassData(collider, cx, cy, cz, mass, inertia);
|
||||
float centerOfMass[3], mass, inertia[6];
|
||||
lovrShapeGetMass(shape, density, centerOfMass, &mass, inertia);
|
||||
lovrColliderSetMassData(collider, centerOfMass, mass, inertia);
|
||||
}
|
||||
|
||||
World* lovrColliderGetWorld(Collider* collider) {
|
||||
|
@ -521,38 +542,50 @@ Collider* lovrColliderGetNext(Collider* collider) {
|
|||
return collider->next;
|
||||
}
|
||||
|
||||
void lovrColliderAddShape(Collider* collider, Shape* shape) {
|
||||
lovrRetain(shape);
|
||||
|
||||
if (shape->collider) {
|
||||
lovrColliderRemoveShape(shape->collider, shape);
|
||||
}
|
||||
|
||||
shape->collider = collider;
|
||||
dGeomSetBody(shape->id, collider->body);
|
||||
dSpaceID newSpace = collider->world->space;
|
||||
dSpaceAdd(newSpace, shape->id);
|
||||
Shape* lovrColliderGetShape(Collider* collider, uint32_t child) {
|
||||
return collider->shape;
|
||||
}
|
||||
|
||||
void lovrColliderRemoveShape(Collider* collider, Shape* shape) {
|
||||
if (shape->collider == collider) {
|
||||
dSpaceRemove(collider->world->space, shape->id);
|
||||
dGeomSetBody(shape->id, 0);
|
||||
shape->collider = NULL;
|
||||
lovrRelease(shape, lovrShapeDestroy);
|
||||
void lovrColliderSetShape(Collider* collider, Shape* shape) {
|
||||
if (collider->shape) {
|
||||
dSpaceRemove(collider->world->space, collider->shape->id);
|
||||
dGeomSetBody(collider->shape->id, 0);
|
||||
collider->shape->collider = NULL;
|
||||
lovrRelease(collider->shape, lovrShapeDestroy);
|
||||
}
|
||||
}
|
||||
|
||||
Shape** lovrColliderGetShapes(Collider* collider, size_t* count) {
|
||||
arr_clear(&collider->shapes);
|
||||
for (dGeomID geom = dBodyGetFirstGeom(collider->body); geom; geom = dBodyGetNextGeom(geom)) {
|
||||
Shape* shape = dGeomGetData(geom);
|
||||
if (shape) {
|
||||
arr_push(&collider->shapes, shape);
|
||||
collider->shape = shape;
|
||||
|
||||
if (shape) {
|
||||
if (shape->collider) {
|
||||
lovrColliderSetShape(shape->collider, NULL);
|
||||
}
|
||||
|
||||
shape->collider = collider;
|
||||
dGeomSetBody(shape->id, collider->body);
|
||||
dSpaceID newSpace = collider->world->space;
|
||||
dSpaceAdd(newSpace, shape->id);
|
||||
lovrRetain(shape);
|
||||
}
|
||||
*count = collider->shapes.length;
|
||||
return collider->shapes.data;
|
||||
}
|
||||
|
||||
void lovrColliderGetShapeOffset(Collider* collider, float position[3], float orientation[4]) {
|
||||
const dReal* p = dGeomGetOffsetPosition(collider->shape->id);
|
||||
position[0] = p[0];
|
||||
position[1] = p[1];
|
||||
position[2] = p[2];
|
||||
dReal q[4];
|
||||
dGeomGetOffsetQuaternion(collider->shape->id, q);
|
||||
orientation[0] = q[1];
|
||||
orientation[1] = q[2];
|
||||
orientation[2] = q[3];
|
||||
orientation[3] = q[0];
|
||||
}
|
||||
|
||||
void lovrColliderSetShapeOffset(Collider* collider, float position[3], float orientation[4]) {
|
||||
dGeomSetOffsetPosition(collider->shape->id, position[0], position[1], position[2]);
|
||||
dReal q[4] = { orientation[3], orientation[0], orientation[1], orientation[2] };
|
||||
dGeomSetOffsetQuaternion(collider->shape->id, q);
|
||||
}
|
||||
|
||||
Joint** lovrColliderGetJoints(Collider* collider, size_t* count) {
|
||||
|
@ -568,6 +601,15 @@ Joint** lovrColliderGetJoints(Collider* collider, size_t* count) {
|
|||
return collider->joints.data;
|
||||
}
|
||||
|
||||
Joint* lovrColliderEnumerateJoints(Collider* collider, Joint* joint, void** private) {
|
||||
if (!joint) {
|
||||
*private = NULL;
|
||||
}
|
||||
|
||||
uintptr_t index = (uintptr_t) *private;
|
||||
return index < collider->joints.length ? collider->joints.data[index] : NULL;
|
||||
}
|
||||
|
||||
const char* lovrColliderGetTag(Collider* collider) {
|
||||
return lovrWorldGetTagName(collider->world, collider->tag);
|
||||
}
|
||||
|
@ -610,6 +652,14 @@ void lovrColliderSetKinematic(Collider* collider, bool kinematic) {
|
|||
}
|
||||
}
|
||||
|
||||
bool lovrColliderIsSensor(Collider* collider) {
|
||||
return collider->sensor;
|
||||
}
|
||||
|
||||
void lovrColliderSetSensor(Collider* collider, bool sensor) {
|
||||
collider->sensor = sensor;
|
||||
}
|
||||
|
||||
bool lovrColliderIsContinuous(Collider* collider) {
|
||||
return false;
|
||||
}
|
||||
|
@ -659,12 +709,10 @@ void lovrColliderSetMass(Collider* collider, float mass) {
|
|||
dBodySetMass(collider->body, &m);
|
||||
}
|
||||
|
||||
void lovrColliderGetMassData(Collider* collider, float* cx, float* cy, float* cz, float* mass, float inertia[6]) {
|
||||
void lovrColliderGetMassData(Collider* collider, float centerOfMass[3], float* mass, float inertia[6]) {
|
||||
dMass m;
|
||||
dBodyGetMass(collider->body, &m);
|
||||
*cx = m.c[0];
|
||||
*cy = m.c[1];
|
||||
*cz = m.c[2];
|
||||
vec3_set(centerOfMass, m.c[0], m.c[1], m.c[2]);
|
||||
*mass = m.mass;
|
||||
|
||||
// Diagonal
|
||||
|
@ -678,30 +726,25 @@ void lovrColliderGetMassData(Collider* collider, float* cx, float* cy, float* cz
|
|||
inertia[5] = m.I[9];
|
||||
}
|
||||
|
||||
void lovrColliderSetMassData(Collider* collider, float cx, float cy, float cz, float mass, float inertia[6]) {
|
||||
void lovrColliderSetMassData(Collider* collider, float centerOfMass[3], float mass, float inertia[6]) {
|
||||
dMass m;
|
||||
dBodyGetMass(collider->body, &m);
|
||||
dMassSetParameters(&m, mass, cx, cy, cz, inertia[0], inertia[1], inertia[2], inertia[3], inertia[4], inertia[5]);
|
||||
dMassSetParameters(&m, mass, centerOfMass[0], centerOfMass[1], centerOfMass[2], inertia[0], inertia[1], inertia[2], inertia[3], inertia[4], inertia[5]);
|
||||
dBodySetMass(collider->body, &m);
|
||||
}
|
||||
|
||||
void lovrColliderGetPosition(Collider* collider, float* x, float* y, float* z) {
|
||||
const dReal* position = dBodyGetPosition(collider->body);
|
||||
*x = position[0];
|
||||
*y = position[1];
|
||||
*z = position[2];
|
||||
void lovrColliderGetPosition(Collider* collider, float position[3]) {
|
||||
const dReal* p = dBodyGetPosition(collider->body);
|
||||
vec3_set(position, p[0], p[1], p[2]);
|
||||
}
|
||||
|
||||
void lovrColliderSetPosition(Collider* collider, float x, float y, float z) {
|
||||
dBodySetPosition(collider->body, x, y, z);
|
||||
void lovrColliderSetPosition(Collider* collider, float position[3]) {
|
||||
dBodySetPosition(collider->body, position[0], position[1], position[2]);
|
||||
}
|
||||
|
||||
void lovrColliderGetOrientation(Collider* collider, float* orientation) {
|
||||
void lovrColliderGetOrientation(Collider* collider, float orientation[4]) {
|
||||
const dReal* q = dBodyGetQuaternion(collider->body);
|
||||
orientation[0] = q[1];
|
||||
orientation[1] = q[2];
|
||||
orientation[2] = q[3];
|
||||
orientation[3] = q[0];
|
||||
quat_set(orientation, q[1], q[2], q[3], q[0]);
|
||||
}
|
||||
|
||||
void lovrColliderSetOrientation(Collider* collider, float* orientation) {
|
||||
|
@ -709,28 +752,24 @@ void lovrColliderSetOrientation(Collider* collider, float* orientation) {
|
|||
dBodySetQuaternion(collider->body, q);
|
||||
}
|
||||
|
||||
void lovrColliderGetLinearVelocity(Collider* collider, float* x, float* y, float* z) {
|
||||
const dReal* velocity = dBodyGetLinearVel(collider->body);
|
||||
*x = velocity[0];
|
||||
*y = velocity[1];
|
||||
*z = velocity[2];
|
||||
void lovrColliderGetLinearVelocity(Collider* collider, float velocity[3]) {
|
||||
const dReal* v = dBodyGetLinearVel(collider->body);
|
||||
vec3_set(velocity, v[0], v[1], v[2]);
|
||||
}
|
||||
|
||||
void lovrColliderSetLinearVelocity(Collider* collider, float x, float y, float z) {
|
||||
void lovrColliderSetLinearVelocity(Collider* collider, float velocity[3]) {
|
||||
dBodyEnable(collider->body);
|
||||
dBodySetLinearVel(collider->body, x, y, z);
|
||||
dBodySetLinearVel(collider->body, velocity[0], velocity[1], velocity[2]);
|
||||
}
|
||||
|
||||
void lovrColliderGetAngularVelocity(Collider* collider, float* x, float* y, float* z) {
|
||||
const dReal* velocity = dBodyGetAngularVel(collider->body);
|
||||
*x = velocity[0];
|
||||
*y = velocity[1];
|
||||
*z = velocity[2];
|
||||
void lovrColliderGetAngularVelocity(Collider* collider, float velocity[3]) {
|
||||
const dReal* v = dBodyGetAngularVel(collider->body);
|
||||
vec3_set(velocity, v[0], v[1], v[2]);
|
||||
}
|
||||
|
||||
void lovrColliderSetAngularVelocity(Collider* collider, float x, float y, float z) {
|
||||
void lovrColliderSetAngularVelocity(Collider* collider, float velocity[3]) {
|
||||
dBodyEnable(collider->body);
|
||||
dBodySetAngularVel(collider->body, x, y, z);
|
||||
dBodySetAngularVel(collider->body, velocity[0], velocity[1], velocity[2]);
|
||||
}
|
||||
|
||||
void lovrColliderGetLinearDamping(Collider* collider, float* damping, float* threshold) {
|
||||
|
@ -753,19 +792,19 @@ void lovrColliderSetAngularDamping(Collider* collider, float damping, float thre
|
|||
dBodySetAngularDampingThreshold(collider->body, threshold);
|
||||
}
|
||||
|
||||
void lovrColliderApplyForce(Collider* collider, float x, float y, float z) {
|
||||
void lovrColliderApplyForce(Collider* collider, float force[3]) {
|
||||
dBodyEnable(collider->body);
|
||||
dBodyAddForce(collider->body, x, y, z);
|
||||
dBodyAddForce(collider->body, force[0], force[1], force[2]);
|
||||
}
|
||||
|
||||
void lovrColliderApplyForceAtPosition(Collider* collider, float x, float y, float z, float cx, float cy, float cz) {
|
||||
void lovrColliderApplyForceAtPosition(Collider* collider, float force[3], float position[3]) {
|
||||
dBodyEnable(collider->body);
|
||||
dBodyAddForceAtPos(collider->body, x, y, z, cx, cy, cz);
|
||||
dBodyAddForceAtPos(collider->body, force[0], force[1], force[2], position[0], position[1], position[2]);
|
||||
}
|
||||
|
||||
void lovrColliderApplyTorque(Collider* collider, float x, float y, float z) {
|
||||
void lovrColliderApplyTorque(Collider* collider, float torque[3]) {
|
||||
dBodyEnable(collider->body);
|
||||
dBodyAddTorque(collider->body, x, y, z);
|
||||
dBodyAddTorque(collider->body, torque[0], torque[1], torque[2]);
|
||||
}
|
||||
|
||||
void lovrColliderApplyLinearImpulse(Collider* collider, float impulse[3]) {
|
||||
|
@ -780,60 +819,46 @@ void lovrColliderApplyAngularImpulse(Collider* collider, float impulse[3]) {
|
|||
//
|
||||
}
|
||||
|
||||
void lovrColliderGetLocalCenter(Collider* collider, float* x, float* y, float* z) {
|
||||
void lovrColliderGetLocalCenter(Collider* collider, float center[3]) {
|
||||
dMass m;
|
||||
dBodyGetMass(collider->body, &m);
|
||||
*x = m.c[0];
|
||||
*y = m.c[1];
|
||||
*z = m.c[2];
|
||||
vec3_set(center, m.c[0], m.c[1], m.c[2]);
|
||||
}
|
||||
|
||||
void lovrColliderGetLocalPoint(Collider* collider, float wx, float wy, float wz, float* x, float* y, float* z) {
|
||||
dReal local[4];
|
||||
dBodyGetPosRelPoint(collider->body, wx, wy, wz, local);
|
||||
*x = local[0];
|
||||
*y = local[1];
|
||||
*z = local[2];
|
||||
void lovrColliderGetLocalPoint(Collider* collider, float world[3], float local[3]) {
|
||||
dReal point[4];
|
||||
dBodyGetPosRelPoint(collider->body, world[0], world[1], world[2], point);
|
||||
vec3_set(local, point[0], point[1], point[2]);
|
||||
}
|
||||
|
||||
void lovrColliderGetWorldPoint(Collider* collider, float x, float y, float z, float* wx, float* wy, float* wz) {
|
||||
dReal world[4];
|
||||
dBodyGetRelPointPos(collider->body, x, y, z, world);
|
||||
*wx = world[0];
|
||||
*wy = world[1];
|
||||
*wz = world[2];
|
||||
void lovrColliderGetWorldPoint(Collider* collider, float local[3], float world[3]) {
|
||||
dReal point[4];
|
||||
dBodyGetRelPointPos(collider->body, local[0], local[1], local[2], point);
|
||||
vec3_set(world, point[0], point[1], point[2]);
|
||||
}
|
||||
|
||||
void lovrColliderGetLocalVector(Collider* collider, float wx, float wy, float wz, float* x, float* y, float* z) {
|
||||
dReal local[4];
|
||||
dBodyVectorFromWorld(collider->body, wx, wy, wz, local);
|
||||
*x = local[0];
|
||||
*y = local[1];
|
||||
*z = local[2];
|
||||
void lovrColliderGetLocalVector(Collider* collider, float world[3], float local[3]) {
|
||||
dReal vector[4];
|
||||
dBodyVectorFromWorld(collider->body, world[0], world[1], world[2], local);
|
||||
vec3_set(local, vector[0], vector[1], vector[2]);
|
||||
}
|
||||
|
||||
void lovrColliderGetWorldVector(Collider* collider, float x, float y, float z, float* wx, float* wy, float* wz) {
|
||||
dReal world[4];
|
||||
dBodyVectorToWorld(collider->body, x, y, z, world);
|
||||
*wx = world[0];
|
||||
*wy = world[1];
|
||||
*wz = world[2];
|
||||
void lovrColliderGetWorldVector(Collider* collider, float local[3], float world[3]) {
|
||||
dReal vector[4];
|
||||
dBodyVectorToWorld(collider->body, local[0], local[1], local[2], world);
|
||||
vec3_set(world, vector[0], vector[1], vector[2]);
|
||||
}
|
||||
|
||||
void lovrColliderGetLinearVelocityFromLocalPoint(Collider* collider, float x, float y, float z, float* vx, float* vy, float* vz) {
|
||||
dReal velocity[4];
|
||||
dBodyGetRelPointVel(collider->body, x, y, z, velocity);
|
||||
*vx = velocity[0];
|
||||
*vy = velocity[1];
|
||||
*vz = velocity[2];
|
||||
void lovrColliderGetLinearVelocityFromLocalPoint(Collider* collider, float point[3], float velocity[3]) {
|
||||
dReal vector[4];
|
||||
dBodyGetRelPointVel(collider->body, point[0], point[1], point[2], vector);
|
||||
vec3_set(velocity, vector[0], vector[1], vector[2]);
|
||||
}
|
||||
|
||||
void lovrColliderGetLinearVelocityFromWorldPoint(Collider* collider, float wx, float wy, float wz, float* vx, float* vy, float* vz) {
|
||||
dReal velocity[4];
|
||||
dBodyGetPointVel(collider->body, wx, wy, wz, velocity);
|
||||
*vx = velocity[0];
|
||||
*vy = velocity[1];
|
||||
*vz = velocity[2];
|
||||
void lovrColliderGetLinearVelocityFromWorldPoint(Collider* collider, float point[3], float velocity[3]) {
|
||||
dReal vector[4];
|
||||
dBodyGetPointVel(collider->body, point[0], point[1], point[2], velocity);
|
||||
vec3_set(velocity, vector[0], vector[1], vector[2]);
|
||||
}
|
||||
|
||||
void lovrColliderGetAABB(Collider* collider, float aabb[6]) {
|
||||
|
@ -888,52 +913,7 @@ Collider* lovrShapeGetCollider(Shape* shape) {
|
|||
return shape->collider;
|
||||
}
|
||||
|
||||
bool lovrShapeIsEnabled(Shape* shape) {
|
||||
return dGeomIsEnabled(shape->id);
|
||||
}
|
||||
|
||||
void lovrShapeSetEnabled(Shape* shape, bool enabled) {
|
||||
if (enabled) {
|
||||
dGeomEnable(shape->id);
|
||||
} else {
|
||||
dGeomDisable(shape->id);
|
||||
}
|
||||
}
|
||||
|
||||
bool lovrShapeIsSensor(Shape* shape) {
|
||||
return shape->sensor;
|
||||
}
|
||||
|
||||
void lovrShapeSetSensor(Shape* shape, bool sensor) {
|
||||
shape->sensor = sensor;
|
||||
}
|
||||
|
||||
void lovrShapeGetPosition(Shape* shape, float* x, float* y, float* z) {
|
||||
const dReal* position = dGeomGetOffsetPosition(shape->id);
|
||||
*x = position[0];
|
||||
*y = position[1];
|
||||
*z = position[2];
|
||||
}
|
||||
|
||||
void lovrShapeSetPosition(Shape* shape, float x, float y, float z) {
|
||||
dGeomSetOffsetPosition(shape->id, x, y, z);
|
||||
}
|
||||
|
||||
void lovrShapeGetOrientation(Shape* shape, float* orientation) {
|
||||
dReal q[4];
|
||||
dGeomGetOffsetQuaternion(shape->id, q);
|
||||
orientation[0] = q[1];
|
||||
orientation[1] = q[2];
|
||||
orientation[2] = q[3];
|
||||
orientation[3] = q[0];
|
||||
}
|
||||
|
||||
void lovrShapeSetOrientation(Shape* shape, float* orientation) {
|
||||
dReal q[4] = { orientation[3], orientation[0], orientation[1], orientation[2] };
|
||||
dGeomSetOffsetQuaternion(shape->id, q);
|
||||
}
|
||||
|
||||
void lovrShapeGetMass(Shape* shape, float density, float* cx, float* cy, float* cz, float* mass, float inertia[6]) {
|
||||
void lovrShapeGetMass(Shape* shape, float density, float centerOfMass[3], float* mass, float inertia[6]) {
|
||||
dMass m;
|
||||
dMassSetZero(&m);
|
||||
switch (shape->type) {
|
||||
|
@ -973,6 +953,8 @@ void lovrShapeGetMass(Shape* shape, float density, float* cx, float* cy, float*
|
|||
case SHAPE_TERRAIN: {
|
||||
break;
|
||||
}
|
||||
|
||||
default: break;
|
||||
}
|
||||
|
||||
const dReal* position = dGeomGetOffsetPosition(shape->id);
|
||||
|
@ -980,9 +962,9 @@ void lovrShapeGetMass(Shape* shape, float density, float* cx, float* cy, float*
|
|||
const dReal* rotation = dGeomGetOffsetRotation(shape->id);
|
||||
dMassRotate(&m, rotation);
|
||||
|
||||
*cx = m.c[0];
|
||||
*cy = m.c[1];
|
||||
*cz = m.c[2];
|
||||
centerOfMass[0] = m.c[0];
|
||||
centerOfMass[1] = m.c[1];
|
||||
centerOfMass[2] = m.c[2];
|
||||
*mass = m.mass;
|
||||
|
||||
// Diagonal
|
||||
|
@ -996,7 +978,7 @@ void lovrShapeGetMass(Shape* shape, float density, float* cx, float* cy, float*
|
|||
inertia[5] = m.I[9];
|
||||
}
|
||||
|
||||
void lovrShapeGetAABB(Shape* shape, float aabb[6]) {
|
||||
void lovrShapeGetAABB(Shape* shape, float position[3], float orientation[4], float aabb[6]) {
|
||||
dGeomGetAABB(shape->id, aabb);
|
||||
}
|
||||
|
||||
|
@ -1019,26 +1001,19 @@ void lovrSphereShapeSetRadius(SphereShape* sphere, float radius) {
|
|||
dGeomSphereSetRadius(sphere->id, radius);
|
||||
}
|
||||
|
||||
BoxShape* lovrBoxShapeCreate(float w, float h, float d) {
|
||||
BoxShape* lovrBoxShapeCreate(float dimensions[3]) {
|
||||
BoxShape* box = lovrCalloc(sizeof(BoxShape));
|
||||
box->ref = 1;
|
||||
box->type = SHAPE_BOX;
|
||||
box->id = dCreateBox(0, w, h, d);
|
||||
box->id = dCreateBox(0, dimensions[0], dimensions[1], dimensions[2]);
|
||||
dGeomSetData(box->id, box);
|
||||
return box;
|
||||
}
|
||||
|
||||
void lovrBoxShapeGetDimensions(BoxShape* box, float* w, float* h, float* d) {
|
||||
dReal dimensions[4];
|
||||
dGeomBoxGetLengths(box->id, dimensions);
|
||||
*w = dimensions[0];
|
||||
*h = dimensions[1];
|
||||
*d = dimensions[2];
|
||||
}
|
||||
|
||||
void lovrBoxShapeSetDimensions(BoxShape* box, float w, float h, float d) {
|
||||
lovrCheck(w > 0.f && h > 0.f && d > 0.f, "BoxShape dimensions must be positive");
|
||||
dGeomBoxSetLengths(box->id, w, h, d);
|
||||
void lovrBoxShapeGetDimensions(BoxShape* box, float dimensions[3]) {
|
||||
dReal d[4];
|
||||
dGeomBoxGetLengths(box->id, d);
|
||||
vec3_set(dimensions, d[0], d[1], d[2]);
|
||||
}
|
||||
|
||||
CapsuleShape* lovrCapsuleShapeCreate(float radius, float length) {
|
||||
|
@ -1057,22 +1032,12 @@ float lovrCapsuleShapeGetRadius(CapsuleShape* capsule) {
|
|||
return radius;
|
||||
}
|
||||
|
||||
void lovrCapsuleShapeSetRadius(CapsuleShape* capsule, float radius) {
|
||||
lovrCheck(radius > 0.f, "CapsuleShape dimensions must be positive");
|
||||
dGeomCapsuleSetParams(capsule->id, radius, lovrCapsuleShapeGetLength(capsule));
|
||||
}
|
||||
|
||||
float lovrCapsuleShapeGetLength(CapsuleShape* capsule) {
|
||||
dReal radius, length;
|
||||
dGeomCapsuleGetParams(capsule->id, &radius, &length);
|
||||
return length;
|
||||
}
|
||||
|
||||
void lovrCapsuleShapeSetLength(CapsuleShape* capsule, float length) {
|
||||
lovrCheck(length > 0.f, "CapsuleShape dimensions must be positive");
|
||||
dGeomCapsuleSetParams(capsule->id, lovrCapsuleShapeGetRadius(capsule), length);
|
||||
}
|
||||
|
||||
CylinderShape* lovrCylinderShapeCreate(float radius, float length) {
|
||||
lovrCheck(radius > 0.f && length > 0.f, "CylinderShape dimensions must be positive");
|
||||
CylinderShape* cylinder = lovrCalloc(sizeof(CylinderShape));
|
||||
|
@ -1089,22 +1054,12 @@ float lovrCylinderShapeGetRadius(CylinderShape* cylinder) {
|
|||
return radius;
|
||||
}
|
||||
|
||||
void lovrCylinderShapeSetRadius(CylinderShape* cylinder, float radius) {
|
||||
lovrCheck(radius > 0.f, "CylinderShape dimensions must be positive");
|
||||
dGeomCylinderSetParams(cylinder->id, radius, lovrCylinderShapeGetLength(cylinder));
|
||||
}
|
||||
|
||||
float lovrCylinderShapeGetLength(CylinderShape* cylinder) {
|
||||
dReal radius, length;
|
||||
dGeomCylinderGetParams(cylinder->id, &radius, &length);
|
||||
return length;
|
||||
}
|
||||
|
||||
void lovrCylinderShapeSetLength(CylinderShape* cylinder, float length) {
|
||||
lovrCheck(length > 0.f, "CylinderShape dimensions must be positive");
|
||||
dGeomCylinderSetParams(cylinder->id, lovrCylinderShapeGetRadius(cylinder), length);
|
||||
}
|
||||
|
||||
MeshShape* lovrMeshShapeCreate(int vertexCount, float* vertices, int indexCount, dTriIndex* indices) {
|
||||
MeshShape* mesh = lovrCalloc(sizeof(MeshShape));
|
||||
mesh->ref = 1;
|
||||
|
@ -1131,6 +1086,42 @@ TerrainShape* lovrTerrainShapeCreate(float* vertices, uint32_t n, float scaleXZ,
|
|||
return terrain;
|
||||
}
|
||||
|
||||
CompoundShape* lovrCompoundShapeCreate(Shape** shapes, float* positions, float* orientations, uint32_t count, bool freeze) {
|
||||
lovrThrow("ODE does not support compound shape");
|
||||
}
|
||||
|
||||
bool lovrCompoundShapeIsFrozen(CompoundShape* shape) {
|
||||
return false;
|
||||
}
|
||||
|
||||
void lovrCompoundShapeAddChild(CompoundShape* shape, Shape* child, float* position, float* orientation) {
|
||||
//
|
||||
}
|
||||
|
||||
void lovrCompoundShapeReplaceChild(CompoundShape* shape, uint32_t index, Shape* child, float* position, float* orientation) {
|
||||
//
|
||||
}
|
||||
|
||||
void lovrCompoundShapeRemoveChild(CompoundShape* shape, uint32_t index) {
|
||||
//
|
||||
}
|
||||
|
||||
Shape* lovrCompoundShapeGetChild(CompoundShape* shape, uint32_t index) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
uint32_t lovrCompoundShapeGetChildCount(CompoundShape* shape) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void lovrCompoundShapeGetChildOffset(CompoundShape* shape, uint32_t index, float* position, float* orientation) {
|
||||
//
|
||||
}
|
||||
|
||||
void lovrCompoundShapeSetChildOffset(CompoundShape* shape, uint32_t index, float* position, float* orientation) {
|
||||
//
|
||||
}
|
||||
|
||||
void lovrJointDestroy(void* ref) {
|
||||
Joint* joint = ref;
|
||||
lovrJointDestroyData(joint);
|
||||
|
@ -1144,6 +1135,10 @@ void lovrJointDestroyData(Joint* joint) {
|
|||
}
|
||||
}
|
||||
|
||||
bool lovrJointIsDestroyed(Joint* joint) {
|
||||
return joint->id == NULL;
|
||||
}
|
||||
|
||||
JointType lovrJointGetType(Joint* joint) {
|
||||
return joint->type;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue