diff --git a/include/osgAnimation/RigGeometry b/include/osgAnimation/RigGeometry index e3b3c4a46..5319b4e0a 100644 --- a/include/osgAnimation/RigGeometry +++ b/include/osgAnimation/RigGeometry @@ -17,7 +17,7 @@ #include #include -#include +#include #include #include diff --git a/include/osgAnimation/RigTransformHardware b/include/osgAnimation/RigTransformHardware index fd10eeec6..cbb825e16 100644 --- a/include/osgAnimation/RigTransformHardware +++ b/include/osgAnimation/RigTransformHardware @@ -38,36 +38,32 @@ namespace osgAnimation META_Object(osgAnimation,RigTransformHardware); - typedef osg::Matrix MatrixType; typedef std::vector > BoneWeightAttribList; typedef std::vector > BonePalette; typedef std::map BoneNamePaletteIndex; - typedef std::vector MatrixPalette; osg::Vec4Array* getVertexAttrib(unsigned int index); - unsigned int getNumVertexAttrib(); + unsigned int getNumVertexAttrib() const {return _boneWeightAttribArrays.size();} + + void setShader(osg::Shader* shader) { _shader = shader; } + osg::Shader* getShader() const { return _shader; } + + const unsigned int &getNumBonesPerVertex() const{ return _bonesPerVertex; } + const unsigned int &getNumVertexes() const { return _nbVertexes; } + + const BoneNamePaletteIndex& getBoneNameToPalette(){ return _boneNameToPalette; } + const BonePalette& getBonePalette() { return _bonePalette; } + osg::Uniform* getMatrixPaletteUniform() { return _uniformMatrixPalette; } - osg::Uniform* getMatrixPaletteUniform(); void computeMatrixPaletteUniform(const osg::Matrix& transformFromSkeletonToGeometry, const osg::Matrix& invTransformFromSkeletonToGeometry); - unsigned int getNumBonesPerVertex() const; - unsigned int getNumVertexes() const; - virtual void operator()(RigGeometry&); virtual bool prepareData(RigGeometry& ); - void setShader(osg::Shader*); - - const BoneNamePaletteIndex& getBoneNameToPalette() { - return _boneNameToPalette; - } - protected: - osg::Uniform* createVertexUniform(); - unsigned int _bonesPerVertex; unsigned int _nbVertexes; @@ -79,7 +75,7 @@ namespace osgAnimation bool _needInit; - bool buildPalette(BoneMap&boneMap ,RigGeometry&rig); + bool buildPalette(const BoneMap& boneMap ,const RigGeometry& rig); }; } diff --git a/include/osgAnimation/RigTransformSoftware b/include/osgAnimation/RigTransformSoftware index 2a9f28c86..ac97f527a 100644 --- a/include/osgAnimation/RigTransformSoftware +++ b/include/osgAnimation/RigTransformSoftware @@ -129,7 +129,7 @@ namespace osgAnimation inline void compute(const osg::Matrix& transform, const osg::Matrix& invTransform, const V* src, V* dst) { // the result of matrix mult should be cached to be used for vertexes transform and normal transform and maybe other computation - for(VertexGroupList::iterator itvg=_uniqInfluenceSet2VertIDList.begin(); itvg!=_uniqInfluenceSet2VertIDList.end(); ++itvg) + for(VertexGroupList::iterator itvg=_uniqVertexGroupList.begin(); itvg!=_uniqVertexGroupList.end(); ++itvg) { VertexGroup& uniq = *itvg; uniq.computeMatrixForVertexSet(); @@ -148,7 +148,7 @@ namespace osgAnimation template inline void computeNormal(const osg::Matrix& transform, const osg::Matrix& invTransform, const V* src, V* dst) { - for(VertexGroupList::iterator itvg=_uniqInfluenceSet2VertIDList.begin(); itvg!=_uniqInfluenceSet2VertIDList.end(); ++itvg) + for(VertexGroupList::iterator itvg=_uniqVertexGroupList.begin(); itvg!=_uniqVertexGroupList.end(); ++itvg) { VertexGroup& uniq = *itvg; uniq.computeMatrixForVertexSet(); @@ -170,7 +170,7 @@ namespace osgAnimation typedef std::vector VertexGroupList; - VertexGroupList _uniqInfluenceSet2VertIDList; + VertexGroupList _uniqVertexGroupList; void buildMinimumUpdateSet(const BoneMap&boneMap,const RigGeometry&rig ); }; diff --git a/src/osgAnimation/RigTransformHardware.cpp b/src/osgAnimation/RigTransformHardware.cpp index 262d99c9a..fb51cb177 100644 --- a/src/osgAnimation/RigTransformHardware.cpp +++ b/src/osgAnimation/RigTransformHardware.cpp @@ -48,17 +48,6 @@ osg::Vec4Array* RigTransformHardware::getVertexAttrib(unsigned int index) return _boneWeightAttribArrays[index].get(); } -unsigned int RigTransformHardware::getNumVertexAttrib() -{ - return _boneWeightAttribArrays.size(); -} - -osg::Uniform* RigTransformHardware::getMatrixPaletteUniform() -{ - return _uniformMatrixPalette.get(); -} - - void RigTransformHardware::computeMatrixPaletteUniform(const osg::Matrix& transformFromSkeletonToGeometry, const osg::Matrix& invTransformFromSkeletonToGeometry) { for (unsigned int i = 0; i < _bonePalette.size(); i++) @@ -74,11 +63,7 @@ void RigTransformHardware::computeMatrixPaletteUniform(const osg::Matrix& transf } -unsigned int RigTransformHardware::getNumBonesPerVertex() const { return _bonesPerVertex;} -unsigned int RigTransformHardware::getNumVertexes() const { return _nbVertexes;} - -typedef std::vector > VertexIndexWeightList; -void createVertexAttribList(RigTransformHardware& rig,const VertexIndexWeightList&_vertexIndexMatrixWeightList,RigTransformHardware::BoneWeightAttribList & boneWeightAttribArrays); +void createVertexAttribList(RigTransformHardware& rig,const std::vector > &perVertexInfluences,RigTransformHardware::BoneWeightAttribList & boneWeightAttribArrays); // // create vertex attribute by 2 bones @@ -89,11 +74,15 @@ void createVertexAttribList(RigTransformHardware& rig,const VertexIndexWeightLis // than the 4 bones using two vertex attributes // -void createVertexAttribList(RigTransformHardware& rig,const VertexIndexWeightList& _vertexIndexMatrixWeightList, RigTransformHardware::BoneWeightAttribList& boneWeightAttribArrays) +typedef std::vector > PerVertexInfList; +void createVertexAttribList(RigTransformHardware& rig, + const PerVertexInfList & perVertexInfluences, + RigTransformHardware::BoneWeightAttribList& boneWeightAttribArrays) { unsigned int nbVertices= rig.getNumVertexes(); unsigned int maxbonepervertex=rig.getNumBonesPerVertex(); unsigned int nbArray = static_cast(ceilf( ((float)maxbonepervertex) * 0.5f)); + if (!nbArray) return ; @@ -105,7 +94,6 @@ void createVertexAttribList(RigTransformHardware& rig,const VertexIndexWeightLis array->resize( nbVertices); for (unsigned int j = 0; j < nbVertices; j++) { - for (unsigned int b = 0; b < 2; b++) { // the granularity is 2 so if we have only one bone @@ -116,8 +104,8 @@ void createVertexAttribList(RigTransformHardware& rig,const VertexIndexWeightLis (*array)[j][1 + boneIndexInVec4] = 0; if (boneIndexInList < maxbonepervertex) { - float boneIndex = static_cast(_vertexIndexMatrixWeightList[j][boneIndexInList].getIndex()); - float boneWeight = _vertexIndexMatrixWeightList[j][boneIndexInList].getWeight(); + float boneIndex = static_cast(perVertexInfluences[j][boneIndexInList].getIndex()); + float boneWeight = perVertexInfluences[j][boneIndexInList].getWeight(); // fill the vec4 (*array)[j][0 + boneIndexInVec4] = boneIndex; (*array)[j][1 + boneIndexInVec4] = boneWeight; @@ -125,19 +113,7 @@ void createVertexAttribList(RigTransformHardware& rig,const VertexIndexWeightLis } } } - return ; -} - -osg::Uniform* RigTransformHardware::createVertexUniform() -{ - osg::Uniform* uniform = new osg::Uniform(osg::Uniform::FLOAT_MAT4, "matrixPalette", _bonePalette.size()); - return uniform; -} - - -void RigTransformHardware::setShader(osg::Shader* shader) -{ - _shader = shader; + return; } bool RigTransformHardware::prepareData(RigGeometry& rig) @@ -252,37 +228,32 @@ bool RigTransformHardware::prepareData(RigGeometry& rig) _needInit = false; return true; } -void createVertexAttribList(RigTransformHardware& rig,const VertexIndexWeightList&_vertexIndexMatrixWeightList,RigTransformHardware::BoneWeightAttribList & boneWeightAttribArrays); -bool RigTransformHardware::buildPalette(BoneMap&boneMap ,RigGeometry&rig) { - - _nbVertexes = rig.getVertexArray()->getNumElements(); - IndexWeightList::size_type maxBonePerVertex=0; - - typedef std::pair FloatInt; - std::vector< FloatInt > sums;///stat totalweight nbref - sums.resize(_nbVertexes); +bool RigTransformHardware::buildPalette(const BoneMap&boneMap ,const RigGeometry&rig) { typedef std::map BoneNameCountMap; + _nbVertexes = rig.getVertexArray()->getNumElements(); + _boneWeightAttribArrays.resize(0); _bonePalette.clear(); _boneNameToPalette.clear(); + + IndexWeightList::size_type maxBonePerVertex=0; BoneNameCountMap boneNameCountMap; - VertexInfluenceMap *vertexInfluenceMap=rig.getInfluenceMap(); + const VertexInfluenceMap &vertexInfluenceMap=*rig.getInfluenceMap(); BoneNamePaletteIndex::iterator boneName2PaletteIndex; - _boneWeightAttribArrays.resize(0); // init temp vertex attribute data - VertexIndexWeightList vertexIndexWeight; - vertexIndexWeight.resize(_nbVertexes); + std::vector > perVertexInfluences; + perVertexInfluences.resize(_nbVertexes); unsigned int paletteindex; - for (osgAnimation::VertexInfluenceMap::iterator mapit = vertexInfluenceMap->begin(); - mapit != vertexInfluenceMap->end(); - ++mapit) + for (osgAnimation::VertexInfluenceMap::const_iterator boneinflistit = vertexInfluenceMap.begin(); + boneinflistit != vertexInfluenceMap.end(); + ++boneinflistit) { - const IndexWeightList& boneinflist = mapit->second; - const std::string& bonename = mapit->first; + const IndexWeightList& boneinflist = boneinflistit->second; + const std::string& bonename = boneinflistit->first; BoneMap::const_iterator bonebyname; if ((bonebyname=boneMap.find(bonename)) == boneMap.end()) { @@ -307,7 +278,7 @@ bool RigTransformHardware::buildPalette(BoneMap&boneMap ,RigGeometry&rig) { const IndexWeight& iw = *infit; const unsigned int &index = iw.getIndex(); const float &weight = iw.getWeight(); - IndexWeightList & iwlist=vertexIndexWeight[index]; + IndexWeightList & iwlist=perVertexInfluences[index]; if(fabs(weight) > 1e-4) // don't use bone with weight too small { @@ -315,7 +286,7 @@ bool RigTransformHardware::buildPalette(BoneMap&boneMap ,RigGeometry&rig) { } 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 Bone " << bonename << " has a weight " << weight << " for vertex " << index << " this bone will not be in the palette" << std::endl; } maxBonePerVertex = osg::maximum(maxBonePerVertex, iwlist.size()); @@ -334,11 +305,11 @@ bool RigTransformHardware::buildPalette(BoneMap&boneMap ,RigGeometry&rig) { } ///normalize - /*unsigned int vertid=0; - for(VertexIndexWeightList::iterator it=vertexIndexWeight.begin();it!=vertexIndexWeight.end();++it,++vertid) + unsigned int vertid=0; + for(PerVertexInfList::iterator vertinfit=perVertexInfluences.begin(); vertinfit != perVertexInfluences.end(); ++vertinfit,++vertid) { float sum=0; - for(IndexWeightList::iterator iwit=it->begin();iwit!=it->end();++iwit) + for(IndexWeightList::iterator iwit = vertinfit->begin(); iwit != vertinfit->end(); ++iwit) sum+=iwit->second; if(sum< 1e-4){ @@ -347,15 +318,15 @@ bool RigTransformHardware::buildPalette(BoneMap&boneMap ,RigGeometry&rig) { else { sum=1.0f/sum; - for(IndexWeightList::iterator iwit=it->begin();iwit!=it->end();++iwit) + for(IndexWeightList::iterator iwit=vertinfit->begin();iwit!=vertinfit->end();++iwit) iwit->second*=sum; } - }*/ + } _bonesPerVertex = maxBonePerVertex; _uniformMatrixPalette = new osg::Uniform(osg::Uniform::FLOAT_MAT4, "matrixPalette", _bonePalette.size()); - createVertexAttribList(*this,vertexIndexWeight,this->_boneWeightAttribArrays); + createVertexAttribList(*this,perVertexInfluences,this->_boneWeightAttribArrays); return true; } diff --git a/src/osgAnimation/RigTransformSoftware.cpp b/src/osgAnimation/RigTransformSoftware.cpp index c36b1aa5a..35bea4823 100644 --- a/src/osgAnimation/RigTransformSoftware.cpp +++ b/src/osgAnimation/RigTransformSoftware.cpp @@ -38,19 +38,19 @@ RigTransformSoftware::RigTransformSoftware(const RigTransformSoftware& rts,const typedef std::vector BonePtrWeightList; -void RigTransformSoftware::buildMinimumUpdateSet(const BoneMap&boneMap,const RigGeometry&rig ){ +void RigTransformSoftware::buildMinimumUpdateSet( const BoneMap&boneMap, const RigGeometry&rig ){ ///1 Create Index2Vec - std::vector _vertex2Bones; - _vertex2Bones.resize(rig.getSourceGeometry()->getVertexArray()->getNumElements()); + const VertexInfluenceMap &vertexInfluenceMap=*rig.getInfluenceMap(); + std::vector perVertexInfluences; + perVertexInfluences.resize(rig.getSourceGeometry()->getVertexArray()->getNumElements()); - const VertexInfluenceMap *_vertexInfluenceMap=rig.getInfluenceMap(); - for (osgAnimation::VertexInfluenceMap::const_iterator it = _vertexInfluenceMap->begin(); - it != _vertexInfluenceMap->end(); - ++it) + for (osgAnimation::VertexInfluenceMap::const_iterator perBoneinfit = vertexInfluenceMap.begin(); + perBoneinfit != vertexInfluenceMap.end(); + ++perBoneinfit) { - const IndexWeightList& inflist = it->second; - const std::string& bonename = it->first; + const IndexWeightList& inflist = perBoneinfit->second; + const std::string& bonename = perBoneinfit->first; if (bonename.empty()) { OSG_WARN << "RigTransformSoftware::VertexInfluenceMap contains unamed bone IndexWeightList" << std::endl; @@ -71,13 +71,13 @@ void RigTransformSoftware::buildMinimumUpdateSet(const BoneMap&boneMap,const Rig const unsigned int &index = iw.getIndex(); float weight = iw.getWeight(); - _vertex2Bones[index].push_back(BonePtrWeight(bone, weight)); + perVertexInfluences[index].push_back(BonePtrWeight(bone, weight)); } } // normalize _vertex2Bones weight per vertex unsigned vertexID=0; - for (std::vector::iterator it = _vertex2Bones.begin(); it != _vertex2Bones.end(); ++it, ++vertexID) + for (std::vector::iterator it = perVertexInfluences.begin(); it != perVertexInfluences.end(); ++it, ++vertexID) { BonePtrWeightList& bones = *it; float sum = 0; @@ -97,32 +97,31 @@ void RigTransformSoftware::buildMinimumUpdateSet(const BoneMap&boneMap,const Rig ///2 Create inverse mapping Vec2Vec from previous built Index2Vec ///in order to minimize weighted matrices computation on update - _uniqInfluenceSet2VertIDList.clear(); + _uniqVertexGroupList.clear(); typedef std::map UnifyBoneGroup; UnifyBoneGroup unifyBuffer; vertexID=0; - ; - for (std::vector::iterator it = _vertex2Bones.begin(); it != _vertex2Bones.end(); ++it,++vertexID) + for (std::vector::iterator perVertinfit = perVertexInfluences.begin(); perVertinfit!=perVertexInfluences.end(); ++perVertinfit,++vertexID) { - BonePtrWeightList &bones = *it; + BonePtrWeightList &boneinfs = *perVertinfit; // sort the vector to have a consistent key - std::sort(bones.begin(), bones.end() ); + std::sort(boneinfs.begin(), boneinfs.end() ); // we use the vector as key to differentiate group - UnifyBoneGroup::iterator result = unifyBuffer.find(bones); + UnifyBoneGroup::iterator result = unifyBuffer.find(boneinfs); if (result != unifyBuffer.end()) result->second.getVertices().push_back(vertexID); else { - VertexGroup& vg = unifyBuffer[bones]; - vg.getBoneWeights() = bones; + VertexGroup& vg = unifyBuffer[boneinfs]; + vg.getBoneWeights() = boneinfs; vg.getVertices().push_back(vertexID); } } - _uniqInfluenceSet2VertIDList.reserve(unifyBuffer.size()); + _uniqVertexGroupList.reserve(unifyBuffer.size()); for (UnifyBoneGroup::const_iterator it = unifyBuffer.begin(); it != unifyBuffer.end(); ++it) - _uniqInfluenceSet2VertIDList.push_back(it->second); - OSG_WARN << "uniq groups " << _uniqInfluenceSet2VertIDList.size() << " for " << rig.getName() << std::endl; + _uniqVertexGroupList.push_back(it->second); + OSG_INFO << "uniq groups " << _uniqVertexGroupList.size() << " for " << rig.getName() << std::endl; } bool RigTransformSoftware::prepareData(RigGeometry&rig) {