- 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 */
|
/** note: memory for output_nodes will be managed by the caller */
|
||||||
void GenerateTransformationNodeChain(const Model& model,
|
void GenerateTransformationNodeChain(const Model& model,
|
||||||
|
@ -431,7 +439,6 @@ private:
|
||||||
if(is_complex && doc.Settings().preservePivots) {
|
if(is_complex && doc.Settings().preservePivots) {
|
||||||
FBXImporter::LogInfo("generating full transformation chain for node: " + name);
|
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) {
|
for (size_t i = 0; i < TransformationComp_MAXIMUM; ++i) {
|
||||||
// XXX this may cause trouble with animations
|
// XXX this may cause trouble with animations
|
||||||
if (chain[i].IsIdentity()) {
|
if (chain[i].IsIdentity()) {
|
||||||
|
@ -440,8 +447,8 @@ private:
|
||||||
|
|
||||||
aiNode* nd = new aiNode();
|
aiNode* nd = new aiNode();
|
||||||
output_nodes.push_back(nd);
|
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];
|
nd->mTransformation = chain[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1466,11 +1473,63 @@ private:
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// otherwise, things get gruesome.
|
// otherwise, things get gruesome and we need separate animation channels
|
||||||
aiNodeAnim* const na = new aiNodeAnim();
|
// 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
|
if (chain[i] != node_property_map.end()) {
|
||||||
ai_assert(false);
|
|
||||||
|
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&) {
|
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
|
// generate node anim, extracting only Rotation, Scaling and Translation from the given chain
|
||||||
aiNodeAnim* GenerateSimpleNodeAnim(const std::string& name,
|
aiNodeAnim* GenerateSimpleNodeAnim(const std::string& name,
|
||||||
|
|
Loading…
Reference in New Issue