diff --git a/include/osgAnimation/RigGeometry b/include/osgAnimation/RigGeometry index 805e9c779..dc96c98f4 100644 --- a/include/osgAnimation/RigGeometry +++ b/include/osgAnimation/RigGeometry @@ -145,9 +145,8 @@ namespace osgAnimation osg::notify(osg::WARN) << "A RigGeometry did not find a parent skeleton for RigGeometry ( " << geom->getName() << " )" << std::endl; return; } - geom->setSkeleton(finder._root.get()); - geom->getRigTransformImplementation()->prepareData(*geom); + geom->setSkeleton(finder._root.get()); } if(!geom->getSkeleton()) diff --git a/include/osgAnimation/RigTransformHardware b/include/osgAnimation/RigTransformHardware index f27aa0506..cf506580f 100644 --- a/include/osgAnimation/RigTransformHardware +++ b/include/osgAnimation/RigTransformHardware @@ -89,6 +89,7 @@ namespace osgAnimation //on first update virtual bool init(RigGeometry& ); + std::vector _perVertexInfluences; }; } diff --git a/include/osgAnimation/RigTransformSoftware b/include/osgAnimation/RigTransformSoftware index ac97f527a..109bf5b85 100644 --- a/include/osgAnimation/RigTransformSoftware +++ b/include/osgAnimation/RigTransformSoftware @@ -40,22 +40,28 @@ namespace osgAnimation //to call when a skeleton is reacheable from the rig to prepare technic data virtual bool prepareData(RigGeometry&); - class BonePtrWeight: std::pair< osg::observer_ptr< Bone >, float> + typedef std::pair LocalBoneIDWeight; + class BonePtrWeight: LocalBoneIDWeight { public: - BonePtrWeight(Bone*bone, float weight) :std::pair< osg::observer_ptr< Bone >, float>(bone,weight) {} - BonePtrWeight(const BonePtrWeight &bw2) : std::pair< osg::observer_ptr< Bone >, float>(bw2.first.get(),bw2.getWeight()) {} - - inline const Bone * getBonePtr() const {return first.get();} - inline void setBonePtr(Bone*b){first=b;} + BonePtrWeight(unsigned int id,float weight, Bone*bone=0 ): LocalBoneIDWeight(id,weight), _boneptr(bone){} + BonePtrWeight(const BonePtrWeight &bw2): LocalBoneIDWeight(bw2.getBoneID(),bw2.getWeight()), _boneptr(bw2._boneptr.get()){} inline const float & getWeight() const {return second;} inline void setWeight(float b) {second=b;} + inline const unsigned int & getBoneID() const {return first;} + inline void setBoneID(unsigned int b) {first=b;} inline bool operator<(const BonePtrWeight &b1) const{ if (second > b1.second)return true; if (second < b1.second)return false; - return (first.get() > b1.first.get()); + return (first > b1.first); } + ///set Bone pointer + inline const Bone * getBonePtr() const {return _boneptr.get();} + inline void setBonePtr(Bone*b){_boneptr=b;} + protected: + osg::observer_ptr< Bone > _boneptr; }; + typedef std::vector BonePtrWeightList; /// map a set of boneinfluence to a list of vertex indices sharing this set @@ -144,7 +150,6 @@ namespace osgAnimation } } - template inline void computeNormal(const osg::Matrix& transform, const osg::Matrix& invTransform, const V* src, V* dst) { @@ -166,12 +171,14 @@ namespace osgAnimation bool _needInit; + virtual bool init(RigGeometry&); + std::map _invalidInfluence; typedef std::vector VertexGroupList; - VertexGroupList _uniqVertexGroupList; - void buildMinimumUpdateSet(const BoneMap&boneMap,const RigGeometry&rig ); + + void buildMinimumUpdateSet(const RigGeometry&rig ); }; } diff --git a/src/osgAnimation/RigTransformHardware.cpp b/src/osgAnimation/RigTransformHardware.cpp index 31a0d7631..c8312a96d 100644 --- a/src/osgAnimation/RigTransformHardware.cpp +++ b/src/osgAnimation/RigTransformHardware.cpp @@ -75,10 +75,11 @@ typedef std::vector > PerVertexInfList; ///create normalized a set of Vertex Attribs given a PerVertexInfList and return the max num bone per vertex unsigned int createVertexAttribList(const PerVertexInfList & perVertexInfluences, - RigTransformHardware::BoneWeightAttribList& boneWeightAttribArrays){ + RigTransformHardware::BoneWeightAttribList& boneWeightAttribArrays) +{ short boneIndexInVec4; unsigned int vertid = 0, - boneIndexInList; + boneIndexInList; IndexWeightList::size_type maxBonePerVertex = 0; ///build vertex attrib arrays //get maxBonePerVertex @@ -110,7 +111,7 @@ unsigned int createVertexAttribList(const PerVertexInfList & perVertexInfluences if(sum< 1e-4) { - OSG_WARN << "RigTransformHardware::buildPalette Warning: vertex with zero sum weights: " < 1) - osg::notify(osg::WARN) << "A RigGeometry should not have multi parent ( " << rig.getName() << " )" << std::endl; - rig.getParents()[0]->accept(finder); + _nbVertices = rig.getSourceGeometry()->getVertexArray()->getNumElements(); + const VertexInfluenceMap &vertexInfluenceMap = *rig.getInfluenceMap(); + _perVertexInfluences.resize(_nbVertices); - if(!finder._root.valid()) + unsigned int localboneid=0; + for (VertexInfluenceMap::const_iterator boneinflistit = vertexInfluenceMap.begin(); + boneinflistit != vertexInfluenceMap.end(); + ++boneinflistit, ++localboneid) + { + const IndexWeightList& boneinflist = boneinflistit->second; + const std::string& bonename = boneinflistit->first; + + for(IndexWeightList::const_iterator infit = boneinflist.begin(); infit!=boneinflist.end(); ++infit) { - osg::notify(osg::WARN) << "A RigGeometry did not find a parent skeleton for RigGeometry ( " << rig.getName() << " )" << std::endl; - return false; + const VertexIndexWeight& iw = *infit; + const unsigned int &index = iw.first; + const float &weight = iw.second; + IndexWeightList & iwlist = _perVertexInfluences[index]; + + if(fabs(weight) > 1e-4) // don't use bone with weight too small + { + iwlist.push_back(VertexIndexWeight(localboneid,weight)); + } + else + { + OSG_WARN << "RigTransformHardware::prepareData Bone " << bonename << " has a weight " << weight << " for vertex " << index << " this bone will not be in the palette" << std::endl; + } } - rig.setSkeleton(finder._root.get()); + } + return true; +} + + +bool RigTransformHardware::buildPalette(const BoneMap&boneMap,const RigGeometry&rig) +{ + + typedef std::map BoneNameCountMap; + _boneWeightAttribArrays.resize(0); + _bonePalette.clear(); + _boneNameToPalette.clear(); + + IndexWeightList::size_type maxBonePerVertex=0; + BoneNameCountMap boneNameCountMap; + + const VertexInfluenceMap &vertexInfluenceMap = *rig.getInfluenceMap(); + BoneNamePaletteIndex::iterator boneName2PaletteIndex; + + ///create local boneid to paletteindex + unsigned int paletteindex; + std::vector localid2bone; + localid2bone.reserve(vertexInfluenceMap.size()); + for (osgAnimation::VertexInfluenceMap::const_iterator perBoneinfit = vertexInfluenceMap.begin(); + perBoneinfit != vertexInfluenceMap.end(); + ++perBoneinfit) + { + const std::string& bonename = perBoneinfit->first; + + if (bonename.empty()) + { + OSG_WARN << "RigTransformHardware::VertexInfluenceMap contains unamed bone IndexWeightList" << std::endl; + } + BoneMap::const_iterator bmit = boneMap.find(bonename); + if (bmit == boneMap.end() ) + { + OSG_WARN << "RigTransformHardware Bone " << bonename << " not found, skip the influence group " << std::endl; + localid2bone.push_back(-1); + continue; + } + if ((boneName2PaletteIndex= _boneNameToPalette.find(bonename)) != _boneNameToPalette.end()) + { + boneNameCountMap[bonename]++; + paletteindex= boneName2PaletteIndex->second ; + } + else + { + boneNameCountMap[bonename] = 1; // for stats + _boneNameToPalette[bonename] = _bonePalette.size() ; + paletteindex= _bonePalette.size() ; + _bonePalette.push_back(bmit->second); + } + localid2bone.push_back(paletteindex); + } + OSG_INFO << "RigTransformHardware::buildPalette matrix palette has " << boneNameCountMap.size() << " entries" << std::endl; + + for (BoneNameCountMap::iterator it = boneNameCountMap.begin(); it != boneNameCountMap.end(); ++it) + { + OSG_INFO << "RigTransformHardware::buildPalette Bone " << it->first << " is used " << it->second << " times" << std::endl; + } + + OSG_INFO << "RigTransformHardware::buildPalette will use " << boneNameCountMap.size() * 4 << " uniforms" << std::endl; + + ///set paletteindices + for( std::vector::iterator idwlistit=_perVertexInfluences.begin(); idwlistit!=_perVertexInfluences.end(); ++idwlistit) + { + for( IndexWeightList::iterator idwit=idwlistit->begin(); idwit!=idwlistit->end();) + { + if(localid2bone[idwit->first]<0)idwit=idwlistit->erase(idwit); + else{ + idwit->first=localid2bone[idwit->first]; + ++idwit; + } + } + } + if( (_bonesPerVertex = createVertexAttribList(_perVertexInfluences, _boneWeightAttribArrays) ) < 1 ) + return false; + + _uniformMatrixPalette = new osg::Uniform(osg::Uniform::FLOAT_MAT4, "matrixPalette", _bonePalette.size()); + + _needInit = true; + return true; +} + +bool RigTransformHardware::init(RigGeometry& rig) +{ + if(_perVertexInfluences.empty()) + { + prepareData(rig); + return false; } if(!rig.getSkeleton()) return false; + BoneMapVisitor mapVisitor; rig.getSkeleton()->accept(mapVisitor); BoneMap boneMap = mapVisitor.getBoneMap(); @@ -179,178 +286,82 @@ bool RigTransformHardware::prepareData(RigGeometry& rig) // copy shallow from source geometry to rig rig.copyFrom(source); - return true; -} + osg::ref_ptr program ; + osg::ref_ptr vertexshader; + osg::ref_ptr stateset = rig.getOrCreateStateSet(); - -bool RigTransformHardware::buildPalette(const BoneMap&boneMap,const RigGeometry&rig) -{ - - typedef std::map BoneNameCountMap; - _nbVertices = rig.getVertexArray()->getNumElements(); - _boneWeightAttribArrays.resize(0); - _bonePalette.clear(); - _boneNameToPalette.clear(); - - IndexWeightList::size_type maxBonePerVertex=0; - BoneNameCountMap boneNameCountMap; - - const VertexInfluenceMap &vertexInfluenceMap = *rig.getInfluenceMap(); - BoneNamePaletteIndex::iterator boneName2PaletteIndex; - - // init temp vertex attribute data - std::vector perVertexInfluences; - perVertexInfluences.resize(_nbVertices); - - unsigned int paletteindex; - for (VertexInfluenceMap::const_iterator boneinflistit = vertexInfluenceMap.begin(); - boneinflistit != vertexInfluenceMap.end(); - ++boneinflistit) + //grab geom source program and vertex shader if _shader is not setted + if(!_shader.valid() && (program = (osg::Program*)stateset->getAttribute(osg::StateAttribute::PROGRAM))) { - const IndexWeightList& boneinflist = boneinflistit->second; - const std::string& bonename = boneinflistit->first; - BoneMap::const_iterator bonebyname; - if ((bonebyname = boneMap.find(bonename)) == boneMap.end()) - { - OSG_WARN << "RigTransformHardware::buildPalette can't find bone " << bonename << "in skeleton bonemap: skip this influence" << std::endl; - continue; - } - if ((boneName2PaletteIndex= _boneNameToPalette.find(bonename)) != _boneNameToPalette.end()) - { - boneNameCountMap[bonename]++; - paletteindex= boneName2PaletteIndex->second ; - } - else - { - boneNameCountMap[bonename] = 1; // for stats - _boneNameToPalette[bonename] = _bonePalette.size() ; - paletteindex= _bonePalette.size() ; - _bonePalette.push_back(bonebyname->second); - - } - for(IndexWeightList::const_iterator infit = boneinflist.begin(); infit!=boneinflist.end(); ++infit) - { - const VertexIndexWeight& iw = *infit; - const unsigned int &index = iw.first; - const float &weight = iw.second; - IndexWeightList & iwlist = perVertexInfluences[index]; - - if(fabs(weight) > 1e-4) // don't use bone with weight too small + for(unsigned int i=0; igetNumShaders(); ++i) + if(program->getShader(i)->getType()==osg::Shader::VERTEX) { - iwlist.push_back(VertexIndexWeight(paletteindex,weight)); + vertexshader=program->getShader(i); + program->removeShader(vertexshader); } - else - { - OSG_WARN << "RigTransformHardware::buildPalette Bone " << bonename << " has a weight " << weight << " for vertex " << index << " this bone will not be in the palette" << std::endl; - } - - } - OSG_INFO << "RigTransformHardware::buildPalette matrix palette has " << boneNameCountMap.size() << " entries" << std::endl; - - for (BoneNameCountMap::iterator it = boneNameCountMap.begin(); it != boneNameCountMap.end(); ++it) - { - OSG_INFO << "RigTransformHardware::buildPalette Bone " << it->first << " is used " << it->second << " times" << std::endl; - } - - OSG_INFO << "RigTransformHardware::buildPalette will use " << boneNameCountMap.size() * 4 << " uniforms" << std::endl; - + } + else + { + program = new osg::Program; + program->setName("HardwareSkinning"); + } + //set default source if _shader is not user setted + if (!vertexshader.valid()) + { + if (!_shader.valid()) + vertexshader = osg::Shader::readShaderFile(osg::Shader::VERTEX,"skinning.vert"); + else vertexshader=_shader; } - - if( (_bonesPerVertex = createVertexAttribList(perVertexInfluences, _boneWeightAttribArrays) ) < 1 ) - return false; - - _uniformMatrixPalette = new osg::Uniform(osg::Uniform::FLOAT_MAT4, "matrixPalette", _bonePalette.size()); - - _needInit = true; - - return true; -} - -bool RigTransformHardware::init(RigGeometry& rig) -{ - //if animdata seams prepared - if(_uniformMatrixPalette.valid()) + if (!vertexshader.valid()) { - osg::ref_ptr program ; - osg::ref_ptr vertexshader; - osg::ref_ptr stateset = rig.getOrCreateStateSet(); + OSG_WARN << "RigTransformHardware can't load VertexShader" << std::endl; + return false; + } - //grab geom source program and vertex shader if _shader is not setted - if(!_shader.valid() && (program = (osg::Program*)stateset->getAttribute(osg::StateAttribute::PROGRAM))) - { - for(unsigned int i=0; igetNumShaders(); ++i) - if(program->getShader(i)->getType()==osg::Shader::VERTEX) - { - vertexshader=program->getShader(i); - program->removeShader(vertexshader); - } - } - else - { - program = new osg::Program; - program->setName("HardwareSkinning"); - } - //set default source if _shader is not user setted - if (!vertexshader.valid()) - { - if (!_shader.valid()) - vertexshader = osg::Shader::readShaderFile(osg::Shader::VERTEX,"skinning.vert"); - else vertexshader=_shader; - } - - - if (!vertexshader.valid()) - { - OSG_WARN << "RigTransformHardware can't load VertexShader" << std::endl; - return false; - } - - // replace max matrix by the value from uniform - { - std::string str = vertexshader->getShaderSource(); - std::string toreplace = std::string("MAX_MATRIX"); - std::size_t start = str.find(toreplace); - if (std::string::npos != start) - { - std::stringstream ss; - ss << getMatrixPaletteUniform()->getNumElements(); - str.replace(start, toreplace.size(), ss.str()); - vertexshader->setShaderSource(str); - } - else - { - OSG_WARN<< "MAX_MATRIX not found in Shader! " << str << std::endl; - } - OSG_INFO << "Shader " << str << std::endl; - } - - unsigned int nbAttribs = getNumVertexAttrib(); - for (unsigned int i = 0; i < nbAttribs; i++) + // replace max matrix by the value from uniform + { + std::string str = vertexshader->getShaderSource(); + std::string toreplace = std::string("MAX_MATRIX"); + std::size_t start = str.find(toreplace); + if (std::string::npos != start) { std::stringstream ss; - ss << "boneWeight" << i; - program->addBindAttribLocation(ss.str(), _minAttribIndex + i); - rig.setVertexAttribArray(_minAttribIndex + i, getVertexAttrib(i)); - OSG_INFO << "set vertex attrib " << ss.str() << std::endl; + ss << getMatrixPaletteUniform()->getNumElements(); + str.replace(start, toreplace.size(), ss.str()); + vertexshader->setShaderSource(str); } - - program->addShader(vertexshader.get()); - - stateset->removeUniform("nbBonesPerVertex"); - stateset->addUniform(new osg::Uniform("nbBonesPerVertex",_bonesPerVertex)); - - stateset->removeUniform("matrixPalette"); - stateset->addUniform(_uniformMatrixPalette); - - stateset->setAttribute(program.get()); - - _needInit = false; - return true; + else + { + OSG_WARN<< "MAX_MATRIX not found in Shader! " << str << std::endl; + } + OSG_INFO << "Shader " << str << std::endl; } - else prepareData(rig); - return false; + + unsigned int nbAttribs = getNumVertexAttrib(); + for (unsigned int i = 0; i < nbAttribs; i++) + { + std::stringstream ss; + ss << "boneWeight" << i; + program->addBindAttribLocation(ss.str(), _minAttribIndex + i); + rig.setVertexAttribArray(_minAttribIndex + i, getVertexAttrib(i)); + OSG_INFO << "set vertex attrib " << ss.str() << std::endl; + } + + program->addShader(vertexshader.get()); + + stateset->removeUniform("nbBonesPerVertex"); + stateset->addUniform(new osg::Uniform("nbBonesPerVertex",_bonesPerVertex)); + + stateset->removeUniform("matrixPalette"); + stateset->addUniform(_uniformMatrixPalette); + + stateset->setAttribute(program.get()); + + _needInit = false; + return true; } + void RigTransformHardware::operator()(RigGeometry& geom) { if (_needInit) diff --git a/src/osgAnimation/RigTransformSoftware.cpp b/src/osgAnimation/RigTransformSoftware.cpp index ccb1a0a11..ca78e6c79 100644 --- a/src/osgAnimation/RigTransformSoftware.cpp +++ b/src/osgAnimation/RigTransformSoftware.cpp @@ -38,39 +38,31 @@ RigTransformSoftware::RigTransformSoftware(const RigTransformSoftware& rts,const typedef std::vector BonePtrWeightList; -void RigTransformSoftware::buildMinimumUpdateSet( const BoneMap&boneMap, const RigGeometry&rig ){ - +void RigTransformSoftware::buildMinimumUpdateSet( const RigGeometry&rig ) +{ ///1 Create Index2Vec const VertexInfluenceMap &vertexInfluenceMap=*rig.getInfluenceMap(); std::vector perVertexInfluences; perVertexInfluences.resize(rig.getSourceGeometry()->getVertexArray()->getNumElements()); + unsigned int vimapBoneID = 0; for (osgAnimation::VertexInfluenceMap::const_iterator perBoneinfit = vertexInfluenceMap.begin(); perBoneinfit != vertexInfluenceMap.end(); - ++perBoneinfit) + ++perBoneinfit,++vimapBoneID) { const IndexWeightList& inflist = perBoneinfit->second; const std::string& bonename = perBoneinfit->first; - if (bonename.empty()) { + if (bonename.empty()) + { OSG_WARN << "RigTransformSoftware::VertexInfluenceMap contains unamed bone IndexWeightList" << std::endl; } - BoneMap::const_iterator bmit = boneMap.find(bonename); - if (bmit == boneMap.end() ) - { - if (_invalidInfluence.find(bonename) != _invalidInfluence.end()) { - _invalidInfluence[bonename] = true; - OSG_WARN << "RigTransformSoftware Bone " << bonename << " not found, skip the influence group " << std::endl; - } - continue; - } - Bone* bone = bmit->second.get(); for(IndexWeightList::const_iterator infit=inflist.begin(); infit!=inflist.end(); ++infit) { const VertexIndexWeight &iw = *infit; const unsigned int &index = iw.first; float weight = iw.second; - perVertexInfluences[index].push_back(BonePtrWeight(bone, weight)); + perVertexInfluences[index].push_back(BonePtrWeight(vimapBoneID, weight)); } } @@ -80,7 +72,7 @@ void RigTransformSoftware::buildMinimumUpdateSet( const BoneMap&boneMap, const R { BonePtrWeightList& bones = *it; float sum = 0; - for(BonePtrWeightList::iterator bwit=bones.begin();bwit!=bones.end();++bwit) + for(BonePtrWeightList::iterator bwit=bones.begin(); bwit!=bones.end(); ++bwit) sum += bwit->getWeight(); if (sum < 1e-4) { @@ -89,7 +81,7 @@ void RigTransformSoftware::buildMinimumUpdateSet( const BoneMap&boneMap, const R else { float mult = 1.0/sum; - for(BonePtrWeightList::iterator bwit=bones.begin();bwit!=bones.end();++bwit) + for(BonePtrWeightList::iterator bwit=bones.begin(); bwit!=bones.end(); ++bwit) bwit->setWeight(bwit->getWeight() * mult); } } @@ -123,37 +115,13 @@ void RigTransformSoftware::buildMinimumUpdateSet( const BoneMap&boneMap, const R OSG_INFO << "uniq groups " << _uniqVertexGroupList.size() << " for " << rig.getName() << std::endl; } -bool RigTransformSoftware::prepareData(RigGeometry&rig) { - ///find skeleton if not set - if(!rig.getSkeleton() && !rig.getParents().empty()) - { - RigGeometry::FindNearestParentSkeleton finder; - if(rig.getParents().size() > 1) - osg::notify(osg::WARN) << "A RigGeometry should not have multi parent ( " << rig.getName() << " )" << std::endl; - rig.getParents()[0]->accept(finder); - - if(!finder._root.valid()) - { - osg::notify(osg::WARN) << "A RigGeometry did not find a parent skeleton for RigGeometry ( " << rig.getName() << " )" << std::endl; - return false; - } - rig.setSkeleton(finder._root.get()); - } - if(!rig.getSkeleton()) - return false; - ///get bonemap from skeleton - BoneMapVisitor mapVisitor; - rig.getSkeleton()->accept(mapVisitor); - BoneMap boneMap = mapVisitor.getBoneMap(); - - /// build minimal set of VertexGroup - buildMinimumUpdateSet(boneMap,rig); +bool RigTransformSoftware::prepareData(RigGeometry&rig) +{ ///set geom as it source if (rig.getSourceGeometry()) rig.copyFrom(*rig.getSourceGeometry()); - osg::Vec3Array* normalSrc = dynamic_cast(rig.getSourceGeometry()->getNormalArray()); osg::Vec3Array* positionSrc = dynamic_cast(rig.getSourceGeometry()->getVertexArray()); @@ -169,24 +137,92 @@ bool RigTransformSoftware::prepareData(RigGeometry&rig) { *positionDst=*positionSrc; positionDst->setDataVariance(osg::Object::DYNAMIC); - if(normalSrc) { + if(normalSrc) + { osg::Vec3Array* normalDst =new osg::Vec3Array; *normalDst=*normalSrc; rig.setNormalArray(normalDst, osg::Array::BIND_PER_VERTEX); normalDst->setDataVariance(osg::Object::DYNAMIC); } - _needInit = false; + /// build minimal set of VertexGroup + buildMinimumUpdateSet(rig); + return true; } +bool RigTransformSoftware::init(RigGeometry&rig) +{ + ///test if dataprepared + if(_uniqVertexGroupList.empty()) + { + prepareData(rig); + return false; + } + + if(!rig.getSkeleton()) + return false; + ///get bonemap from skeleton + BoneMapVisitor mapVisitor; + rig.getSkeleton()->accept(mapVisitor); + BoneMap boneMap = mapVisitor.getBoneMap(); + VertexInfluenceMap & vertexInfluenceMap= *rig.getInfluenceMap(); + + ///create local bonemap + std::vector localid2bone; + localid2bone.reserve(vertexInfluenceMap.size()); + for (osgAnimation::VertexInfluenceMap::const_iterator perBoneinfit = vertexInfluenceMap.begin(); + perBoneinfit != vertexInfluenceMap.end(); + ++perBoneinfit) + { + const std::string& bonename = perBoneinfit->first; + + if (bonename.empty()) + { + OSG_WARN << "RigTransformSoftware::VertexInfluenceMap contains unamed bone IndexWeightList" << std::endl; + } + BoneMap::const_iterator bmit = boneMap.find(bonename); + if (bmit == boneMap.end() ) + { + if (_invalidInfluence.find(bonename) != _invalidInfluence.end()) + { + _invalidInfluence[bonename] = true; + OSG_WARN << "RigTransformSoftware Bone " << bonename << " not found, skip the influence group " << std::endl; + } + + localid2bone.push_back(0); + continue; + } + Bone* bone = bmit->second.get(); + localid2bone.push_back(bone); + } + + ///fill bone ptr in the _uniqVertexGroupList + for(VertexGroupList::iterator itvg=_uniqVertexGroupList.begin(); itvg!=_uniqVertexGroupList.end(); ++itvg) + { + VertexGroup& uniq = *itvg; + for(BonePtrWeightList::iterator bwit= uniq.getBoneWeights().begin(); bwit!=uniq.getBoneWeights().end(); ) + { + Bone * b=localid2bone[bwit->getBoneID()]; + if(!b) + bwit=uniq.getBoneWeights().erase(bwit); + else + bwit++->setBonePtr(b); + } + } + + _needInit = false; + + return true; +} void RigTransformSoftware::operator()(RigGeometry& geom) { if (_needInit) - if (!prepareData(geom)) + if (!init(geom)) return; - if (!geom.getSourceGeometry()) { + if (!geom.getSourceGeometry()) + { OSG_WARN << this << " RigTransformSoftware no source geometry found on RigGeometry" << std::endl; return; } @@ -209,11 +245,11 @@ void RigTransformSoftware::operator()(RigGeometry& geom) if (normalSrc ) { - computeNormal(geom.getMatrixFromSkeletonToGeometry(), - geom.getInvMatrixFromSkeletonToGeometry(), - &normalSrc->front(), - &normalDst->front()); - normalDst->dirty(); + computeNormal(geom.getMatrixFromSkeletonToGeometry(), + geom.getInvMatrixFromSkeletonToGeometry(), + &normalSrc->front(), + &normalDst->front()); + normalDst->dirty(); } }