From 1d1bfa1b397c78201dfdf4aa372d35d21700a7ce Mon Sep 17 00:00:00 2001 From: Denys Koch Date: Mon, 28 Aug 2017 14:34:39 +0200 Subject: [PATCH 1/9] Fix flawed BoundingSphere inequality operator --- include/osg/BoundingSphere | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/osg/BoundingSphere b/include/osg/BoundingSphere index 0b62c2cdd..4502e4595 100644 --- a/include/osg/BoundingSphere +++ b/include/osg/BoundingSphere @@ -64,7 +64,7 @@ class BoundingSphereImpl inline bool valid() const { return _radius>=0.0; } inline bool operator == (const BoundingSphereImpl& rhs) const { return _center==rhs._center && _radius==rhs._radius; } - inline bool operator != (const BoundingSphereImpl& rhs) const { return _center!=rhs._center || _radius==rhs._radius; } + inline bool operator != (const BoundingSphereImpl& rhs) const { return _center!=rhs._center || _radius!=rhs._radius; } /** Set the bounding sphere to the given center/radius using floats. */ inline void set(const vec_type& center,value_type radius) From e2f826b8fcfc49b9ce07577af15ad4a3fd2c158e Mon Sep 17 00:00:00 2001 From: Mathieu MARACHE Date: Tue, 29 Aug 2017 11:34:27 +0200 Subject: [PATCH 2/9] Under macOS the glValidateProgram reports too many false negatives (errors) about missing buffers, etc.. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit From the internet https://stackoverflow.com/questions/15335510/opengl-glvalidateprogram-error-on-mac-os-x : « […] The purpose of glValidateProgram is not to use it as an added "check" step after linking the program, because the GL and application state is hardly ready for actually using that program at this point, probably it's even before we get around to initializing the default framebuffer (its bitdepth, its multisample buffers, etc), and that's what the error hints at. An appropriate place to call glValidateProgram would be right before you make a real render call. » --- src/osg/Program.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/osg/Program.cpp b/src/osg/Program.cpp index 7092a565a..85c49a37d 100644 --- a/src/osg/Program.cpp +++ b/src/osg/Program.cpp @@ -517,9 +517,10 @@ void Program::apply( osg::State& state ) const // for shader debugging: to minimize performance impact, // optionally validate based on notify level. // TODO: enable this using notify level, or perhaps its own getenv()? +#ifndef __APPLE__ if( osg::isNotifyEnabled(osg::INFO) ) pcp->validateProgram(); - +#endif pcp->useProgram(); state.setLastAppliedProgramObject(pcp); } From 4c4f760d4a337e92bf1f77cb63a32850dae6a38f Mon Sep 17 00:00:00 2001 From: Julien Valentin Date: Wed, 30 Aug 2017 23:15:01 +0200 Subject: [PATCH 3/9] fix a bug in how vertexattributes are filled --- src/osgAnimation/RigTransformHardware.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/osgAnimation/RigTransformHardware.cpp b/src/osgAnimation/RigTransformHardware.cpp index fbe4e9de1..651e48cf7 100644 --- a/src/osgAnimation/RigTransformHardware.cpp +++ b/src/osgAnimation/RigTransformHardware.cpp @@ -136,9 +136,6 @@ bool RigTransformHardware::createPalette(int nbVertexes, BoneMap boneMap, const OSG_INFO << "RigTransformHardware::createPalette will use " << boneNameCountMap.size() * 4 << " uniforms" << std::endl; - for (int i = 0 ; i < (int)vertexIndexWeight.size(); i++) - vertexIndexWeight[i].resize(maxBonePerVertex); - _nbVertexes = nbVertexes; _bonesPerVertex = maxBonePerVertex; _bonePalette = palette; @@ -181,7 +178,7 @@ RigTransformHardware::BoneWeightAttribList RigTransformHardware::createVertexAtt int boneIndexInVec4 = b*2; (*array)[j][0 + boneIndexInVec4] = 0; (*array)[j][1 + boneIndexInVec4] = 0; - if (boneIndexInList < getNumBonesPerVertex()) + if (boneIndexInList < _vertexIndexMatrixWeightList[j].size()) { float boneIndex = static_cast(_vertexIndexMatrixWeightList[j][boneIndexInList].getIndex()); float boneWeight = _vertexIndexMatrixWeightList[j][boneIndexInList].getWeight(); From 78dd81a8b4ffcd2e92125eb04d448c7d1c13647b Mon Sep 17 00:00:00 2001 From: Julien Valentin Date: Fri, 1 Sep 2017 17:48:28 +0200 Subject: [PATCH 4/9] add void InfluenceMap::removeUnexpressedBones(Skeleton &skel) const; a bit experimental but work well without further process on my test set --- include/osgAnimation/VertexInfluence | 5 + src/osgAnimation/VertexInfluence.cpp | 147 +++++++++++++++++++++++---- 2 files changed, 132 insertions(+), 20 deletions(-) diff --git a/include/osgAnimation/VertexInfluence b/include/osgAnimation/VertexInfluence index 2ddd39ebe..eb2956b72 100644 --- a/include/osgAnimation/VertexInfluence +++ b/include/osgAnimation/VertexInfluence @@ -24,6 +24,8 @@ namespace osgAnimation { + class Skeleton; + // first is bonename, and second the weight typedef std::pair BoneWeight; // first is vertex index, and second the weight @@ -77,6 +79,9 @@ namespace osgAnimation /// compute the minimal VertexGroup Set in which vertices shares the same influence set void computeMinimalVertexGroupList(std::vector&uniqVertexGroupList, unsigned int numvert)const; + + //Experimental removal of unexpressed bone from the skeleton + void removeUnexpressedBones(Skeleton &skel) const; }; } diff --git a/src/osgAnimation/VertexInfluence.cpp b/src/osgAnimation/VertexInfluence.cpp index 3c2c50c42..2548d6ed9 100644 --- a/src/osgAnimation/VertexInfluence.cpp +++ b/src/osgAnimation/VertexInfluence.cpp @@ -14,6 +14,8 @@ */ #include +#include +#include #include #include #include @@ -31,14 +33,17 @@ struct invweight_ordered } }; -void VertexInfluenceMap::normalize(unsigned int numvert) { +void VertexInfluenceMap::normalize(unsigned int numvert) +{ typedef std::pair > PerVertWeights; std::vector localstore; localstore.resize(numvert); - for(VertexInfluenceMap::iterator mapit=this->begin(); mapit!=this->end(); ++mapit) { + for(VertexInfluenceMap::iterator mapit=this->begin(); mapit!=this->end(); ++mapit) + { IndexWeightList &curvecinf=mapit->second; - for(IndexWeightList::iterator curinf=curvecinf.begin(); curinf!=curvecinf.end(); ++curinf) { + for(IndexWeightList::iterator curinf=curvecinf.begin(); curinf!=curvecinf.end(); ++curinf) + { VertexIndexWeight& inf=*curinf; localstore[inf.first].first+=inf.second; localstore[inf.first].second.push_back(&inf.second); @@ -46,7 +51,8 @@ void VertexInfluenceMap::normalize(unsigned int numvert) { } } unsigned int vertid=0; - for(std::vector::iterator itvert=localstore.begin(); itvert!=localstore.end(); ++itvert, ++vertid) { + for(std::vector::iterator itvert=localstore.begin(); itvert!=localstore.end(); ++itvert, ++vertid) + { PerVertWeights & weights=*itvert; if(weights.first< 1e-4) { @@ -62,41 +68,51 @@ void VertexInfluenceMap::normalize(unsigned int numvert) { } ///remove weakest influences in order to fit targetted numbonepervertex -void VertexInfluenceMap::cullInfluenceCountPerVertex(unsigned int numbonepervertex,float minweight, bool renormalize) { +void VertexInfluenceMap::cullInfluenceCountPerVertex(unsigned int numbonepervertex,float minweight, bool renormalize) +{ - typedef std::set BoneWeightOrdered; - std::map tempVec2Bones; + typedef std::set BoneWeightOrdered; + std::map tempVec2Bones; for(VertexInfluenceMap::iterator mapit=this->begin(); mapit!=this->end(); ++mapit) { const std::string& bonename=mapit->first; IndexWeightList &curvecinf=mapit->second; - for(IndexWeightList::iterator curinf=curvecinf.begin(); curinf!=curvecinf.end(); ++curinf) { + for(IndexWeightList::iterator curinf=curvecinf.begin(); curinf!=curvecinf.end(); ++curinf) + { VertexIndexWeight& inf=*curinf; - if( bonename.empty()) { + if( bonename.empty()) + { OSG_WARN << "VertexInfluenceSet::cullInfluenceCountPerVertex warning vertex " << inf.first << " is not assigned to a bone" << std::endl; } else if(inf.second>minweight)tempVec2Bones[inf.first].insert(BoneWeight(bonename, inf.second)); } } this->clear(); - for( std::map::iterator mapit=tempVec2Bones.begin(); mapit!=tempVec2Bones.end(); ++mapit) { + for( std::map::iterator mapit=tempVec2Bones.begin(); mapit!=tempVec2Bones.end(); ++mapit) + { BoneWeightOrdered& bwset=mapit->second; unsigned int newsize=numbonepervertexnewsize)bwset.erase(*bwset.rbegin()); - if(renormalize){ + if(renormalize) + { for(BoneWeightOrdered::iterator bwit=bwset.begin(); bwit!=bwset.end(); ++bwit) sum+=bwit->second; - if(sum>1e-4){ + if(sum>1e-4) + { sum=1.0f/sum; - for(BoneWeightOrdered::iterator bwit=bwset.begin(); bwit!=bwset.end(); ++bwit) { + for(BoneWeightOrdered::iterator bwit=bwset.begin(); bwit!=bwset.end(); ++bwit) + { VertexInfluence & inf= (*this)[bwit->first]; inf.push_back(VertexIndexWeight(mapit->first, bwit->second*sum)); inf.setName(bwit->first); } } - }else{ - for(BoneWeightOrdered::iterator bwit=bwset.begin(); bwit!=bwset.end(); ++bwit) { + } + else + { + for(BoneWeightOrdered::iterator bwit=bwset.begin(); bwit!=bwset.end(); ++bwit) + { VertexInfluence & inf= (*this)[bwit->first]; inf.push_back(VertexIndexWeight(mapit->first,bwit->second)); inf.setName(bwit->first); @@ -108,13 +124,14 @@ void VertexInfluenceMap::cullInfluenceCountPerVertex(unsigned int numbonepervert void VertexInfluenceMap::computePerVertexInfluenceList(std::vector& vertex2Bones,unsigned int numvert)const { - vertex2Bones.resize(numvert); - for (osgAnimation::VertexInfluenceMap::const_iterator it = begin(); + vertex2Bones.resize(numvert); + for (osgAnimation::VertexInfluenceMap::const_iterator it = begin(); it != end(); ++it) { const IndexWeightList& inflist = it->second; - if (it->first.empty()) { + if (it->first.empty()) + { OSG_WARN << "VertexInfluenceMap::computePerVertexInfluenceList contains unamed bone IndexWeightList" << std::endl; } for(IndexWeightList::const_iterator infit=inflist.begin(); infit!=inflist.end(); ++infit) @@ -135,7 +152,7 @@ struct SortByNameAndWeight : public std::less { if (b0.first < b1.first) return true; - else if (b0.first> b1.first) + else if (b0.first > b1.first) return false; return (b0.second < b1.second); } @@ -182,7 +199,8 @@ void VertexInfluenceMap::computeMinimalVertexGroupList(std::vector& unifyBuffer[boneweightlist].setBoneWeights(boneweightlist); unifyBuffer[boneweightlist].vertIDs().push_back(vertexID); } - if(vertex2Bones.size()==unifyBuffer.size()) { + if(vertex2Bones.size()==unifyBuffer.size()) + { OSG_WARN << "VertexInfluenceMap::computeMinimalVertexGroupList is useless no duplicate VertexGroup" << std::endl; } uniqVertexGroupList.reserve(unifyBuffer.size()); @@ -191,3 +209,92 @@ void VertexInfluenceMap::computeMinimalVertexGroupList(std::vector& uniqVertexGroupList.push_back(it->second); } } + + +//Expermental +typedef std::vector RigList; +class CollectRigVisitor : public osg::NodeVisitor +{ +public: + META_NodeVisitor(osgAnimation, CollectRigVisitor) + CollectRigVisitor(); + + //void apply(osg::Node&); + void apply(osg::Geometry& node); + const RigList& getRigList() const; + +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); +} + +const RigList& CollectRigVisitor::getRigList() const +{ + return _map; +} + +void VertexInfluenceMap::removeUnexpressedBones(Skeleton &skel) const +{ + BoneMapVisitor mapVisitor; + skel.accept(mapVisitor); + + CollectRigVisitor rigvis; + skel.accept(rigvis); + + 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())) + { + ++bmit; + continue; + } + + ///Bone can be removed + Bone * bone2rm=bmit->second; + for(unsigned int numchild=0; numchildgetNumChildren(); numchild++) + { + if( (child = dynamic_cast(bone2rm->getChild(numchild))) ) + { + par->addChild(child); + bone2rm->removeChild(child); + } + } + par->removeChild(bone2rm); + ///rebuild bonemap after bone removal + skel.accept(mapVisitor); + boneMap = mapVisitor.getBoneMap(); + bmit=boneMap.begin(); + } + else ++bmit; + } + +} From 95605487223421b51530808f1f77418ad99400fa Mon Sep 17 00:00:00 2001 From: Julien Valentin Date: Fri, 1 Sep 2017 18:08:37 +0200 Subject: [PATCH 5/9] add MorphTransformHardware serializer --- src/osgWrappers/serializers/osgAnimation/RigTransform.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/osgWrappers/serializers/osgAnimation/RigTransform.cpp b/src/osgWrappers/serializers/osgAnimation/RigTransform.cpp index 8b1197f83..c3e40ca30 100644 --- a/src/osgWrappers/serializers/osgAnimation/RigTransform.cpp +++ b/src/osgWrappers/serializers/osgAnimation/RigTransform.cpp @@ -2,6 +2,7 @@ #include #include #include +#include #include #include #include @@ -37,3 +38,9 @@ namespace wrap_osgAnimationMorphTransformSoftWare{ osgAnimation::MorphTransformSoftware, "osg::Object osgAnimation::MorphTransform osgAnimation::MorphTransformSoftware" ){} } +namespace wrap_osgAnimationMorphTransformHardware{ + REGISTER_OBJECT_WRAPPER( osgAnimation_MorphTransformHardware, + new osgAnimation::MorphTransformHardware, + osgAnimation::MorphTransformHardware, + "osg::Object osgAnimation::MorphTransform osgAnimation::MorphTransformHardware" ){} +} From a73c20d7f5abe0cbc3b3daa9b6779c40ca16f67b Mon Sep 17 00:00:00 2001 From: Julien Valentin Date: Fri, 1 Sep 2017 19:13:01 +0200 Subject: [PATCH 6/9] update serializer with new properties --- include/osgAnimation/MorphTransformHardware | 12 ++++++++---- include/osgAnimation/RigTransformHardware | 5 ++++- src/osgAnimation/MorphTransformHardware.cpp | 5 +---- src/osgAnimation/RigTransformHardware.cpp | 4 +--- .../serializers/osgAnimation/RigTransform.cpp | 14 ++++++++++---- 5 files changed, 24 insertions(+), 16 deletions(-) diff --git a/include/osgAnimation/MorphTransformHardware b/include/osgAnimation/MorphTransformHardware index b061cccae..650f62efd 100644 --- a/include/osgAnimation/MorphTransformHardware +++ b/include/osgAnimation/MorphTransformHardware @@ -22,6 +22,9 @@ #include #include +///texture unit reserved for morphtarget TBO +#define MORPHTRANSHW_DEFAULTMORPHTEXTUREUNIT 7 + namespace osgAnimation { class MorphGeometry; @@ -39,12 +42,13 @@ namespace osgAnimation virtual void operator()(MorphGeometry&); - inline void setShader(osg::Shader*s){_shader=s;} - inline osg::Shader * getShader()const{return _shader;} + inline void setShader( osg::Shader*s ) { _shader=s; } + inline const osg::Shader * getShader() const{ return _shader; } + inline osg::Shader * getShader() { return _shader; } ///texture unit reserved for morphtarget TBO default is 7 - void setReservedTextureUnit(unsigned int t){_reservedTextureUnit=t;} - unsigned int getReservedTextureUnit() const {return _reservedTextureUnit;} + void setReservedTextureUnit(unsigned int t) { _reservedTextureUnit=t; } + unsigned int getReservedTextureUnit() const { return _reservedTextureUnit;} protected: diff --git a/include/osgAnimation/RigTransformHardware b/include/osgAnimation/RigTransformHardware index 2f7ea868b..f27aa0506 100644 --- a/include/osgAnimation/RigTransformHardware +++ b/include/osgAnimation/RigTransformHardware @@ -23,6 +23,8 @@ #include #include +#define RIGTRANSHW_DEFAULT_FIRST_VERTATTRIB_TARGETTED 11 + namespace osgAnimation { class RigGeometry; @@ -48,7 +50,8 @@ namespace osgAnimation unsigned int getFirstVertexAttributeTarget()const { return _minAttribIndex;} void setShader(osg::Shader* shader) { _shader = shader; } - osg::Shader* getShader() const { return _shader; } + const osg::Shader* getShader() const { return _shader; } + osg::Shader* getShader() { return _shader; } osg::Vec4Array* getVertexAttrib(unsigned int index); unsigned int getNumVertexAttrib() const {return _boneWeightAttribArrays.size();} diff --git a/src/osgAnimation/MorphTransformHardware.cpp b/src/osgAnimation/MorphTransformHardware.cpp index 48119c813..a275d5680 100644 --- a/src/osgAnimation/MorphTransformHardware.cpp +++ b/src/osgAnimation/MorphTransformHardware.cpp @@ -18,14 +18,11 @@ #include #include -///texture unit reserved for morphtarget TBO -#define DEFAULTMORPHTEXTUREUNIT 7 - using namespace osgAnimation; MorphTransformHardware::MorphTransformHardware(): _needInit(true), - _reservedTextureUnit(DEFAULTMORPHTEXTUREUNIT) + _reservedTextureUnit(MORPHTRANSHW_DEFAULTMORPHTEXTUREUNIT) { } diff --git a/src/osgAnimation/RigTransformHardware.cpp b/src/osgAnimation/RigTransformHardware.cpp index c34ec2831..31a0d7631 100644 --- a/src/osgAnimation/RigTransformHardware.cpp +++ b/src/osgAnimation/RigTransformHardware.cpp @@ -20,13 +20,11 @@ using namespace osgAnimation; -#define DEFAULT_FIRST_VERTATTRIB_TARGETTED 11 - RigTransformHardware::RigTransformHardware(): _bonesPerVertex (0), _nbVertices (0), _needInit (true), - _minAttribIndex(DEFAULT_FIRST_VERTATTRIB_TARGETTED) + _minAttribIndex(RIGTRANSHW_DEFAULT_FIRST_VERTATTRIB_TARGETTED) {} RigTransformHardware::RigTransformHardware(const RigTransformHardware& rth, const osg::CopyOp& copyop): diff --git a/src/osgWrappers/serializers/osgAnimation/RigTransform.cpp b/src/osgWrappers/serializers/osgAnimation/RigTransform.cpp index c3e40ca30..f89bd0d6a 100644 --- a/src/osgWrappers/serializers/osgAnimation/RigTransform.cpp +++ b/src/osgWrappers/serializers/osgAnimation/RigTransform.cpp @@ -2,8 +2,8 @@ #include #include #include -#include -#include + #include + #include #include #include @@ -23,7 +23,10 @@ namespace wrap_osgAnimationRigTransformHardWare{ REGISTER_OBJECT_WRAPPER( osgAnimation_RigTransformHardware, new osgAnimation::RigTransformHardware, osgAnimation::RigTransformHardware, - "osg::Object osgAnimation::RigTransform osgAnimation::RigTransformHardware" ){} + "osg::Object osgAnimation::RigTransform osgAnimation::RigTransformHardware" ){ + ADD_OBJECT_SERIALIZER(Shader,osg::Shader,NULL); + ADD_UINT_SERIALIZER(FirstVertexAttributeTarget,RIGTRANSHW_DEFAULT_FIRST_VERTATTRIB_TARGETTED); + } } namespace wrap_osgAnimationMorphTransform{ @@ -42,5 +45,8 @@ namespace wrap_osgAnimationMorphTransformHardware{ REGISTER_OBJECT_WRAPPER( osgAnimation_MorphTransformHardware, new osgAnimation::MorphTransformHardware, osgAnimation::MorphTransformHardware, - "osg::Object osgAnimation::MorphTransform osgAnimation::MorphTransformHardware" ){} + "osg::Object osgAnimation::MorphTransform osgAnimation::MorphTransformHardware" ){ + ADD_OBJECT_SERIALIZER(Shader,osg::Shader,NULL); + ADD_UINT_SERIALIZER(ReservedTextureUnit,MORPHTRANSHW_DEFAULTMORPHTEXTUREUNIT); + } } From 041a2a6e72cce2a910d168bb09fd38c073e018f7 Mon Sep 17 00:00:00 2001 From: Julien Valentin Date: Sun, 3 Sep 2017 17:37:06 +0200 Subject: [PATCH 7/9] make preparedata skeleton independant (as it was with the Rig::buildInfluenceSet) no more divergence with master i think --- include/osgAnimation/RigGeometry | 3 +- include/osgAnimation/RigTransformHardware | 1 + include/osgAnimation/RigTransformSoftware | 27 +- src/osgAnimation/RigTransformHardware.cpp | 355 +++++++++++----------- src/osgAnimation/RigTransformSoftware.cpp | 140 +++++---- 5 files changed, 290 insertions(+), 236 deletions(-) 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(); } } From 7da072b43365fb956b131936a32a284231c9cd52 Mon Sep 17 00:00:00 2001 From: Julien Valentin Date: Mon, 4 Sep 2017 02:27:54 +0200 Subject: [PATCH 8/9] cleanup --- src/osgAnimation/RigTransformHardware.cpp | 55 ++++++++------ src/osgAnimation/RigTransformSoftware.cpp | 46 ++++++------ src/osgAnimation/VertexInfluence.cpp | 90 +++++++++++------------ 3 files changed, 101 insertions(+), 90 deletions(-) diff --git a/src/osgAnimation/RigTransformHardware.cpp b/src/osgAnimation/RigTransformHardware.cpp index c8312a96d..38d592a55 100644 --- a/src/osgAnimation/RigTransformHardware.cpp +++ b/src/osgAnimation/RigTransformHardware.cpp @@ -94,18 +94,23 @@ unsigned int createVertexAttribList(const PerVertexInfList & perVertexInfluences return 0; ///create vertex attrib arrays + boneWeightAttribArrays.reserve(nbArray); boneWeightAttribArrays.resize(nbArray); - for(unsigned int j=0; j< nbArray; ++j) + for(unsigned int j = 0; j< nbArray; ++j) { - boneWeightAttribArrays[j] = new osg::Vec4Array(osg::Array::BIND_PER_VERTEX); - boneWeightAttribArrays[j]->resize(perVertexInfluences.size()); + osg::Vec4Array* vecattr = new osg::Vec4Array(osg::Array::BIND_PER_VERTEX); + vecattr->reserve(perVertexInfluences.size()); + vecattr->resize(perVertexInfluences.size()); + boneWeightAttribArrays[j] = vecattr; } ///populate vertex attrib arrays - for(PerVertexInfList::const_iterator vertinfit=perVertexInfluences.begin(); vertinfit != perVertexInfluences.end(); ++vertinfit,++vertid) + for(PerVertexInfList::const_iterator vertinfit = perVertexInfluences.begin(); + vertinfit != perVertexInfluences.end(); + ++vertinfit, ++vertid) { //sum for normalization - float sum=0; + float sum = 0; for(IndexWeightList::const_iterator iwit = vertinfit->begin(); iwit != vertinfit->end(); ++iwit) sum+=iwit->second; @@ -116,10 +121,10 @@ unsigned int createVertexAttribList(const PerVertexInfList & perVertexInfluences } else { - sum=1.0f/sum; + sum = 1.0f/sum; for (unsigned int j = 0; j < nbArray; ++j) { - osg::Vec4& dest=(* boneWeightAttribArrays[j])[vertid]; + osg::Vec4& dest = (* boneWeightAttribArrays[j])[vertid]; for (unsigned int b = 0; b < 2; ++b) { boneIndexInVec4 = b*2; @@ -148,9 +153,10 @@ bool RigTransformHardware::prepareData(RigGeometry& rig) { _nbVertices = rig.getSourceGeometry()->getVertexArray()->getNumElements(); const VertexInfluenceMap &vertexInfluenceMap = *rig.getInfluenceMap(); + _perVertexInfluences.reserve(_nbVertices); _perVertexInfluences.resize(_nbVertices); - unsigned int localboneid=0; + unsigned int localboneid = 0; for (VertexInfluenceMap::const_iterator boneinflistit = vertexInfluenceMap.begin(); boneinflistit != vertexInfluenceMap.end(); ++boneinflistit, ++localboneid) @@ -179,7 +185,7 @@ bool RigTransformHardware::prepareData(RigGeometry& rig) } -bool RigTransformHardware::buildPalette(const BoneMap&boneMap,const RigGeometry&rig) +bool RigTransformHardware::buildPalette(const BoneMap& boneMap, const RigGeometry& rig) { typedef std::map BoneNameCountMap; @@ -187,7 +193,7 @@ bool RigTransformHardware::buildPalette(const BoneMap&boneMap,const RigGeometry& _bonePalette.clear(); _boneNameToPalette.clear(); - IndexWeightList::size_type maxBonePerVertex=0; + IndexWeightList::size_type maxBonePerVertex = 0; BoneNameCountMap boneNameCountMap; const VertexInfluenceMap &vertexInfluenceMap = *rig.getInfluenceMap(); @@ -214,37 +220,37 @@ bool RigTransformHardware::buildPalette(const BoneMap&boneMap,const RigGeometry& localid2bone.push_back(-1); continue; } - if ((boneName2PaletteIndex= _boneNameToPalette.find(bonename)) != _boneNameToPalette.end()) + if ( (boneName2PaletteIndex = _boneNameToPalette.find(bonename)) != _boneNameToPalette.end()) { boneNameCountMap[bonename]++; - paletteindex= boneName2PaletteIndex->second ; + paletteindex = boneName2PaletteIndex->second ; } else { boneNameCountMap[bonename] = 1; // for stats _boneNameToPalette[bonename] = _bonePalette.size() ; - paletteindex= _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( std::vector::iterator idwlistit = _perVertexInfluences.begin(); idwlistit!=_perVertexInfluences.end(); ++idwlistit) { - for( IndexWeightList::iterator idwit=idwlistit->begin(); idwit!=idwlistit->end();) + for( IndexWeightList::iterator idwit = idwlistit->begin(); idwit!=idwlistit->end();) { - if(localid2bone[idwit->first]<0)idwit=idwlistit->erase(idwit); - else{ - idwit->first=localid2bone[idwit->first]; + if(localid2bone[idwit->first]<0) + idwit = idwlistit->erase(idwit); + else + { + idwit->first = localid2bone[idwit->first]; ++idwit; } } @@ -277,6 +283,7 @@ bool RigTransformHardware::init(RigGeometry& rig) osg::Geometry& source = *rig.getSourceGeometry(); osg::Vec3Array* positionSrc = dynamic_cast(source.getVertexArray()); + if (!positionSrc) { OSG_WARN << "RigTransformHardware no vertex array in the geometry " << rig.getName() << std::endl; @@ -293,10 +300,10 @@ bool RigTransformHardware::init(RigGeometry& rig) //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) + for(unsigned int i = 0; igetNumShaders(); ++i) + if(program->getShader(i)->getType() == osg::Shader::VERTEX) { - vertexshader=program->getShader(i); + vertexshader = program->getShader(i); program->removeShader(vertexshader); } } @@ -310,7 +317,7 @@ bool RigTransformHardware::init(RigGeometry& rig) { if (!_shader.valid()) vertexshader = osg::Shader::readShaderFile(osg::Shader::VERTEX,"skinning.vert"); - else vertexshader=_shader; + else vertexshader = _shader; } if (!vertexshader.valid()) diff --git a/src/osgAnimation/RigTransformSoftware.cpp b/src/osgAnimation/RigTransformSoftware.cpp index ca78e6c79..955f42424 100644 --- a/src/osgAnimation/RigTransformSoftware.cpp +++ b/src/osgAnimation/RigTransformSoftware.cpp @@ -36,14 +36,14 @@ RigTransformSoftware::RigTransformSoftware(const RigTransformSoftware& rts,const } -typedef std::vector BonePtrWeightList; - void RigTransformSoftware::buildMinimumUpdateSet( const RigGeometry&rig ) { ///1 Create Index2Vec - const VertexInfluenceMap &vertexInfluenceMap=*rig.getInfluenceMap(); + unsigned int nbVertices=rig.getSourceGeometry()->getVertexArray()->getNumElements(); + const VertexInfluenceMap &vertexInfluenceMap = *rig.getInfluenceMap(); std::vector perVertexInfluences; - perVertexInfluences.resize(rig.getSourceGeometry()->getVertexArray()->getNumElements()); + perVertexInfluences.reserve(nbVertices); + perVertexInfluences.resize(nbVertices); unsigned int vimapBoneID = 0; for (osgAnimation::VertexInfluenceMap::const_iterator perBoneinfit = vertexInfluenceMap.begin(); @@ -57,7 +57,7 @@ void RigTransformSoftware::buildMinimumUpdateSet( const RigGeometry&rig ) { OSG_WARN << "RigTransformSoftware::VertexInfluenceMap contains unamed bone IndexWeightList" << std::endl; } - for(IndexWeightList::const_iterator infit=inflist.begin(); infit!=inflist.end(); ++infit) + for(IndexWeightList::const_iterator infit = inflist.begin(); infit!=inflist.end(); ++infit) { const VertexIndexWeight &iw = *infit; const unsigned int &index = iw.first; @@ -67,12 +67,14 @@ void RigTransformSoftware::buildMinimumUpdateSet( const RigGeometry&rig ) } // normalize _vertex2Bones weight per vertex - unsigned vertexID=0; - for (std::vector::iterator it = perVertexInfluences.begin(); it != perVertexInfluences.end(); ++it, ++vertexID) + unsigned vertexID = 0; + for (std::vector::iterator it = perVertexInfluences.begin(); + it != perVertexInfluences.end(); + ++it, ++vertexID) { 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) { @@ -81,7 +83,7 @@ void RigTransformSoftware::buildMinimumUpdateSet( const RigGeometry&rig ) 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); } } @@ -92,8 +94,10 @@ void RigTransformSoftware::buildMinimumUpdateSet( const RigGeometry&rig ) typedef std::map UnifyBoneGroup; UnifyBoneGroup unifyBuffer; - vertexID=0; - for (std::vector::iterator perVertinfit = perVertexInfluences.begin(); perVertinfit!=perVertexInfluences.end(); ++perVertinfit,++vertexID) + vertexID = 0; + for (std::vector::iterator perVertinfit = perVertexInfluences.begin(); + perVertinfit!=perVertexInfluences.end(); + ++perVertinfit,++vertexID) { BonePtrWeightList &boneinfs = *perVertinfit; // sort the vector to have a consistent key @@ -127,20 +131,20 @@ bool RigTransformSoftware::prepareData(RigGeometry&rig) if(!(positionSrc) || positionSrc->empty() ) return false; - if(normalSrc&& normalSrc->size()!=positionSrc->size()) + if(normalSrc && normalSrc->size() != positionSrc->size()) return false; /// setup Vertex and Normal arrays with copy of sources rig.setVertexArray(new osg::Vec3Array); - osg::Vec3Array* positionDst =new osg::Vec3Array; + osg::Vec3Array* positionDst = new osg::Vec3Array; rig.setVertexArray(positionDst); - *positionDst=*positionSrc; + *positionDst = *positionSrc; positionDst->setDataVariance(osg::Object::DYNAMIC); if(normalSrc) { - osg::Vec3Array* normalDst =new osg::Vec3Array; - *normalDst=*normalSrc; + osg::Vec3Array* normalDst = new osg::Vec3Array; + *normalDst = *normalSrc; rig.setNormalArray(normalDst, osg::Array::BIND_PER_VERTEX); normalDst->setDataVariance(osg::Object::DYNAMIC); } @@ -166,7 +170,7 @@ bool RigTransformSoftware::init(RigGeometry&rig) BoneMapVisitor mapVisitor; rig.getSkeleton()->accept(mapVisitor); BoneMap boneMap = mapVisitor.getBoneMap(); - VertexInfluenceMap & vertexInfluenceMap= *rig.getInfluenceMap(); + VertexInfluenceMap & vertexInfluenceMap = *rig.getInfluenceMap(); ///create local bonemap std::vector localid2bone; @@ -198,14 +202,14 @@ bool RigTransformSoftware::init(RigGeometry&rig) } ///fill bone ptr in the _uniqVertexGroupList - for(VertexGroupList::iterator itvg=_uniqVertexGroupList.begin(); itvg!=_uniqVertexGroupList.end(); ++itvg) + for(VertexGroupList::iterator itvg = _uniqVertexGroupList.begin(); itvg != _uniqVertexGroupList.end(); ++itvg) { VertexGroup& uniq = *itvg; - for(BonePtrWeightList::iterator bwit= uniq.getBoneWeights().begin(); bwit!=uniq.getBoneWeights().end(); ) + for(BonePtrWeightList::iterator bwit= uniq.getBoneWeights().begin(); bwit != uniq.getBoneWeights().end(); ) { - Bone * b=localid2bone[bwit->getBoneID()]; + Bone * b = localid2bone[bwit->getBoneID()]; if(!b) - bwit=uniq.getBoneWeights().erase(bwit); + bwit = uniq.getBoneWeights().erase(bwit); else bwit++->setBonePtr(b); } diff --git a/src/osgAnimation/VertexInfluence.cpp b/src/osgAnimation/VertexInfluence.cpp index 2548d6ed9..42ca1f254 100644 --- a/src/osgAnimation/VertexInfluence.cpp +++ b/src/osgAnimation/VertexInfluence.cpp @@ -29,7 +29,7 @@ struct invweight_ordered { if (bw1.second > bw2.second)return true; if (bw1.second < bw2.second)return false; - return(bw1.first > PerVertWeights; std::vector localstore; localstore.resize(numvert); - for(VertexInfluenceMap::iterator mapit=this->begin(); mapit!=this->end(); ++mapit) + for(VertexInfluenceMap::iterator mapit = this->begin(); mapit != this->end(); ++mapit) { - IndexWeightList &curvecinf=mapit->second; - for(IndexWeightList::iterator curinf=curvecinf.begin(); curinf!=curvecinf.end(); ++curinf) + IndexWeightList &curvecinf = mapit->second; + for(IndexWeightList::iterator curinf = curvecinf.begin(); curinf != curvecinf.end(); ++curinf) { - VertexIndexWeight& inf=*curinf; - localstore[inf.first].first+=inf.second; + VertexIndexWeight& inf = *curinf; + localstore[inf.first].first += inf.second; localstore[inf.first].second.push_back(&inf.second); } } - unsigned int vertid=0; - for(std::vector::iterator itvert=localstore.begin(); itvert!=localstore.end(); ++itvert, ++vertid) + unsigned int vertid = 0; + for(std::vector::iterator itvert = localstore.begin(); + itvert != localstore.end(); + ++itvert, ++vertid) { - PerVertWeights & weights=*itvert; + PerVertWeights & weights = *itvert; if(weights.first< 1e-4) { OSG_WARN << "VertexInfluenceMap::normalize warning the vertex " <::iterator itf =weights.second.begin(); itf!=weights.second.end(); ++itf) - **itf*=mult; + for (std::vector::iterator itf = weights.second.begin(); itf != weights.second.end(); ++itf) + **itf *= mult; } } @@ -73,13 +75,13 @@ void VertexInfluenceMap::cullInfluenceCountPerVertex(unsigned int numbonepervert typedef std::set BoneWeightOrdered; std::map tempVec2Bones; - for(VertexInfluenceMap::iterator mapit=this->begin(); mapit!=this->end(); ++mapit) + for(VertexInfluenceMap::iterator mapit = this->begin(); mapit != this->end(); ++mapit) { - const std::string& bonename=mapit->first; - IndexWeightList &curvecinf=mapit->second; - for(IndexWeightList::iterator curinf=curvecinf.begin(); curinf!=curvecinf.end(); ++curinf) + const std::string& bonename = mapit->first; + IndexWeightList &curvecinf = mapit->second; + for(IndexWeightList::iterator curinf = curvecinf.begin(); curinf != curvecinf.end(); ++curinf) { - VertexIndexWeight& inf=*curinf; + VertexIndexWeight& inf = *curinf; if( bonename.empty()) { OSG_WARN << "VertexInfluenceSet::cullInfluenceCountPerVertex warning vertex " << inf.first << " is not assigned to a bone" << std::endl; @@ -88,22 +90,22 @@ void VertexInfluenceMap::cullInfluenceCountPerVertex(unsigned int numbonepervert } } this->clear(); - for( std::map::iterator mapit=tempVec2Bones.begin(); mapit!=tempVec2Bones.end(); ++mapit) + for( std::map::iterator mapit = tempVec2Bones.begin(); mapit != tempVec2Bones.end(); ++mapit) { - BoneWeightOrdered& bwset=mapit->second; - unsigned int newsize=numbonepervertexsecond; + unsigned int newsize = numbonepervertexnewsize)bwset.erase(*bwset.rbegin()); if(renormalize) { - for(BoneWeightOrdered::iterator bwit=bwset.begin(); bwit!=bwset.end(); ++bwit) - sum+=bwit->second; - if(sum>1e-4) + for(BoneWeightOrdered::iterator bwit = bwset.begin(); bwit != bwset.end(); ++bwit) + sum += bwit->second; + if(sum > 1e-4) { - sum=1.0f/sum; - for(BoneWeightOrdered::iterator bwit=bwset.begin(); bwit!=bwset.end(); ++bwit) + sum = 1.0f/sum; + for(BoneWeightOrdered::iterator bwit = bwset.begin(); bwit != bwset.end(); ++bwit) { - VertexInfluence & inf= (*this)[bwit->first]; + VertexInfluence & inf = (*this)[bwit->first]; inf.push_back(VertexIndexWeight(mapit->first, bwit->second*sum)); inf.setName(bwit->first); } @@ -111,9 +113,9 @@ void VertexInfluenceMap::cullInfluenceCountPerVertex(unsigned int numbonepervert } else { - for(BoneWeightOrdered::iterator bwit=bwset.begin(); bwit!=bwset.end(); ++bwit) + for(BoneWeightOrdered::iterator bwit = bwset.begin(); bwit != bwset.end(); ++bwit) { - VertexInfluence & inf= (*this)[bwit->first]; + VertexInfluence & inf = (*this)[bwit->first]; inf.push_back(VertexIndexWeight(mapit->first,bwit->second)); inf.setName(bwit->first); } @@ -125,16 +127,14 @@ void VertexInfluenceMap::cullInfluenceCountPerVertex(unsigned int numbonepervert void VertexInfluenceMap::computePerVertexInfluenceList(std::vector& vertex2Bones,unsigned int numvert)const { vertex2Bones.resize(numvert); - for (osgAnimation::VertexInfluenceMap::const_iterator it = begin(); - it != end(); - ++it) + for (osgAnimation::VertexInfluenceMap::const_iterator it = begin(); it != end(); ++it) { const IndexWeightList& inflist = it->second; if (it->first.empty()) { OSG_WARN << "VertexInfluenceMap::computePerVertexInfluenceList contains unamed bone IndexWeightList" << std::endl; } - for(IndexWeightList::const_iterator infit=inflist.begin(); infit!=inflist.end(); ++infit) + for(IndexWeightList::const_iterator infit = inflist.begin(); infit != inflist.end(); ++infit) { const VertexIndexWeight &iw = *infit; const unsigned int &index = iw.first; @@ -179,7 +179,7 @@ struct SortByBoneWeightList : public std::less return false; } }; -void VertexInfluenceMap::computeMinimalVertexGroupList(std::vector& uniqVertexGroupList, unsigned int numvert)const +void VertexInfluenceMap::computeMinimalVertexGroupList(std::vector& uniqVertexGroupList, unsigned int numvert) const { uniqVertexGroupList.clear(); std::vector vertex2Bones; @@ -187,7 +187,7 @@ void VertexInfluenceMap::computeMinimalVertexGroupList(std::vector& typedef std::map UnifyBoneGroup; UnifyBoneGroup unifyBuffer; - unsigned int vertexID=0; + unsigned int vertexID = 0; for (std::vector::iterator it = vertex2Bones.begin(); it != vertex2Bones.end(); ++it,++vertexID) { BoneWeightList &boneweightlist = *it; @@ -199,7 +199,7 @@ void VertexInfluenceMap::computeMinimalVertexGroupList(std::vector& unifyBuffer[boneweightlist].setBoneWeights(boneweightlist); unifyBuffer[boneweightlist].vertIDs().push_back(vertexID); } - if(vertex2Bones.size()==unifyBuffer.size()) + if(vertex2Bones.size() == unifyBuffer.size()) { OSG_WARN << "VertexInfluenceMap::computeMinimalVertexGroupList is useless no duplicate VertexGroup" << std::endl; } @@ -255,32 +255,32 @@ void VertexInfluenceMap::removeUnexpressedBones(Skeleton &skel) const CollectRigVisitor rigvis; skel.accept(rigvis); - RigList rigs=rigvis.getRigList(); + RigList rigs = rigvis.getRigList(); BoneMap boneMap = mapVisitor.getBoneMap(); Bone* child,*par; - for(BoneMap::iterator bmit=boneMap.begin(); bmit!=boneMap.end();) + 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) + bool isusless = true; + for(RigList::iterator rigit = rigs.begin(); rigit != rigs.end(); ++rigit) { - if( ((*rigit)->getInfluenceMap()->find(bmit->first) !=(*rigit)->getInfluenceMap()->end())) + if( ((*rigit)->getInfluenceMap()->find(bmit->first) != (*rigit)->getInfluenceMap()->end())) { - isusless=false; + isusless = false; break; } } - if(!isusless||!(par=bmit->second->getBoneParent())) + if(!isusless || !(par = bmit->second->getBoneParent())) { ++bmit; continue; } ///Bone can be removed - Bone * bone2rm=bmit->second; - for(unsigned int numchild=0; numchildgetNumChildren(); numchild++) + Bone * bone2rm = bmit->second; + for(unsigned int numchild = 0; numchild < bone2rm->getNumChildren(); numchild++) { if( (child = dynamic_cast(bone2rm->getChild(numchild))) ) { @@ -292,7 +292,7 @@ void VertexInfluenceMap::removeUnexpressedBones(Skeleton &skel) const ///rebuild bonemap after bone removal skel.accept(mapVisitor); boneMap = mapVisitor.getBoneMap(); - bmit=boneMap.begin(); + bmit = boneMap.begin(); } else ++bmit; } From 0a93569b9ef83136307b48981eb23f61a2750f46 Mon Sep 17 00:00:00 2001 From: Julien Valentin Date: Mon, 4 Sep 2017 12:04:37 +0200 Subject: [PATCH 9/9] add DSO scope in modified XXXTransformHardware serializers --- .../serializers/osgAnimation/RigTransform.cpp | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/osgWrappers/serializers/osgAnimation/RigTransform.cpp b/src/osgWrappers/serializers/osgAnimation/RigTransform.cpp index f89bd0d6a..5b69cdcd1 100644 --- a/src/osgWrappers/serializers/osgAnimation/RigTransform.cpp +++ b/src/osgWrappers/serializers/osgAnimation/RigTransform.cpp @@ -24,8 +24,11 @@ namespace wrap_osgAnimationRigTransformHardWare{ new osgAnimation::RigTransformHardware, osgAnimation::RigTransformHardware, "osg::Object osgAnimation::RigTransform osgAnimation::RigTransformHardware" ){ - ADD_OBJECT_SERIALIZER(Shader,osg::Shader,NULL); - ADD_UINT_SERIALIZER(FirstVertexAttributeTarget,RIGTRANSHW_DEFAULT_FIRST_VERTATTRIB_TARGETTED); + { + UPDATE_TO_VERSION_SCOPED(150) + ADD_OBJECT_SERIALIZER(Shader, osg::Shader, NULL); + ADD_UINT_SERIALIZER(FirstVertexAttributeTarget, RIGTRANSHW_DEFAULT_FIRST_VERTATTRIB_TARGETTED); + } } } @@ -46,7 +49,10 @@ namespace wrap_osgAnimationMorphTransformHardware{ new osgAnimation::MorphTransformHardware, osgAnimation::MorphTransformHardware, "osg::Object osgAnimation::MorphTransform osgAnimation::MorphTransformHardware" ){ - ADD_OBJECT_SERIALIZER(Shader,osg::Shader,NULL); - ADD_UINT_SERIALIZER(ReservedTextureUnit,MORPHTRANSHW_DEFAULTMORPHTEXTUREUNIT); + { + UPDATE_TO_VERSION_SCOPED(150) + ADD_OBJECT_SERIALIZER(Shader, osg::Shader, NULL); + ADD_UINT_SERIALIZER(ReservedTextureUnit, MORPHTRANSHW_DEFAULTMORPHTEXTUREUNIT); + } } }