diff --git a/code/nel/tools/3d/mesh_utils/mesh_utils.cpp b/code/nel/tools/3d/mesh_utils/mesh_utils.cpp index 57fea70e6..011ed36f6 100644 --- a/code/nel/tools/3d/mesh_utils/mesh_utils.cpp +++ b/code/nel/tools/3d/mesh_utils/mesh_utils.cpp @@ -64,7 +64,7 @@ struct CMeshUtilsContext const aiScene *AssimpScene; CSceneMeta SceneMeta; - TNodeContextMap Nodes; + TNodeContextMap Nodes; // Impl note: Should never end up containing the scene root node. // std::map MeshNames; // Maps meshes to a node name ********************* todo *************** }; @@ -139,15 +139,23 @@ void flagAssimpBones(CMeshUtilsContext &context) } } } + + // Find out which nodes are bones by checking the animation info + // TODO } -void flagRecursiveBones(CMeshUtilsContext &context, CNodeContext &nodeContext) +void flagRecursiveBones(CMeshUtilsContext &context, CNodeContext &nodeContext, bool autoStop = false) { nodeContext.IsBone = true; const aiNode *node = nodeContext.AssimpNode; nlassert(node); for (unsigned int i = 0; i < node->mNumChildren; ++i) - flagRecursiveBones(context, context.Nodes[node->mName.C_Str()]); + { + CNodeContext &ctx = context.Nodes[node->mName.C_Str()]; + if (autoStop && ctx.IsBone) + continue; + flagRecursiveBones(context, ctx); + } } void flagMetaBones(CMeshUtilsContext &context) @@ -168,11 +176,24 @@ void flagLocalParentBones(CMeshUtilsContext &context, CNodeContext &nodeContext) const aiNode *node = nodeContext.AssimpNode; } -void flagAllParentBones(CMeshUtilsContext &context, CNodeContext &nodeContext) +void flagAllParentBones(CMeshUtilsContext &context, CNodeContext &nodeContext, bool autoStop = false) { const aiNode *parent = nodeContext.AssimpNode; - while (parent = parent->mParent) if (parent->mName.length) - context.Nodes[parent->mName.C_Str()].IsBone = true; + while (parent = parent->mParent) if (parent->mName.length && parent != context.AssimpScene->mRootNode) + { + CNodeContext &ctx = context.Nodes[parent->mName.C_Str()]; + if (autoStop && ctx.IsBone) + break; + ctx.IsBone = true; + } +} + +bool hasIndirectParentBone(CMeshUtilsContext &context, CNodeContext &nodeContext) +{ + const aiNode *parent = nodeContext.AssimpNode; + while (parent = parent->mParent) if (parent->mName.length && parent != context.AssimpScene->mRootNode) + if (context.Nodes[parent->mName.C_Str()].IsBone) return true; + return false; } void flagExpandedBones(CMeshUtilsContext &context) @@ -183,10 +204,8 @@ void flagExpandedBones(CMeshUtilsContext &context) for (TNodeContextMap::iterator it(context.Nodes.begin()), end(context.Nodes.end()); it != end; ++it) { CNodeContext &nodeContext = it->second; - if (nodeContext.IsBone) - { - - } + if (nodeContext.IsBone && hasIndirectParentBone(context, nodeContext)) + flagAllParentBones(context, nodeContext, true); } break; case TSkelRoot: @@ -194,9 +213,7 @@ void flagExpandedBones(CMeshUtilsContext &context) { CNodeContext &nodeContext = it->second; if (nodeContext.IsBone) - { - - } + flagAllParentBones(context, nodeContext, true); } break; case TSkelFull: @@ -204,9 +221,13 @@ void flagExpandedBones(CMeshUtilsContext &context) { CNodeContext &nodeContext = it->second; if (nodeContext.IsBone) - { - - } + flagAllParentBones(context, nodeContext, true); + } + for (TNodeContextMap::iterator it(context.Nodes.begin()), end(context.Nodes.end()); it != end; ++it) + { + CNodeContext &nodeContext = it->second; + if (nodeContext.IsBone) + flagRecursiveBones(context, nodeContext, true); } break; } @@ -248,9 +269,19 @@ int exportScene(const CMeshUtilsSettings &settings) context.ToolLogger.writeDepend(NLMISC::BUILD, "*", context.SceneMeta.metaFilePath().c_str()); // Meta input file validateAssimpNodeNames(context, context.AssimpScene->mRootNode); + + // -- SKEL FLAG -- flagAssimpBones(context); flagMetaBones(context); flagExpandedBones(context); + // TODO + // [ + // Only necessary in TSkelLocal + // For each shape test if all the bones have the same root bones for their skeleton + // 1) Iterate each until a different is found + // 2) When a different root is found, connect the two to the nearest common bone + // ] + // -- SKEL FLAG -- importNode(context, scene->mRootNode); diff --git a/code/nel/tools/3d/mesh_utils/scene_meta.cpp b/code/nel/tools/3d/mesh_utils/scene_meta.cpp index 19260d201..4c3440819 100644 --- a/code/nel/tools/3d/mesh_utils/scene_meta.cpp +++ b/code/nel/tools/3d/mesh_utils/scene_meta.cpp @@ -46,7 +46,7 @@ void CNodeMeta::serial(NLMISC::IStream &s) CSceneMeta::CSceneMeta() : DefaultInstanceGroup(false), - SkeletonMode(TSkelLocal) + SkeletonMode(TSkelRoot) { } diff --git a/code/nel/tools/3d/mesh_utils/scene_meta.h b/code/nel/tools/3d/mesh_utils/scene_meta.h index a3791bb50..04c5660c0 100644 --- a/code/nel/tools/3d/mesh_utils/scene_meta.h +++ b/code/nel/tools/3d/mesh_utils/scene_meta.h @@ -57,7 +57,7 @@ struct CNodeMeta enum TSkel { TSkelLocal = 0, // Export smallest skeleton possible from connected bones - TSkelRoot = 1, // Export skeleton from direct child node in the scene root node + TSkelRoot = 1, // Export skeleton from a direct child node in the scene root node TSkelFull = 2, // Include all connected child nodes in the skeleton };