diff --git a/include/asset.h b/include/asset.h index c6ce2f3..a690cd3 100644 --- a/include/asset.h +++ b/include/asset.h @@ -25,6 +25,10 @@ struct mesh glm::mat4* xform; }; +// TODO: will eventually need a tree structure with child nodes and transforms +// at each branch. Can then combine each transform down from the root node to +// the mesh, and send the final combination down to the shader + #define MAX_PATH_SIZE 256 struct model { diff --git a/src/asset.cpp b/src/asset.cpp index 0b69511..f838418 100644 --- a/src/asset.cpp +++ b/src/asset.cpp @@ -2,6 +2,7 @@ #include #include +#include #include "tiny_gltf.h" #include "asset.h" @@ -168,7 +169,40 @@ copyBuffer(uint8_t*& buffer_ref, buffer_ref = (uint8_t*) arenaAllocateBlock(arena, bv.byteLength); std::memcpy(buffer_ref, &t_buf.data[bv.byteOffset], bv.byteLength); - return buffer_ref == nullptr; + return buffer_ref != nullptr; +} + +glm::mat4* +parseNodeTransform(memory_arena* arena, const tinygltf::Node* node) +{ + if (node->rotation.size() == 4 + && node->scale.size() == 3 + && node->translation.size() == 3) + { + glm::mat4* xform = + (glm::mat4*) arenaAllocateBlock(arena, sizeof(glm::mat4)); + *xform = glm::mat4(1.0f); + *xform = glm::rotate(*xform, (float) node->rotation[3], + glm::vec3((float) node->rotation[0], + (float) node->rotation[1], + (float) node->rotation[2]) + ); + *xform = glm::scale(*xform, + glm::vec3((float) node->scale[0], + (float) node->scale[0], + (float) node->scale[0]) + ); + *xform = glm::translate(*xform, + glm::vec3((float) node->translation[0], + (float) node->translation[0], + (float) node->translation[0]) + ); + + return xform; + } + + LOG(Error) << "Unknown transform\n"; + return nullptr; } bool @@ -194,16 +228,29 @@ parseMeshNode(mesh& m, m.num_vertices = vert_acc.count; m.num_indices = index_acc.count; m.draw_mode = prim.mode; - m.usage = GL_STATIC_DRAW; // TODO: logic for updating meshes + m.usage = GL_STATIC_DRAW; // TODO: logic for updating dynamic meshes + // FIXME: the node transforms from blender only work as part of a node tree +#if 1 m.xform = (glm::mat4*) arenaAllocateBlock(arena, sizeof(glm::mat4)); - copyBuffer( - (uint8_t*&) m.vertices, arena, prim.attributes["POSITION"], t_mdl); - copyBuffer((uint8_t*&) m.normals, arena, prim.attributes["NORMAL"], t_mdl); - copyBuffer((uint8_t*&) m.texture_coords, - arena, prim.attributes["TEXCOORD_0"], t_mdl); - copyBuffer((uint8_t*&) m.indices, arena, prim.indices, t_mdl); - - return true; + *m.xform = glm::mat4(1.0f); +#else + m.xform = parseNodeTransform(arena, &node); +#endif + + if (m.xform != nullptr + && copyBuffer((uint8_t*&) m.vertices, arena, + prim.attributes["POSITION"], t_mdl) + && copyBuffer((uint8_t*&) m.normals, arena, + prim.attributes["NORMAL"], t_mdl) + && copyBuffer((uint8_t*&) m.texture_coords, arena, + prim.attributes["TEXCOORD_0"], t_mdl) + && copyBuffer((uint8_t*&) m.indices, arena, + prim.indices, t_mdl)) + { + return true; + } + + return false; } model* @@ -227,8 +274,8 @@ assetLoadFromFile(model_assets* assets, // NOTE: assume we're working with a single buffer assert(t_mdl.buffers.size() == 1); model* mdl = initModel(assets, arena, t_mdl, filename); - // TODO: also need to get each node xform - // TODO: also need to dump textures/materials + // FIXME: also need to get each node xform + // FIXME: also need to dump textures/materials //dumpNodes(t_mdl); uint mesh_idx = 0; @@ -236,8 +283,7 @@ assetLoadFromFile(model_assets* assets, for (tinygltf::Node node : t_mdl.nodes) { if (node.mesh >= 0) { if (!parseMeshNode(mdl->meshes[mesh_idx++], arena, node, t_mdl)) { - // FIXME: error handling - LOG(Error) << "Some mesh parsing error\n"; + LOG(Error) << "Error parsing node\n"; return nullptr; } }