Merge pull request #374 from mp3butcher/osganimation

fix InfluenceMap "remove useless bones" method
This commit is contained in:
OpenSceneGraph git repository 2017-10-27 17:15:38 +01:00 committed by GitHub
commit d664c09a79
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

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