diff --git a/src/osgAnimation/VertexInfluence.cpp b/src/osgAnimation/VertexInfluence.cpp index 444651ce4..ad575662c 100644 --- a/src/osgAnimation/VertexInfluence.cpp +++ b/src/osgAnimation/VertexInfluence.cpp @@ -210,8 +210,7 @@ void VertexInfluenceMap::computeMinimalVertexGroupList(std::vector& } } - -//Expermental +//Experimental Bone removal stuff typedef std::vector RigList; class CollectRigVisitor : public osg::NodeVisitor { @@ -219,32 +218,33 @@ public: META_NodeVisitor(osgAnimation, CollectRigVisitor) CollectRigVisitor(); - //void apply(osg::Node&); void apply(osg::Geometry& node); - const RigList& getRigList() const; + inline const RigList& getRigList() const{return _map;} protected: RigList _map; }; + CollectRigVisitor::CollectRigVisitor() : osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN) {} -//void CollectRigVisitor::apply(osg::Node&) { return; } void CollectRigVisitor::apply(osg::Geometry& node) { - RigGeometry* bone = dynamic_cast(&node); - if (bone) - { - _map.push_back( bone); - traverse(node); - } - Skeleton* skeleton = dynamic_cast(&node); - if (skeleton) - traverse(node); + RigGeometry* rig = dynamic_cast(&node); + if ( rig ) + _map.push_back(rig); } -const RigList& CollectRigVisitor::getRigList() const -{ - return _map; +bool recursiveisUsefull( Bone* bone, std::set foundnames) { + for(unsigned int i=0; igetNumChildren(); ++i) { + Bone* child = dynamic_cast< Bone* >(bone->getChild(i)); + if(child){ + if( foundnames.find(child->getName()) != foundnames.end() ) + return true; + if( recursiveisUsefull(child,foundnames) ) + return true; + } + } + return false; } void VertexInfluenceMap::removeUnexpressedBones(Skeleton &skel) const @@ -257,44 +257,62 @@ void VertexInfluenceMap::removeUnexpressedBones(Skeleton &skel) const RigList rigs = rigvis.getRigList(); BoneMap boneMap = mapVisitor.getBoneMap(); - Bone* child,*par; - for(BoneMap::iterator bmit = boneMap.begin(); bmit != boneMap.end();) - { - if( this->find(bmit->first) == this->end()) - { - bool isusless = true; - for(RigList::iterator rigit = rigs.begin(); rigit != rigs.end(); ++rigit) - { - if( ((*rigit)->getInfluenceMap()->find(bmit->first) != (*rigit)->getInfluenceMap()->end())) - { - isusless = false; - break; - } - } - if(!isusless || !(par = bmit->second->getBoneParent())) + unsigned int removed=0; + Bone* child, *par; + + std::set usebones; + for(RigList::iterator rigit = rigs.begin(); rigit != rigs.end(); ++rigit) { + for(VertexInfluenceMap::iterator mapit = (*rigit)->getInfluenceMap()->begin(); + mapit != (*rigit)->getInfluenceMap()->end(); + ++mapit) { + usebones.insert((*mapit).first); + } + } + + for(BoneMap::iterator bmit = boneMap.begin(); bmit != boneMap.end();) { + if(usebones.find(bmit->second->getName()) == usebones.end()) { + if( !(par = bmit->second->getBoneParent()) ) { ++bmit; continue; } + Bone * bone2rm = bmit->second; + + if( recursiveisUsefull(bone2rm,usebones)) { + ++bmit; + continue; + } + ///Bone can be removed - Bone * bone2rm = bmit->second.get(); + ++ removed; + OSG_INFO<<"removing useless bone: "<< bone2rm->getName() <getNumChildren(); numchild++) { if( (child = dynamic_cast(bone2rm->getChild(numchild))) ) { - par->addChild(child); - bone2rm->removeChild(child); + if(par!=child &&child!=bone2rm) { + par->addChild(child); + nodes.push_back(child); + } } } + for(unsigned int i=0; iremoveChild(nodes[i]); par->removeChild(bone2rm); + ///rebuild bonemap after bone removal - skel.accept(mapVisitor); - boneMap = mapVisitor.getBoneMap(); - bmit = boneMap.begin(); + BoneMapVisitor mapVis ; + skel.accept(mapVis); + boneMap = mapVis.getBoneMap(); + bmit = boneMap.begin(); + } else ++bmit; } + OSG_WARN<<"Number of bone removed "<