Compile mesh bones and weights into binary

Rig structure still WIP
This commit is contained in:
Xiao Qi 2022-11-12 15:55:41 +08:00
parent 310765f4f6
commit 66baaf374d
3 changed files with 65 additions and 25 deletions

View File

@ -74,10 +74,27 @@ namespace SH_COMP
meshData.vertexTangent.reserve(mesh.mNumVertices); meshData.vertexTangent.reserve(mesh.mNumVertices);
meshData.texCoords.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) for (auto i {0}; i < mesh.mNumBones; ++i)
{ {
auto& bone = *mesh.mBones[i]; auto const& bone = *mesh.mBones[i];
std::cout << "bone" << std::endl; 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) 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) for (auto const& mesh : asset.meshes)
{ {
@ -139,6 +156,7 @@ namespace SH_COMP
head.charCount = mesh.name.size(); head.charCount = mesh.name.size();
head.indexCount = mesh.indices.size(); head.indexCount = mesh.indices.size();
head.vertexCount = mesh.vertexPosition.size(); head.vertexCount = mesh.vertexPosition.size();
head.boneCount = mesh.bonesInfo.size();
asset.header.meshCount++; 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 const aiScene* scene = aiImporter.ReadFile(path.string().c_str(),
//aiProcess_Triangulate // Make sure we get triangles rather than nvert polygons aiProcess_Triangulate // Make sure we get triangles rather than nvert polygons
//| aiProcess_GenUVCoords // Convert any type of mapping to uv mapping | aiProcess_GenUVCoords // Convert any type of mapping to uv mapping
//| aiProcess_TransformUVCoords // preprocess UV transformations (scaling, translation ...) | aiProcess_TransformUVCoords // preprocess UV transformations (scaling, translation ...)
//| aiProcess_FindInstances // search for instanced meshes and remove them by references to one master | aiProcess_FindInstances // search for instanced meshes and remove them by references to one master
//| aiProcess_CalcTangentSpace // calculate tangents and bitangents if possible | aiProcess_CalcTangentSpace // calculate tangents and bitangents if possible
//| aiProcess_JoinIdenticalVertices // join identical vertices/ optimize indexing | aiProcess_JoinIdenticalVertices // join identical vertices/ optimize indexing
//| aiProcess_FindInvalidData // detect invalid model data, such as invalid normal vectors | 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_FlipUVs // flip the V to match the Vulkans way of doing UVs
//| aiProcess_ValidateDataStructure | aiProcess_ValidateDataStructure
); );
if (!scene || !scene->HasMeshes()) if (!scene || !scene->HasMeshes())
@ -215,7 +233,7 @@ namespace SH_COMP
aiImporter.FreeScene(); 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('.')) }; std::string newPath{ path.string().substr(0, path.string().find_last_of('.')) };
newPath += MODEL_EXTENSION; newPath += MODEL_EXTENSION;
@ -254,7 +272,7 @@ namespace SH_COMP
{ {
RigNode* current = new RigNode(); RigNode* current = new RigNode();
current->name = source.mName.C_Str(); current->name = source.mName.C_Str();
std::memcpy(&current->transform, &source.mTransformation, sizeof(float) * 16); std::memcpy(&current->transform, &source.mTransformation, sizeof(SHMat4));
for (auto i {0}; i < source.mNumChildren; ++i) for (auto i {0}; i < source.mNumChildren; ++i)
{ {
@ -269,7 +287,7 @@ namespace SH_COMP
void MeshCompiler::LoadAndCompile(AssetPath path) noexcept void MeshCompiler::LoadAndCompile(AssetPath path) noexcept
{ {
auto const asset = new MeshAsset(); auto const asset = new ModelAsset();
asset->rig.root = nullptr; asset->rig.root = nullptr;

View File

@ -33,13 +33,13 @@ namespace SH_COMP
static void ProcessNode(aiNode const& node, aiScene const& scene, MeshVectorRef meshes, RigNode*& root) noexcept; 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 ExtractAnimations(aiScene const& scene, AnimVectorRef anims) noexcept;
static void GetMesh(aiMesh const& mesh, MeshData& meshData) 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 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 LoadFromFile(AssetPath path, ModelAsset& asset) noexcept;
static void CompileMeshBinary(AssetPath path, MeshAsset const& asset) noexcept; static void CompileMeshBinary(AssetPath path, ModelAsset const& asset) noexcept;
static void BuildArmature(aiNode const& node, RigNode*& root) noexcept; static void BuildArmature(aiNode const& node, RigNode*& root) noexcept;
static void CopyNode(aiNode const& source, RigNode* parent) noexcept; static void CopyNode(aiNode const& source, RigNode* parent) noexcept;

View File

@ -38,6 +38,26 @@ namespace SH_COMP
uint32_t vertexCount; uint32_t vertexCount;
uint32_t indexCount; uint32_t indexCount;
uint32_t charCount; 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<BoneWeight> weights;
}; };
struct MeshData struct MeshData
@ -48,11 +68,14 @@ namespace SH_COMP
std::vector<SHVec3> vertexNormal; std::vector<SHVec3> vertexNormal;
std::vector<SHVec2> texCoords; std::vector<SHVec2> texCoords;
std::vector<uint32_t> indices; std::vector<uint32_t> indices;
std::vector<MeshBoneInfo> bonesInfo;
std::vector<MeshBone> bones;
}; };
struct RigNode struct RigNode
{ {
std::string name; std::string name;
uint32_t id;
SHMat4 transform; SHMat4 transform;
std::vector<RigNode*> children; std::vector<RigNode*> children;
}; };
@ -62,15 +85,14 @@ namespace SH_COMP
RigNode* root; RigNode* root;
}; };
struct MeshAssetHeader struct ModelAssetHeader
{ {
size_t meshCount; size_t meshCount;
}; };
struct MeshAsset struct ModelAsset
{ {
MeshAssetHeader header; ModelAssetHeader header;
RigData rig;
std::vector<MeshDataHeader> headers; std::vector<MeshDataHeader> headers;
std::vector<MeshData> meshes; std::vector<MeshData> meshes;
}; };