Implemented node<->joint mapping across the asset

This commit is contained in:
Xiao Qi 2023-03-06 21:41:52 +08:00
parent 810c1e4c08
commit ffb489a0d6
2 changed files with 28 additions and 20 deletions

View File

@ -57,8 +57,8 @@ namespace SH_COMP
} }
ProcessMesh(model, asset); ProcessMesh(model, asset);
ProcessAnimationChannels(model, asset);
ProcessRigNodes(model, asset); ProcessRigNodes(model, asset);
ProcessAnimationChannels(model, asset);
} }
inline void MeshCompiler::ProcessMesh(ModelData const& data, ModelRef asset) noexcept inline void MeshCompiler::ProcessMesh(ModelData const& data, ModelRef asset) noexcept
@ -228,6 +228,12 @@ namespace SH_COMP
inline void MeshCompiler::ProcessAnimationChannels(ModelData const& data, ModelRef asset) noexcept inline void MeshCompiler::ProcessAnimationChannels(ModelData const& data, ModelRef asset) noexcept
{ {
if (data.animations.empty())
{
std::cout << "[Model Compiler] Animations do not exist\n";
return;
}
asset.anims.resize(data.animations.size()); asset.anims.resize(data.animations.size());
for (auto i {0}; i < data.animations.size(); ++i) for (auto i {0}; i < data.animations.size(); ++i)
{ {
@ -239,19 +245,20 @@ namespace SH_COMP
for (auto const& channel : animData.channels) for (auto const& channel : animData.channels)
{ {
auto const& sampler{ animData.samplers[channel.sampler] }; auto const& sampler{ animData.samplers[channel.sampler] };
auto const& targetNode{asset.nodeIndexMap[channel.target_node]};
// Resize nodes vector to latest largest index called // Resize nodes vector to latest largest index called
if (anim.nodes.size() <= channel.target_node) if (anim.nodes.size() <= targetNode)
anim.nodes.resize(channel.target_node + 1); anim.nodes.resize(targetNode + 1);
if (channel.target_path == TRANSLATION_PATH.data()) if (channel.target_path == TRANSLATION_PATH.data())
FetchChannelKeyFrame(sampler.input, sampler.output, anim.nodes[channel.target_node].positionKeys); FetchChannelKeyFrame(sampler.input, sampler.output, anim.nodes[targetNode].positionKeys);
else if (channel.target_path == SCALE_PATH.data()) else if (channel.target_path == SCALE_PATH.data())
FetchChannelKeyFrame(sampler.input, sampler.output, anim.nodes[channel.target_node].scaleKeys); FetchChannelKeyFrame(sampler.input, sampler.output, anim.nodes[targetNode].scaleKeys);
else if (channel.target_path == ROTATION_PATH.data()) else if (channel.target_path == ROTATION_PATH.data())
FetchChannelKeyFrame(sampler.input, sampler.output, anim.nodes[channel.target_node].rotationKeys); FetchChannelKeyFrame(sampler.input, sampler.output, anim.nodes[targetNode].rotationKeys);
anim.nodes[channel.target_node].interpolation = anim.nodes[targetNode].interpolation =
sampler.interpolation == LINEAR_INTERPOLATION.data() ? AnimationInterpolation::LINEAR : sampler.interpolation == LINEAR_INTERPOLATION.data() ? AnimationInterpolation::LINEAR :
sampler.interpolation == STEP_INTERPOLATION.data() ? AnimationInterpolation::STEP : sampler.interpolation == STEP_INTERPOLATION.data() ? AnimationInterpolation::STEP :
sampler.interpolation == CUBICSPLINE_INTERPOLATION.data() ? AnimationInterpolation::CUBICSPLINE : sampler.interpolation == CUBICSPLINE_INTERPOLATION.data() ? AnimationInterpolation::CUBICSPLINE :
@ -265,10 +272,7 @@ namespace SH_COMP
inline void MeshCompiler::ProcessRigNodes(ModelData const& data, ModelRef asset) noexcept inline void MeshCompiler::ProcessRigNodes(ModelData const& data, ModelRef asset) noexcept
{ {
if (asset.anims.empty()) if (data.skins.empty())
return;
if (data.skins.size() == 0)
{ {
std::cout << "[Model Compiler] Unable to load rigs without skin, aborting"; std::cout << "[Model Compiler] Unable to load rigs without skin, aborting";
return; return;
@ -279,10 +283,15 @@ namespace SH_COMP
auto const& skin = data.skins[0]; auto const& skin = data.skins[0];
auto const jointsCount {skin.joints.size()}; auto const jointsCount {skin.joints.size()};
auto const& joints = skin.joints; auto const& joints = skin.joints;
auto const& nodeMap {asset.nodeIndexMap};
std::vector<SHMat4> inverseBindMatrices; std::vector<SHMat4> inverseBindMatrices;
FetchData(skin.inverseBindMatrices, inverseBindMatrices); FetchData(skin.inverseBindMatrices, inverseBindMatrices);
for (auto i{0}; i < skin.joints.size(); ++i)
{
asset.nodeIndexMap.insert({skin.joints[i], i});
}
std::vector<NodeAsset> nodesOrdered; std::vector<NodeAsset> nodesOrdered;
nodesOrdered.reserve(jointsCount); nodesOrdered.reserve(jointsCount);
auto& nodes{ data.nodes }; auto& nodes{ data.nodes };
@ -291,17 +300,12 @@ namespace SH_COMP
{ {
auto const& node{nodes[joints[i]]}; auto const& node{nodes[joints[i]]};
std::vector<IndexType> intermediate(node.children.size()); std::vector<IndexType> intermediate(node.children.size());
std::ranges::transform( std::ranges::transform(
node.children, node.children,
intermediate.begin(), intermediate.begin(),
[joints, jointsCount](auto const& index)->IndexType [nodeMap](auto const& index)->IndexType
{ {
for (IndexType i{0}; i < jointsCount; ++i) return nodeMap.at(static_cast<uint32_t>(index));
{
if (joints[i] == index)
return i;
}
} }
); );

View File

@ -13,6 +13,7 @@
#pragma once #pragma once
#include <vector> #include <vector>
#include <unordered_map>
#include "MeshAsset.h" #include "MeshAsset.h"
#include "AnimationAsset.h" #include "AnimationAsset.h"
@ -30,12 +31,15 @@ namespace SH_COMP
struct ModelAsset struct ModelAsset
{ {
ModelAssetHeader header; ModelAssetHeader header;
RigData rig;
std::vector<MeshDataHeader> meshHeaders; std::vector<MeshDataHeader> meshHeaders;
std::vector<AnimDataHeader> animHeaders; std::vector<AnimDataHeader> animHeaders;
std::vector<MeshData> meshes; std::vector<MeshData> meshes;
std::vector<AnimData> anims; std::vector<AnimData> anims;
};
RigData rig;
std::unordered_map<uint32_t, uint32_t> nodeIndexMap;
; };
} }