From e2168332864742cf4455c34e6f9efaadf4aadb85 Mon Sep 17 00:00:00 2001 From: Julien Valentin Date: Mon, 28 Aug 2017 14:23:15 +0200 Subject: [PATCH] few refactoring --- include/osgAnimation/MorphTransformSoftware | 1 + include/osgAnimation/RigTransformSoftware | 53 +++++++++++-------- include/osgAnimation/VertexInfluence | 25 +++++++-- src/osgAnimation/RigTransformSoftware.cpp | 42 ++++++++++++++- src/osgAnimation/VertexInfluence.cpp | 4 +- .../serializers/osgAnimation/RigGeometry.cpp | 2 +- 6 files changed, 97 insertions(+), 30 deletions(-) diff --git a/include/osgAnimation/MorphTransformSoftware b/include/osgAnimation/MorphTransformSoftware index 8ac451b38..1130cdedc 100644 --- a/include/osgAnimation/MorphTransformSoftware +++ b/include/osgAnimation/MorphTransformSoftware @@ -36,6 +36,7 @@ namespace osgAnimation bool init(MorphGeometry&); virtual void operator()(MorphGeometry&); + protected: bool _needInit; diff --git a/include/osgAnimation/RigTransformSoftware b/include/osgAnimation/RigTransformSoftware index 8492a215d..677f5e619 100644 --- a/include/osgAnimation/RigTransformSoftware +++ b/include/osgAnimation/RigTransformSoftware @@ -37,35 +37,43 @@ namespace osgAnimation virtual void operator()(RigGeometry&); - class BonePtrWeight + class BonePtrWeight: public BoneWeight { public: - BonePtrWeight(Bone* bone, float weight) : _bone(bone), _weight(weight) {} - const Bone* getBone() const { return _bone.get(); } - float getWeight() const { return _weight; } - void setWeight(float w) { _weight = w; } + BonePtrWeight(const std::string& name, float weight, Bone *bptr=0) :BoneWeight(name,weight), _boneptr(bptr) {} + BonePtrWeight(const BonePtrWeight &bw2) : BoneWeight(bw2), _boneptr(bw2._boneptr) {} + + const Bone * getBonePtr()const{return _boneptr.get();} + void setBonePtr(Bone*b){_boneptr=b;} + + bool operator==(const BonePtrWeight& b) const { return (getBoneName() == b.getBoneName() && getWeight() == b.getWeight()); } + //default order : sort by weight desc and bonename if equal + /*bool operator<(const BoneWeight& bw2)const{ if (_weight > bw2._weight)return true; + if (_weight < bw2._weight)return false; + return(_boneName _bone; - float _weight; + osg::observer_ptr< Bone > _boneptr; }; + typedef std::vector BonePtrWeightList; + typedef std::vector IndexList; - typedef std::vector BonePtrWeightList; - typedef std::vector VertexList; - + /// map a set of boneinfluence to a list of vertex indices sharing this set class VertexGroup { public: - BonePtrWeightList& getBoneWeights() { return _boneweights; } - VertexList& getVertexes() { return _vertexes; } + inline BonePtrWeightList& getBoneWeights() { return _boneweights; } - void resetMatrix() + inline IndexList& getVertexes() { return _vertexes; } + + inline void resetMatrix() { _result.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1); } - void accummulateMatrix(const osg::Matrix& invBindMatrix, const osg::Matrix& matrix, osg::Matrix::value_type weight) + inline void accummulateMatrix(const osg::Matrix& invBindMatrix, const osg::Matrix& matrix, osg::Matrix::value_type weight) { osg::Matrix m = invBindMatrix * matrix; osg::Matrix::value_type* ptr = m.ptr(); @@ -86,7 +94,7 @@ namespace osgAnimation ptrresult[13] += ptr[13] * weight; ptrresult[14] += ptr[14] * weight; } - void computeMatrixForVertexSet() + inline void computeMatrixForVertexSet() { if (_boneweights.empty()) { @@ -98,7 +106,7 @@ namespace osgAnimation for(BonePtrWeightList::iterator bwit=_boneweights.begin();bwit!=_boneweights.end();++bwit ) { - const Bone* bone = bwit->getBone(); + const Bone* bone = bwit->getBonePtr(); if (!bone) { osg::notify(osg::WARN) << this << " RigTransformSoftware::computeMatrixForVertexSet Warning a bone is null, skip it" << std::endl; @@ -110,10 +118,10 @@ namespace osgAnimation accummulateMatrix(invBindMatrix, matrix, w); } } - const osg::Matrix& getMatrix() const { return _result;} + inline const osg::Matrix& getMatrix() const { return _result;} protected: BonePtrWeightList _boneweights; - VertexList _vertexes; + IndexList _vertexes; osg::Matrix _result; }; @@ -128,8 +136,8 @@ namespace osgAnimation uniq.computeMatrixForVertexSet(); osg::Matrix matrix = transform * uniq.getMatrix() * invTransform; - const VertexList& vertexes = uniq.getVertexes(); - for(VertexList::const_iterator vertIDit=vertexes.begin(); vertIDit!=vertexes.end(); ++vertIDit) + const IndexList& vertexes = uniq.getVertexes(); + for(IndexList::const_iterator vertIDit=vertexes.begin(); vertIDit!=vertexes.end(); ++vertIDit) { dst[*vertIDit] = src[*vertIDit] * matrix; } @@ -146,8 +154,8 @@ namespace osgAnimation uniq.computeMatrixForVertexSet(); osg::Matrix matrix = transform * uniq.getMatrix() * invTransform; - const VertexList& vertexes = uniq.getVertexes(); - for(VertexList::const_iterator vertIDit=vertexes.begin(); vertIDit!=vertexes.end(); ++vertIDit) + const IndexList& vertexes = uniq.getVertexes(); + for(IndexList::const_iterator vertIDit=vertexes.begin(); vertIDit!=vertexes.end(); ++vertIDit) { dst[*vertIDit] = osg::Matrix::transform3x3(src[*vertIDit],matrix); } @@ -163,6 +171,7 @@ namespace osgAnimation bool _needInit; std::map _invalidInfluence; + }; } diff --git a/include/osgAnimation/VertexInfluence b/include/osgAnimation/VertexInfluence index 0b777e283..4b2adb347 100644 --- a/include/osgAnimation/VertexInfluence +++ b/include/osgAnimation/VertexInfluence @@ -23,15 +23,32 @@ namespace osgAnimation { + // first is bonename, and second the weight + struct BoneWeight: public std::pair + { + BoneWeight( std::string f,float s): + std::pair(f,s){} + inline const std::string& getBoneName()const{return first;} + inline void setBoneName(const std::string&s){first=s;} + inline const float &getWeight()const{return second;} + inline void setWeight(float i){second=i;} + }; + // first is vertex index, and second the weight + struct IndexWeight: public std::pair + { + IndexWeight( unsigned int f,float s): std::pair(f,s){} + inline const unsigned int& getIndex()const{return first;} + inline void setIndex(unsigned int i){first=i;} + inline const float &getWeight()const{return second;} + inline void setWeight(float i){second=i;} + }; - // first is vertex index, and second the weight, the - typedef std::pair IndexWeight; typedef std::vector VertexList; class OSGANIMATION_EXPORT BoneInfluenceList : public VertexList { public: - const std::string& getName() const { return _name;} - void setName(const std::string& name) { _name = name;} + const std::string& getBoneName() const { return _name;} + void setBoneName(const std::string& name) { _name = name;} protected: // the name is the bone to link to diff --git a/src/osgAnimation/RigTransformSoftware.cpp b/src/osgAnimation/RigTransformSoftware.cpp index 4ab524cdb..455fddb2b 100644 --- a/src/osgAnimation/RigTransformSoftware.cpp +++ b/src/osgAnimation/RigTransformSoftware.cpp @@ -34,6 +34,46 @@ RigTransformSoftware::RigTransformSoftware(const RigTransformSoftware& rts,const } +typedef std::vector BoneWeightList; +// sort by name and weight +struct SortByNameAndWeight : public std::less +{ + bool operator()(const RigTransformSoftware::BonePtrWeight& b0, + const RigTransformSoftware::BonePtrWeight& b1) const + { + if (b0.getBoneName() < b1.getBoneName()) + return true; + else if (b0.getBoneName() > b1.getBoneName()) + return false; + if (b0.getWeight() < b1.getWeight()) + return true; + return false; + } +}; + +struct SortByBoneWeightList : public std::less +{ + bool operator()(const BoneWeightList& b0, + const BoneWeightList& b1) const + { + if (b0.size() < b1.size()) + return true; + else if (b0.size() > b1.size()) + return false; + + int size = b0.size(); + for (int i = 0; i < size; i++) + { + bool result = SortByNameAndWeight()(b0[i], b1[i]); + if (result) + return true; + else if (SortByNameAndWeight()(b1[i], b0[i])) + return false; + } + return false; + } +}; + bool RigTransformSoftware::init(RigGeometry& geom) { if (!geom.getSkeleton()) @@ -142,7 +182,7 @@ void RigTransformSoftware::initVertexSetFromBones(const BoneMap& map, const Vert continue; } Bone* bone = it->second.get(); - boneList.push_back(BonePtrWeight(bone, weight)); + boneList.push_back(BonePtrWeight(bone->getName(), weight, bone)); sumOfWeight += weight; } // if a bone referenced by a vertexinfluence is missed it can make the sum less than 1.0 diff --git a/src/osgAnimation/VertexInfluence.cpp b/src/osgAnimation/VertexInfluence.cpp index b1b10fa26..bcb626190 100644 --- a/src/osgAnimation/VertexInfluence.cpp +++ b/src/osgAnimation/VertexInfluence.cpp @@ -40,10 +40,10 @@ void VertexInfluenceSet::buildVertex2BoneList(unsigned int numvertices) IndexWeight viw = vi[i]; int index = viw.first; float weight = viw.second; - if (vi.getName().empty()){ + if (vi.getBoneName().empty()){ OSG_WARN << "VertexInfluenceSet::buildVertex2BoneList warning vertex " << index << " is not assigned to a bone" << std::endl; } - _vertex2Bones[index].push_back(BoneWeight(vi.getName(), weight)); + _vertex2Bones[index].push_back(BoneWeight(vi.getBoneName(), weight)); } } diff --git a/src/osgWrappers/serializers/osgAnimation/RigGeometry.cpp b/src/osgWrappers/serializers/osgAnimation/RigGeometry.cpp index 5259d1e95..0d88de08d 100644 --- a/src/osgWrappers/serializers/osgAnimation/RigGeometry.cpp +++ b/src/osgWrappers/serializers/osgAnimation/RigGeometry.cpp @@ -21,7 +21,7 @@ static bool readInfluenceMap( osgDB::InputStream& is, osgAnimation::RigGeometry& viSize = is.readSize(); is >> is.BEGIN_BRACKET; osgAnimation::BoneInfluenceList vi; - vi.setName( name ); + vi.setBoneName( name ); vi.reserve( viSize ); for ( unsigned int j=0; j