mirror of https://github.com/bjornbytes/lovr.git
Add ConvexShape;
Also luax_readmesh supports ModelData input, and the indices pointer can be NULL to only request the vertex positions.
This commit is contained in:
parent
f1ba4d1a1e
commit
aef71192ac
|
@ -515,18 +515,13 @@ void luax_optcolor(lua_State* L, int index, float color[4]) {
|
|||
|
||||
int luax_readmesh(lua_State* L, int index, float** vertices, uint32_t* vertexCount, uint32_t** indices, uint32_t* indexCount, bool* shouldFree) {
|
||||
if (lua_istable(L, index)) {
|
||||
luaL_checktype(L, index + 1, LUA_TTABLE);
|
||||
lua_rawgeti(L, index, 1);
|
||||
bool nested = lua_type(L, -1) == LUA_TTABLE;
|
||||
lua_pop(L, 1);
|
||||
|
||||
*vertexCount = luax_len(L, index) / (nested ? 1 : 3);
|
||||
*indexCount = luax_len(L, index + 1);
|
||||
lovrCheck(*vertexCount > 0, "Invalid mesh data: vertex count is zero");
|
||||
lovrCheck(*indexCount > 0, "Invalid mesh data: index count is zero");
|
||||
lovrCheck(*indexCount % 3 == 0, "Index count must be a multiple of 3");
|
||||
*vertices = lovrMalloc(sizeof(float) * *vertexCount * 3);
|
||||
*indices = lovrMalloc(sizeof(uint32_t) * *indexCount);
|
||||
*shouldFree = true;
|
||||
|
||||
if (nested) {
|
||||
|
@ -548,17 +543,33 @@ int luax_readmesh(lua_State* L, int index, float** vertices, uint32_t* vertexCou
|
|||
}
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < *indexCount; i++) {
|
||||
lua_rawgeti(L, index + 1, i + 1);
|
||||
uint32_t index = luaL_checkinteger(L, -1) - 1;
|
||||
lovrCheck(index < *vertexCount, "Invalid vertex index %d (expected [%d, %d])", index + 1, 1, *vertexCount);
|
||||
(*indices)[i] = index;
|
||||
lua_pop(L, 1);
|
||||
if (indices) {
|
||||
luaL_checktype(L, index + 1, LUA_TTABLE);
|
||||
*indexCount = luax_len(L, index + 1);
|
||||
lovrCheck(*indexCount > 0, "Invalid mesh data: index count is zero");
|
||||
lovrCheck(*indexCount % 3 == 0, "Index count must be a multiple of 3");
|
||||
*indices = lovrMalloc(sizeof(uint32_t) * *indexCount);
|
||||
|
||||
for (uint32_t i = 0; i < *indexCount; i++) {
|
||||
lua_rawgeti(L, index + 1, i + 1);
|
||||
uint32_t index = luaL_checkinteger(L, -1) - 1;
|
||||
lovrCheck(index < *vertexCount, "Invalid vertex index %d (expected [%d, %d])", index + 1, 1, *vertexCount);
|
||||
(*indices)[i] = index;
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
}
|
||||
|
||||
return index + 2;
|
||||
}
|
||||
|
||||
ModelData* modelData = luax_totype(L, index, ModelData);
|
||||
|
||||
if (modelData) {
|
||||
lovrModelDataGetTriangles(modelData, vertices, indices, vertexCount, indexCount);
|
||||
*shouldFree = false;
|
||||
return index + 1;
|
||||
}
|
||||
|
||||
#ifndef LOVR_DISABLE_GRAPHICS
|
||||
Model* model = luax_totype(L, index, Model);
|
||||
|
||||
|
@ -576,7 +587,9 @@ int luax_readmesh(lua_State* L, int index, float** vertices, uint32_t* vertexCou
|
|||
*shouldFree = true;
|
||||
return index + 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
return luaL_argerror(L, index, "table, Mesh, or Model");
|
||||
return luaL_argerror(L, index, "table, ModelData, Model, or Mesh expected");
|
||||
#else
|
||||
return luaL_argerror(L, index, "table or ModelData expected");
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -201,6 +201,7 @@ struct Shape* luax_newsphereshape(lua_State* L, int index);
|
|||
struct Shape* luax_newboxshape(lua_State* L, int index);
|
||||
struct Shape* luax_newcapsuleshape(lua_State* L, int index);
|
||||
struct Shape* luax_newcylindershape(lua_State* L, int index);
|
||||
struct Shape* luax_newconvexshape(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);
|
||||
|
|
|
@ -7,6 +7,7 @@ StringEntry lovrShapeType[] = {
|
|||
[SHAPE_BOX] = ENTRY("box"),
|
||||
[SHAPE_CAPSULE] = ENTRY("capsule"),
|
||||
[SHAPE_CYLINDER] = ENTRY("cylinder"),
|
||||
[SHAPE_CONVEX] = ENTRY("convex"),
|
||||
[SHAPE_MESH] = ENTRY("mesh"),
|
||||
[SHAPE_TERRAIN] = ENTRY("terrain"),
|
||||
[SHAPE_COMPOUND] = ENTRY("compound"),
|
||||
|
@ -121,6 +122,13 @@ static int l_lovrPhysicsNewCapsuleShape(lua_State* L) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
static int l_lovrPhysicsNewConvexShape(lua_State* L) {
|
||||
ConvexShape* convex = luax_newconvexshape(L, 1);
|
||||
luax_pushtype(L, ConvexShape, convex);
|
||||
lovrRelease(convex, lovrShapeDestroy);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int l_lovrPhysicsNewCylinderShape(lua_State* L) {
|
||||
CylinderShape* cylinder = luax_newcylindershape(L, 1);
|
||||
luax_pushtype(L, CylinderShape, cylinder);
|
||||
|
@ -196,6 +204,7 @@ static const luaL_Reg lovrPhysics[] = {
|
|||
{ "newBallJoint", l_lovrPhysicsNewBallJoint },
|
||||
{ "newBoxShape", l_lovrPhysicsNewBoxShape },
|
||||
{ "newCapsuleShape", l_lovrPhysicsNewCapsuleShape },
|
||||
{ "newConvexShape", l_lovrPhysicsNewConvexShape },
|
||||
{ "newCylinderShape", l_lovrPhysicsNewCylinderShape },
|
||||
{ "newDistanceJoint", l_lovrPhysicsNewDistanceJoint },
|
||||
{ "newHingeJoint", l_lovrPhysicsNewHingeJoint },
|
||||
|
@ -217,6 +226,7 @@ extern const luaL_Reg lovrSphereShape[];
|
|||
extern const luaL_Reg lovrBoxShape[];
|
||||
extern const luaL_Reg lovrCapsuleShape[];
|
||||
extern const luaL_Reg lovrCylinderShape[];
|
||||
extern const luaL_Reg lovrConvexShape[];
|
||||
extern const luaL_Reg lovrMeshShape[];
|
||||
extern const luaL_Reg lovrTerrainShape[];
|
||||
extern const luaL_Reg lovrCompoundShape[];
|
||||
|
@ -234,6 +244,7 @@ int luaopen_lovr_physics(lua_State* L) {
|
|||
luax_registertype(L, BoxShape);
|
||||
luax_registertype(L, CapsuleShape);
|
||||
luax_registertype(L, CylinderShape);
|
||||
luax_registertype(L, ConvexShape);
|
||||
luax_registertype(L, MeshShape);
|
||||
luax_registertype(L, TerrainShape);
|
||||
luax_registertype(L, CompoundShape);
|
||||
|
|
|
@ -12,6 +12,7 @@ void luax_pushshape(lua_State* L, Shape* shape) {
|
|||
case SHAPE_BOX: luax_pushtype(L, BoxShape, shape); break;
|
||||
case SHAPE_CAPSULE: luax_pushtype(L, CapsuleShape, shape); break;
|
||||
case SHAPE_CYLINDER: luax_pushtype(L, CylinderShape, shape); break;
|
||||
case SHAPE_CONVEX: luax_pushtype(L, ConvexShape, 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;
|
||||
|
@ -28,6 +29,7 @@ Shape* luax_checkshape(lua_State* L, int index) {
|
|||
hash64("BoxShape", strlen("BoxShape")),
|
||||
hash64("CapsuleShape", strlen("CapsuleShape")),
|
||||
hash64("CylinderShape", strlen("CylinderShape")),
|
||||
hash64("ConvexShape", strlen("ConvexShape")),
|
||||
hash64("MeshShape", strlen("MeshShape")),
|
||||
hash64("TerrainShape", strlen("TerrainShape")),
|
||||
hash64("CompoundShape", strlen("CompoundShape"))
|
||||
|
@ -67,6 +69,16 @@ Shape* luax_newcylindershape(lua_State* L, int index) {
|
|||
return lovrCylinderShapeCreate(radius, length);
|
||||
}
|
||||
|
||||
Shape* luax_newconvexshape(lua_State* L, int index) {
|
||||
float* points;
|
||||
uint32_t count;
|
||||
bool shouldFree;
|
||||
luax_readmesh(L, index, &points, &count, NULL, NULL, &shouldFree);
|
||||
ConvexShape* shape = lovrConvexShapeCreate(points, count);
|
||||
if (shouldFree) lovrFree(points);
|
||||
return shape;
|
||||
}
|
||||
|
||||
Shape* luax_newmeshshape(lua_State* L, int index) {
|
||||
float* vertices;
|
||||
uint32_t* indices;
|
||||
|
@ -371,6 +383,11 @@ const luaL_Reg lovrCylinderShape[] = {
|
|||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
const luaL_Reg lovrConvexShape[] = {
|
||||
lovrShape,
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
const luaL_Reg lovrMeshShape[] = {
|
||||
lovrShape,
|
||||
{ NULL, NULL }
|
||||
|
|
|
@ -150,6 +150,19 @@ static int l_lovrWorldNewCylinderCollider(lua_State* L) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
static int l_lovrWorldNewConvexCollider(lua_State* L) {
|
||||
World* world = luax_checktype(L, 1, World);
|
||||
float position[3];
|
||||
int index = luax_readvec3(L, 2, position, NULL);
|
||||
ConvexShape* shape = luax_newconvexshape(L, index);
|
||||
Collider* collider = lovrColliderCreate(world, shape, position);
|
||||
lovrColliderInitInertia(collider, shape);
|
||||
luax_pushtype(L, Collider, collider);
|
||||
lovrRelease(collider, lovrColliderDestroy);
|
||||
lovrRelease(shape, lovrShapeDestroy);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int l_lovrWorldNewSphereCollider(lua_State* L) {
|
||||
World* world = luax_checktype(L, 1, World);
|
||||
float position[3];
|
||||
|
@ -530,6 +543,7 @@ const luaL_Reg lovrWorld[] = {
|
|||
{ "newBoxCollider", l_lovrWorldNewBoxCollider },
|
||||
{ "newCapsuleCollider", l_lovrWorldNewCapsuleCollider },
|
||||
{ "newCylinderCollider", l_lovrWorldNewCylinderCollider },
|
||||
{ "newConvexCollider", l_lovrWorldNewConvexCollider },
|
||||
{ "newSphereCollider", l_lovrWorldNewSphereCollider },
|
||||
{ "newMeshCollider", l_lovrWorldNewMeshCollider },
|
||||
{ "newTerrainCollider", l_lovrWorldNewTerrainCollider },
|
||||
|
|
|
@ -527,7 +527,7 @@ static void collectVertices(ModelData* model, uint32_t nodeIndex, float** vertic
|
|||
*baseIndex += positions->count;
|
||||
}
|
||||
|
||||
if (index) {
|
||||
if (indices && index) {
|
||||
lovrAssert(index->type == U16 || index->type == U32, "Unreachable");
|
||||
|
||||
char* data = (char*) model->buffers[index->buffer].data + index->offset;
|
||||
|
@ -558,19 +558,18 @@ void lovrModelDataGetTriangles(ModelData* model, float** vertices, uint32_t** in
|
|||
}
|
||||
|
||||
if (vertices && !model->vertices) {
|
||||
uint32_t* tempIndices;
|
||||
uint32_t baseIndex = 0;
|
||||
model->vertices = lovrMalloc(model->totalVertexCount * 3 * sizeof(float));
|
||||
model->indices = lovrMalloc(model->totalIndexCount * sizeof(uint32_t));
|
||||
*vertices = model->vertices;
|
||||
*indices = model->indices;
|
||||
collectVertices(model, model->rootNode, vertices, indices, &baseIndex, (float[16]) MAT4_IDENTITY);
|
||||
tempIndices = model->indices;
|
||||
collectVertices(model, model->rootNode, vertices, &tempIndices, &baseIndex, (float[16]) MAT4_IDENTITY);
|
||||
}
|
||||
|
||||
*vertexCount = model->totalVertexCount;
|
||||
*indexCount = model->totalIndexCount;
|
||||
if (vertexCount) *vertexCount = model->totalVertexCount;
|
||||
if (indexCount) *indexCount = model->totalIndexCount;
|
||||
|
||||
if (vertices) {
|
||||
*vertices = model->vertices;
|
||||
*indices = model->indices;
|
||||
}
|
||||
if (vertices) *vertices = model->vertices;
|
||||
if (indices) *indices = model->indices;
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@ typedef Shape SphereShape;
|
|||
typedef Shape BoxShape;
|
||||
typedef Shape CapsuleShape;
|
||||
typedef Shape CylinderShape;
|
||||
typedef Shape ConvexShape;
|
||||
typedef Shape MeshShape;
|
||||
typedef Shape TerrainShape;
|
||||
typedef Shape CompoundShape;
|
||||
|
@ -157,6 +158,7 @@ typedef enum {
|
|||
SHAPE_BOX,
|
||||
SHAPE_CAPSULE,
|
||||
SHAPE_CYLINDER,
|
||||
SHAPE_CONVEX,
|
||||
SHAPE_MESH,
|
||||
SHAPE_TERRAIN,
|
||||
SHAPE_COMPOUND
|
||||
|
@ -182,6 +184,8 @@ CylinderShape* lovrCylinderShapeCreate(float radius, float length);
|
|||
float lovrCylinderShapeGetRadius(CylinderShape* cylinder);
|
||||
float lovrCylinderShapeGetLength(CylinderShape* cylinder);
|
||||
|
||||
ConvexShape* lovrConvexShapeCreate(float points[], uint32_t count);
|
||||
|
||||
MeshShape* lovrMeshShapeCreate(int vertexCount, float vertices[], int indexCount, uint32_t indices[]);
|
||||
|
||||
TerrainShape* lovrTerrainShapeCreate(float* vertices, uint32_t n, float scaleXZ, float scaleY);
|
||||
|
@ -201,6 +205,7 @@ void lovrCompoundShapeSetChildOffset(CompoundShape* shape, uint32_t index, float
|
|||
#define lovrBoxShapeDestroy lovrShapeDestroy
|
||||
#define lovrCapsuleShapeDestroy lovrShapeDestroy
|
||||
#define lovrCylinderShapeDestroy lovrShapeDestroy
|
||||
#define lovrConvexShapeDestroy lovrShapeDestroy
|
||||
#define lovrMeshShapeDestroy lovrShapeDestroy
|
||||
#define lovrTerrainShapeDestroy lovrShapeDestroy
|
||||
#define lovrCompoundShapeDestroy lovrShapeDestroy
|
||||
|
|
|
@ -915,6 +915,16 @@ float lovrCylinderShapeGetLength(CylinderShape* cylinder) {
|
|||
return JPH_CylinderShape_GetHalfHeight((JPH_CylinderShape*) cylinder->shape) * 2.f;
|
||||
}
|
||||
|
||||
ConvexShape* lovrConvexShapeCreate(float points[], uint32_t count) {
|
||||
ConvexShape* convex = lovrCalloc(sizeof(ConvexShape));
|
||||
convex->ref = 1;
|
||||
convex->type = SHAPE_CONVEX;
|
||||
JPH_ConvexHullShapeSettings* settings = JPH_ConvexHullShapeSettings_Create((const JPH_Vec3*) points, count, .05f);
|
||||
convex->shape = (JPH_Shape*) JPH_ConvexHullShapeSettings_CreateShape(settings);
|
||||
JPH_ShapeSettings_Destroy((JPH_ShapeSettings*) settings);
|
||||
return convex;
|
||||
}
|
||||
|
||||
MeshShape* lovrMeshShapeCreate(int vertexCount, float vertices[], int indexCount, uint32_t indices[]) {
|
||||
MeshShape* mesh = lovrCalloc(sizeof(MeshShape));
|
||||
mesh->ref = 1;
|
||||
|
|
|
@ -1048,6 +1048,10 @@ float lovrCylinderShapeGetLength(CylinderShape* cylinder) {
|
|||
return length;
|
||||
}
|
||||
|
||||
ConvexShape* lovrConvexShapeCreate(float positions[], uint32_t count) {
|
||||
lovrThrow("ODE does not support ConvexShape");
|
||||
}
|
||||
|
||||
MeshShape* lovrMeshShapeCreate(int vertexCount, float* vertices, int indexCount, dTriIndex* indices) {
|
||||
MeshShape* mesh = lovrCalloc(sizeof(MeshShape));
|
||||
mesh->ref = 1;
|
||||
|
@ -1075,7 +1079,7 @@ TerrainShape* lovrTerrainShapeCreate(float* vertices, uint32_t n, float scaleXZ,
|
|||
}
|
||||
|
||||
CompoundShape* lovrCompoundShapeCreate(Shape** shapes, float* positions, float* orientations, uint32_t count, bool freeze) {
|
||||
lovrThrow("ODE does not support compound shape");
|
||||
lovrThrow("ODE does not support CompoundShape");
|
||||
}
|
||||
|
||||
bool lovrCompoundShapeIsFrozen(CompoundShape* shape) {
|
||||
|
|
Loading…
Reference in New Issue