Merge pull request #374 from mp3butcher/osganimation
fix InfluenceMap "remove useless bones" method
This commit is contained in:
commit
d664c09a79
@ -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;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user