- fbx: always set all tracks in aiNodeAnim to pass validation.

pull/14/head
Alexander Gessler 2012-07-21 22:29:42 +02:00
parent e4305149be
commit fd828a1b44
1 changed files with 55 additions and 14 deletions

View File

@ -942,6 +942,9 @@ private:
BOOST_FOREACH(const NodeMap::value_type& kv, node_map) { BOOST_FOREACH(const NodeMap::value_type& kv, node_map) {
node_property_map.clear(); node_property_map.clear();
ai_assert(kv.second.size());
const AnimationCurveNode* curve_node;
BOOST_FOREACH(const AnimationCurveNode* node, kv.second) { BOOST_FOREACH(const AnimationCurveNode* node, kv.second) {
ai_assert(node); ai_assert(node);
@ -950,6 +953,7 @@ private:
continue; continue;
} }
curve_node = node;
if (node->Curves().empty()) { if (node->Curves().empty()) {
FBXImporter::LogWarn("no animation curves assigned to AnimationCurveNode"); FBXImporter::LogWarn("no animation curves assigned to AnimationCurveNode");
continue; continue;
@ -958,6 +962,8 @@ private:
node_property_map[node->TargetProperty()].push_back(node); node_property_map[node->TargetProperty()].push_back(node);
} }
ai_assert(curve_node);
const NodeMap::const_iterator itScale = node_property_map.find("Lcl Scaling"); const NodeMap::const_iterator itScale = node_property_map.find("Lcl Scaling");
const NodeMap::const_iterator itRotation = node_property_map.find("Lcl Rotation"); const NodeMap::const_iterator itRotation = node_property_map.find("Lcl Rotation");
const NodeMap::const_iterator itTranslation = node_property_map.find("Lcl Translation"); const NodeMap::const_iterator itTranslation = node_property_map.find("Lcl Translation");
@ -974,17 +980,46 @@ private:
aiNodeAnim* const na = new aiNodeAnim(); aiNodeAnim* const na = new aiNodeAnim();
node_anims.push_back(na); node_anims.push_back(na);
const PropertyTable& props = curve_node->TargetNode()->Props();
// if a particular transformation is not given, grab it from
// the corresponding node to meet the semantics of aiNodeAnim,
// which requires all of rotation, scaling and translation
// to be set.
if(hasScale) { if(hasScale) {
ConvertScaleKeys(na, (*itScale).second, layer_map); ConvertScaleKeys(na, (*itScale).second, layer_map);
} }
else {
na->mScalingKeys = new aiVectorKey[1];
na->mNumScalingKeys = 1;
na->mScalingKeys[0].mTime = 0.;
na->mScalingKeys[0].mValue = PropertyGet(props,"Lcl Scaling",aiVector3D(1.f,1.f,1.f));
}
if(hasRotation) { if(hasRotation) {
ConvertRotationKeys(na, (*itRotation).second, layer_map); ConvertRotationKeys(na, (*itRotation).second, layer_map);
} }
else {
na->mRotationKeys = new aiQuatKey[1];
na->mNumRotationKeys = 1;
na->mRotationKeys[0].mTime = 0.;
na->mRotationKeys[0].mValue = EulerToQuaternion(
PropertyGet(props,"Lcl Rotation",aiVector3D(0.f,0.f,0.f))
);
}
if(hasTranslation) { if(hasTranslation) {
ConvertTranslationKeys(na, (*itTranslation).second, layer_map); ConvertTranslationKeys(na, (*itTranslation).second, layer_map);
} }
else {
na->mPositionKeys = new aiVectorKey[1];
na->mNumPositionKeys = 1;
na->mPositionKeys[0].mTime = 0.;
na->mPositionKeys[0].mValue = PropertyGet(props,"Lcl Translation",aiVector3D(0.f,0.f,0.f));
}
} }
} }
catch(std::exception&) { catch(std::exception&) {
@ -1164,25 +1199,31 @@ private:
for (size_t i = 0, c = keys.size(); i < c; ++i) { for (size_t i = 0, c = keys.size(); i < c; ++i) {
const aiVector3D rot = temp[i].mValue;
aiMatrix4x4 m, mtemp;
if(fabs(rot.x) > 1e-6f) {
m *= aiMatrix4x4::RotationX(rot.x,mtemp);
}
if(fabs(rot.y) > 1e-6f) {
m *= aiMatrix4x4::RotationY(rot.y,mtemp);
}
if(fabs(rot.z) > 1e-6f) {
m *= aiMatrix4x4::RotationZ(rot.z,mtemp);
}
valOut[i].mTime = temp[i].mTime; valOut[i].mTime = temp[i].mTime;
valOut[i].mValue = aiQuaternion(aiMatrix3x3(m)); valOut[i].mValue = EulerToQuaternion(temp[i].mValue);
} }
} }
// ------------------------------------------------------------------------------------------------
// euler xyz -> quat
aiQuaternion EulerToQuaternion(const aiVector3D& rot)
{
aiMatrix4x4 m, mtemp;
if(fabs(rot.x) > 1e-6f) {
m *= aiMatrix4x4::RotationX(rot.x,mtemp);
}
if(fabs(rot.y) > 1e-6f) {
m *= aiMatrix4x4::RotationY(rot.y,mtemp);
}
if(fabs(rot.z) > 1e-6f) {
m *= aiMatrix4x4::RotationZ(rot.z,mtemp);
}
return aiQuaternion(aiMatrix3x3(m));
}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void ConvertScaleKeys(aiNodeAnim* na, const std::vector<const AnimationCurveNode*>& nodes, const LayerMap& layers) void ConvertScaleKeys(aiNodeAnim* na, const std::vector<const AnimationCurveNode*>& nodes, const LayerMap& layers)
{ {