UNTESTED: Loading of new format for animations and rigs

This commit is contained in:
Xiao Qi 2023-03-01 23:13:02 +08:00
parent f118c1c2ca
commit af944b3083
4 changed files with 94 additions and 70 deletions

View File

@ -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<PositionKey> positionKeys;
std::vector<RotationKey> rotationKeys;

View File

@ -34,8 +34,6 @@ namespace SHADE
uint32_t nodeCount{};
uint32_t startNode{};
std::vector<uint32_t> charCounts{};
std::vector<uint32_t> childCount{};
std::vector<NodeDataFlag> dataFlags{};
};
struct SHRigNodeData
@ -49,9 +47,17 @@ namespace SHADE
SHMatrix inverseBindMatrix;
};
struct SH_API SHRigAsset final : SHAssetData
struct SHRigNodeAsset
{
uint32_t idRef;
std::vector<SHRigNodeAsset*> children;
};
struct SH_API SHRigAsset : SHAssetData
{
~SHRigAsset();
SHRigDataHeader header;
std::vector<SHRigNodeData> nodeDataCollection{};
SHRigNodeAsset* root;
};
}

View File

@ -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<char*>(&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<char*>(data.positionKeys.data()),
sizeof(PositionKey) * frameCount
);
file.read(
reinterpret_cast<char*>(data.rotationKeys.data()),
sizeof(RotationKey) * frameCount
);
file.read(
reinterpret_cast<char*>(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<char*>(&header.startNode),
sizeof(uint32_t)
);
header.charCounts.resize(header.nodeCount);
file.read(
reinterpret_cast<char*>(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<char*>(&data[i].transform),
sizeof(SHMatrix)
);
NodeDataFlag flag;
file.get(reinterpret_cast<char&>(flag));
file.read(
reinterpret_cast<char*>(&data[i].offset),
sizeof(SHMatrix)
);
if (flag & NODE_DATA_ROTATION)
{
node.rotation.resize(NODE_COMPONENT_COUNT_ROTATION);
file.read(
reinterpret_cast<char*>(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<char*>(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<char*>(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<char*>(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<SHMeshDataHeader> 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<char*>(data.VertexPositions.data()), vertexVec3Byte);
@ -180,48 +228,10 @@ namespace SHADE
file.read(reinterpret_cast<char*>(data.VertexTexCoords.data()), vertexVec2Byte);
file.read(reinterpret_cast<char*>(data.Indices.data()), sizeof(uint32_t) * header.indexCount);
if (header.boneCount)
if (header.hasWeights)
{
std::vector<MeshBoneInfo> boneInfos(header.boneCount);
std::vector<MeshBone> bones(header.boneCount);
file.read(reinterpret_cast<char*>(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<char*>(&bone.offset), sizeof(SHMatrix));
bone.weights.resize(info.weightCount);
file.read(reinterpret_cast<char*>(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<char*>(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;

View File

@ -23,11 +23,11 @@ namespace SHADE
void ReadRigHeader(FileReference file, SHRigDataHeader& header);
void ReadRigData(FileReference file, SHRigDataHeader const& header, std::vector<SHRigNodeData>& 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<SHMeshDataHeader> const& headers, std::vector<SHMeshAsset*>& meshes);
void ReadAnimData(FileReference file, std::vector<SHAnimDataHeader> const& headers, std::vector<SHAnimAsset*>& anims);
void ReadAnimNode(FileReference file, uint32_t frameCount, SHAnimNode& data);
void ReadHeaders(FileReference file, SHModelAsset& asset);
void ReadData(FileReference file, SHModelAsset& asset);