Node and material accessors for ModelData;

This commit is contained in:
bjorn 2018-02-11 13:03:52 -08:00
parent d7bf96f952
commit ece5bf2f9c
6 changed files with 159 additions and 6 deletions

View File

@ -1,5 +1,9 @@
#include "api.h"
#include "data/model.h"
#include "math/transform.h"
#include "math/mat4.h"
#include "math/quat.h"
#include "math/vec3.h"
int l_lovrModelDataGetVertexData(lua_State* L) {
ModelData* modelData = luax_checktype(L, 1, ModelData);
@ -19,6 +23,111 @@ int l_lovrModelDataGetNodeCount(lua_State* L) {
return 1;
}
int l_lovrModelDataGetNodeName(lua_State* L) {
ModelData* modelData = luax_checktype(L, 1, ModelData);
int index = luaL_checkint(L, 2) - 1;
lovrAssert(index >= 0 && index < modelData->nodeCount, "Invalid node index: %d", index);
ModelNode* node = &modelData->nodes[index];
lua_pushstring(L, node->name);
return 1;
}
static int luax_writenodetransform(lua_State* L, mat4 m, int transformIndex) {
Transform* transform;
if ((transform = luax_totype(L, transformIndex, Transform)) != NULL) {
lovrTransformSetMatrix(transform, m);
lua_settop(L, transformIndex);
return 1;
} else {
float x, y, z, sx, sy, sz, angle, ax, ay, az;
mat4_getTransform(m, &x, &y, &z, &sx, &sy, &sz, &angle, &ax, &ay, &az);
lua_pushnumber(L, x);
lua_pushnumber(L, y);
lua_pushnumber(L, z);
lua_pushnumber(L, sx);
lua_pushnumber(L, sy);
lua_pushnumber(L, sz);
lua_pushnumber(L, angle);
lua_pushnumber(L, ax);
lua_pushnumber(L, ay);
lua_pushnumber(L, az);
return 10;
}
}
int l_lovrModelDataGetLocalNodeTransform(lua_State* L) {
ModelData* modelData = luax_checktype(L, 1, ModelData);
int index = luaL_checkint(L, 2) - 1;
lovrAssert(index >= 0 && index < modelData->nodeCount, "Invalid node index: %d", index);
ModelNode* node = &modelData->nodes[index];
return luax_writenodetransform(L, node->transform, 3);
}
int l_lovrModelDataGetGlobalNodeTransform(lua_State* L) {
ModelData* modelData = luax_checktype(L, 1, ModelData);
int index = luaL_checkint(L, 2) - 1;
lovrAssert(index >= 0 && index < modelData->nodeCount, "Invalid node index: %d", index);
ModelNode* node = &modelData->nodes[index];
return luax_writenodetransform(L, node->globalTransform, 3);
}
int l_lovrModelDataGetNodeParent(lua_State* L) {
ModelData* modelData = luax_checktype(L, 1, ModelData);
int index = luaL_checkint(L, 2) - 1;
lovrAssert(index >= 0 && index < modelData->nodeCount, "Invalid node index: %d", index);
ModelNode* node = &modelData->nodes[index];
if (node->parent == -1) {
lua_pushnil(L);
} else {
lua_pushinteger(L, node->parent);
}
return 1;
}
int l_lovrModelDataGetNodeChildren(lua_State* L) {
ModelData* modelData = luax_checktype(L, 1, ModelData);
int index = luaL_checkint(L, 2) - 1;
lovrAssert(index >= 0 && index < modelData->nodeCount, "Invalid node index: %d", index);
ModelNode* node = &modelData->nodes[index];
if (lua_istable(L, 3)) {
lua_settop(L, 3);
} else {
lua_settop(L, 2);
lua_createtable(L, node->children.length, 0);
}
for (int i = 0; i < node->children.length; i++) {
lua_pushinteger(L, node->children.data[i]);
lua_rawseti(L, 3, i + 1);
}
return 1;
}
int l_lovrModelDataGetNodeComponentCount(lua_State* L) {
ModelData* modelData = luax_checktype(L, 1, ModelData);
int index = luaL_checkint(L, 2) - 1;
lovrAssert(index >= 0 && index < modelData->nodeCount, "Invalid node index: %d", index);
ModelNode* node = &modelData->nodes[index];
lua_pushinteger(L, node->primitives.length);
return 1;
}
int l_lovrModelDataGetNodeComponent(lua_State* L) {
ModelData* modelData = luax_checktype(L, 1, ModelData);
int nodeIndex = luaL_checkint(L, 2) - 1;
int primitiveIndex = luaL_checkint(L, 3) - 1;
lovrAssert(nodeIndex >= 0 && nodeIndex < modelData->nodeCount, "Invalid node index: %d", nodeIndex + 1);
ModelNode* node = &modelData->nodes[nodeIndex];
lovrAssert(primitiveIndex >= 0 && primitiveIndex < node->primitives.length, "Invalid component index: %d", primitiveIndex + 1);
ModelPrimitive* primitive = &modelData->primitives[node->primitives.data[primitiveIndex]];
lua_pushinteger(L, primitive->drawStart);
lua_pushinteger(L, primitive->drawCount);
lua_pushinteger(L, primitive->material);
return 3;
}
int l_lovrModelDataGetAnimationCount(lua_State* L) {
ModelData* modelData = luax_checktype(L, 1, ModelData);
lua_pushinteger(L, modelData->animationCount);
@ -31,22 +140,43 @@ int l_lovrModelDataGetMaterialCount(lua_State* L) {
return 1;
}
int l_lovrModelDataGetVertexCount(lua_State* L) {
int l_lovrModelDataGetDiffuseColor(lua_State* L) {
ModelData* modelData = luax_checktype(L, 1, ModelData);
lua_pushinteger(L, modelData->vertexData->count);
return 1;
int materialIndex = luaL_checkint(L, 2) - 1;
lovrAssert(materialIndex >= 0 && materialIndex < modelData->materialCount, "Invalid material index: %d", materialIndex + 1);
ModelMaterial* material = &modelData->materials[materialIndex];
Color color = material->diffuseColor;
lua_pushnumber(L, color.r);
lua_pushnumber(L, color.g);
lua_pushnumber(L, color.b);
lua_pushnumber(L, color.a);
return 4;
}
int l_lovrModelDataGetVertexFormat(lua_State* L) {
int l_lovrModelDataGetDiffuseTexture(lua_State* L) {
ModelData* modelData = luax_checktype(L, 1, ModelData);
return luax_pushvertexformat(L, &modelData->vertexData->format);
int materialIndex = luaL_checkint(L, 2) - 1;
lovrAssert(materialIndex >= 0 && materialIndex < modelData->materialCount, "Invalid material index: %d", materialIndex + 1);
ModelMaterial* material = &modelData->materials[materialIndex];
TextureData* textureData = modelData->textures.data[material->diffuseTexture];
luax_pushtype(L, TextureData, textureData);
return 1;
}
const luaL_Reg lovrModelData[] = {
{ "getVertexData", l_lovrModelDataGetVertexData },
{ "getTriangleCount", l_lovrModelDataGetTriangleCount },
{ "getNodeCount", l_lovrModelDataGetNodeCount },
{ "getNodeName", l_lovrModelDataGetNodeName },
{ "getLocalNodeTransform", l_lovrModelDataGetLocalNodeTransform },
{ "getGlobalNodeTransform", l_lovrModelDataGetGlobalNodeTransform },
{ "getNodeParent", l_lovrModelDataGetNodeParent },
{ "getNodeChildren", l_lovrModelDataGetNodeChildren },
{ "getNodeComponentCount", l_lovrModelDataGetNodeComponentCount },
{ "getNodeComponent", l_lovrModelDataGetNodeComponent },
{ "getAnimationCount", l_lovrModelDataGetAnimationCount },
{ "getMaterialCount", l_lovrModelDataGetMaterialCount },
{ "getDiffuseColor", l_lovrModelDataGetDiffuseColor },
{ "getDiffuseTexture", l_lovrModelDataGetDiffuseTexture },
{ NULL, NULL }
};

View File

@ -72,6 +72,12 @@ static void assimpNodeTraversal(ModelData* modelData, struct aiNode* assimpNode,
struct aiMatrix4x4 m = assimpNode->mTransformation;
aiTransposeMatrix4(&m);
mat4_set(node->transform, (float*) &m);
if (node->parent == -1) {
mat4_set(node->globalTransform, node->transform);
} else {
mat4_set(node->globalTransform, modelData->nodes[node->parent].globalTransform);
mat4_multiply(node->globalTransform, node->transform);
}
// Primitives
vec_init(&node->primitives);

View File

@ -26,6 +26,7 @@ typedef struct {
typedef struct ModelNode {
const char* name;
float transform[16];
float globalTransform[16];
int parent;
vec_uint_t children;
vec_uint_t primitives;

View File

@ -1,5 +1,5 @@
#include "util.h"
#include "graphics/texture.h"
#include "util.h"
#include <stdbool.h>
#pragma once

View File

@ -208,6 +208,21 @@ mat4 mat4_scale(mat4 m, float x, float y, float z) {
return m;
}
void mat4_getTransform(mat4 m, float* x, float* y, float* z, float* sx, float* sy, float* sz, float* angle, float* ax, float* ay, float* az) {
*x = m[12];
*y = m[13];
*z = m[14];
float a[3] = { m[0], m[1], m[2] };
float b[3] = { m[4], m[5], m[6] };
float c[3] = { m[8], m[9], m[10] };
*sx = vec3_length(a);
*sy = vec3_length(b);
*sz = vec3_length(c);
float quat[4];
quat_fromMat4(quat, m);
quat_getAngleAxis(quat, angle, ax, ay, az);
}
mat4 mat4_setTransform(mat4 m, float x, float y, float z, float sx, float sy, float sz, float angle, float ax, float ay, float az) {
mat4_identity(m);
mat4_translate(m, x, y, z);

View File

@ -14,6 +14,7 @@ mat4 mat4_translate(mat4 m, float x, float y, float z);
mat4 mat4_rotate(mat4 m, float angle, float x, float y, float z);
mat4 mat4_rotateQuat(mat4 m, quat q);
mat4 mat4_scale(mat4 m, float x, float y, float z);
void mat4_getTransform(mat4 m, float* x, float* y, float* z, float* sx, float* sy, float* sz, float* angle, float* ax, float* ay, float* az);
mat4 mat4_setTransform(mat4 m, float x, float y, float z, float sx, float sy, float sz, float angle, float ax, float ay, float az);
mat4 mat4_orthographic(mat4 m, float left, float right, float top, float bottom, float near, float far);
mat4 mat4_perspective(mat4 m, float near, float far, float fov, float aspect);