- fbx: generate node anims for complex transformation chains with pivots and offsets.
parent
94e1e78c55
commit
3c37c8e7da
|
@ -339,6 +339,14 @@ private:
|
|||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// note: name must be a FixNodeName() result
|
||||
std::string NameTransformationChainNode(const std::string& name, TransformationComp comp)
|
||||
{
|
||||
return name + std::string(MAGIC_NODE_TAG) + "_" + NameTransformationComp(comp);
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
/** note: memory for output_nodes will be managed by the caller */
|
||||
void GenerateTransformationNodeChain(const Model& model,
|
||||
|
@ -431,7 +439,6 @@ private:
|
|||
if(is_complex && doc.Settings().preservePivots) {
|
||||
FBXImporter::LogInfo("generating full transformation chain for node: " + name);
|
||||
|
||||
const std::string mid = std::string(MAGIC_NODE_TAG) + "_";
|
||||
for (size_t i = 0; i < TransformationComp_MAXIMUM; ++i) {
|
||||
// XXX this may cause trouble with animations
|
||||
if (chain[i].IsIdentity()) {
|
||||
|
@ -440,8 +447,8 @@ private:
|
|||
|
||||
aiNode* nd = new aiNode();
|
||||
output_nodes.push_back(nd);
|
||||
|
||||
nd->mName.Set(name + mid + NameTransformationComp(static_cast<TransformationComp>(i)));
|
||||
|
||||
nd->mName.Set(NameTransformationChainNode(name, static_cast<TransformationComp>(i)));
|
||||
nd->mTransformation = chain[i];
|
||||
}
|
||||
|
||||
|
@ -1466,11 +1473,63 @@ private:
|
|||
continue;
|
||||
}
|
||||
|
||||
// otherwise, things get gruesome.
|
||||
aiNodeAnim* const na = new aiNodeAnim();
|
||||
// otherwise, things get gruesome and we need separate animation channels
|
||||
// for each part of the transformation chain.
|
||||
for (size_t i = 0; i < TransformationComp_MAXIMUM; ++i) {
|
||||
const TransformationComp comp = static_cast<TransformationComp>(i);
|
||||
|
||||
// XXX todo
|
||||
ai_assert(false);
|
||||
if (chain[i] != node_property_map.end()) {
|
||||
|
||||
const std::string& chain_name = NameTransformationChainNode(kv.first, comp);
|
||||
|
||||
aiNodeAnim* na;
|
||||
switch(comp)
|
||||
{
|
||||
case TransformationComp_Rotation:
|
||||
case TransformationComp_PreRotation:
|
||||
case TransformationComp_PostRotation:
|
||||
na = GenerateRotationNodeAnim(chain_name,
|
||||
target,
|
||||
(*chain[i]).second,
|
||||
layer_map,
|
||||
max_time,
|
||||
min_time
|
||||
);
|
||||
break;
|
||||
|
||||
case TransformationComp_RotationOffset:
|
||||
case TransformationComp_RotationPivot:
|
||||
case TransformationComp_ScalingOffset:
|
||||
case TransformationComp_ScalingPivot:
|
||||
case TransformationComp_Translation:
|
||||
na = GenerateTranslationNodeAnim(chain_name,
|
||||
target,
|
||||
(*chain[i]).second,
|
||||
layer_map,
|
||||
max_time,
|
||||
min_time
|
||||
);
|
||||
break;
|
||||
|
||||
case TransformationComp_Scaling:
|
||||
na = GenerateScalingNodeAnim(chain_name,
|
||||
target,
|
||||
(*chain[i]).second,
|
||||
layer_map,
|
||||
max_time,
|
||||
min_time
|
||||
);
|
||||
break;
|
||||
|
||||
default:
|
||||
ai_assert(false);
|
||||
}
|
||||
|
||||
ai_assert(na);
|
||||
node_anims.push_back(na);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch(std::exception&) {
|
||||
|
@ -1499,6 +1558,99 @@ private:
|
|||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
aiNodeAnim* GenerateRotationNodeAnim(const std::string& name,
|
||||
const Model& target,
|
||||
const std::vector<const AnimationCurveNode*>& curves,
|
||||
const LayerMap& layer_map,
|
||||
double& max_time,
|
||||
double& min_time)
|
||||
{
|
||||
ScopeGuard<aiNodeAnim> na(new aiNodeAnim());
|
||||
na->mNodeName.Set(name);
|
||||
|
||||
ConvertRotationKeys(na, curves, layer_map, max_time,min_time);
|
||||
|
||||
// dummy scaling key
|
||||
na->mScalingKeys = new aiVectorKey[1];
|
||||
na->mNumScalingKeys = 1;
|
||||
|
||||
na->mScalingKeys[0].mTime = 0.;
|
||||
na->mScalingKeys[0].mValue = aiVector3D(1.0f,1.0f,1.0f);
|
||||
|
||||
// dummy position key
|
||||
na->mPositionKeys = new aiVectorKey[1];
|
||||
na->mNumPositionKeys = 1;
|
||||
|
||||
na->mPositionKeys[0].mTime = 0.;
|
||||
na->mPositionKeys[0].mValue = aiVector3D();
|
||||
|
||||
return na.dismiss();
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
aiNodeAnim* GenerateScalingNodeAnim(const std::string& name,
|
||||
const Model& target,
|
||||
const std::vector<const AnimationCurveNode*>& curves,
|
||||
const LayerMap& layer_map,
|
||||
double& max_time,
|
||||
double& min_time)
|
||||
{
|
||||
ScopeGuard<aiNodeAnim> na(new aiNodeAnim());
|
||||
na->mNodeName.Set(name);
|
||||
|
||||
ConvertScaleKeys(na, curves, layer_map, max_time,min_time);
|
||||
|
||||
// dummy rotation key
|
||||
na->mRotationKeys = new aiQuatKey[1];
|
||||
na->mNumRotationKeys = 1;
|
||||
|
||||
na->mRotationKeys[0].mTime = 0.;
|
||||
na->mRotationKeys[0].mValue = aiQuaternion();
|
||||
|
||||
// dummy position key
|
||||
na->mPositionKeys = new aiVectorKey[1];
|
||||
na->mNumPositionKeys = 1;
|
||||
|
||||
na->mPositionKeys[0].mTime = 0.;
|
||||
na->mPositionKeys[0].mValue = aiVector3D();
|
||||
|
||||
return na.dismiss();
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
aiNodeAnim* GenerateTranslationNodeAnim(const std::string& name,
|
||||
const Model& target,
|
||||
const std::vector<const AnimationCurveNode*>& curves,
|
||||
const LayerMap& layer_map,
|
||||
double& max_time,
|
||||
double& min_time)
|
||||
{
|
||||
ScopeGuard<aiNodeAnim> na(new aiNodeAnim());
|
||||
na->mNodeName.Set(name);
|
||||
|
||||
ConvertTranslationKeys(na, curves, layer_map, max_time,min_time);
|
||||
|
||||
// dummy scaling key
|
||||
na->mScalingKeys = new aiVectorKey[1];
|
||||
na->mNumScalingKeys = 1;
|
||||
|
||||
na->mScalingKeys[0].mTime = 0.;
|
||||
na->mScalingKeys[0].mValue = aiVector3D(1.0f,1.0f,1.0f);
|
||||
|
||||
// dummy rotation key
|
||||
na->mRotationKeys = new aiQuatKey[1];
|
||||
na->mNumRotationKeys = 1;
|
||||
|
||||
na->mRotationKeys[0].mTime = 0.;
|
||||
na->mRotationKeys[0].mValue = aiQuaternion();
|
||||
|
||||
return na.dismiss();
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// generate node anim, extracting only Rotation, Scaling and Translation from the given chain
|
||||
aiNodeAnim* GenerateSimpleNodeAnim(const std::string& name,
|
||||
|
|
Loading…
Reference in New Issue