mirror of https://github.com/bjornbytes/lovr.git
CompoundShape API;
This commit is contained in:
parent
6f0b6391df
commit
b3e9e55b8a
|
@ -138,7 +138,82 @@ Shape* luax_newterrainshape(lua_State* L, int index) {
|
|||
}
|
||||
|
||||
Shape* luax_newcompoundshape(lua_State* L, int index) {
|
||||
return NULL; // TODO
|
||||
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_totype(L, -1, Shape);
|
||||
lovrCheck(shapes[i], "Expected a Shape for CompoundShape entry #%d", i + 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++);
|
||||
lua_rawgeti(L, -3, index++);
|
||||
vec3_set(&positions[3 * i], luax_tofloat(L, -3), luax_tofloat(L, -2), luax_tofloat(L, -1));
|
||||
lua_pop(L, 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) {
|
||||
|
@ -379,6 +454,63 @@ const luaL_Reg lovrTerrainShape[] = {
|
|||
{ 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_lovrCompoundShapeAddShape(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);
|
||||
lovrCompoundShapeAddShape(shape, child, position, orientation);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int l_lovrCompoundShapeReplaceShape(lua_State* L) {
|
||||
CompoundShape* shape = luax_checktype(L, 1, CompoundShape);
|
||||
uint32_t index = luax_checku32(L, 2);
|
||||
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);
|
||||
lovrCompoundShapeReplaceShape(shape, index, child, position, orientation);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int l_lovrCompoundShapeRemoveShape(lua_State* L) {
|
||||
CompoundShape* shape = luax_checktype(L, 1, CompoundShape);
|
||||
uint32_t index = luax_checku32(L, 2);
|
||||
lovrCompoundShapeRemoveShape(shape, index);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int l_lovrCompoundShapeGetShape(lua_State* L) {
|
||||
CompoundShape* shape = luax_checktype(L, 1, CompoundShape);
|
||||
uint32_t index = luax_checku32(L, 2);
|
||||
Shape* child = lovrCompoundShapeGetShape(shape, index);
|
||||
luax_pushshape(L, child);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int l_lovrCompoundShapeGetShapes(lua_State* L) {
|
||||
CompoundShape* shape = luax_checktype(L, 1, CompoundShape);
|
||||
int count = (int) lovrCompoundShapeGetShapeCount(shape);
|
||||
lua_createtable(L, count, 0);
|
||||
for (int i = 0; i < count; i++) {
|
||||
Shape* shape = lovrCompoundShapeGetShape(shape, (uint32_t) i);
|
||||
luax_pushshape(L, shape);
|
||||
lua_rawseti(L, -2, i + 1);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int l_lovrCompoundShapeGetShapeCount(lua_State* L) {
|
||||
CompoundShape* shape = luax_checktype(L, 1, CompoundShape);
|
||||
uint32_t count = lovrCompoundShapeGetShapeCount(shape);
|
||||
|
@ -386,8 +518,44 @@ static int l_lovrCompoundShapeGetShapeCount(lua_State* L) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
static int l_lovrCompoundShapeGetShapeOffset(lua_State* L) {
|
||||
CompoundShape* shape = luax_checktype(L, 1, CompoundShape);
|
||||
uint32_t index = luax_checku32(L, 2);
|
||||
float position[3], orientation[4], angle, ax, ay, az;
|
||||
lovrCompoundShapeGetShapeOffset(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_lovrCompoundShapeSetShapeOffset(lua_State* L) {
|
||||
CompoundShape* shape = luax_checktype(L, 1, CompoundShape);
|
||||
uint32_t index = luax_checku32(L, 2);
|
||||
float position[3], orientation[4];
|
||||
int i = 3;
|
||||
i = luax_readvec3(L, i, position, NULL);
|
||||
i = luax_readquat(L, i, orientation, NULL);
|
||||
lovrCompoundShapeSetShapeOffset(shape, index, position, orientation);
|
||||
return 0;
|
||||
}
|
||||
|
||||
const luaL_Reg lovrCompoundShape[] = {
|
||||
lovrShape,
|
||||
{ "getShapeCount", l_lovrCompoundShapeGetShapeCount },
|
||||
{ "isFrozen", l_lovrCompoundShapeIsFrozen },
|
||||
{ "addShape", l_lovrCompoundShapeAddShape },
|
||||
{ "replaceShape", l_lovrCompoundShapeReplaceShape },
|
||||
{ "removeShape", l_lovrCompoundShapeRemoveShape },
|
||||
{ "getShape", l_lovrCompoundShapeGetShape },
|
||||
{ "getShapes", l_lovrCompoundShapeGetShapes },
|
||||
{ "getShapeCount", l_lovrCompoundShapeGetShapes },
|
||||
{ "getShapeOffset", l_lovrCompoundShapeGetShapeOffset },
|
||||
{ "setShapeOffset", l_lovrCompoundShapeSetShapeOffset },
|
||||
{ "__len", l_lovrCompoundShapeGetShapeCount }, // :)
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
|
|
@ -193,8 +193,15 @@ MeshShape* lovrMeshShapeCreate(int vertexCount, float vertices[], int indexCount
|
|||
|
||||
TerrainShape* lovrTerrainShapeCreate(float* vertices, uint32_t n, float scaleXZ, float scaleY);
|
||||
|
||||
CompoundShape* lovrCompoundShapeCreate(Shape** shapes, float* positions, float* orientations, uint32_t count);
|
||||
CompoundShape* lovrCompoundShapeCreate(Shape** shapes, float* positions, float* orientations, uint32_t count, bool freeze);
|
||||
bool lovrCompoundShapeIsFrozen(CompoundShape* shape);
|
||||
void lovrCompoundShapeAddShape(CompoundShape* shape, Shape* child, float* position, float* orientation);
|
||||
void lovrCompoundShapeReplaceShape(CompoundShape* shape, uint32_t index, Shape* child, float* position, float* orientation);
|
||||
void lovrCompoundShapeRemoveShape(CompoundShape* shape, uint32_t index);
|
||||
Shape* lovrCompoundShapeGetShape(CompoundShape* shape, uint32_t index);
|
||||
uint32_t lovrCompoundShapeGetShapeCount(CompoundShape* shape);
|
||||
void lovrCompoundShapeGetShapeOffset(CompoundShape* shape, uint32_t index, float* position, float* orientation);
|
||||
void lovrCompoundShapeSetShapeOffset(CompoundShape* shape, uint32_t index, float* position, float* orientation);
|
||||
|
||||
// These tokens need to exist for Lua bindings
|
||||
#define lovrSphereShapeDestroy lovrShapeDestroy
|
||||
|
|
|
@ -761,6 +761,14 @@ void lovrShapeDestroy(void* ref) {
|
|||
|
||||
void lovrShapeDestroyData(Shape* shape) {
|
||||
if (shape->shape) {
|
||||
if (shape->type == SHAPE_COMPOUND) {
|
||||
uint32_t count = lovrCompoundShapeGetShapeCount(shape);
|
||||
for (uint32_t i = 0; i < count; i++) {
|
||||
Shape* child = lovrCompoundShapeGetShape(shape, i);
|
||||
lovrRelease(child, lovrShapeDestroy);
|
||||
}
|
||||
}
|
||||
|
||||
JPH_Shape_Destroy(shape->shape);
|
||||
shape->shape = NULL;
|
||||
}
|
||||
|
@ -940,20 +948,20 @@ TerrainShape* lovrTerrainShapeCreate(float* vertices, uint32_t n, float scaleXZ,
|
|||
return terrain;
|
||||
}
|
||||
|
||||
CompoundShape* lovrCompoundShapeCreate(Shape** shapes, vec3 positions, quat orientations, uint32_t count) {
|
||||
CompoundShape* lovrCompoundShapeCreate(Shape** shapes, vec3 positions, quat orientations, uint32_t count, bool freeze) {
|
||||
CompoundShape* parent = lovrCalloc(sizeof(CompoundShape));
|
||||
parent->ref = 1;
|
||||
parent->type = SHAPE_COMPOUND;
|
||||
|
||||
JPH_MutableCompoundShapeSettings* settings = JPH_MutableCompoundShapeSettings_Create();
|
||||
JPH_CompoundShapeSettings* settingsSuper = (JPH_CompoundShapeSettings*) settings;
|
||||
JPH_CompoundShapeSettings* superSettings = (JPH_CompoundShapeSettings*) settings;
|
||||
|
||||
for (uint32_t i = 0; i < count; i++) {
|
||||
JPH_Vec3 position;
|
||||
JPH_Quat rotation;
|
||||
vec3_init(&position.x, positions + 3 * i);
|
||||
quat_init(&rotation.x, orientations + 3 * i);
|
||||
JPH_CompoundShapeSettings_AddShape2(settingsSuper, &position, &rotation, shapes[i]->shape, 0);
|
||||
JPH_CompoundShapeSettings_AddShape2(superSettings, &position, &rotation, shapes[i]->shape, 0);
|
||||
lovrRetain(shapes[i]);
|
||||
}
|
||||
|
||||
|
@ -962,10 +970,62 @@ CompoundShape* lovrCompoundShapeCreate(Shape** shapes, vec3 positions, quat orie
|
|||
return parent;
|
||||
}
|
||||
|
||||
bool lovrCompoundShapeIsFrozen(CompoundShape* shape) {
|
||||
return JPH_Shape_GetSubType(shape->shape) == JPH_ShapeSubType_StaticCompound;
|
||||
}
|
||||
|
||||
void lovrCompoundShapeAddShape(CompoundShape* shape, Shape* child, float* position, float* orientation) {
|
||||
lovrCheck(!lovrCompoundShapeIsFrozen(shape), "CompoundShape is frozen and can not be changed");
|
||||
lovrCheck(child->type != SHAPE_COMPOUND, "Currently, nesting compound shapes is not supported");
|
||||
JPH_Vec3 pos = { position[0], position[1], position[2] };
|
||||
JPH_Quat rot = { orientation[0], orientation[1], orientation[2], orientation[3] };
|
||||
JPH_MutableCompoundShape_AddShape((JPH_MutableCompoundShape*) shape->shape, &pos, &rot, child->shape, 0);
|
||||
lovrRetain(child);
|
||||
}
|
||||
|
||||
void lovrCompoundShapeReplaceShape(CompoundShape* shape, uint32_t index, Shape* child, float* position, float* orientation) {
|
||||
lovrCheck(!lovrCompoundShapeIsFrozen(shape), "CompoundShape is frozen and can not be changed");
|
||||
lovrCheck(child->type != SHAPE_COMPOUND, "Currently, nesting compound shapes is not supported");
|
||||
JPH_Vec3 pos = { position[0], position[1], position[2] };
|
||||
JPH_Quat rot = { orientation[0], orientation[1], orientation[2], orientation[3] };
|
||||
JPH_MutableCompoundShape_ModifyShape2((JPH_MutableCompoundShape*) shape->shape, index, &pos, &rot, child->shape);
|
||||
lovrRetain(child);
|
||||
}
|
||||
|
||||
void lovrCompoundShapeRemoveShape(CompoundShape* shape, uint32_t index) {
|
||||
lovrCheck(!lovrCompoundShapeIsFrozen(shape), "CompoundShape is frozen and can not be changed");
|
||||
Shape* child = lovrCompoundShapeGetShape(shape, index);
|
||||
JPH_MutableCompoundShape_RemoveShape((JPH_MutableCompoundShape*) shape->shape, index);
|
||||
lovrRelease(child, lovrShapeDestroy);
|
||||
}
|
||||
|
||||
Shape* lovrCompoundShapeGetShape(CompoundShape* shape, uint32_t index) {
|
||||
const JPH_Shape* child;
|
||||
JPH_CompoundShape_GetSubShape((JPH_CompoundShape*) shape->shape, index, &child, NULL, NULL, NULL);
|
||||
return (Shape*) (uintptr_t) JPH_Shape_GetUserData(child);
|
||||
}
|
||||
|
||||
uint32_t lovrCompoundShapeGetShapeCount(CompoundShape* shape) {
|
||||
return JPH_CompoundShape_GetNumSubShapes((JPH_CompoundShape*) shape->shape);
|
||||
}
|
||||
|
||||
void lovrCompoundShapeGetShapeOffset(CompoundShape* shape, uint32_t index, float* position, float* orientation) {
|
||||
const JPH_Shape* child;
|
||||
JPH_Vec3 pos;
|
||||
JPH_Quat rot;
|
||||
uint32_t userData;
|
||||
JPH_CompoundShape_GetSubShape((JPH_CompoundShape*) shape->shape, index, &child, &pos, &rot, &userData);
|
||||
vec3_init(position, &pos.x);
|
||||
quat_init(orientation, &rot.x);
|
||||
}
|
||||
|
||||
void lovrCompoundShapeSetShapeOffset(CompoundShape* shape, uint32_t index, float* position, float* orientation) {
|
||||
lovrCheck(!lovrCompoundShapeIsFrozen(shape), "CompoundShape is frozen and can not be changed");
|
||||
JPH_Vec3 pos = { position[0], position[1], position[2] };
|
||||
JPH_Quat rot = { orientation[0], orientation[1], orientation[2], orientation[3] };
|
||||
JPH_MutableCompoundShape_ModifyShape((JPH_MutableCompoundShape*) shape->shape, index, &pos, &rot);
|
||||
}
|
||||
|
||||
// Joints
|
||||
|
||||
void lovrJointGetAnchors(Joint* joint, float anchor1[3], float anchor2[3]) {
|
||||
|
|
Loading…
Reference in New Issue