From af944b308386ff97be67f02e31eb2d3751cb085a Mon Sep 17 00:00:00 2001 From: Xiao Qi Date: Wed, 1 Mar 2023 23:13:02 +0800 Subject: [PATCH] UNTESTED: Loading of new format for animations and rigs --- .../Asset Types/Models/SHAnimationAsset.h | 18 ++- .../Assets/Asset Types/Models/SHRigAsset.h | 12 +- .../Libraries/Loaders/SHModelLoader.cpp | 130 ++++++++++-------- .../Assets/Libraries/Loaders/SHModelLoader.h | 4 +- 4 files changed, 94 insertions(+), 70 deletions(-) diff --git a/SHADE_Engine/src/Assets/Asset Types/Models/SHAnimationAsset.h b/SHADE_Engine/src/Assets/Asset Types/Models/SHAnimationAsset.h index 424f8cf3..bdc2a88d 100644 --- a/SHADE_Engine/src/Assets/Asset Types/Models/SHAnimationAsset.h +++ b/SHADE_Engine/src/Assets/Asset Types/Models/SHAnimationAsset.h @@ -30,15 +30,23 @@ namespace SHADE struct KeyBase { float time; - SHVec3 value; }; // Smallest data containers - struct PositionKey :KeyBase {}; + struct PositionKey :KeyBase + { + SHVec3 value; + }; - struct RotationKey : KeyBase {}; + struct RotationKey : KeyBase + { + SHVec4 value; + }; - struct ScaleKey :KeyBase {}; + struct ScaleKey :KeyBase + { + SHVec3 value; + }; // Headers for read/write struct SHAnimDataHeader @@ -51,7 +59,7 @@ namespace SHADE // Main data containers struct SHAnimNode { - std::string name; + AnimationInterpolation interpolation; std::vector positionKeys; std::vector rotationKeys; diff --git a/SHADE_Engine/src/Assets/Asset Types/Models/SHRigAsset.h b/SHADE_Engine/src/Assets/Asset Types/Models/SHRigAsset.h index 85f0c540..66edc081 100644 --- a/SHADE_Engine/src/Assets/Asset Types/Models/SHRigAsset.h +++ b/SHADE_Engine/src/Assets/Asset Types/Models/SHRigAsset.h @@ -34,8 +34,6 @@ namespace SHADE uint32_t nodeCount{}; uint32_t startNode{}; std::vector charCounts{}; - std::vector childCount{}; - std::vector dataFlags{}; }; struct SHRigNodeData @@ -49,9 +47,17 @@ namespace SHADE SHMatrix inverseBindMatrix; }; - struct SH_API SHRigAsset final : SHAssetData + struct SHRigNodeAsset + { + uint32_t idRef; + std::vector children; + }; + + struct SH_API SHRigAsset : SHAssetData { + ~SHRigAsset(); SHRigDataHeader header; std::vector nodeDataCollection{}; + SHRigNodeAsset* root; }; } diff --git a/SHADE_Engine/src/Assets/Libraries/Loaders/SHModelLoader.cpp b/SHADE_Engine/src/Assets/Libraries/Loaders/SHModelLoader.cpp index 6f0e5fc5..ba2b8be4 100644 --- a/SHADE_Engine/src/Assets/Libraries/Loaders/SHModelLoader.cpp +++ b/SHADE_Engine/src/Assets/Libraries/Loaders/SHModelLoader.cpp @@ -56,19 +56,35 @@ namespace SHADE { ReadRigHeader(file, asset.rig.header); ReadRigData(file, asset.rig.header, asset.rig.nodeDataCollection); + ReadRigTree(file, asset.rig.header, asset.rig.root); } } - void SHModelLoader::ReadAnimNode(FileReference file, SHAnimDataHeader const& info, SHAnimNode& data) + void SHModelLoader::ReadAnimNode(FileReference file, uint32_t frameCount, SHAnimNode& data) { - data.name.resize(info.charCount); file.read( - data.name.data(), - info.charCount + reinterpret_cast(&data.interpolation), + 1 ); - //TODO read and parse data flags - //TODO read channels + data.positionKeys.resize(frameCount); + data.rotationKeys.resize(frameCount); + data.scaleKeys.resize(frameCount); + + file.read( + reinterpret_cast(data.positionKeys.data()), + sizeof(PositionKey) * frameCount + ); + + file.read( + reinterpret_cast(data.rotationKeys.data()), + sizeof(RotationKey) * frameCount + ); + + file.read( + reinterpret_cast(data.scaleKeys.data()), + sizeof(ScaleKey) * frameCount + ); } void SHModelLoader::ReadRigHeader(FileReference file, SHRigDataHeader& header) @@ -78,6 +94,11 @@ namespace SHADE sizeof(uint32_t) ); + file.read( + reinterpret_cast(&header.startNode), + sizeof(uint32_t) + ); + header.charCounts.resize(header.nodeCount); file.read( reinterpret_cast(header.charCounts.data()), @@ -91,21 +112,51 @@ namespace SHADE for (auto i {0}; i < header.nodeCount; ++i) { - data[i].name.resize(header.charCounts[i]); + auto& node = data[i]; + node.name.resize(header.charCounts[i]); file.read( data[i].name.data(), header.charCounts[i] ); - file.read( - reinterpret_cast(&data[i].transform), - sizeof(SHMatrix) - ); + NodeDataFlag flag; + file.get(reinterpret_cast(flag)); - file.read( - reinterpret_cast(&data[i].offset), - sizeof(SHMatrix) - ); + if (flag & NODE_DATA_ROTATION) + { + node.rotation.resize(NODE_COMPONENT_COUNT_ROTATION); + file.read( + reinterpret_cast(node.rotation.data()), + sizeof(double) * NODE_COMPONENT_COUNT_ROTATION + ); + } + + if (flag & NODE_DATA_SCALE) + { + node.scale.resize(NODE_COMPONENT_COUNT_SCALE); + file.read( + reinterpret_cast(node.scale.data()), + sizeof(double) * NODE_COMPONENT_COUNT_SCALE + ); + } + + if (flag & NODE_DATA_TRANSLATION) + { + node.translation.resize(NODE_COMPONENT_COUNT_TRANSLATION); + file.read( + reinterpret_cast(node.translation.data()), + sizeof(double) * NODE_COMPONENT_COUNT_TRANSLATION + ); + } + + if (flag & NODE_DATA_MATRIX) + { + node.matrix.resize(NODE_COMPONENT_COUNT_MATRIX); + file.read( + reinterpret_cast(node.matrix.data()), + sizeof(double) * NODE_DATA_MATRIX + ); + } } } @@ -149,8 +200,6 @@ namespace SHADE nodeQueue.emplace(depthPtr++, depthTempPtr++); } } - - delete[] dst; } void SHModelLoader::ReadMeshData(FileReference file, std::vector const& headers, @@ -171,7 +220,6 @@ namespace SHADE data.VertexNormals.resize(header.vertexCount); data.VertexTexCoords.resize(header.vertexCount); data.Indices.resize(header.indexCount); - data.BoneCount = header.boneCount; file.read(data.name.data(), header.charCount); file.read(reinterpret_cast(data.VertexPositions.data()), vertexVec3Byte); @@ -180,48 +228,10 @@ namespace SHADE file.read(reinterpret_cast(data.VertexTexCoords.data()), vertexVec2Byte); file.read(reinterpret_cast(data.Indices.data()), sizeof(uint32_t) * header.indexCount); - if (header.boneCount) + if (header.hasWeights) { - std::vector boneInfos(header.boneCount); - std::vector bones(header.boneCount); - - file.read(reinterpret_cast(boneInfos.data()), sizeof(MeshBoneInfo) * header.boneCount); - - for (auto i{ 0 }; i < header.boneCount; ++i) - { - auto& bone = bones[i]; - auto const& info = boneInfos[i]; - - bone.name.resize(info.charCount); - file.read(bone.name.data(), info.charCount); - file.read(reinterpret_cast(&bone.offset), sizeof(SHMatrix)); - - bone.weights.resize(info.weightCount); - file.read(reinterpret_cast(bone.weights.data()), sizeof(BoneWeight) * info.weightCount); - } - - data.VertexBoneIndices.resize(header.vertexCount); - data.VertexBoneWeights.resize(header.vertexCount); - - for (uint32_t boneIndex{0}; boneIndex < bones.size(); ++boneIndex) - { - auto const& bone = bones[boneIndex]; - for (auto const& weight : bone.weights) - { - auto& boneIndices = data.VertexBoneIndices[weight.index]; - auto& boneWeight = data.VertexBoneWeights[weight.index]; - - for (auto j{0}; j < BONE_INDEX_ALIGHTMENT; ++j) - { - if (boneWeight[j] == 0.f) - { - boneIndices[j] = boneIndex; - boneWeight[j] = weight.weight; - break; - } - } - } - } + data.VertexWeights.resize(header.vertexCount); + file.read(reinterpret_cast(data.VertexWeights.data()), sizeof(VertexWeight) * header.vertexCount); } meshes[i] = &data; @@ -256,7 +266,7 @@ namespace SHADE animAsset.nodeChannels.resize(header.animNodeCount); for (auto i {0}; i < header.animNodeCount; ++i) { - ReadAnimNode(file, header.nodeHeaders[i], animAsset.nodeChannels[i]); + ReadAnimNode(file, header.frameCount, animAsset.nodeChannels[i]); } anims[i] = &animAsset; diff --git a/SHADE_Engine/src/Assets/Libraries/Loaders/SHModelLoader.h b/SHADE_Engine/src/Assets/Libraries/Loaders/SHModelLoader.h index 82fe43b4..d1afba6a 100644 --- a/SHADE_Engine/src/Assets/Libraries/Loaders/SHModelLoader.h +++ b/SHADE_Engine/src/Assets/Libraries/Loaders/SHModelLoader.h @@ -23,11 +23,11 @@ namespace SHADE void ReadRigHeader(FileReference file, SHRigDataHeader& header); void ReadRigData(FileReference file, SHRigDataHeader const& header, std::vector& data); - void ReadAnimNode(FileReference file, SHAnimDataHeader const& info, SHAnimNode& data); - void ReadAnimNode(FileReference file, SHAnimNode& data); + void ReadRigTree(FileReference file, SHRigDataHeader const& header, SHRigNodeAsset*& root); void ReadMeshData(FileReference file, std::vector const& headers, std::vector& meshes); void ReadAnimData(FileReference file, std::vector const& headers, std::vector& anims); + void ReadAnimNode(FileReference file, uint32_t frameCount, SHAnimNode& data); void ReadHeaders(FileReference file, SHModelAsset& asset); void ReadData(FileReference file, SHModelAsset& asset);