From 66baaf374dc98443e828d8dd1a047c84c4e6d59d Mon Sep 17 00:00:00 2001 From: Xiao Qi Date: Sat, 12 Nov 2022 15:55:41 +0800 Subject: [PATCH] Compile mesh bones and weights into binary Rig structure still WIP --- src/Libraries/MeshCompiler.cpp | 52 +++++++++++++++++++++++----------- src/Libraries/MeshCompiler.h | 8 +++--- src/Types/MeshAsset.h | 30 +++++++++++++++++--- 3 files changed, 65 insertions(+), 25 deletions(-) diff --git a/src/Libraries/MeshCompiler.cpp b/src/Libraries/MeshCompiler.cpp index a047362..af49fd1 100644 --- a/src/Libraries/MeshCompiler.cpp +++ b/src/Libraries/MeshCompiler.cpp @@ -74,10 +74,27 @@ namespace SH_COMP meshData.vertexTangent.reserve(mesh.mNumVertices); meshData.texCoords.reserve(mesh.mNumVertices); + meshData.bonesInfo.resize(mesh.mNumBones); + meshData.bones.resize(mesh.mNumBones); + for (auto i {0}; i < mesh.mNumBones; ++i) { - auto& bone = *mesh.mBones[i]; - std::cout << "bone" << std::endl; + auto const& bone = *mesh.mBones[i]; + auto& newBone = meshData.bones[i]; + auto& newBoneInfo = meshData.bonesInfo[i]; + + newBone.name = bone.mName.C_Str(); + newBoneInfo.charCount = newBone.name.length(); + + std::memcpy(&newBone.offset, &bone.mOffsetMatrix, sizeof(SHMat4)); + + newBone.weights.resize(bone.mNumWeights); + for (auto j {0}; j < bone.mNumWeights; ++j) + { + newBone.weights[j].index = bone.mWeights[j].mVertexId; + newBone.weights[j].weight = bone.mWeights[j].mWeight; + } + newBoneInfo.weightCount = bone.mNumWeights; } for (size_t i{ 0 }; i < mesh.mNumVertices; ++i) @@ -129,7 +146,7 @@ namespace SH_COMP } } - void MeshCompiler::BuildHeaders(MeshAsset& asset) noexcept + void MeshCompiler::BuildHeaders(ModelAsset& asset) noexcept { for (auto const& mesh : asset.meshes) { @@ -139,6 +156,7 @@ namespace SH_COMP head.charCount = mesh.name.size(); head.indexCount = mesh.indices.size(); head.vertexCount = mesh.vertexPosition.size(); + head.boneCount = mesh.bonesInfo.size(); asset.header.meshCount++; } @@ -188,18 +206,18 @@ namespace SH_COMP ); } - void MeshCompiler::LoadFromFile(AssetPath path, MeshAsset& asset) noexcept + void MeshCompiler::LoadFromFile(AssetPath path, ModelAsset& asset) noexcept { - const aiScene* scene = aiImporter.ReadFile(path.string().c_str(),0 - //aiProcess_Triangulate // Make sure we get triangles rather than nvert polygons - //| aiProcess_GenUVCoords // Convert any type of mapping to uv mapping - //| aiProcess_TransformUVCoords // preprocess UV transformations (scaling, translation ...) - //| aiProcess_FindInstances // search for instanced meshes and remove them by references to one master - //| aiProcess_CalcTangentSpace // calculate tangents and bitangents if possible - //| aiProcess_JoinIdenticalVertices // join identical vertices/ optimize indexing - //| aiProcess_FindInvalidData // detect invalid model data, such as invalid normal vectors - //| aiProcess_FlipUVs // flip the V to match the Vulkans way of doing UVs - //| aiProcess_ValidateDataStructure + const aiScene* scene = aiImporter.ReadFile(path.string().c_str(), + aiProcess_Triangulate // Make sure we get triangles rather than nvert polygons + | aiProcess_GenUVCoords // Convert any type of mapping to uv mapping + | aiProcess_TransformUVCoords // preprocess UV transformations (scaling, translation ...) + | aiProcess_FindInstances // search for instanced meshes and remove them by references to one master + | aiProcess_CalcTangentSpace // calculate tangents and bitangents if possible + | aiProcess_JoinIdenticalVertices // join identical vertices/ optimize indexing + | aiProcess_FindInvalidData // detect invalid model data, such as invalid normal vectors + | aiProcess_FlipUVs // flip the V to match the Vulkans way of doing UVs + | aiProcess_ValidateDataStructure ); if (!scene || !scene->HasMeshes()) @@ -215,7 +233,7 @@ namespace SH_COMP aiImporter.FreeScene(); } - void MeshCompiler::CompileMeshBinary(AssetPath path, MeshAsset const& asset) noexcept + void MeshCompiler::CompileMeshBinary(AssetPath path, ModelAsset const& asset) noexcept { std::string newPath{ path.string().substr(0, path.string().find_last_of('.')) }; newPath += MODEL_EXTENSION; @@ -254,7 +272,7 @@ namespace SH_COMP { RigNode* current = new RigNode(); current->name = source.mName.C_Str(); - std::memcpy(¤t->transform, &source.mTransformation, sizeof(float) * 16); + std::memcpy(¤t->transform, &source.mTransformation, sizeof(SHMat4)); for (auto i {0}; i < source.mNumChildren; ++i) { @@ -269,7 +287,7 @@ namespace SH_COMP void MeshCompiler::LoadAndCompile(AssetPath path) noexcept { - auto const asset = new MeshAsset(); + auto const asset = new ModelAsset(); asset->rig.root = nullptr; diff --git a/src/Libraries/MeshCompiler.h b/src/Libraries/MeshCompiler.h index 8fa9c9a..757b3a2 100644 --- a/src/Libraries/MeshCompiler.h +++ b/src/Libraries/MeshCompiler.h @@ -33,13 +33,13 @@ namespace SH_COMP static void ProcessNode(aiNode const& node, aiScene const& scene, MeshVectorRef meshes, RigNode*& root) noexcept; static void ExtractAnimations(aiScene const& scene, AnimVectorRef anims) noexcept; static void GetMesh(aiMesh const& mesh, MeshData& meshData) noexcept; - static void BuildHeaders(MeshAsset& asset) noexcept; + static void BuildHeaders(ModelAsset& asset) noexcept; static void WriteMeshHeader(std::ofstream& file, MeshDataHeader const& header); - static void WriteMeshData(std::ofstream& file, MeshDataHeader const& header, MeshData const& data); + static void WriteMeshData(std::ofstream& file, MeshDataHeader const& header, MeshData const& asset); - static void LoadFromFile(AssetPath path, MeshAsset& asset) noexcept; - static void CompileMeshBinary(AssetPath path, MeshAsset const& asset) noexcept; + static void LoadFromFile(AssetPath path, ModelAsset& asset) noexcept; + static void CompileMeshBinary(AssetPath path, ModelAsset const& asset) noexcept; static void BuildArmature(aiNode const& node, RigNode*& root) noexcept; static void CopyNode(aiNode const& source, RigNode* parent) noexcept; diff --git a/src/Types/MeshAsset.h b/src/Types/MeshAsset.h index adff44a..f5e1eb0 100644 --- a/src/Types/MeshAsset.h +++ b/src/Types/MeshAsset.h @@ -38,6 +38,26 @@ namespace SH_COMP uint32_t vertexCount; uint32_t indexCount; uint32_t charCount; + uint32_t boneCount; + }; + + struct MeshBoneInfo + { + uint32_t charCount; + uint32_t weightCount; // Size should be same as boneCount + }; + + struct BoneWeight + { + uint32_t index; + float weight; + }; + + struct MeshBone + { + std::string name; + SHMat4 offset; + std::vector weights; }; struct MeshData @@ -48,11 +68,14 @@ namespace SH_COMP std::vector vertexNormal; std::vector texCoords; std::vector indices; + std::vector bonesInfo; + std::vector bones; }; struct RigNode { std::string name; + uint32_t id; SHMat4 transform; std::vector children; }; @@ -62,15 +85,14 @@ namespace SH_COMP RigNode* root; }; - struct MeshAssetHeader + struct ModelAssetHeader { size_t meshCount; }; - struct MeshAsset + struct ModelAsset { - MeshAssetHeader header; - RigData rig; + ModelAssetHeader header; std::vector headers; std::vector meshes; };