- fbx: refactor animation code.

pull/14/head
Alexander Gessler 2012-07-27 15:53:17 +02:00
parent ffd084a7a7
commit 80e7e18e28
1 changed files with 179 additions and 164 deletions

View File

@ -1400,15 +1400,55 @@ private:
double max_time = -1e10; double max_time = -1e10;
try { try {
BOOST_FOREACH(const NodeMap::value_type& kv, node_map) {
GenerateNodeAnimations(node_anims,
kv.first,
kv.second,
layer_map,
min_time,
max_time);
}
}
catch(std::exception&) {
std::for_each(node_anims.begin(), node_anims.end(), Util::delete_fun<aiNodeAnim>());
throw;
}
if(node_anims.size()) {
anim->mChannels = new aiNodeAnim*[node_anims.size()]();
anim->mNumChannels = static_cast<unsigned int>(node_anims.size());
std::swap_ranges(node_anims.begin(),node_anims.end(),anim->mChannels);
}
else {
// empty animations would fail validation, so drop them
delete anim;
animations.pop_back();
FBXImporter::LogInfo("ignoring empty AnimationStack: " + name);
return;
}
// for some mysterious reason, mDuration is simply the maximum key -- the
// validator always assumes animations to start at zero.
anim->mDuration = max_time /*- min_time */;
anim->mTicksPerSecond = 1000.0;
}
// ------------------------------------------------------------------------------------------------
void GenerateNodeAnimations(std::vector<aiNodeAnim*>& node_anims,
const std::string& fixed_name,
const std::vector<const AnimationCurveNode*>& curves,
const LayerMap& layer_map,
double& max_time,
double& min_time)
{
NodeMap node_property_map; NodeMap node_property_map;
BOOST_FOREACH(const NodeMap::value_type& kv, node_map) { ai_assert(curves.size());
node_property_map.clear();
ai_assert(kv.second.size());
const AnimationCurveNode* curve_node; const AnimationCurveNode* curve_node;
BOOST_FOREACH(const AnimationCurveNode* node, kv.second) { BOOST_FOREACH(const AnimationCurveNode* node, curves) {
ai_assert(node); ai_assert(node);
if (node->TargetProperty().empty()) { if (node->TargetProperty().empty()) {
@ -1456,7 +1496,7 @@ private:
if (!has_any) { if (!has_any) {
FBXImporter::LogWarn("ignoring node animation, did not find any transformation key frames"); FBXImporter::LogWarn("ignoring node animation, did not find any transformation key frames");
continue; return;
} }
ai_assert(curve_node->TargetAsModel()); ai_assert(curve_node->TargetAsModel());
@ -1468,7 +1508,7 @@ private:
const Model& target = *curve_node->TargetAsModel(); const Model& target = *curve_node->TargetAsModel();
if (!has_complex && !NeedsComplexTransformationChain(target)) { if (!has_complex && !NeedsComplexTransformationChain(target)) {
aiNodeAnim* const nd = GenerateSimpleNodeAnim(kv.first, target, chain, aiNodeAnim* const nd = GenerateSimpleNodeAnim(fixed_name, target, chain,
node_property_map.end(), node_property_map.end(),
layer_map, layer_map,
max_time, max_time,
@ -1477,7 +1517,7 @@ private:
ai_assert(nd); ai_assert(nd);
node_anims.push_back(nd); node_anims.push_back(nd);
continue; return;
} }
// otherwise, things get gruesome and we need separate animation channels // otherwise, things get gruesome and we need separate animation channels
@ -1487,7 +1527,7 @@ private:
if (chain[i] != node_property_map.end()) { if (chain[i] != node_property_map.end()) {
const std::string& chain_name = NameTransformationChainNode(kv.first, comp); const std::string& chain_name = NameTransformationChainNode(fixed_name, comp);
aiNodeAnim* na; aiNodeAnim* na;
switch(comp) switch(comp)
@ -1518,7 +1558,7 @@ private:
// pivoting requires us to generate an inverse channel to undo the pivot translation // pivoting requires us to generate an inverse channel to undo the pivot translation
if (comp == TransformationComp_RotationPivot) { if (comp == TransformationComp_RotationPivot) {
const std::string& invName = NameTransformationChainNode(kv.first, TransformationComp_RotationPivotInverse); const std::string& invName = NameTransformationChainNode(fixed_name, TransformationComp_RotationPivotInverse);
aiNodeAnim* const inv = GenerateTranslationNodeAnim(invName, aiNodeAnim* const inv = GenerateTranslationNodeAnim(invName,
target, target,
(*chain[i]).second, (*chain[i]).second,
@ -1531,7 +1571,7 @@ private:
node_anims.push_back(inv); node_anims.push_back(inv);
} }
else if (comp == TransformationComp_ScalingPivot) { else if (comp == TransformationComp_ScalingPivot) {
const std::string& invName = NameTransformationChainNode(kv.first, TransformationComp_ScalingPivotInverse); const std::string& invName = NameTransformationChainNode(fixed_name, TransformationComp_ScalingPivotInverse);
aiNodeAnim* const inv = GenerateTranslationNodeAnim(invName, aiNodeAnim* const inv = GenerateTranslationNodeAnim(invName,
target, target,
(*chain[i]).second, (*chain[i]).second,
@ -1566,31 +1606,6 @@ private:
} }
} }
} }
}
catch(std::exception&) {
std::for_each(node_anims.begin(), node_anims.end(), Util::delete_fun<aiNodeAnim>());
throw;
}
if(node_anims.size()) {
anim->mChannels = new aiNodeAnim*[node_anims.size()]();
anim->mNumChannels = static_cast<unsigned int>(node_anims.size());
std::swap_ranges(node_anims.begin(),node_anims.end(),anim->mChannels);
}
else {
// empty animations would fail validation, so drop them
delete anim;
animations.pop_back();
FBXImporter::LogInfo("ignoring empty AnimationStack: " + name);
return;
}
// for some mysterious reason, mDuration is simply the maximum key -- the
// validator always assumes animations to start at zero.
anim->mDuration = max_time /*- min_time */;
anim->mTicksPerSecond = 1000.0;
}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------