diff --git a/include/havokxmlparser.h b/include/havokxmlparser.h index 50f502e..2be3ecb 100644 --- a/include/havokxmlparser.h +++ b/include/havokxmlparser.h @@ -3,13 +3,14 @@ #include #include #include +#include struct Bone { std::string name; Bone* parent = nullptr; - std::array localTransform, finalTransform; + glm::mat4 localTransform, finalTransform, inversePose; std::array position; std::array rotation; diff --git a/include/mdlparser.h b/include/mdlparser.h index 246a725..d55187f 100644 --- a/include/mdlparser.h +++ b/include/mdlparser.h @@ -8,12 +8,23 @@ struct Vertex { std::array position; + std::array uv; std::array normal; + + std::array boneWeights; + std::array boneIds; +}; + +struct PartSubmesh { + uint32_t indexOffset, indexCount; + uint32_t boneStartIndex, boneCount; }; struct Part { std::vector vertices; std::vector indices; + + std::vector submeshes; }; struct Lod { @@ -22,6 +33,8 @@ struct Lod { struct Model { std::vector lods; + + std::vector affectedBoneNames; }; Model parseMDL(MemorySpan data); \ No newline at end of file diff --git a/include/memorybuffer.h b/include/memorybuffer.h index 7ccd065..7232020 100644 --- a/include/memorybuffer.h +++ b/include/memorybuffer.h @@ -58,7 +58,7 @@ private: }; template<> -void MemoryBuffer::write>(const std::vector& t) { +inline void MemoryBuffer::write>(const std::vector& t) { size_t end = position + (sizeof(uint8_t) * t.size()); if(end > data.size()) data.resize(end); diff --git a/src/mdlparser.cpp b/src/mdlparser.cpp index 65603c1..976af77 100644 --- a/src/mdlparser.cpp +++ b/src/mdlparser.cpp @@ -159,8 +159,8 @@ struct Mesh { }; struct Submesh { - unsigned int indexOffset; - unsigned int indexCount; + int32_t indexOffset; + int32_t indexCount; unsigned int attributeIndexMask; unsigned short boneStartIndex; unsigned short boneCount; @@ -292,6 +292,18 @@ Model parseMDL(MemorySpan data) { Model model; + for(auto offset : boneNameOffsets) { + std::string name; + char nextChar = strings[offset]; + while(nextChar != '\0') { + name += nextChar; + offset++; + nextChar = strings[offset]; + } + + model.affectedBoneNames.push_back(name); + } + for(int i = 0; i < modelHeader.lodCount; i++) { Lod lod; @@ -303,11 +315,22 @@ Model parseMDL(MemorySpan data) { int vertexCount = meshes[j].vertexCount; std::vector vertices(vertexCount); + for(int k = meshes[j].subMeshIndex; k < (meshes[j].subMeshIndex + meshes[j].subMeshCount); k++) { + PartSubmesh submesh; + submesh.indexCount = submeshes[k].indexCount; + submesh.indexOffset = submeshes[k].indexOffset; + submesh.boneCount = submeshes[k].boneCount; + submesh.boneStartIndex = submeshes[k].boneStartIndex; + + part.submeshes.push_back(submesh); + } + for(int k = 0; k < vertexCount; k++) { for(auto& element : decl.elements) { data.seek(lods[i].vertexDataOffset + meshes[j].vertexBufferOffset[element.stream] + element.offset + meshes[i].vertexBufferStride[element.stream] * k, Seek::Set); std::array floatData = {}; + std::array intData = {}; switch(element.type) { case VertexType::Single3: data.read_array(floatData.data(), 3); @@ -316,7 +339,7 @@ Model parseMDL(MemorySpan data) { data.read_array(floatData.data(), 4); break; case VertexType::UInt: - data.seek(sizeof(uint8_t) * 4, Seek::Current); + data.read_array(intData.data(), 4); break; case VertexType::ByteFloat4: { uint8_t values[4]; @@ -329,7 +352,7 @@ Model parseMDL(MemorySpan data) { } break; case VertexType::Half2: { - uint16_t values[2]; + uint16_t values[2] = {}; data.read_array(values, 2); floatData[0] = half_to_float(values[0]); @@ -337,7 +360,7 @@ Model parseMDL(MemorySpan data) { } break; case VertexType::Half4: { - uint16_t values[4]; + uint16_t values[4] = {}; data.read_array(values, 4); floatData[0] = half_to_float(values[0]); @@ -356,10 +379,13 @@ Model parseMDL(MemorySpan data) { memcpy(vertices[k].normal.data(), floatData.data(), sizeof(float) * 3); break; case BlendWeights: + memcpy(vertices[k].boneWeights.data(), floatData.data(), sizeof(float) * 4); break; case BlendIndices: + memcpy(vertices[k].boneIds.data(), intData.data(), sizeof(uint8_t) * 4); break; case UV: + memcpy(vertices[k].uv.data(), floatData.data(), sizeof(float) * 2); break; case Tangent2: break;