|
@@ -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&) {
|
|
@@ -1163,26 +1198,32 @@ private:
|
|
InterpolateKeys(temp.get(),keys,inputs,geom);
|
|
InterpolateKeys(temp.get(),keys,inputs,geom);
|
|
|
|
|
|
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)
|
|
{
|
|
{
|