- fbx: take care not to drop transformation chain nodes that have node animations assigned, even if they specify identity transform in bind pose.
parent
80e7e18e28
commit
bead86a830
|
@ -75,8 +75,11 @@ public:
|
||||||
: out(out)
|
: out(out)
|
||||||
, doc(doc)
|
, doc(doc)
|
||||||
{
|
{
|
||||||
ConvertRootNode();
|
// animations need to be converted first since this will
|
||||||
|
// populate the node_anim_chain_bits map, which is needed
|
||||||
|
// to determine which nodes need to be generated.
|
||||||
ConvertAnimations();
|
ConvertAnimations();
|
||||||
|
ConvertRootNode();
|
||||||
|
|
||||||
if(doc.Settings().readAllMaterials) {
|
if(doc.Settings().readAllMaterials) {
|
||||||
// unfortunately this means we have to evaluate all objects
|
// unfortunately this means we have to evaluate all objects
|
||||||
|
@ -439,16 +442,24 @@ 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);
|
||||||
|
|
||||||
for (size_t i = 0; i < TransformationComp_MAXIMUM; ++i) {
|
// query the anim_chain_bits dictionary to find out which chain elements
|
||||||
// XXX this may cause trouble with animations
|
// have associated node animation channels. These can not be dropped
|
||||||
if (chain[i].IsIdentity()) {
|
// even if they have identity transform in bind pose.
|
||||||
|
NodeAnimBitMap::const_iterator it = node_anim_chain_bits.find(name);
|
||||||
|
const unsigned int anim_chain_bitmask = (it == node_anim_chain_bits.end() ? 0 : (*it).second);
|
||||||
|
|
||||||
|
unsigned int bit = 0x1;
|
||||||
|
for (size_t i = 0; i < TransformationComp_MAXIMUM; ++i, bit <<= 1) {
|
||||||
|
const TransformationComp comp = static_cast<TransformationComp>(i);
|
||||||
|
|
||||||
|
if (chain[i].IsIdentity() && (anim_chain_bitmask & bit) == 0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
aiNode* nd = new aiNode();
|
aiNode* nd = new aiNode();
|
||||||
output_nodes.push_back(nd);
|
output_nodes.push_back(nd);
|
||||||
|
|
||||||
nd->mName.Set(NameTransformationChainNode(name, static_cast<TransformationComp>(i)));
|
nd->mName.Set(NameTransformationChainNode(name, comp));
|
||||||
nd->mTransformation = chain[i];
|
nd->mTransformation = chain[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1521,11 +1532,19 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
// otherwise, things get gruesome and we need separate animation channels
|
// otherwise, things get gruesome and we need separate animation channels
|
||||||
// for each part of the transformation chain.
|
// for each part of the transformation chain. Remember which channels
|
||||||
for (size_t i = 0; i < TransformationComp_MAXIMUM; ++i) {
|
// we generated and pass this information to the node conversion
|
||||||
|
// code to avoid nodes that have identity transform, but non-identity
|
||||||
|
// animations, being dropped.
|
||||||
|
unsigned int flags = 0, bit = 0x1;
|
||||||
|
for (size_t i = 0; i < TransformationComp_MAXIMUM; ++i, bit <<= 1) {
|
||||||
const TransformationComp comp = static_cast<TransformationComp>(i);
|
const TransformationComp comp = static_cast<TransformationComp>(i);
|
||||||
|
|
||||||
if (chain[i] != node_property_map.end()) {
|
if (chain[i] != node_property_map.end()) {
|
||||||
|
flags |= bit;
|
||||||
|
|
||||||
|
ai_assert(comp != TransformationComp_RotationPivotInverse);
|
||||||
|
ai_assert(comp != TransformationComp_ScalingPivotInverse);
|
||||||
|
|
||||||
const std::string& chain_name = NameTransformationChainNode(fixed_name, comp);
|
const std::string& chain_name = NameTransformationChainNode(fixed_name, comp);
|
||||||
|
|
||||||
|
@ -1556,7 +1575,7 @@ private:
|
||||||
max_time,
|
max_time,
|
||||||
min_time);
|
min_time);
|
||||||
|
|
||||||
// pivoting requires us to generate an inverse channel to undo the pivot translation
|
// pivoting requires us to generate an implicit inverse channel to undo the pivot translation
|
||||||
if (comp == TransformationComp_RotationPivot) {
|
if (comp == TransformationComp_RotationPivot) {
|
||||||
const std::string& invName = NameTransformationChainNode(fixed_name, TransformationComp_RotationPivotInverse);
|
const std::string& invName = NameTransformationChainNode(fixed_name, TransformationComp_RotationPivotInverse);
|
||||||
aiNodeAnim* const inv = GenerateTranslationNodeAnim(invName,
|
aiNodeAnim* const inv = GenerateTranslationNodeAnim(invName,
|
||||||
|
@ -1569,6 +1588,9 @@ private:
|
||||||
|
|
||||||
ai_assert(inv);
|
ai_assert(inv);
|
||||||
node_anims.push_back(inv);
|
node_anims.push_back(inv);
|
||||||
|
|
||||||
|
ai_assert(TransformationComp_RotationPivotInverse > i);
|
||||||
|
flags |= bit << (TransformationComp_RotationPivotInverse - i);
|
||||||
}
|
}
|
||||||
else if (comp == TransformationComp_ScalingPivot) {
|
else if (comp == TransformationComp_ScalingPivot) {
|
||||||
const std::string& invName = NameTransformationChainNode(fixed_name, TransformationComp_ScalingPivotInverse);
|
const std::string& invName = NameTransformationChainNode(fixed_name, TransformationComp_ScalingPivotInverse);
|
||||||
|
@ -1582,6 +1604,9 @@ private:
|
||||||
|
|
||||||
ai_assert(inv);
|
ai_assert(inv);
|
||||||
node_anims.push_back(inv);
|
node_anims.push_back(inv);
|
||||||
|
|
||||||
|
ai_assert(TransformationComp_RotationPivotInverse > i);
|
||||||
|
flags |= bit << (TransformationComp_RotationPivotInverse - i);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
@ -1605,6 +1630,8 @@ private:
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
node_anim_chain_bits[fixed_name] = flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -2078,6 +2105,10 @@ private:
|
||||||
typedef std::map<const Geometry*, std::vector<unsigned int> > MeshMap;
|
typedef std::map<const Geometry*, std::vector<unsigned int> > MeshMap;
|
||||||
MeshMap meshes_converted;
|
MeshMap meshes_converted;
|
||||||
|
|
||||||
|
typedef std::map<std::string, unsigned int> NodeAnimBitMap;
|
||||||
|
NodeAnimBitMap node_anim_chain_bits;
|
||||||
|
|
||||||
|
|
||||||
aiScene* const out;
|
aiScene* const out;
|
||||||
const FBX::Document& doc;
|
const FBX::Document& doc;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue