Finish Model API;

This commit is contained in:
bjorn 2022-07-12 19:35:23 -07:00
parent cd65e8d34c
commit 1c571001e7
8 changed files with 555 additions and 238 deletions

View File

@ -49,6 +49,7 @@ extern StringEntry lovrKeyboardKey[];
extern StringEntry lovrMaterialColor[];
extern StringEntry lovrMaterialScalar[];
extern StringEntry lovrMaterialTexture[];
extern StringEntry lovrMeshMode[];
extern StringEntry lovrPassType[];
extern StringEntry lovrPermission[];
extern StringEntry lovrSampleFormat[];
@ -64,7 +65,6 @@ extern StringEntry lovrTextureType[];
extern StringEntry lovrTextureUsage[];
extern StringEntry lovrTimeUnit[];
extern StringEntry lovrUniformAccess[];
extern StringEntry lovrVertexMode[];
extern StringEntry lovrVerticalAlign[];
extern StringEntry lovrVolumeUnit[];
extern StringEntry lovrWinding[];

View File

@ -90,18 +90,86 @@ static int l_lovrModelDataGetImage(lua_State* L) {
return 1;
}
static int l_lovrModelDataGetNodeCount(lua_State* L) {
static int l_lovrModelDataGetWidth(lua_State* L) {
ModelData* model = luax_checktype(L, 1, ModelData);
lua_pushinteger(L, model->nodeCount);
float bounds[6];
lovrModelDataGetBoundingBox(model, bounds);
lua_pushnumber(L, bounds[1] - bounds[0]);
return 1;
}
static int l_lovrModelDataGetHeight(lua_State* L) {
ModelData* model = luax_checktype(L, 1, ModelData);
float bounds[6];
lovrModelDataGetBoundingBox(model, bounds);
lua_pushnumber(L, bounds[3] - bounds[2]);
return 1;
}
static int l_lovrModelDataGetDepth(lua_State* L) {
ModelData* model = luax_checktype(L, 1, ModelData);
float bounds[6];
lovrModelDataGetBoundingBox(model, bounds);
lua_pushnumber(L, bounds[5] - bounds[4]);
return 1;
}
static int l_lovrModelDataGetDimensions(lua_State* L) {
ModelData* model = luax_checktype(L, 1, ModelData);
float bounds[6];
lovrModelDataGetBoundingBox(model, bounds);
lua_pushnumber(L, bounds[1] - bounds[0]);
lua_pushnumber(L, bounds[3] - bounds[2]);
lua_pushnumber(L, bounds[5] - bounds[4]);
return 3;
}
static int l_lovrModelDataGetCenter(lua_State* L) {
ModelData* model = luax_checktype(L, 1, ModelData);
float bounds[6];
lovrModelDataGetBoundingBox(model, bounds);
lua_pushnumber(L, (bounds[0] + bounds[1]) / 2.f);
lua_pushnumber(L, (bounds[2] + bounds[3]) / 2.f);
lua_pushnumber(L, (bounds[4] + bounds[5]) / 2.f);
return 3;
}
static int l_lovrModelDataGetBoundingBox(lua_State* L) {
ModelData* model = luax_checktype(L, 1, ModelData);
float bounds[6];
lovrModelDataGetBoundingBox(model, bounds);
lua_pushnumber(L, bounds[0]);
lua_pushnumber(L, bounds[1]);
lua_pushnumber(L, bounds[2]);
lua_pushnumber(L, bounds[3]);
lua_pushnumber(L, bounds[4]);
lua_pushnumber(L, bounds[5]);
return 6;
}
static int l_lovrModelDataGetBoundingSphere(lua_State* L) {
ModelData* model = luax_checktype(L, 1, ModelData);
float sphere[4];
lovrModelDataGetBoundingSphere(model, sphere);
lua_pushnumber(L, sphere[0]);
lua_pushnumber(L, sphere[1]);
lua_pushnumber(L, sphere[2]);
lua_pushnumber(L, sphere[3]);
return 4;
}
static int l_lovrModelDataGetRootNode(lua_State* L) {
ModelData* model = luax_checktype(L, 1, ModelData);
lua_pushinteger(L, model->rootNode + 1);
return 1;
}
static int l_lovrModelDataGetNodeCount(lua_State* L) {
ModelData* model = luax_checktype(L, 1, ModelData);
lua_pushinteger(L, model->nodeCount);
return 1;
}
static int l_lovrModelDataGetNodeName(lua_State* L) {
ModelData* model = luax_checktype(L, 1, ModelData);
uint32_t index = luax_checku32(L, 2) - 1;
@ -110,6 +178,28 @@ static int l_lovrModelDataGetNodeName(lua_State* L) {
return 1;
}
static int l_lovrModelDataGetNodeParent(lua_State* L) {
ModelData* model = luax_checktype(L, 1, ModelData);
ModelNode* node = luax_checknode(L, 2, model);
if (node->parent == ~0u) {
lua_pushnil(L);
} else {
lua_pushinteger(L, node->parent + 1);
}
return 1;
}
static int l_lovrModelDataGetNodeChildren(lua_State* L) {
ModelData* model = luax_checktype(L, 1, ModelData);
ModelNode* node = luax_checknode(L, 2, model);
lua_createtable(L, node->childCount, 0);
for (uint32_t i = 0; i < node->childCount; i++) {
lua_pushinteger(L, node->children[i] + 1);
lua_rawseti(L, -2, i + 1);
}
return 1;
}
static int l_lovrModelDataGetNodePosition(lua_State* L) {
ModelData* model = luax_checktype(L, 1, ModelData);
ModelNode* node = luax_checknode(L, 2, model);
@ -161,6 +251,34 @@ static int l_lovrModelDataGetNodeScale(lua_State* L) {
return 3;
}
static int l_lovrModelDataGetNodePose(lua_State* L) {
ModelData* model = luax_checktype(L, 1, ModelData);
ModelNode* node = luax_checknode(L, 2, model);
if (node->matrix) {
float position[3], angle, ax, ay, az;
mat4_getPosition(node->transform.matrix, position);
mat4_getAngleAxis(node->transform.matrix, &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);
} else {
float angle, ax, ay, az;
quat_getAngleAxis(node->transform.properties.rotation, &angle, &ax, &ay, &az);
lua_pushnumber(L, node->transform.properties.translation[0]);
lua_pushnumber(L, node->transform.properties.translation[1]);
lua_pushnumber(L, node->transform.properties.translation[2]);
lua_pushnumber(L, angle);
lua_pushnumber(L, ax);
lua_pushnumber(L, ay);
lua_pushnumber(L, az);
}
return 7;
}
static int l_lovrModelDataGetNodeTransform(lua_State* L) {
ModelData* model = luax_checktype(L, 1, ModelData);
ModelNode* node = luax_checknode(L, 2, model);
@ -196,28 +314,6 @@ static int l_lovrModelDataGetNodeTransform(lua_State* L) {
return 10;
}
static int l_lovrModelDataGetNodeParent(lua_State* L) {
ModelData* model = luax_checktype(L, 1, ModelData);
ModelNode* node = luax_checknode(L, 2, model);
if (node->parent == ~0u) {
lua_pushnil(L);
} else {
lua_pushinteger(L, node->parent + 1);
}
return 1;
}
static int l_lovrModelDataGetNodeChildren(lua_State* L) {
ModelData* model = luax_checktype(L, 1, ModelData);
ModelNode* node = luax_checknode(L, 2, model);
lua_createtable(L, node->childCount, 0);
for (uint32_t i = 0; i < node->childCount; i++) {
lua_pushinteger(L, node->children[i] + 1);
lua_rawseti(L, -2, i + 1);
}
return 1;
}
static int l_lovrModelDataGetNodeMeshes(lua_State* L) {
ModelData* model = luax_checktype(L, 1, ModelData);
ModelNode* node = luax_checknode(L, 2, model);
@ -398,6 +494,46 @@ static int l_lovrModelDataGetMeshIndex(lua_State* L) {
}
}
static int l_lovrModelDataGetTriangles(lua_State* L) {
ModelData* model = luax_checktype(L, 1, ModelData);
float* vertices = NULL;
uint32_t* indices = NULL;
uint32_t vertexCount = 0;
uint32_t indexCount = 0;
lovrModelDataGetTriangles(model, &vertices, &indices, &vertexCount, &indexCount);
lua_createtable(L, vertexCount * 3, 0);
for (uint32_t i = 0; i < vertexCount * 3; i++) {
lua_pushnumber(L, vertices[i]);
lua_rawseti(L, -2, i + 1);
}
lua_createtable(L, indexCount, 0);
for (uint32_t i = 0; i < indexCount; i++) {
lua_pushinteger(L, indices[i] + 1);
lua_rawseti(L, -2, i + 1);
}
return 2;
}
static int l_lovrModelDataGetTriangleCount(lua_State* L) {
ModelData* model = luax_checktype(L, 1, ModelData);
uint32_t vertexCount, indexCount;
lovrModelDataGetTriangles(model, NULL, NULL, &vertexCount, &indexCount);
lua_pushinteger(L, indexCount / 3);
return 1;
}
static int l_lovrModelDataGetVertexCount(lua_State* L) {
ModelData* model = luax_checktype(L, 1, ModelData);
uint32_t vertexCount, indexCount;
lovrModelDataGetTriangles(model, NULL, NULL, &vertexCount, &indexCount);
lua_pushinteger(L, vertexCount);
return 1;
}
static int l_lovrModelDataGetMaterialCount(lua_State* L) {
ModelData* model = luax_checktype(L, 1, ModelData);
lua_pushinteger(L, model->materialCount);
@ -494,7 +630,7 @@ static int l_lovrModelDataGetAnimationChannelCount(lua_State* L) {
return 1;
}
static int l_lovrModelDataGetAnimationChannelNode(lua_State* L) {
static int l_lovrModelDataGetAnimationNode(lua_State* L) {
ModelData* model = luax_checktype(L, 1, ModelData);
ModelAnimation* animation = luax_checkanimation(L, 2, model);
uint32_t index = luax_checku32(L, 3) - 1;
@ -504,7 +640,7 @@ static int l_lovrModelDataGetAnimationChannelNode(lua_State* L) {
return 1;
}
static int l_lovrModelDataGetAnimationChannelProperty(lua_State* L) {
static int l_lovrModelDataGetAnimationProperty(lua_State* L) {
ModelData* model = luax_checktype(L, 1, ModelData);
ModelAnimation* animation = luax_checkanimation(L, 2, model);
uint32_t index = luax_checku32(L, 3) - 1;
@ -514,7 +650,7 @@ static int l_lovrModelDataGetAnimationChannelProperty(lua_State* L) {
return 1;
}
static int l_lovrModelDataGetAnimationChannelSmoothMode(lua_State* L) {
static int l_lovrModelDataGetAnimationSmoothMode(lua_State* L) {
ModelData* model = luax_checktype(L, 1, ModelData);
ModelAnimation* animation = luax_checkanimation(L, 2, model);
uint32_t index = luax_checku32(L, 3) - 1;
@ -524,7 +660,7 @@ static int l_lovrModelDataGetAnimationChannelSmoothMode(lua_State* L) {
return 1;
}
static int l_lovrModelDataGetAnimationChannelKeyframeCount(lua_State* L) {
static int l_lovrModelDataGetAnimationKeyframeCount(lua_State* L) {
ModelData* model = luax_checktype(L, 1, ModelData);
ModelAnimation* animation = luax_checkanimation(L, 2, model);
uint32_t index = luax_checku32(L, 3) - 1;
@ -534,7 +670,7 @@ static int l_lovrModelDataGetAnimationChannelKeyframeCount(lua_State* L) {
return 1;
}
static int l_lovrModelDataGetAnimationChannelKeyframe(lua_State* L) {
static int l_lovrModelDataGetAnimationKeyframe(lua_State* L) {
ModelData* model = luax_checktype(L, 1, ModelData);
ModelAnimation* animation = luax_checkanimation(L, 2, model);
uint32_t index = luax_checku32(L, 3) - 1;
@ -589,15 +725,16 @@ const luaL_Reg lovrModelData[] = {
{ "getBlob", l_lovrModelDataGetBlob },
{ "getImageCount", l_lovrModelDataGetImageCount },
{ "getImage", l_lovrModelDataGetImage },
{ "getNodeCount", l_lovrModelDataGetNodeCount },
{ "getRootNode", l_lovrModelDataGetRootNode },
{ "getNodeCount", l_lovrModelDataGetNodeCount },
{ "getNodeName", l_lovrModelDataGetNodeName },
{ "getNodeParent", l_lovrModelDataGetNodeParent },
{ "getNodeChildren", l_lovrModelDataGetNodeChildren },
{ "getNodePosition", l_lovrModelDataGetNodePosition },
{ "getNodeOrientation", l_lovrModelDataGetNodeOrientation },
{ "getNodeScale", l_lovrModelDataGetNodeScale },
{ "getNodePose", l_lovrModelDataGetNodePose },
{ "getNodeTransform", l_lovrModelDataGetNodeTransform },
{ "getNodeParent", l_lovrModelDataGetNodeParent },
{ "getNodeChildren", l_lovrModelDataGetNodeChildren },
{ "getNodeMeshes", l_lovrModelDataGetNodeMeshes },
{ "getNodeSkin", l_lovrModelDataGetNodeSkin },
{ "getMeshCount", l_lovrModelDataGetMeshCount },
@ -609,7 +746,16 @@ const luaL_Reg lovrModelData[] = {
{ "getMeshIndexFormat", l_lovrModelDataGetMeshIndexFormat },
{ "getMeshVertex", l_lovrModelDataGetMeshVertex },
{ "getMeshIndex", l_lovrModelDataGetMeshIndex },
{ "getMeshIndex", l_lovrModelDataGetMeshIndex },
{ "getTriangles", l_lovrModelDataGetTriangles },
{ "getTriangleCount", l_lovrModelDataGetTriangleCount },
{ "getVertexCount", l_lovrModelDataGetVertexCount },
{ "getWidth", l_lovrModelDataGetWidth },
{ "getHeight", l_lovrModelDataGetHeight },
{ "getDepth", l_lovrModelDataGetDepth },
{ "getDimensions", l_lovrModelDataGetDimensions },
{ "getCenter", l_lovrModelDataGetCenter },
{ "getBoundingBox", l_lovrModelDataGetBoundingBox },
{ "getBoundingSphere", l_lovrModelDataGetBoundingSphere },
{ "getMaterialCount", l_lovrModelDataGetMaterialCount },
{ "getMaterialName", l_lovrModelDataGetMaterialName },
{ "getMaterialImage", l_lovrModelDataGetMaterialImage },
@ -619,11 +765,11 @@ const luaL_Reg lovrModelData[] = {
{ "getAnimationName", l_lovrModelDataGetAnimationName },
{ "getAnimationDuration", l_lovrModelDataGetAnimationDuration },
{ "getAnimationChannelCount", l_lovrModelDataGetAnimationChannelCount },
{ "getAnimationChannelNode", l_lovrModelDataGetAnimationChannelNode },
{ "getAnimationChannelProperty", l_lovrModelDataGetAnimationChannelProperty },
{ "getAnimationChannelSmoothMode", l_lovrModelDataGetAnimationChannelSmoothMode },
{ "getAnimationChannelKeyframeCount", l_lovrModelDataGetAnimationChannelKeyframeCount },
{ "getAnimationChannelKeyframe", l_lovrModelDataGetAnimationChannelKeyframe },
{ "getAnimationNode", l_lovrModelDataGetAnimationNode },
{ "getAnimationProperty", l_lovrModelDataGetAnimationProperty },
{ "getAnimationSmoothMode", l_lovrModelDataGetAnimationSmoothMode },
{ "getAnimationKeyframeCount", l_lovrModelDataGetAnimationKeyframeCount },
{ "getAnimationKeyframe", l_lovrModelDataGetAnimationKeyframe },
{ "getSkinCount", l_lovrModelDataGetSkinCount },
{ "getSkinJoints", l_lovrModelDataGetSkinJoints },
{ "getSkinInverseBindMatrix", l_lovrModelDataGetSkinInverseBindMatrix },

View File

@ -124,6 +124,13 @@ StringEntry lovrHorizontalAlign[] = {
{ 0 }
};
StringEntry lovrMeshMode[] = {
[MESH_POINTS] = ENTRY("points"),
[MESH_LINES] = ENTRY("lines"),
[MESH_TRIANGLES] = ENTRY("triangles"),
{ 0 }
};
StringEntry lovrPassType[] = {
[PASS_RENDER] = ENTRY("render"),
[PASS_COMPUTE] = ENTRY("compute"),
@ -189,13 +196,6 @@ StringEntry lovrTextureUsage[] = {
{ 0 }
};
StringEntry lovrVertexMode[] = {
[VERTEX_POINTS] = ENTRY("points"),
[VERTEX_LINES] = ENTRY("lines"),
[VERTEX_TRIANGLES] = ENTRY("triangles"),
{ 0 }
};
StringEntry lovrVerticalAlign[] = {
[ALIGN_TOP] = ENTRY("top"),
[ALIGN_MIDDLE] = ENTRY("middle"),

View File

@ -2,6 +2,8 @@
#include <lua.h>
#include <lauxlib.h>
const luaL_Reg lovrMaterial[] = {
{ NULL, NULL }
};

View File

@ -6,6 +6,20 @@
#include <lua.h>
#include <lauxlib.h>
// This adds about 2-3us of overhead, which sucks, but the reduction in complexity is large
static int luax_callmodeldata(lua_State* L, const char* method, int nrets) {
int nargs = lua_gettop(L);
Model* model = luax_checktype(L, 1, Model);
ModelData* data = lovrModelGetInfo(model)->data;
luax_pushtype(L, ModelData, data);
lua_pushstring(L, method);
lua_gettable(L, -2);
lua_insert(L, 1);
lua_replace(L, 2);
lua_call(L, nargs, nrets);
return nrets;
}
static uint32_t luax_checkanimation(lua_State* L, int index, Model* model) {
switch (lua_type(L, index)) {
case LUA_TSTRING: {
@ -36,38 +50,139 @@ uint32_t luax_checknodeindex(lua_State* L, int index, Model* model) {
}
}
static int l_lovrModelGetModelData(lua_State* L) {
static int l_lovrModelGetData(lua_State* L) {
Model* model = luax_checktype(L, 1, Model);
ModelData* data = lovrModelGetInfo(model)->data;
luax_pushtype(L, ModelData, data);
return 1;
}
static int l_lovrModelAnimate(lua_State* L) {
static int l_lovrModelGetRootNode(lua_State* L) {
return luax_callmodeldata(L, "getRootNode", 1);
}
static int l_lovrModelGetNodeCount(lua_State* L) {
return luax_callmodeldata(L, "getNodeCount", 1);
}
static int l_lovrModelGetNodeName(lua_State* L) {
return luax_callmodeldata(L, "getNodeName", 1);
}
static int l_lovrModelGetNodeParent(lua_State* L) {
return luax_callmodeldata(L, "getNodeParent", 1);
}
static int l_lovrModelGetNodeChildren(lua_State* L) {
return luax_callmodeldata(L, "getNodeChildren", 1);
}
static int l_lovrModelGetNodeDrawCount(lua_State* L) {
Model* model = luax_checktype(L, 1, Model);
uint32_t animation = luax_checkanimation(L, 2, model);
float time = luax_checkfloat(L, 3);
float alpha = luax_optfloat(L, 4, 1.f);
lovrModelAnimate(model, animation, time, alpha);
uint32_t node = luax_checknodeindex(L, 2, model);
uint32_t count = lovrModelGetNodeDrawCount(model, node);
lua_pushinteger(L, count);
return 1;
}
static int l_lovrModelGetNodeDraw(lua_State* L) {
Model* model = luax_checktype(L, 1, Model);
uint32_t node = luax_checknodeindex(L, 2, model);
uint32_t index = luax_optu32(L, 3, 1) - 1;
ModelDraw draw;
lovrModelGetNodeDraw(model, node, index, &draw);
luax_pushenum(L, MeshMode, draw.mode);
luax_pushtype(L, Material, draw.material);
lua_pushinteger(L, draw.start);
lua_pushinteger(L, draw.count);
if (draw.indexed) {
lua_pushinteger(L, draw.base);
return 5;
} else {
return 4;
}
}
static int l_lovrModelGetNodePosition(lua_State* L) {
Model* model = luax_checktype(L, 1, Model);
uint32_t node = luax_checknodeindex(L, 2, model);
CoordinateSpace space = luax_checkenum(L, 3, CoordinateSpace, "global");
float position[4], scale[4], rotation[4];
lovrModelGetNodeTransform(model, node, position, scale, rotation, space);
lua_pushnumber(L, position[0]);
lua_pushnumber(L, position[1]);
lua_pushnumber(L, position[2]);
return 3;
}
static int l_lovrModelSetNodePosition(lua_State* L) {
Model* model = luax_checktype(L, 1, Model);
uint32_t node = luax_checknodeindex(L, 2, model);
float position[4];
int index = luax_readvec3(L, 3, position, NULL);
float alpha = luax_optfloat(L, index, 1.f);
lovrModelSetNodeTransform(model, node, position, NULL, NULL, alpha);
return 0;
}
static int l_lovrModelResetPose(lua_State* L) {
static int l_lovrModelGetNodeScale(lua_State* L) {
Model* model = luax_checktype(L, 1, Model);
lovrModelResetPose(model);
uint32_t node = luax_checknodeindex(L, 2, model);
CoordinateSpace space = luax_checkenum(L, 3, CoordinateSpace, "global");
float position[4], scale[4], rotation[4], angle, ax, ay, az;
lovrModelGetNodeTransform(model, node, position, scale, rotation, space);
quat_getAngleAxis(rotation, &angle, &ax, &ay, &az);
lua_pushnumber(L, angle);
lua_pushnumber(L, ax);
lua_pushnumber(L, ay);
lua_pushnumber(L, az);
return 4;
}
static int l_lovrModelSetNodeScale(lua_State* L) {
Model* model = luax_checktype(L, 1, Model);
uint32_t node = luax_checknodeindex(L, 2, model);
float scale[4];
int index = luax_readscale(L, 3, scale, 3, NULL);
float alpha = luax_optfloat(L, index, 1.f);
lovrModelSetNodeTransform(model, node, NULL, scale, NULL, alpha);
return 0;
}
static int l_lovrModelGetNodeOrientation(lua_State* L) {
Model* model = luax_checktype(L, 1, Model);
uint32_t node = luax_checknodeindex(L, 2, model);
CoordinateSpace space = luax_checkenum(L, 3, CoordinateSpace, "global");
float position[4], scale[4], rotation[4], angle, ax, ay, az;
lovrModelGetNodeTransform(model, node, position, scale, rotation, space);
quat_getAngleAxis(rotation, &angle, &ax, &ay, &az);
lua_pushnumber(L, angle);
lua_pushnumber(L, ax);
lua_pushnumber(L, ay);
lua_pushnumber(L, az);
return 4;
}
static int l_lovrModelSetNodeOrientation(lua_State* L) {
Model* model = luax_checktype(L, 1, Model);
uint32_t node = luax_checknodeindex(L, 2, model);
float rotation[4];
int index = luax_readquat(L, 3, rotation, NULL);
float alpha = luax_optfloat(L, index, 1.f);
lovrModelSetNodeTransform(model, node, NULL, NULL, rotation, alpha);
return 0;
}
static int l_lovrModelGetNodePose(lua_State* L) {
Model* model = luax_checktype(L, 1, Model);
uint32_t node = luax_checknodeindex(L, 2, model);
float position[4], rotation[4], angle, ax, ay, az;
CoordinateSpace space = luax_checkenum(L, 3, CoordinateSpace, "global");
lovrModelGetNodePose(model, node, position, rotation, space);
float position[4], scale[4], rotation[4], angle, ax, ay, az;
lovrModelGetNodeTransform(model, node, position, scale, rotation, space);
quat_getAngleAxis(rotation, &angle, &ax, &ay, &az);
lua_pushnumber(L, position[0]);
lua_pushnumber(L, position[1]);
lua_pushnumber(L, position[2]);
quat_getAngleAxis(rotation, &angle, &ax, &ay, &az);
lua_pushnumber(L, angle);
lua_pushnumber(L, ax);
lua_pushnumber(L, ay);
@ -83,24 +198,122 @@ static int l_lovrModelSetNodePose(lua_State* L) {
index = luax_readvec3(L, index, position, NULL);
index = luax_readquat(L, index, rotation, NULL);
float alpha = luax_optfloat(L, index, 1.f);
lovrModelSetNodePose(model, node, position, rotation, alpha);
lovrModelSetNodeTransform(model, node, position, NULL, rotation, alpha);
return 0;
}
static int l_lovrModelGetTexture(lua_State* L) {
static int l_lovrModelGetNodeTransform(lua_State* L) {
Model* model = luax_checktype(L, 1, Model);
uint32_t index = luaL_checkinteger(L, 2);
Texture* texture = lovrModelGetTexture(model, index);
luax_pushtype(L, Texture, texture);
uint32_t node = luax_checknodeindex(L, 2, model);
CoordinateSpace space = luax_checkenum(L, 3, CoordinateSpace, "global");
float position[4], scale[4], rotation[4], angle, ax, ay, az;
lovrModelGetNodeTransform(model, node, position, scale, rotation, space);
quat_getAngleAxis(rotation, &angle, &ax, &ay, &az);
lua_pushnumber(L, position[0]);
lua_pushnumber(L, position[1]);
lua_pushnumber(L, position[2]);
lua_pushnumber(L, scale[0]);
lua_pushnumber(L, scale[1]);
lua_pushnumber(L, scale[2]);
lua_pushnumber(L, angle);
lua_pushnumber(L, ax);
lua_pushnumber(L, ay);
lua_pushnumber(L, az);
return 10;
}
static int l_lovrModelSetNodeTransform(lua_State* L) {
Model* model = luax_checktype(L, 1, Model);
uint32_t node = luax_checknodeindex(L, 2, model);
int index = 3;
VectorType type;
float position[4], scale[4], rotation[4];
float* m = luax_tovector(L, index, &type);
if (m && type == V_MAT4) {
mat4_getPosition(m, position);
mat4_getScale(m, scale);
mat4_getOrientation(m, rotation);
index = 4;
} else {
index = luax_readvec3(L, index, position, NULL);
index = luax_readscale(L, index, scale, 3, NULL);
index = luax_readquat(L, index, rotation, NULL);
}
float alpha = luax_optfloat(L, index, 1.f);
lovrModelSetNodeTransform(model, node, position, scale, rotation, alpha);
return 0;
}
static int l_lovrModelGetAnimationCount(lua_State* L) {
return luax_callmodeldata(L, "getAnimationCount", 1);
}
static int l_lovrModelGetAnimationName(lua_State* L) {
return luax_callmodeldata(L, "getAnimationName", 1);
}
static int l_lovrModelGetAnimationDuration(lua_State* L) {
return luax_callmodeldata(L, "getAnimationDuration", 1);
}
static int l_lovrModelHasJoints(lua_State* L) {
Model* model = luax_checktype(L, 1, Model);
ModelData* data = lovrModelGetInfo(model)->data;
lua_pushboolean(L, data->skinCount > 0);
return 1;
}
static int l_lovrModelGetMaterial(lua_State* L) {
static int l_lovrModelAnimate(lua_State* L) {
Model* model = luax_checktype(L, 1, Model);
uint32_t index = luaL_checkinteger(L, 2);
Material* material = lovrModelGetMaterial(model, index);
luax_pushtype(L, Material, material);
return 1;
if (lua_isnoneornil(L, 2)) {
lovrModelResetNodeTransforms(model);
} else {
uint32_t animation = luax_checkanimation(L, 2, model);
float time = luax_checkfloat(L, 3);
float alpha = luax_optfloat(L, 4, 1.f);
lovrModelAnimate(model, animation, time, alpha);
}
return 0;
}
static int l_lovrModelGetTriangles(lua_State* L) {
return luax_callmodeldata(L, "getTriangles", 2);
}
static int l_lovrModelGetTriangleCount(lua_State* L) {
return luax_callmodeldata(L, "getTriangleCount", 1);
}
static int l_lovrModelGetVertexCount(lua_State* L) {
return luax_callmodeldata(L, "getVertexCount", 1);
}
static int l_lovrModelGetWidth(lua_State* L) {
return luax_callmodeldata(L, "getWidth", 1);
}
static int l_lovrModelGetHeight(lua_State* L) {
return luax_callmodeldata(L, "getHeight", 1);
}
static int l_lovrModelGetDepth(lua_State* L) {
return luax_callmodeldata(L, "getDepth", 1);
}
static int l_lovrModelGetDimensions(lua_State* L) {
return luax_callmodeldata(L, "getDimensions", 3);
}
static int l_lovrModelGetCenter(lua_State* L) {
return luax_callmodeldata(L, "getCenter", 3);
}
static int l_lovrModelGetBoundingBox(lua_State* L) {
return luax_callmodeldata(L, "getBoundingBox", 6);
}
static int l_lovrModelGetBoundingSphere(lua_State* L) {
return luax_callmodeldata(L, "getBoundingSphere", 4);
}
static int l_lovrModelGetVertexBuffer(lua_State* L) {
@ -117,134 +330,54 @@ static int l_lovrModelGetIndexBuffer(lua_State* L) {
return 1;
}
static int l_lovrModelGetTriangles(lua_State* L) {
Model* model = luax_checktype(L, 1, Model);
ModelData* data = lovrModelGetInfo(model)->data;
float* vertices = NULL;
uint32_t* indices = NULL;
uint32_t vertexCount = 0;
uint32_t indexCount = 0;
lovrModelDataGetTriangles(data, &vertices, &indices, &vertexCount, &indexCount);
lua_createtable(L, vertexCount * 3, 0);
for (uint32_t i = 0; i < vertexCount * 3; i++) {
lua_pushnumber(L, vertices[i]);
lua_rawseti(L, -2, i + 1);
}
lua_createtable(L, indexCount, 0);
for (uint32_t i = 0; i < indexCount; i++) {
lua_pushinteger(L, indices[i] + 1);
lua_rawseti(L, -2, i + 1);
}
return 2;
static int l_lovrModelGetMaterialCount(lua_State* L) {
return luax_callmodeldata(L, "getMaterialCount", 1);
}
static int l_lovrModelGetTriangleCount(lua_State* L) {
static int l_lovrModelGetTextureCount(lua_State* L) {
return luax_callmodeldata(L, "getImageCount", 1);
}
static int l_lovrModelGetMaterial(lua_State* L) {
Model* model = luax_checktype(L, 1, Model);
ModelData* data = lovrModelGetInfo(model)->data;
uint32_t vertexCount, indexCount;
lovrModelDataGetTriangles(data, NULL, NULL, &vertexCount, &indexCount);
lua_pushinteger(L, indexCount / 3);
uint32_t index = luaL_checkinteger(L, 2);
Material* material = lovrModelGetMaterial(model, index);
luax_pushtype(L, Material, material);
return 1;
}
static int l_lovrModelGetVertexCount(lua_State* L) {
static int l_lovrModelGetTexture(lua_State* L) {
Model* model = luax_checktype(L, 1, Model);
ModelData* data = lovrModelGetInfo(model)->data;
uint32_t vertexCount, indexCount;
lovrModelDataGetTriangles(data, NULL, NULL, &vertexCount, &indexCount);
lua_pushinteger(L, vertexCount);
uint32_t index = luaL_checkinteger(L, 2);
Texture* texture = lovrModelGetTexture(model, index);
luax_pushtype(L, Texture, texture);
return 1;
}
static int l_lovrModelGetWidth(lua_State* L) {
Model* model = luax_checktype(L, 1, Model);
ModelData* data = lovrModelGetInfo(model)->data;
float bounds[6];
lovrModelDataGetBoundingBox(data, bounds);
lua_pushnumber(L, bounds[1] - bounds[0]);
return 1;
}
static int l_lovrModelGetHeight(lua_State* L) {
Model* model = luax_checktype(L, 1, Model);
ModelData* data = lovrModelGetInfo(model)->data;
float bounds[6];
lovrModelDataGetBoundingBox(data, bounds);
lua_pushnumber(L, bounds[3] - bounds[2]);
return 1;
}
static int l_lovrModelGetDepth(lua_State* L) {
Model* model = luax_checktype(L, 1, Model);
ModelData* data = lovrModelGetInfo(model)->data;
float bounds[6];
lovrModelDataGetBoundingBox(data, bounds);
lua_pushnumber(L, bounds[5] - bounds[4]);
return 1;
}
static int l_lovrModelGetDimensions(lua_State* L) {
Model* model = luax_checktype(L, 1, Model);
ModelData* data = lovrModelGetInfo(model)->data;
float bounds[6];
lovrModelDataGetBoundingBox(data, bounds);
lua_pushnumber(L, bounds[1] - bounds[0]);
lua_pushnumber(L, bounds[3] - bounds[2]);
lua_pushnumber(L, bounds[5] - bounds[4]);
return 3;
}
static int l_lovrModelGetCenter(lua_State* L) {
Model* model = luax_checktype(L, 1, Model);
ModelData* data = lovrModelGetInfo(model)->data;
float bounds[6];
lovrModelDataGetBoundingBox(data, bounds);
lua_pushnumber(L, (bounds[0] + bounds[1]) / 2.f);
lua_pushnumber(L, (bounds[2] + bounds[3]) / 2.f);
lua_pushnumber(L, (bounds[4] + bounds[5]) / 2.f);
return 3;
}
static int l_lovrModelGetBoundingBox(lua_State* L) {
Model* model = luax_checktype(L, 1, Model);
ModelData* data = lovrModelGetInfo(model)->data;
float bounds[6];
lovrModelDataGetBoundingBox(data, bounds);
lua_pushnumber(L, bounds[0]);
lua_pushnumber(L, bounds[1]);
lua_pushnumber(L, bounds[2]);
lua_pushnumber(L, bounds[3]);
lua_pushnumber(L, bounds[4]);
lua_pushnumber(L, bounds[5]);
return 6;
}
static int l_lovrModelGetBoundingSphere(lua_State* L) {
Model* model = luax_checktype(L, 1, Model);
ModelData* data = lovrModelGetInfo(model)->data;
float sphere[4];
lovrModelDataGetBoundingSphere(data, sphere);
lua_pushnumber(L, sphere[0]);
lua_pushnumber(L, sphere[1]);
lua_pushnumber(L, sphere[2]);
lua_pushnumber(L, sphere[3]);
return 4;
}
const luaL_Reg lovrModel[] = {
{ "getModelData", l_lovrModelGetModelData },
{ "animate", l_lovrModelAnimate },
{ "resetPose", l_lovrModelResetPose },
{ "getData", l_lovrModelGetData },
{ "getRootNode", l_lovrModelGetRootNode },
{ "getNodeCount", l_lovrModelGetNodeCount },
{ "getNodeName", l_lovrModelGetNodeName },
{ "getNodeParent", l_lovrModelGetNodeParent },
{ "getNodeChildren", l_lovrModelGetNodeChildren },
{ "getNodeDrawCount", l_lovrModelGetNodeDrawCount },
{ "getNodeDraw", l_lovrModelGetNodeDraw },
{ "getNodePosition", l_lovrModelGetNodePosition },
{ "setNodePosition", l_lovrModelSetNodePosition },
{ "getNodeOrientation", l_lovrModelGetNodeOrientation },
{ "setNodeOrientation", l_lovrModelSetNodeOrientation },
{ "getNodeScale", l_lovrModelGetNodeScale },
{ "setNodeScale", l_lovrModelSetNodeScale },
{ "getNodePose", l_lovrModelGetNodePose },
{ "setNodePose", l_lovrModelSetNodePose },
{ "getTexture", l_lovrModelGetTexture },
{ "getMaterial", l_lovrModelGetMaterial },
{ "getVertexBuffer", l_lovrModelGetVertexBuffer },
{ "getIndexBuffer", l_lovrModelGetIndexBuffer },
{ "getNodeTransform", l_lovrModelGetNodeTransform },
{ "setNodeTransform", l_lovrModelSetNodeTransform },
{ "getAnimationCount", l_lovrModelGetAnimationCount },
{ "getAnimationName", l_lovrModelGetAnimationName },
{ "getAnimationDuration", l_lovrModelGetAnimationDuration },
{ "hasJoints", l_lovrModelHasJoints },
{ "animate", l_lovrModelAnimate },
{ "getTriangles", l_lovrModelGetTriangles },
{ "getTriangleCount", l_lovrModelGetTriangleCount },
{ "getVertexCount", l_lovrModelGetVertexCount },
@ -255,5 +388,11 @@ const luaL_Reg lovrModel[] = {
{ "getCenter", l_lovrModelGetCenter },
{ "getBoundingBox", l_lovrModelGetBoundingBox },
{ "getBoundingSphere", l_lovrModelGetBoundingSphere },
{ "getVertexBuffer", l_lovrModelGetVertexBuffer },
{ "getIndexBuffer", l_lovrModelGetIndexBuffer },
{ "getMaterialCount", l_lovrModelGetMaterialCount },
{ "getTextureCount", l_lovrModelGetTextureCount },
{ "getMaterial", l_lovrModelGetMaterial },
{ "getTexture", l_lovrModelGetTexture },
{ NULL, NULL }
};

View File

@ -247,10 +247,10 @@ static int l_lovrPassSetMaterial(lua_State* L) {
return 0;
}
static int l_lovrPassSetVertexMode(lua_State* L) {
static int l_lovrPassSetMeshMode(lua_State* L) {
Pass* pass = luax_checktype(L, 1, Pass);
VertexMode mode = luax_checkenum(L, 2, VertexMode, NULL);
lovrPassSetVertexMode(pass, mode);
MeshMode mode = luax_checkenum(L, 2, MeshMode, NULL);
lovrPassSetMeshMode(pass, mode);
return 0;
}
@ -875,12 +875,12 @@ const luaL_Reg lovrPass[] = {
{ "setDepthOffset", l_lovrPassSetDepthOffset },
{ "setDepthClamp", l_lovrPassSetDepthClamp },
{ "setMaterial", l_lovrPassSetMaterial },
{ "setMeshMode", l_lovrPassSetMeshMode },
{ "setSampler", l_lovrPassSetSampler },
{ "setScissor", l_lovrPassSetScissor },
{ "setShader", l_lovrPassSetShader },
{ "setStencilTest", l_lovrPassSetStencilTest },
{ "setStencilWrite", l_lovrPassSetStencilWrite },
{ "setVertexMode", l_lovrPassSetVertexMode },
{ "setViewport", l_lovrPassSetViewport },
{ "setWinding", l_lovrPassSetWinding },
{ "setWireframe", l_lovrPassSetWireframe },

View File

@ -172,7 +172,7 @@ typedef enum {
typedef struct {
uint64_t hash;
VertexMode mode;
MeshMode mode;
DefaultShader shader;
Material* material;
float* transform;
@ -239,7 +239,7 @@ typedef struct {
float viewport[4];
float depthRange[2];
uint32_t scissor[4];
VertexMode drawMode;
MeshMode mode;
bool dirty;
} Pipeline;
@ -2378,9 +2378,9 @@ Model* lovrModelCreate(ModelInfo* info) {
Draw* draw = &model->draws[map[i] & ~0u];
switch (primitive->mode) {
case DRAW_POINTS: draw->mode = VERTEX_POINTS; break;
case DRAW_LINES: draw->mode = VERTEX_LINES; break;
case DRAW_TRIANGLES: draw->mode = VERTEX_TRIANGLES; break;
case DRAW_POINTS: draw->mode = MESH_POINTS; break;
case DRAW_LINES: draw->mode = MESH_LINES; break;
case DRAW_TRIANGLES: draw->mode = MESH_TRIANGLES; break;
default: lovrThrow("Model uses an unsupported draw mode (lineloop, linestrip, strip, fan)");
}
@ -2435,7 +2435,7 @@ Model* lovrModelCreate(ModelInfo* info) {
model->localTransforms = malloc(sizeof(NodeTransform) * data->nodeCount);
model->globalTransforms = malloc(16 * sizeof(float) * data->nodeCount);
lovrAssert(model->localTransforms && model->globalTransforms, "Out of memory");
lovrModelResetPose(model);
lovrModelResetNodeTransforms(model);
tempPop(stack);
return model;
@ -2467,7 +2467,26 @@ const ModelInfo* lovrModelGetInfo(Model* model) {
return &model->info;
}
void lovrModelResetPose(Model* model) {
uint32_t lovrModelGetNodeDrawCount(Model* model, uint32_t node) {
ModelData* data = model->info.data;
lovrCheck(node < data->nodeCount, "Invalid model node index %d", node + 1);
return data->nodes[node].primitiveCount;
}
void lovrModelGetNodeDraw(Model* model, uint32_t node, uint32_t index, ModelDraw* mesh) {
ModelData* data = model->info.data;
lovrCheck(node < data->nodeCount, "Invalid model node index %d", node + 1);
lovrCheck(index < data->nodes[node].primitiveCount, "Invalid model node draw index %d", index + 1);
Draw* draw = &model->draws[data->nodes[node].primitiveIndex + index];
mesh->mode = draw->mode;
mesh->material = draw->material;
mesh->start = draw->start;
mesh->count = draw->count;
mesh->base = draw->base;
mesh->indexed = draw->index.buffer;
}
void lovrModelResetNodeTransforms(Model* model) {
ModelData* data = model->info.data;
for (uint32_t i = 0; i < data->nodeCount; i++) {
vec3 position = model->localTransforms[i].properties[PROP_TRANSLATION];
@ -2564,35 +2583,35 @@ void lovrModelAnimate(Model* model, uint32_t animationIndex, float time, float a
model->transformsDirty = true;
}
void lovrModelGetNodePose(Model* model, uint32_t node, float position[4], float rotation[4], CoordinateSpace space) {
ModelData* data = model->info.data;
lovrAssert(node < data->nodeCount, "Invalid node index '%d' (Model has %d node%s)", node, data->nodeCount, data->nodeCount == 1 ? "" : "s");
void lovrModelGetNodeTransform(Model* model, uint32_t node, float position[4], float scale[4], float rotation[4], CoordinateSpace space) {
if (space == SPACE_LOCAL) {
vec3_init(position, model->localTransforms[node].properties[PROP_TRANSLATION]);
vec3_init(scale, model->localTransforms[node].properties[PROP_SCALE]);
quat_init(rotation, model->localTransforms[node].properties[PROP_ROTATION]);
} else {
if (model->transformsDirty) {
updateModelTransforms(model, data->rootNode, (float[]) MAT4_IDENTITY);
updateModelTransforms(model, model->info.data->rootNode, (float[]) MAT4_IDENTITY);
model->transformsDirty = false;
}
mat4_getPosition(model->globalTransforms + 16 * node, position);
mat4_getScale(model->globalTransforms + 16 * node, scale);
mat4_getOrientation(model->globalTransforms + 16 * node, rotation);
}
}
void lovrModelSetNodePose(Model* model, uint32_t node, float position[4], float rotation[4], float alpha) {
void lovrModelSetNodeTransform(Model* model, uint32_t node, float position[4], float scale[4], float rotation[4], float alpha) {
if (alpha <= 0.f) return;
ModelData* data = model->info.data;
lovrAssert(node < data->nodeCount, "Invalid node index '%d' (Model has %d node%s)", node, data->nodeCount, data->nodeCount == 1 ? "" : "s");
NodeTransform* transform = &model->localTransforms[node];
if (alpha >= 1.f) {
vec3_init(transform->properties[PROP_TRANSLATION], position);
quat_init(transform->properties[PROP_ROTATION], rotation);
if (position) vec3_init(transform->properties[PROP_TRANSLATION], position);
if (scale) vec3_init(transform->properties[PROP_SCALE], scale);
if (rotation) quat_init(transform->properties[PROP_ROTATION], rotation);
} else {
vec3_lerp(transform->properties[PROP_TRANSLATION], position, alpha);
quat_slerp(transform->properties[PROP_ROTATION], rotation, alpha);
if (position) vec3_lerp(transform->properties[PROP_TRANSLATION], position, alpha);
if (scale) vec3_lerp(transform->properties[PROP_SCALE], scale, alpha);
if (rotation) quat_slerp(transform->properties[PROP_ROTATION], rotation, alpha);
}
model->transformsDirty = true;
@ -2879,7 +2898,7 @@ Pass* lovrGraphicsGetPass(PassInfo* info) {
memcpy(pass->pipeline->color, defaultColor, sizeof(defaultColor));
pass->pipeline->formatHash = 0;
pass->pipeline->shader = NULL;
pass->pipeline->drawMode = VERTEX_TRIANGLES;
pass->pipeline->mode = MESH_TRIANGLES;
pass->pipeline->dirty = true;
pass->pipeline->material = state.defaultMaterial;
lovrRetain(pass->pipeline->material);
@ -3154,6 +3173,10 @@ void lovrPassSetMaterial(Pass* pass, Material* material, Texture* texture) {
}
}
void lovrPassSetMeshMode(Pass* pass, MeshMode mode) {
pass->pipeline->mode = mode;
}
void lovrPassSetSampler(Pass* pass, Sampler* sampler) {
if (sampler != pass->pipeline->sampler) {
lovrRetain(sampler);
@ -3267,10 +3290,6 @@ void lovrPassSetStencilWrite(Pass* pass, StencilAction actions[3], uint8_t value
pass->pipeline->dirty = true;
}
void lovrPassSetVertexMode(Pass* pass, VertexMode mode) {
pass->pipeline->drawMode = mode;
}
void lovrPassSetViewport(Pass* pass, float viewport[4], float depthRange[2]) {
gpu_set_viewport(pass->stream, viewport, depthRange);
memcpy(pass->pipeline->viewport, viewport, 4 * sizeof(float));
@ -3691,7 +3710,7 @@ static void lovrPassDraw(Pass* pass, Draw* draw) {
void lovrPassPoints(Pass* pass, uint32_t count, float** points) {
lovrPassDraw(pass, &(Draw) {
.mode = VERTEX_POINTS,
.mode = MESH_POINTS,
.vertex.format = VERTEX_POINT,
.vertex.pointer = (void**) points,
.vertex.count = count
@ -3702,7 +3721,7 @@ void lovrPassLine(Pass* pass, uint32_t count, float** points) {
uint16_t* indices;
lovrPassDraw(pass, &(Draw) {
.mode = VERTEX_LINES,
.mode = MESH_LINES,
.vertex.format = VERTEX_POINT,
.vertex.pointer = (void**) points,
.vertex.count = count,
@ -3729,7 +3748,7 @@ void lovrPassPlane(Pass* pass, float* transform, DrawStyle style, uint32_t cols,
lovrPassDraw(pass, &(Draw) {
.hash = hash64(key, sizeof(key)),
.mode = VERTEX_LINES,
.mode = MESH_LINES,
.transform = transform,
.vertex.pointer = (void**) &vertices,
.vertex.count = vertexCount,
@ -3741,7 +3760,7 @@ void lovrPassPlane(Pass* pass, float* transform, DrawStyle style, uint32_t cols,
lovrPassDraw(pass, &(Draw) {
.hash = hash64(key, sizeof(key)),
.mode = VERTEX_TRIANGLES,
.mode = MESH_TRIANGLES,
.transform = transform,
.vertex.pointer = (void**) &vertices,
.vertex.count = vertexCount,
@ -3822,7 +3841,7 @@ void lovrPassBox(Pass* pass, float* transform, DrawStyle style) {
lovrPassDraw(pass, &(Draw) {
.hash = hash64(key, sizeof(key)),
.mode = VERTEX_LINES,
.mode = MESH_LINES,
.transform = transform,
.vertex.pointer = (void**) &vertices,
.vertex.count = COUNTOF(vertexData),
@ -3873,7 +3892,7 @@ void lovrPassBox(Pass* pass, float* transform, DrawStyle style) {
lovrPassDraw(pass, &(Draw) {
.hash = hash64(key, sizeof(key)),
.mode = VERTEX_TRIANGLES,
.mode = MESH_TRIANGLES,
.transform = transform,
.vertex.pointer = (void**) &vertices,
.vertex.count = COUNTOF(vertexData),
@ -3904,7 +3923,7 @@ void lovrPassCircle(Pass* pass, float* transform, DrawStyle style, float angle1,
lovrPassDraw(pass, &(Draw) {
.hash = hash64(key, sizeof(key)),
.mode = VERTEX_LINES,
.mode = MESH_LINES,
.transform = transform,
.vertex.pointer = (void**) &vertices,
.vertex.count = vertexCount,
@ -3921,7 +3940,7 @@ void lovrPassCircle(Pass* pass, float* transform, DrawStyle style, float angle1,
lovrPassDraw(pass, &(Draw) {
.hash = hash64(key, sizeof(key)),
.mode = VERTEX_TRIANGLES,
.mode = MESH_TRIANGLES,
.transform = transform,
.vertex.pointer = (void**) &vertices,
.vertex.count = vertexCount,
@ -3970,7 +3989,7 @@ void lovrPassSphere(Pass* pass, float* transform, uint32_t segmentsH, uint32_t s
lovrPassDraw(pass, &(Draw) {
.hash = hash64(key, sizeof(key)),
.mode = VERTEX_TRIANGLES,
.mode = MESH_TRIANGLES,
.transform = transform,
.vertex.pointer = (void**) &vertices,
.vertex.count = vertexCount,
@ -4055,7 +4074,7 @@ void lovrPassCylinder(Pass* pass, float* transform, bool capped, float angle1, f
lovrPassDraw(pass, &(Draw) {
.hash = hash64(key, sizeof(key)),
.mode = VERTEX_TRIANGLES,
.mode = MESH_TRIANGLES,
.transform = transform,
.vertex.pointer = (void**) &vertices,
.vertex.count = vertexCount,
@ -4138,7 +4157,7 @@ void lovrPassCapsule(Pass* pass, float* transform, uint32_t segments) {
lovrPassDraw(pass, &(Draw) {
.hash = hash64(key, sizeof(key)),
.mode = VERTEX_TRIANGLES,
.mode = MESH_TRIANGLES,
.transform = transform,
.vertex.pointer = (void**) &vertices,
.vertex.count = vertexCount,
@ -4230,7 +4249,7 @@ void lovrPassTorus(Pass* pass, float* transform, uint32_t segmentsT, uint32_t se
lovrPassDraw(pass, &(Draw) {
.hash = hash64(key, sizeof(key)),
.mode = VERTEX_TRIANGLES,
.mode = MESH_TRIANGLES,
.transform = transform,
.vertex.pointer = (void**) &vertices,
.vertex.count = vertexCount,
@ -4405,7 +4424,7 @@ void lovrPassText(Pass* pass, Font* font, ColoredString* strings, uint32_t count
GlyphVertex* vertexPointer;
uint16_t* indices;
lovrPassDraw(pass, &(Draw) {
.mode = VERTEX_TRIANGLES,
.mode = MESH_TRIANGLES,
.shader = SHADER_FONT,
.material = font->material,
.transform = transform,
@ -4430,7 +4449,7 @@ void lovrPassText(Pass* pass, Font* font, ColoredString* strings, uint32_t count
void lovrPassSkybox(Pass* pass, Texture* texture) {
if (texture->info.type == TEXTURE_2D) {
lovrPassDraw(pass, &(Draw) {
.mode = VERTEX_TRIANGLES,
.mode = MESH_TRIANGLES,
.shader = SHADER_PANO,
.material = texture ? lovrTextureGetMaterial(texture) : NULL,
.vertex.format = VERTEX_EMPTY,
@ -4438,7 +4457,7 @@ void lovrPassSkybox(Pass* pass, Texture* texture) {
});
} else {
lovrPassDraw(pass, &(Draw) {
.mode = VERTEX_TRIANGLES,
.mode = MESH_TRIANGLES,
.shader = SHADER_CUBE,
.material = texture ? lovrTextureGetMaterial(texture) : NULL,
.vertex.format = VERTEX_EMPTY,
@ -4449,7 +4468,7 @@ void lovrPassSkybox(Pass* pass, Texture* texture) {
void lovrPassFill(Pass* pass, Texture* texture) {
lovrPassDraw(pass, &(Draw) {
.mode = VERTEX_TRIANGLES,
.mode = MESH_TRIANGLES,
.shader = SHADER_FILL,
.material = texture ? lovrTextureGetMaterial(texture) : NULL,
.vertex.format = VERTEX_EMPTY,
@ -4465,7 +4484,7 @@ void lovrPassMonkey(Pass* pass, float* transform) {
lovrPassDraw(pass, &(Draw) {
.hash = hash64(key, sizeof(key)),
.mode = VERTEX_TRIANGLES,
.mode = MESH_TRIANGLES,
.vertex.pointer = (void**) &vertices,
.vertex.count = vertexCount,
.index.pointer = (void**) &indices,
@ -4543,7 +4562,7 @@ void lovrPassMesh(Pass* pass, Buffer* vertices, Buffer* indices, float* transfor
}
lovrPassDraw(pass, &(Draw) {
.mode = pass->pipeline->drawMode,
.mode = pass->pipeline->mode,
.vertex.buffer = vertices,
.index.buffer = indices,
.transform = transform,
@ -4562,7 +4581,7 @@ void lovrPassMultimesh(Pass* pass, Buffer* vertices, Buffer* indices, Buffer* dr
lovrCheck(offset + totalSize < draws->size, "Multimesh draw range exceeds size of draw buffer");
Draw draw = (Draw) {
.mode = pass->pipeline->drawMode,
.mode = pass->pipeline->mode,
.vertex.buffer = vertices,
.index.buffer = indices
};

View File

@ -397,13 +397,30 @@ typedef enum {
SPACE_GLOBAL
} CoordinateSpace;
typedef enum {
MESH_POINTS,
MESH_LINES,
MESH_TRIANGLES
} MeshMode;
typedef struct {
MeshMode mode;
Material* material;
uint32_t start;
uint32_t count;
uint32_t base;
bool indexed;
} ModelDraw;
Model* lovrModelCreate(ModelInfo* info);
void lovrModelDestroy(void* ref);
const ModelInfo* lovrModelGetInfo(Model* model);
void lovrModelResetPose(Model* model);
uint32_t lovrModelGetNodeDrawCount(Model* model, uint32_t node);
void lovrModelGetNodeDraw(Model* model, uint32_t node, uint32_t index, ModelDraw* draw);
void lovrModelResetNodeTransforms(Model* model);
void lovrModelAnimate(Model* model, uint32_t animationIndex, float time, float alpha);
void lovrModelGetNodePose(Model* model, uint32_t node, float position[4], float rotation[4], CoordinateSpace space);
void lovrModelSetNodePose(Model* model, uint32_t node, float position[4], float rotation[4], float alpha);
void lovrModelGetNodeTransform(Model* model, uint32_t node, float position[4], float scale[4], float rotation[4], CoordinateSpace space);
void lovrModelSetNodeTransform(Model* model, uint32_t node, float position[4], float scale[4], float rotation[4], float alpha);
Texture* lovrModelGetTexture(Model* model, uint32_t index);
Material* lovrModelGetMaterial(Model* model, uint32_t index);
Buffer* lovrModelGetVertexBuffer(Model* model);
@ -478,12 +495,6 @@ typedef enum {
STENCIL_INVERT
} StencilAction;
typedef enum {
VERTEX_POINTS,
VERTEX_LINES,
VERTEX_TRIANGLES
} VertexMode;
typedef enum {
WINDING_COUNTERCLOCKWISE,
WINDING_CLOCKWISE
@ -541,12 +552,12 @@ void lovrPassSetDepthWrite(Pass* pass, bool write);
void lovrPassSetDepthOffset(Pass* pass, float offset, float sloped);
void lovrPassSetDepthClamp(Pass* pass, bool clamp);
void lovrPassSetMaterial(Pass* pass, Material* material, Texture* texture);
void lovrPassSetMeshMode(Pass* pass, MeshMode mode);
void lovrPassSetSampler(Pass* pass, Sampler* sampler);
void lovrPassSetScissor(Pass* pass, uint32_t scissor[4]);
void lovrPassSetShader(Pass* pass, Shader* shader);
void lovrPassSetStencilTest(Pass* pass, CompareMode test, uint8_t value, uint8_t mask);
void lovrPassSetStencilWrite(Pass* pass, StencilAction actions[3], uint8_t value, uint8_t mask);
void lovrPassSetVertexMode(Pass* pass, VertexMode mode);
void lovrPassSetViewport(Pass* pass, float viewport[4], float depthRange[2]);
void lovrPassSetWinding(Pass* pass, Winding winding);
void lovrPassSetWireframe(Pass* pass, bool wireframe);