From 32aaeccee1e1b50928dc1d9afaf8457262e12333 Mon Sep 17 00:00:00 2001 From: Julien Valentin Date: Sat, 26 Aug 2017 20:37:10 +0200 Subject: [PATCH 001/327] refactoring and fixes only change in design: decouplage between MorphGeometry and MorphTransform technique no real change in behavior (i hope) --- include/osgAnimation/AnimationManagerBase | 10 + include/osgAnimation/MorphGeometry | 58 ++++-- include/osgAnimation/MorphTransformSoftware | 45 +++++ include/osgAnimation/RigGeometry | 28 +-- include/osgAnimation/RigTransform | 17 ++ include/osgAnimation/RigTransformHardware | 37 ++-- include/osgAnimation/RigTransformSoftware | 52 +++-- include/osgAnimation/VertexInfluence | 33 ++-- src/osgAnimation/AnimationManagerBase.cpp | 5 +- src/osgAnimation/CMakeLists.txt | 2 + src/osgAnimation/MorphGeometry.cpp | 151 +------------- src/osgAnimation/MorphTransformSoftware.cpp | 182 +++++++++++++++++ src/osgAnimation/RigGeometry.cpp | 57 +++--- src/osgAnimation/RigTransformHardware.cpp | 205 ++++++++++++-------- src/osgAnimation/RigTransformSoftware.cpp | 150 ++++++++------ src/osgAnimation/VertexInfluence.cpp | 33 ++-- 16 files changed, 643 insertions(+), 422 deletions(-) create mode 100644 include/osgAnimation/MorphTransformSoftware create mode 100644 src/osgAnimation/MorphTransformSoftware.cpp diff --git a/include/osgAnimation/AnimationManagerBase b/include/osgAnimation/AnimationManagerBase index bdc0c5c89..15b4617ab 100644 --- a/include/osgAnimation/AnimationManagerBase +++ b/include/osgAnimation/AnimationManagerBase @@ -42,6 +42,16 @@ namespace osgAnimation const AnimationList& getAnimationList() const { return _animations;} AnimationList& getAnimationList() { return _animations;} + //uniformisation of the API + inline Animation * getRegisteredAnimation(unsigned int i){return _animations[i].get();} + inline unsigned int getNumRegisteredAnimations()const{return _animations.size();} + inline void addRegisteredAnimation(Animation* animation){ + _needToLink = true; + _animations.push_back(animation); + buildTargetReference(); + } + void removeRegisteredAnimation(Animation* animation); + /** Callback method called by the NodeVisitor when visiting a node.*/ virtual void operator()(osg::Node* node, osg::NodeVisitor* nv); diff --git a/include/osgAnimation/MorphGeometry b/include/osgAnimation/MorphGeometry index 1a242efd7..e8c89d22d 100644 --- a/include/osgAnimation/MorphGeometry +++ b/include/osgAnimation/MorphGeometry @@ -17,6 +17,7 @@ #include #include +#include #include #include @@ -59,7 +60,10 @@ namespace osgAnimation virtual const char* libraryName() const { return "osgAnimation"; } virtual const char* className() const { return "MorphGeometry"; } - virtual void transformSoftwareMethod(); + // set implementation of rig method + void setMorphTransformImplementation(MorphTransform*); + MorphTransform* getMorphTransformImplementation(); + const MorphTransform* getMorphTransformImplementation() const { return _rigTransformImplementation.get(); } /** Set the morphing method. */ void setMethod(Method method) { _method = method; } @@ -71,6 +75,30 @@ namespace osgAnimation /** Get the flag for morphing normals. */ inline bool getMorphNormals() const { return _morphNormals; } + /** Get the list of MorphTargets.*/ + const MorphTargetList& getMorphTargetList() const { return _morphTargets; } + + /** Get the list of MorphTargets. Warning if you modify this array you will have to call dirty() */ + MorphTargetList& getMorphTargetList() { return _morphTargets; } + + /** Return the \c MorphTarget at position \c i.*/ + inline const MorphTarget& getMorphTarget( unsigned int i ) const { return _morphTargets[i]; } + + /** Return the \c MorphTarget at position \c i.*/ + inline MorphTarget& getMorphTarget( unsigned int i ) { return _morphTargets[i]; } + + /** Set source of vertices for this morph geometry */ + inline void setVertexSource(osg::Vec3Array *v){ _positionSource=v;} + + /** Get source of vertices for this morph geometry */ + inline osg::Vec3Array * getVertexSource()const{return _positionSource;} + + /** Set source of normals for this morph geometry */ + inline void setNormalSource(osg::Vec3Array *n){ _normalSource=n;} + + /** Get source of normals for this morph geometry */ + inline osg::Vec3Array * getNormalSource()const{return _normalSource;} + /** Add a \c MorphTarget to the \c MorphGeometry. * If \c MorphTarget is not \c NULL and is not contained in the \c MorphGeometry * then increment its reference count, add it to the MorphTargets list and @@ -101,6 +129,7 @@ namespace osgAnimation } + /** update a morph target at index setting its current weight to morphWeight */ void setWeight(unsigned int index, float morphWeight) { if (index < _morphTargets.size()) @@ -111,29 +140,20 @@ namespace osgAnimation } /** Set the MorphGeometry dirty.*/ - void dirty() { _dirty = true; } + inline void dirty(bool b=true) { _dirty = b; } + inline bool isDirty()const { return _dirty; } - /** Get the list of MorphTargets.*/ - const MorphTargetList& getMorphTargetList() const { return _morphTargets; } - - /** Get the list of MorphTargets. Warning if you modify this array you will have to call dirty() */ - MorphTargetList& getMorphTargetList() { return _morphTargets; } - - /** Return the \c MorphTarget at position \c i.*/ - inline const MorphTarget& getMorphTarget( unsigned int i ) const { return _morphTargets[i]; } - - /** Return the \c MorphTarget at position \c i.*/ - inline MorphTarget& getMorphTarget( unsigned int i ) { return _morphTargets[i]; } protected: + osg::ref_ptr _rigTransformImplementation; /// Do we need to recalculate the morphed geometry? bool _dirty; Method _method; MorphTargetList _morphTargets; - std::vector _positionSource; - std::vector _normalSource; + osg::ref_ptr _positionSource; + osg::ref_ptr _normalSource; /// Do we also morph between normals? bool _morphNormals; @@ -195,7 +215,13 @@ namespace osgAnimation if (!geom) return; - geom->transformSoftwareMethod(); + if (!geom->getMorphTransformImplementation()) + { + geom->setMorphTransformImplementation( new MorphTransformSoftware); + } + + MorphTransform& implementation = *geom->getMorphTransformImplementation(); + (implementation)(*geom); } }; diff --git a/include/osgAnimation/MorphTransformSoftware b/include/osgAnimation/MorphTransformSoftware new file mode 100644 index 000000000..8ac451b38 --- /dev/null +++ b/include/osgAnimation/MorphTransformSoftware @@ -0,0 +1,45 @@ +/* -*-c++-*- + * Copyright (C) 2009 Cedric Pinson + * + * This library is open source and may be redistributed and/or modified under + * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or + * (at your option) any later version. The full license is in LICENSE file + * included with this distribution, and on the openscenegraph.org website. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * OpenSceneGraph Public License for more details. + */ + +#ifndef OSGANIMATION_MORPHTRANSFORM_SOFTWARE +#define OSGANIMATION_MORPHTRANSFORM_SOFTWARE 1 + +#include +#include +#include +#include + +namespace osgAnimation +{ + + class MorphGeometry; + + /// This class manage format for software morphing + class OSGANIMATION_EXPORT MorphTransformSoftware : public MorphTransform + { + public: + MorphTransformSoftware():_needInit(true){} + MorphTransformSoftware(const MorphTransformSoftware& rts,const osg::CopyOp& copyop): MorphTransform(rts, copyop), _needInit(true){} + + META_Object(osgAnimation,MorphTransformSoftware) + + bool init(MorphGeometry&); + virtual void operator()(MorphGeometry&); + protected: + bool _needInit; + + }; +} + +#endif diff --git a/include/osgAnimation/RigGeometry b/include/osgAnimation/RigGeometry index 74a5cf00f..31cda0179 100644 --- a/include/osgAnimation/RigGeometry +++ b/include/osgAnimation/RigGeometry @@ -57,14 +57,14 @@ namespace osgAnimation META_Object(osgAnimation, RigGeometry); - void setInfluenceMap(VertexInfluenceMap* vertexInfluenceMap) { _vertexInfluenceMap = vertexInfluenceMap; } - const VertexInfluenceMap* getInfluenceMap() const { return _vertexInfluenceMap.get();} - VertexInfluenceMap* getInfluenceMap() { return _vertexInfluenceMap.get();} + inline void setInfluenceMap(VertexInfluenceMap* vertexInfluenceMap) { _vertexInfluenceMap = vertexInfluenceMap; } + inline const VertexInfluenceMap* getInfluenceMap() const { return _vertexInfluenceMap.get();} + inline VertexInfluenceMap* getInfluenceMap() { return _vertexInfluenceMap.get();} - const Skeleton* getSkeleton() const; - Skeleton* getSkeleton(); + inline const Skeleton* getSkeleton() const { return _root.get(); } + inline Skeleton* getSkeleton() { return _root.get(); } // will be used by the update callback to init correctly the rig mesh - void setSkeleton(Skeleton*); + inline void setSkeleton(Skeleton* root){ _root = root;} void setNeedToComputeMatrix(bool state) { _needToComputeMatrix = state;} bool getNeedToComputeMatrix() const { return _needToComputeMatrix;} @@ -72,25 +72,25 @@ namespace osgAnimation // this build the internal database about vertex influence and bones void buildVertexInfluenceSet(); - const VertexInfluenceSet& getVertexInfluenceSet() const; + inline const VertexInfluenceSet& getVertexInfluenceSet() const { return _vertexInfluenceSet;} void computeMatrixFromRootSkeleton(); // set implementation of rig method - void setRigTransformImplementation(RigTransform*); - RigTransform* getRigTransformImplementation(); - const RigTransform* getRigTransformImplementation() const { return _rigTransformImplementation.get(); } + inline RigTransform* getRigTransformImplementation() { return _rigTransformImplementation.get(); } + inline void setRigTransformImplementation(RigTransform* rig) { _rigTransformImplementation = rig; } + inline const RigTransform* getRigTransformImplementation() const { return _rigTransformImplementation.get(); } - virtual void drawImplementation(osg::RenderInfo& renderInfo) const; void update(); const osg::Matrix& getMatrixFromSkeletonToGeometry() const; const osg::Matrix& getInvMatrixFromSkeletonToGeometry() const; - osg::Geometry* getSourceGeometry(); - const osg::Geometry* getSourceGeometry() const; - void setSourceGeometry(osg::Geometry* geometry); + + inline osg::Geometry* getSourceGeometry() { return _geometry.get(); } + inline const osg::Geometry* getSourceGeometry() const { return _geometry.get(); } + inline void setSourceGeometry(osg::Geometry* geometry) { _geometry = geometry; } void copyFrom(osg::Geometry& from); diff --git a/include/osgAnimation/RigTransform b/include/osgAnimation/RigTransform index 66ae0a219..184cdae0c 100644 --- a/include/osgAnimation/RigTransform +++ b/include/osgAnimation/RigTransform @@ -37,6 +37,23 @@ namespace osgAnimation virtual ~RigTransform() {} }; + class MorphGeometry; + + class MorphTransform : public osg::Object + { + public: + MorphTransform() {} + MorphTransform(const MorphTransform& org, const osg::CopyOp& copyop): + osg::Object(org, copyop) {} + + META_Object(osgAnimation,MorphTransform) + + virtual void operator()(MorphGeometry&) {} + + protected: + virtual ~MorphTransform() {} + + }; } diff --git a/include/osgAnimation/RigTransformHardware b/include/osgAnimation/RigTransformHardware index ce9006ddd..28330e87e 100644 --- a/include/osgAnimation/RigTransformHardware +++ b/include/osgAnimation/RigTransformHardware @@ -38,37 +38,36 @@ namespace osgAnimation META_Object(osgAnimation,RigTransformHardware); typedef osg::Matrix MatrixType; - typedef osgAnimation::Bone BoneType; typedef std::vector > BoneWeightAttribList; - typedef std::vector > BonePalette; - typedef std::map BoneNamePaletteIndex; + typedef std::vector > BonePalette; + typedef std::map BoneNamePaletteIndex; typedef std::vector MatrixPalette; struct IndexWeightEntry { - int _boneIndex; + IndexWeightEntry(unsigned int index=0, float weight=0.0f): _boneIndex(index), _boneWeight(weight){} + IndexWeightEntry(const IndexWeightEntry&o): _boneIndex(o._boneIndex), _boneWeight(o._boneWeight){} + bool operator <(const IndexWeightEntry &o)const{return (_boneIndex > VertexIndexWeightList; - - osg::Vec4Array* getVertexAttrib(int index); - int getNumVertexAttrib(); + osg::Vec4Array* getVertexAttrib(unsigned int index); + unsigned int getNumVertexAttrib(); osg::Uniform* getMatrixPaletteUniform(); void computeMatrixPaletteUniform(const osg::Matrix& transformFromSkeletonToGeometry, const osg::Matrix& invTransformFromSkeletonToGeometry); - int getNumBonesPerVertex() const; - int getNumVertexes() const; + unsigned int getNumBonesPerVertex() const; + unsigned int getNumVertexes() const; - bool createPalette(int nbVertexes, BoneMap boneMap, const VertexInfluenceSet::VertexIndexToBoneWeightMap& vertexIndexToBoneWeightMap); + bool createPalette(unsigned int nbVertexes,const BoneMap& boneMap, const VertexInfluenceSet::VertIDToBoneWeightList& vertexIndexToBoneWeightMap); virtual void operator()(RigGeometry&); + void setShader(osg::Shader*); const BoneNamePaletteIndex& getBoneNameToPalette() { @@ -78,13 +77,11 @@ namespace osgAnimation protected: bool init(RigGeometry&); + osg::Uniform* createVertexUniform(); - BoneWeightAttribList createVertexAttribList(); - osg::Uniform* createVertexUniform(); + unsigned int _bonesPerVertex; + unsigned int _nbVertexes; - int _bonesPerVertex; - int _nbVertexes; - VertexIndexWeightList _vertexIndexMatrixWeightList; BonePalette _bonePalette; BoneNamePaletteIndex _boneNameToPalette; BoneWeightAttribList _boneWeightAttribArrays; diff --git a/include/osgAnimation/RigTransformSoftware b/include/osgAnimation/RigTransformSoftware index 300e513fd..8492a215d 100644 --- a/include/osgAnimation/RigTransformSoftware +++ b/include/osgAnimation/RigTransformSoftware @@ -37,10 +37,10 @@ namespace osgAnimation virtual void operator()(RigGeometry&); - class BoneWeight + class BonePtrWeight { public: - BoneWeight(Bone* bone, float weight) : _bone(bone), _weight(weight) {} + 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; } @@ -49,13 +49,13 @@ namespace osgAnimation float _weight; }; - typedef std::vector BoneWeightList; - typedef std::vector VertexList; + typedef std::vector BonePtrWeightList; + typedef std::vector VertexList; - class UniqBoneSetVertexSet + class VertexGroup { public: - BoneWeightList& getBones() { return _bones; } + BonePtrWeightList& getBoneWeights() { return _boneweights; } VertexList& getVertexes() { return _vertexes; } void resetMatrix() @@ -88,18 +88,17 @@ namespace osgAnimation } void computeMatrixForVertexSet() { - if (_bones.empty()) + if (_boneweights.empty()) { - osg::notify(osg::WARN) << this << " RigTransformSoftware::UniqBoneSetVertexSet no bones found" << std::endl; + osg::notify(osg::WARN) << this << " RigTransformSoftware::VertexGroup no bones found" << std::endl; _result = osg::Matrix::identity(); return; } resetMatrix(); - int size = _bones.size(); - for (int i = 0; i < size; i++) + for(BonePtrWeightList::iterator bwit=_boneweights.begin();bwit!=_boneweights.end();++bwit ) { - const Bone* bone = _bones[i].getBone(); + const Bone* bone = bwit->getBone(); if (!bone) { osg::notify(osg::WARN) << this << " RigTransformSoftware::computeMatrixForVertexSet Warning a bone is null, skip it" << std::endl; @@ -107,13 +106,13 @@ namespace osgAnimation } const osg::Matrix& invBindMatrix = bone->getInvBindMatrixInSkeletonSpace(); const osg::Matrix& matrix = bone->getMatrixInSkeletonSpace(); - osg::Matrix::value_type w = _bones[i].getWeight(); + osg::Matrix::value_type w = bwit->getWeight(); accummulateMatrix(invBindMatrix, matrix, w); } } const osg::Matrix& getMatrix() const { return _result;} protected: - BoneWeightList _bones; + BonePtrWeightList _boneweights; VertexList _vertexes; osg::Matrix _result; }; @@ -123,39 +122,34 @@ namespace osgAnimation template 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 - int size = _boneSetVertexSet.size(); - for (int i = 0; i < size; i++) + for(std::vector::iterator itvg=_uniqInfluenceSet2VertIDList.begin(); itvg!=_uniqInfluenceSet2VertIDList.end(); ++itvg) { - UniqBoneSetVertexSet& uniq = _boneSetVertexSet[i]; + VertexGroup& uniq = *itvg; uniq.computeMatrixForVertexSet(); osg::Matrix matrix = transform * uniq.getMatrix() * invTransform; const VertexList& vertexes = uniq.getVertexes(); - int vertexSize = vertexes.size(); - for (int j = 0; j < vertexSize; j++) + for(VertexList::const_iterator vertIDit=vertexes.begin(); vertIDit!=vertexes.end(); ++vertIDit) { - int idx = vertexes[j]; - dst[idx] = src[idx] * matrix; + dst[*vertIDit] = src[*vertIDit] * matrix; } + } } template void computeNormal(const osg::Matrix& transform, const osg::Matrix& invTransform, const V* src, V* dst) { - int size = _boneSetVertexSet.size(); - for (int i = 0; i < size; i++) + for(std::vector::iterator itvg=_uniqInfluenceSet2VertIDList.begin(); itvg!=_uniqInfluenceSet2VertIDList.end(); ++itvg) { - UniqBoneSetVertexSet& uniq = _boneSetVertexSet[i]; + VertexGroup& uniq = *itvg; uniq.computeMatrixForVertexSet(); osg::Matrix matrix = transform * uniq.getMatrix() * invTransform; const VertexList& vertexes = uniq.getVertexes(); - int vertexSize = vertexes.size(); - for (int j = 0; j < vertexSize; j++) + for(VertexList::const_iterator vertIDit=vertexes.begin(); vertIDit!=vertexes.end(); ++vertIDit) { - int idx = vertexes[j]; - dst[idx] = osg::Matrix::transform3x3(src[idx],matrix); + dst[*vertIDit] = osg::Matrix::transform3x3(src[*vertIDit],matrix); } } } @@ -163,8 +157,8 @@ namespace osgAnimation protected: bool init(RigGeometry&); - void initVertexSetFromBones(const BoneMap& map, const VertexInfluenceSet::UniqVertexSetToBoneSetList& influence); - std::vector _boneSetVertexSet; + void initVertexSetFromBones(const BoneMap& map, const VertexInfluenceSet::UniqVertexGroupList& influence); + std::vector _uniqInfluenceSet2VertIDList; bool _needInit; diff --git a/include/osgAnimation/VertexInfluence b/include/osgAnimation/VertexInfluence index 47941a43f..345b25db4 100644 --- a/include/osgAnimation/VertexInfluence +++ b/include/osgAnimation/VertexInfluence @@ -25,7 +25,7 @@ namespace osgAnimation { // first is vertex index, and second the weight, the - typedef std::pair VertexIndexWeight; + typedef std::pair VertexIndexWeight; typedef std::vector VertexList; class OSGANIMATION_EXPORT VertexInfluence : public VertexList { @@ -62,43 +62,48 @@ namespace osgAnimation { public: BoneWeight(const std::string& name, float weight) : _boneName(name), _weight(weight) {} + BoneWeight(const BoneWeight &bw2) : _boneName(bw2._boneName), _weight(bw2._weight) {} const std::string& getBoneName() const { return _boneName; } float getWeight() const { return _weight; } void setWeight(float weight) { _weight = weight; } bool operator==(const BoneWeight& b) const { return (_boneName == b.getBoneName() && _weight == b.getWeight()); } + protected: std::string _boneName; float _weight; }; typedef std::vector BoneWeightList; - typedef std::map VertexIndexToBoneWeightMap; + typedef std::vector VertIDToBoneWeightList; - class UniqVertexSetToBoneSet + class VertexGroup { public: + // set Influences of the VertexGroup void setBones(BoneWeightList& bones) { _bones = bones;} const BoneWeightList& getBones() const { return _bones;} - std::vector& getVertexes() { return _vertexes;} - const std::vector& getVertexes() const { return _vertexes;} + // set Vertex Indices of the VertexGroup + std::vector& getVertexes() { return _vertexes;} + const std::vector& getVertexes() const { return _vertexes;} protected: - std::vector _vertexes; + std::vector _vertexes; BoneWeightList _bones; // here we could limit matrix operation by caching (weight * matrix) }; - typedef std::vector UniqVertexSetToBoneSetList; - - const UniqVertexSetToBoneSetList& getUniqVertexSetToBoneSetList() const { return _uniqVertexSetToBoneSet;} + typedef std::vector UniqVertexGroupList; + /** construct a vector of unique VertexGroups and their influences**/ + void buildUniqVertexGroupList(); + /** return a list of unique VertexGroups and their influences**/ + const UniqVertexGroupList& getUniqVertexGroupList() const { return _uniqVertexSetToBoneSet;} void addVertexInfluence(const VertexInfluence& v); - void buildVertex2BoneList(); - void buildUniqVertexSetToBoneSetList(); + void buildVertex2BoneList(unsigned int numvertices); void clear(); - const VertexIndexToBoneWeightMap& getVertexToBoneList() const; + const VertIDToBoneWeightList& getVertexToBoneList() const; protected: BoneToVertexList _bone2Vertexes; - VertexIndexToBoneWeightMap _vertex2Bones; - UniqVertexSetToBoneSetList _uniqVertexSetToBoneSet; + VertIDToBoneWeightList _vertex2Bones; + UniqVertexGroupList _uniqVertexSetToBoneSet; }; } diff --git a/src/osgAnimation/AnimationManagerBase.cpp b/src/osgAnimation/AnimationManagerBase.cpp index 1c47851a7..d5a95b421 100644 --- a/src/osgAnimation/AnimationManagerBase.cpp +++ b/src/osgAnimation/AnimationManagerBase.cpp @@ -101,7 +101,10 @@ void AnimationManagerBase::registerAnimation (Animation* animation) buildTargetReference(); } -void AnimationManagerBase::unregisterAnimation (Animation* animation) +void AnimationManagerBase::removeRegisteredAnimation(Animation* animation){ + unregisterAnimation(animation); +} +void AnimationManagerBase::unregisterAnimation(Animation* animation) { AnimationList::iterator it = std::find(_animations.begin(), _animations.end(), animation); if (it != _animations.end()) diff --git a/src/osgAnimation/CMakeLists.txt b/src/osgAnimation/CMakeLists.txt index b0e920544..dc199ef9c 100644 --- a/src/osgAnimation/CMakeLists.txt +++ b/src/osgAnimation/CMakeLists.txt @@ -34,6 +34,7 @@ SET(TARGET_H ${HEADER_PATH}/RigTransform ${HEADER_PATH}/RigTransformHardware ${HEADER_PATH}/RigTransformSoftware + ${HEADER_PATH}/MorphTransformSoftware ${HEADER_PATH}/Sampler ${HEADER_PATH}/Skeleton ${HEADER_PATH}/StackedMatrixElement @@ -75,6 +76,7 @@ SET(TARGET_SRC RigGeometry.cpp RigTransformHardware.cpp RigTransformSoftware.cpp + MorphTransformSoftware.cpp Skeleton.cpp StackedMatrixElement.cpp StackedQuaternionElement.cpp diff --git a/src/osgAnimation/MorphGeometry.cpp b/src/osgAnimation/MorphGeometry.cpp index 9735c06f9..f52c04c3a 100644 --- a/src/osgAnimation/MorphGeometry.cpp +++ b/src/osgAnimation/MorphGeometry.cpp @@ -23,23 +23,23 @@ using namespace osgAnimation; MorphGeometry::MorphGeometry() : _dirty(false), _method(NORMALIZED), + _positionSource(0),_normalSource(0), _morphNormals(true) { setUseDisplayList(false); setUpdateCallback(new UpdateMorphGeometry); - setDataVariance(osg::Object::DYNAMIC); setUseVertexBufferObjects(true); } -MorphGeometry::MorphGeometry(const osg::Geometry& b) : - osg::Geometry(b, osg::CopyOp::DEEP_COPY_ARRAYS), +MorphGeometry::MorphGeometry(const osg::Geometry& g) : + osg::Geometry(g, osg::CopyOp::DEEP_COPY_ARRAYS), _dirty(false), _method(NORMALIZED), + _positionSource(0),_normalSource(0), _morphNormals(true) { setUseDisplayList(false); setUpdateCallback(new UpdateMorphGeometry); - setDataVariance(osg::Object::DYNAMIC); setUseVertexBufferObjects(true); } @@ -56,151 +56,14 @@ MorphGeometry::MorphGeometry(const MorphGeometry& b, const osg::CopyOp& copyop) setUseVertexBufferObjects(true); } - -void MorphGeometry::transformSoftwareMethod() -{ - if (_dirty) - { - // See if we have an internal optimized geometry - osg::Geometry* morphGeometry = this; - - osg::Vec3Array* pos = dynamic_cast(morphGeometry->getVertexArray()); - - if(pos) - { - if ( _positionSource.size() != pos->size()) - { - _positionSource = std::vector(pos->begin(),pos->end()); - pos->setDataVariance(osg::Object::DYNAMIC); - } - - osg::Vec3Array* normal = dynamic_cast(morphGeometry->getNormalArray()); - bool normalmorphable = _morphNormals && normal; - if (normal && _normalSource.size() != normal->size()) - { - _normalSource = std::vector(normal->begin(),normal->end()); - normal->setDataVariance(osg::Object::DYNAMIC); - } - - - if (!_positionSource.empty()) - { - bool initialized = false; - if (_method == NORMALIZED) - { - // base * 1 - (sum of weights) + sum of (weight * target) - float baseWeight = 0; - for (unsigned int i=0; i < _morphTargets.size(); i++) - { - baseWeight += _morphTargets[i].getWeight(); - } - baseWeight = 1 - baseWeight; - - if (baseWeight != 0) - { - initialized = true; - for (unsigned int i=0; i < pos->size(); i++) - { - (*pos)[i] = _positionSource[i] * baseWeight; - } - if (normalmorphable) - { - for (unsigned int i=0; i < normal->size(); i++) - { - (*normal)[i] = _normalSource[i] * baseWeight; - } - } - } - } - else //if (_method == RELATIVE) - { - // base + sum of (weight * target) - initialized = true; - for (unsigned int i=0; i < pos->size(); i++) - { - (*pos)[i] = _positionSource[i]; - } - if (normalmorphable) - { - for (unsigned int i=0; i < normal->size(); i++) - { - (*normal)[i] = _normalSource[i]; - } - } - } - - for (unsigned int i=0; i < _morphTargets.size(); i++) - { - if (_morphTargets[i].getWeight() > 0) - { - // See if any the targets use the internal optimized geometry - osg::Geometry* targetGeometry = _morphTargets[i].getGeometry(); - - osg::Vec3Array* targetPos = dynamic_cast(targetGeometry->getVertexArray()); - osg::Vec3Array* targetNormals = dynamic_cast(targetGeometry->getNormalArray()); - normalmorphable = normalmorphable && targetNormals; - if(targetPos) - { - if (initialized) - { - // If vertices are initialized, add the morphtargets - for (unsigned int j=0; j < pos->size(); j++) - { - (*pos)[j] += (*targetPos)[j] * _morphTargets[i].getWeight(); - } - - if (normalmorphable) - { - for (unsigned int j=0; j < normal->size(); j++) - { - (*normal)[j] += (*targetNormals)[j] * _morphTargets[i].getWeight(); - } - } - } - else - { - // If not initialized, initialize with this morph target - initialized = true; - for (unsigned int j=0; j < pos->size(); j++) - { - (*pos)[j] = (*targetPos)[j] * _morphTargets[i].getWeight(); - } - - if (normalmorphable) - { - for (unsigned int j=0; j < normal->size(); j++) - { - (*normal)[j] = (*targetNormals)[j] * _morphTargets[i].getWeight(); - } - } - } - } - } - } - - pos->dirty(); - if (normalmorphable) - { - for (unsigned int j=0; j < normal->size(); j++) - { - (*normal)[j].normalize(); - } - normal->dirty(); - } - } - - dirtyBound(); - - } - _dirty = false; - } -} +MorphTransform* MorphGeometry::getMorphTransformImplementation() { return _rigTransformImplementation.get(); } +void MorphGeometry::setMorphTransformImplementation(MorphTransform* rig) { _rigTransformImplementation = rig; } UpdateMorph::UpdateMorph(const UpdateMorph& apc,const osg::CopyOp& copyop) : osg::Object(apc, copyop), osg::Callback(apc, copyop), AnimationUpdateCallback(apc, copyop) -{ +{_targetNames=apc._targetNames; } UpdateMorph::UpdateMorph(const std::string& name) : AnimationUpdateCallback(name) diff --git a/src/osgAnimation/MorphTransformSoftware.cpp b/src/osgAnimation/MorphTransformSoftware.cpp new file mode 100644 index 000000000..7080d8a4d --- /dev/null +++ b/src/osgAnimation/MorphTransformSoftware.cpp @@ -0,0 +1,182 @@ +/* -*-c++-*- + * Copyright (C) 2009 Cedric Pinson + * + * This library is open source and may be redistributed and/or modified under + * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or + * (at your option) any later version. The full license is in LICENSE file + * included with this distribution, and on the openscenegraph.org website. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * OpenSceneGraph Public License for more details. + */ + + +#include +#include +#include +#include + +using namespace osgAnimation; + + +bool MorphTransformSoftware::init(MorphGeometry& morphGeometry){ + + + morphGeometry.setDataVariance(osg::Object::DYNAMIC); + osg::Vec3Array* pos = dynamic_cast(morphGeometry.getVertexArray()); + osg::Vec3Array * vertexSource = (morphGeometry.getVertexSource()); + osg::Vec3Array * normalSource = (morphGeometry.getNormalSource()); + + // See if we have an internal optimized geometry + + if(pos) + { + if (!vertexSource|| vertexSource->size() != pos->size()) + { + morphGeometry.setVertexSource(new osg::Vec3Array(pos->begin(),pos->end())); + pos->setDataVariance(osg::Object::DYNAMIC); + } + + osg::Vec3Array* normal = dynamic_cast(morphGeometry.getNormalArray()); + bool normalmorphable = morphGeometry.getMorphNormals() && normal; + morphGeometry.setMorphNormals(normalmorphable); + if (normalmorphable && (!normalSource || normalSource->size() != normal->size())) + { + morphGeometry.setNormalSource(new osg::Vec3Array(normal->begin(),normal->end())); + normal->setDataVariance(osg::Object::DYNAMIC); + } + }else return false; + + _needInit=false; + return true; +} + +void MorphTransformSoftware::operator()(MorphGeometry& morphGeometry) +{ + if (_needInit) + if (!init(morphGeometry)) + return; + if (morphGeometry.isDirty()) + { + osg::Vec3Array* pos = static_cast(morphGeometry.getVertexArray()); + osg::Vec3Array & vertexSource = *(morphGeometry.getVertexSource()); + osg::Vec3Array& normalSource = *(morphGeometry.getNormalSource()); + osg::Vec3Array* normal = static_cast(morphGeometry.getNormalArray()); + bool normalmorphable = morphGeometry.getMorphNormals() && normal; + + + if (!vertexSource.empty()) + { + bool initialized = false; + if (morphGeometry.getMethod() == MorphGeometry::NORMALIZED) + { + // base * 1 - (sum of weights) + sum of (weight * target) + float baseWeight = 0; + for (unsigned int i=0; i < morphGeometry.getMorphTargetList().size(); i++) + { + baseWeight += morphGeometry.getMorphTarget(i).getWeight(); + } + baseWeight = 1 - baseWeight; + + if (baseWeight != 0) + { + initialized = true; + for (unsigned int i=0; i < pos->size(); i++) + { + (*pos)[i] = vertexSource[i] * baseWeight; + } + if (normalmorphable) + { + for (unsigned int i=0; i < normal->size(); i++) + { + (*normal)[i] = normalSource[i] * baseWeight; + } + } + } + } + else //if (_method == RELATIVE) + { + // base + sum of (weight * target) + initialized = true; + for (unsigned int i=0; i < pos->size(); i++) + { + (*pos)[i] = vertexSource[i]; + } + if (normalmorphable) + { + for (unsigned int i=0; i < normal->size(); i++) + { + (*normal)[i] = normalSource[i]; + } + } + } + + for (unsigned int i=0; i < morphGeometry.getMorphTargetList().size(); i++) + { + if (morphGeometry.getMorphTarget(i).getWeight() > 0) + { + // See if any the targets use the internal optimized geometry + osg::Geometry* targetGeometry = morphGeometry.getMorphTarget(i).getGeometry(); + + osg::Vec3Array* targetPos = dynamic_cast(targetGeometry->getVertexArray()); + osg::Vec3Array* targetNormals = dynamic_cast(targetGeometry->getNormalArray()); + normalmorphable = normalmorphable && targetNormals; + if(targetPos) + { + if (initialized) + { + // If vertices are initialized, add the morphtargets + for (unsigned int j=0; j < pos->size(); j++) + { + (*pos)[j] += (*targetPos)[j] * morphGeometry.getMorphTarget(i).getWeight(); + } + + if (normalmorphable) + { + for (unsigned int j=0; j < normal->size(); j++) + { + (*normal)[j] += (*targetNormals)[j] * morphGeometry.getMorphTarget(i).getWeight(); + } + } + } + else + { + // If not initialized, initialize with this morph target + initialized = true; + for (unsigned int j=0; j < pos->size(); j++) + { + (*pos)[j] = (*targetPos)[j] * morphGeometry.getMorphTarget(i).getWeight(); + } + + if (normalmorphable) + { + for (unsigned int j=0; j < normal->size(); j++) + { + (*normal)[j] = (*targetNormals)[j] * morphGeometry.getMorphTarget(i).getWeight(); + } + } + } + } + } + } + + pos->dirty(); + if (normalmorphable) + { + for (unsigned int j=0; j < normal->size(); j++) + { + (*normal)[j].normalize(); + } + normal->dirty(); + } + } + + morphGeometry.dirtyBound(); + + + morphGeometry.dirty(false); + } + +} diff --git a/src/osgAnimation/RigGeometry.cpp b/src/osgAnimation/RigGeometry.cpp index 938629a97..b09c61966 100644 --- a/src/osgAnimation/RigGeometry.cpp +++ b/src/osgAnimation/RigGeometry.cpp @@ -58,7 +58,7 @@ RigGeometry::RigGeometry() _needToComputeMatrix = true; _matrixFromSkeletonToGeometry = _invMatrixFromSkeletonToGeometry = osg::Matrix::identity(); // disable the computation of boundingbox for the rig mesh - setComputeBoundingBoxCallback(new RigComputeBoundingBoxCallback); + setComputeBoundingBoxCallback(new RigComputeBoundingBoxCallback()); } @@ -69,9 +69,12 @@ RigGeometry::RigGeometry(const RigGeometry& b, const osg::CopyOp& copyop) : _vertexInfluenceSet(b._vertexInfluenceSet), _vertexInfluenceMap(b._vertexInfluenceMap), _needToComputeMatrix(b._needToComputeMatrix) -{ +{ + _needToComputeMatrix = true; + _matrixFromSkeletonToGeometry = _invMatrixFromSkeletonToGeometry = osg::Matrix::identity(); // disable the computation of boundingbox for the rig mesh - setComputeBoundingBoxCallback(new RigComputeBoundingBoxCallback); + + setComputeBoundingBoxCallback(new RigComputeBoundingBoxCallback()); // we don't copy the RigImplementation yet. because the RigImplementation need to be initialized in a valid graph, with a skeleton ... // don't know yet what to do with a clone of a RigGeometry @@ -81,12 +84,6 @@ RigGeometry::RigGeometry(const RigGeometry& b, const osg::CopyOp& copyop) : const osg::Matrix& RigGeometry::getMatrixFromSkeletonToGeometry() const { return _matrixFromSkeletonToGeometry; } const osg::Matrix& RigGeometry::getInvMatrixFromSkeletonToGeometry() const { return _invMatrixFromSkeletonToGeometry;} - -void RigGeometry::drawImplementation(osg::RenderInfo& renderInfo) const -{ - osg::Geometry::drawImplementation(renderInfo); -} - void RigGeometry::buildVertexInfluenceSet() { if (!_vertexInfluenceMap.valid()) @@ -97,12 +94,12 @@ void RigGeometry::buildVertexInfluenceSet() _vertexInfluenceSet.clear(); for (osgAnimation::VertexInfluenceMap::iterator it = _vertexInfluenceMap->begin(); it != _vertexInfluenceMap->end(); - ++it) + ++it){ _vertexInfluenceSet.addVertexInfluence(it->second); - - _vertexInfluenceSet.buildVertex2BoneList(); - _vertexInfluenceSet.buildUniqVertexSetToBoneSetList(); - OSG_DEBUG << "uniq groups " << _vertexInfluenceSet.getUniqVertexSetToBoneSetList().size() << " for " << getName() << std::endl; + } + _vertexInfluenceSet.buildVertex2BoneList(getSourceGeometry()->getVertexArray()->getNumElements()); + _vertexInfluenceSet.buildUniqVertexGroupList(); + OSG_DEBUG << "uniq groups " << _vertexInfluenceSet.getUniqVertexGroupList().size() << " for " << getName() << std::endl; } void RigGeometry::computeMatrixFromRootSkeleton() @@ -116,7 +113,7 @@ void RigGeometry::computeMatrixFromRootSkeleton() osg::Matrix notRoot = _root->getMatrix(); _matrixFromSkeletonToGeometry = mtxList[0] * osg::Matrix::inverse(notRoot); _invMatrixFromSkeletonToGeometry = osg::Matrix::inverse(_matrixFromSkeletonToGeometry); - _needToComputeMatrix = false; + _needToComputeMatrix = false; } void RigGeometry::update() @@ -132,45 +129,45 @@ void RigGeometry::update() void RigGeometry::copyFrom(osg::Geometry& from) { - bool copyToSelf = (this==&from); + if (this==&from) return; osg::Geometry& target = *this; - if (!copyToSelf) target.setStateSet(from.getStateSet()); + target.setStateSet(from.getStateSet()); // copy over primitive sets. - if (!copyToSelf) target.getPrimitiveSetList() = from.getPrimitiveSetList(); + target.getPrimitiveSetList() = from.getPrimitiveSetList(); if (from.getVertexArray()) { - if (!copyToSelf) target.setVertexArray(from.getVertexArray()); + target.setVertexArray(from.getVertexArray()); } if (from.getNormalArray()) { - if (!copyToSelf) target.setNormalArray(from.getNormalArray()); + target.setNormalArray(from.getNormalArray()); } if (from.getColorArray()) { - if (!copyToSelf) target.setColorArray(from.getColorArray()); + target.setColorArray(from.getColorArray()); } if (from.getSecondaryColorArray()) { - if (!copyToSelf) target.setSecondaryColorArray(from.getSecondaryColorArray()); + target.setSecondaryColorArray(from.getSecondaryColorArray()); } if (from.getFogCoordArray()) { - if (!copyToSelf) target.setFogCoordArray(from.getFogCoordArray()); + target.setFogCoordArray(from.getFogCoordArray()); } for(unsigned int ti=0;ti= (int)_boneWeightAttribArrays.size()) + if (index >= _boneWeightAttribArrays.size()) return 0; return _boneWeightAttribArrays[index].get(); } -int RigTransformHardware::getNumVertexAttrib() +unsigned int RigTransformHardware::getNumVertexAttrib() { return _boneWeightAttribArrays.size(); } @@ -61,68 +60,83 @@ osg::Uniform* RigTransformHardware::getMatrixPaletteUniform() void RigTransformHardware::computeMatrixPaletteUniform(const osg::Matrix& transformFromSkeletonToGeometry, const osg::Matrix& invTransformFromSkeletonToGeometry) { - for (int i = 0; i < (int)_bonePalette.size(); i++) + for (unsigned int i = 0; i < _bonePalette.size(); i++) { osg::ref_ptr bone = _bonePalette[i].get(); - const osg::Matrix& invBindMatrix = bone->getInvBindMatrixInSkeletonSpace(); - const osg::Matrix& boneMatrix = bone->getMatrixInSkeletonSpace(); - osg::Matrix resultBoneMatrix = invBindMatrix * boneMatrix; - osg::Matrix result = transformFromSkeletonToGeometry * resultBoneMatrix * invTransformFromSkeletonToGeometry; + const osg::Matrixf& invBindMatrix = bone->getInvBindMatrixInSkeletonSpace(); + const osg::Matrixf& boneMatrix = bone->getMatrixInSkeletonSpace(); + osg::Matrixf resultBoneMatrix = invBindMatrix * boneMatrix; + osg::Matrixf result = transformFromSkeletonToGeometry * resultBoneMatrix * invTransformFromSkeletonToGeometry; if (!_uniformMatrixPalette->setElement(i, result)) OSG_WARN << "RigTransformHardware::computeUniformMatrixPalette can't set uniform at " << i << " elements" << std::endl; } } -int RigTransformHardware::getNumBonesPerVertex() const { return _bonesPerVertex;} -int RigTransformHardware::getNumVertexes() const { return _nbVertexes;} +unsigned int RigTransformHardware::getNumBonesPerVertex() const { return _bonesPerVertex;} +unsigned int RigTransformHardware::getNumVertexes() const { return _nbVertexes;} -bool RigTransformHardware::createPalette(int nbVertexes, BoneMap boneMap, const VertexInfluenceSet::VertexIndexToBoneWeightMap& vertexIndexToBoneWeightMap) +typedef std::vector > VertexIndexWeightList; +void createVertexAttribList(RigTransformHardware& rig,const VertexIndexWeightList&_vertexIndexMatrixWeightList,RigTransformHardware::BoneWeightAttribList & boneWeightAttribArrays); + +bool RigTransformHardware::createPalette(unsigned int nbVertexes, const BoneMap &boneMap, const VertexInfluenceSet::VertIDToBoneWeightList& vertexIndexToBoneWeightMap) { + _nbVertexes = nbVertexes; typedef std::map BoneNameCountMap; - BonePalette palette; + _bonePalette.clear(); + _boneNameToPalette.clear(); BoneNameCountMap boneNameCountMap; - // init vertex attribute data VertexIndexWeightList vertexIndexWeight; vertexIndexWeight.resize(nbVertexes); - int maxBonePerVertex = 0; - for (VertexInfluenceSet::VertexIndexToBoneWeightMap::const_iterator vit = vertexIndexToBoneWeightMap.begin(); vit != vertexIndexToBoneWeightMap.end(); ++vit) + unsigned int maxBonePerVertex = 0; + if(vertexIndexToBoneWeightMap.size()!=nbVertexes) { + OSG_WARN << "RigTransformHardware::some vertex has no transform " <first; - const VertexInfluenceSet::BoneWeightList& boneWeightList = vit->second; - int bonesForThisVertex = 0; + const VertexInfluenceSet::BoneWeightList& boneWeightList = *vit; + unsigned int bonesForThisVertex = 0; for (VertexInfluenceSet::BoneWeightList::const_iterator it = boneWeightList.begin(); it != boneWeightList.end(); ++it) { const VertexInfluenceSet::BoneWeight& bw = *it; - if(fabs(bw.getWeight()) > 1e-2) // don't use bone with weight too small + if(fabs(bw.getWeight()) > 1e-4) // don't use bone with weight too small { - if (boneNameCountMap.find(bw.getBoneName()) != boneNameCountMap.end()) + if ((boneName2PaletteIndex= _boneNameToPalette.find(bw.getBoneName())) != _boneNameToPalette.end()) { boneNameCountMap[bw.getBoneName()]++; bonesForThisVertex++; // count max number of bones per vertexes - vertexIndexWeight[vertexIndex].push_back(IndexWeightEntry(_boneNameToPalette[bw.getBoneName()],bw.getWeight())); + vertexIndexWeight[vertexID].push_back(IndexWeightEntry(boneName2PaletteIndex->second,bw.getWeight())); } else { - if (boneMap.find(bw.getBoneName()) == boneMap.end()) + BoneMap::const_iterator bonebyname; + if ((bonebyname=boneMap.find(bw.getBoneName())) == boneMap.end()) { - OSG_INFO << "RigTransformHardware::createPalette can't find bone " << bw.getBoneName() << " skip this influence" << std::endl; + OSG_WARN << "RigTransformHardware::createPalette can't find bone " << bw.getBoneName() << "in skeleton bonemap: skip this influence" << std::endl; continue; } boneNameCountMap[bw.getBoneName()] = 1; // for stats bonesForThisVertex++; - palette.push_back(boneMap[bw.getBoneName()]); - _boneNameToPalette[bw.getBoneName()] = palette.size()-1; - vertexIndexWeight[vertexIndex].push_back(IndexWeightEntry(_boneNameToPalette[bw.getBoneName()],bw.getWeight())); - } + + _boneNameToPalette[bw.getBoneName()] = _bonePalette.size() ; + vertexIndexWeight[vertexID].push_back(IndexWeightEntry(_bonePalette.size(),bw.getWeight())); + _bonePalette.push_back(bonebyname->second); + } } else { - OSG_WARN << "RigTransformHardware::createPalette Bone " << bw.getBoneName() << " has a weight " << bw.getWeight() << " for vertex " << vertexIndex << " this bone will not be in the palette" << std::endl; + OSG_WARN << "RigTransformHardware::createPalette Bone " << bw.getBoneName() << " has a weight " << bw.getWeight() << " for vertex " << vertexID << " this bone will not be in the palette" << std::endl; } } + if(bonesForThisVertex==0) { + OSG_WARN << "RigTransformHardware::no transform for vertex " << vertexID << " this will induce a bug in vertex shader" << std::endl; + } maxBonePerVertex = osg::maximum(maxBonePerVertex, bonesForThisVertex); } OSG_INFO << "RigTransformHardware::createPalette maximum number of bone per vertex is " << maxBonePerVertex << std::endl; @@ -136,15 +150,12 @@ 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; - _vertexIndexMatrixWeightList = vertexIndexWeight; + for (int i = 0 ; i < (int)vertexIndexWeight.size(); i++) + vertexIndexWeight[i].resize(maxBonePerVertex); + _uniformMatrixPalette = createVertexUniform(); - _boneWeightAttribArrays = createVertexAttribList(); + createVertexAttribList(*this,vertexIndexWeight,this->_boneWeightAttribArrays); return true; } @@ -157,33 +168,34 @@ bool RigTransformHardware::createPalette(int nbVertexes, BoneMap boneMap, const // the idea is to use this format to have a granularity smaller // than the 4 bones using two vertex attributes // -RigTransformHardware::BoneWeightAttribList RigTransformHardware::createVertexAttribList() +void createVertexAttribList(RigTransformHardware& rig,const VertexIndexWeightList& _vertexIndexMatrixWeightList, RigTransformHardware::BoneWeightAttribList& boneWeightAttribArrays) { - BoneWeightAttribList arrayList; - int nbArray = static_cast(ceilf(getNumBonesPerVertex() * 0.5)); + unsigned int nbVertices= rig.getNumVertexes(); + unsigned int maxbonepervertex=rig.getNumBonesPerVertex(); + unsigned int nbArray = static_cast(ceilf( ((float)maxbonepervertex) * 0.5f)); if (!nbArray) - return arrayList; + return ; - arrayList.resize(nbArray); - for (int i = 0; i < nbArray; i++) + boneWeightAttribArrays.resize(nbArray); + for (unsigned int i = 0; i < nbArray; i++) { osg::ref_ptr array = new osg::Vec4Array(osg::Array::BIND_PER_VERTEX); - arrayList[i] = array; - int nbVertexes = getNumVertexes(); - array->resize(nbVertexes); - for (int j = 0; j < nbVertexes; j++) + boneWeightAttribArrays[i] = array; + array->resize( nbVertices); + for (unsigned int j = 0; j < nbVertices; j++) { - for (int b = 0; b < 2; b++) + + for (unsigned int b = 0; b < 2; b++) { // the granularity is 2 so if we have only one bone // it's convenient to init the second with a weight 0 - int boneIndexInList = i*2 + b; - int boneIndexInVec4 = b*2; + unsigned int boneIndexInList = i*2 + b; + unsigned int boneIndexInVec4 = b*2; (*array)[j][0 + boneIndexInVec4] = 0; (*array)[j][1 + boneIndexInVec4] = 0; - if (boneIndexInList < getNumBonesPerVertex()) + if (boneIndexInList < maxbonepervertex) { - float boneIndex = static_cast(_vertexIndexMatrixWeightList[j][boneIndexInList].getIndex()); + float boneIndex = static_cast(_vertexIndexMatrixWeightList[j][boneIndexInList].getBoneIndex()); float boneWeight = _vertexIndexMatrixWeightList[j][boneIndexInList].getWeight(); // fill the vec4 (*array)[j][0 + boneIndexInVec4] = boneIndex; @@ -192,10 +204,9 @@ RigTransformHardware::BoneWeightAttribList RigTransformHardware::createVertexAtt } } } - return arrayList; + return ; } - osg::Uniform* RigTransformHardware::createVertexUniform() { osg::Uniform* uniform = new osg::Uniform(osg::Uniform::FLOAT_MAT4, "matrixPalette", _bonePalette.size()); @@ -210,6 +221,15 @@ void RigTransformHardware::setShader(osg::Shader* shader) bool RigTransformHardware::init(RigGeometry& geom) { + if (!geom.getSkeleton()) + { + OSG_WARN << "RigTransformHardware no skeleton set in geometry " << geom.getName() << std::endl; + return false; + } + BoneMapVisitor mapVisitor; + geom.getSkeleton()->accept(mapVisitor); + BoneMap bm = mapVisitor.getBoneMap(); + osg::Geometry& source = *geom.getSourceGeometry(); osg::Vec3Array* positionSrc = dynamic_cast(source.getVertexArray()); if (!positionSrc) @@ -218,72 +238,93 @@ bool RigTransformHardware::init(RigGeometry& geom) return false; } - if (!geom.getSkeleton()) - { - OSG_WARN << "RigTransformHardware no skeleton set in geometry " << geom.getName() << std::endl; - return false; - } - - // copy shallow from source geometry to rig geom.copyFrom(source); - - BoneMapVisitor mapVisitor; - geom.getSkeleton()->accept(mapVisitor); - BoneMap bm = mapVisitor.getBoneMap(); - - if (!createPalette(positionSrc->size(),bm, geom.getVertexInfluenceSet().getVertexToBoneList())) + if (!createPalette(positionSrc->size(),bm,geom.getVertexInfluenceSet().getVertexToBoneList())) return false; - osg::ref_ptr program = new osg::Program; - program->setName("HardwareSkinning"); - if (!_shader.valid()) - _shader = osg::Shader::readShaderFile(osg::Shader::VERTEX,"skinning.vert"); + osg::ref_ptr program ; + osg::ref_ptr vertexshader; + osg::ref_ptr stateset = geom.getOrCreateStateSet(); - if (!_shader.valid()) { + //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 = _shader->getShaderSource(); + 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()); - _shader->setShaderSource(str); + vertexshader->setShaderSource(str); } else { - OSG_WARN << "MAX_MATRIX not found in Shader! " << str << std::endl; + OSG_INFO<< "MAX_MATRIX not found in Shader! " << str << std::endl; } OSG_INFO << "Shader " << str << std::endl; } - int attribIndex = 11; - int nbAttribs = getNumVertexAttrib(); - for (int i = 0; i < nbAttribs; i++) + unsigned int attribIndex = 11; + unsigned int nbAttribs = getNumVertexAttrib(); + if(nbAttribs==0) + OSG_WARN << "nbAttribs== " << nbAttribs << std::endl; + for (unsigned int i = 0; i < nbAttribs; i++) { std::stringstream ss; ss << "boneWeight" << i; program->addBindAttribLocation(ss.str(), attribIndex + i); + + if(getVertexAttrib(i)->getNumElements()!=_nbVertexes) + OSG_WARN << "getVertexAttrib== " << getVertexAttrib(i)->getNumElements() << std::endl; geom.setVertexAttribArray(attribIndex + i, getVertexAttrib(i)); OSG_INFO << "set vertex attrib " << ss.str() << std::endl; } - program->addShader(_shader.get()); - osg::ref_ptr ss = geom.getOrCreateStateSet(); - ss->addUniform(getMatrixPaletteUniform()); - ss->addUniform(new osg::Uniform("nbBonesPerVertex", getNumBonesPerVertex())); - ss->setAttributeAndModes(program.get()); + program->addShader(vertexshader.get()); + + stateset->removeUniform("matrixPalette"); + stateset->addUniform(getMatrixPaletteUniform()); + + stateset->removeUniform("nbBonesPerVertex"); + stateset->addUniform(new osg::Uniform("nbBonesPerVertex",_bonesPerVertex)); + + stateset->removeAttribute(osg::StateAttribute::PROGRAM); + if(!stateset->getAttribute(osg::StateAttribute::PROGRAM)) + stateset->setAttributeAndModes(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 b9537cf8d..79224cdd1 100644 --- a/src/osgAnimation/RigTransformSoftware.cpp +++ b/src/osgAnimation/RigTransformSoftware.cpp @@ -18,6 +18,7 @@ #include #include +#include using namespace osgAnimation; RigTransformSoftware::RigTransformSoftware() @@ -33,6 +34,45 @@ RigTransformSoftware::RigTransformSoftware(const RigTransformSoftware& rts,const } +// sort by name and weight +struct SortByNameAndWeight : public std::less +{ + bool operator()(const VertexInfluenceSet::BoneWeight& b0, + const VertexInfluenceSet::BoneWeight& 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 VertexInfluenceSet::BoneWeightList& b0, + const VertexInfluenceSet::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()) @@ -41,12 +81,34 @@ bool RigTransformSoftware::init(RigGeometry& geom) BoneMapVisitor mapVisitor; geom.getSkeleton()->accept(mapVisitor); BoneMap bm = mapVisitor.getBoneMap(); - initVertexSetFromBones(bm, geom.getVertexInfluenceSet().getUniqVertexSetToBoneSetList()); + initVertexSetFromBones(bm, geom.getVertexInfluenceSet().getUniqVertexGroupList()); if (geom.getSourceGeometry()) geom.copyFrom(*geom.getSourceGeometry()); - geom.setVertexArray(0); - geom.setNormalArray(0); + + + osg::Vec3Array* normalSrc = dynamic_cast(geom.getSourceGeometry()->getNormalArray()); + osg::Vec3Array* positionSrc = dynamic_cast(geom.getSourceGeometry()->getVertexArray()); + + if(!(positionSrc) || positionSrc->empty() ) + return false; + if(normalSrc&& normalSrc->size()!=positionSrc->size()) + return false; + + + geom.setVertexArray(new osg::Vec3Array); + osg::Vec3Array* positionDst =new osg::Vec3Array; + geom.setVertexArray(positionDst); + *positionDst=*positionSrc; + positionDst->setDataVariance(osg::Object::DYNAMIC); + + + if(normalSrc){ + osg::Vec3Array* normalDst =new osg::Vec3Array; + *normalDst=*normalSrc; + geom.setNormalArray(normalDst, osg::Array::BIND_PER_VERTEX); + normalDst->setDataVariance(osg::Object::DYNAMIC); + } _needInit = false; return true; @@ -65,74 +127,50 @@ void RigTransformSoftware::operator()(RigGeometry& geom) osg::Geometry& source = *geom.getSourceGeometry(); osg::Geometry& destination = geom; - osg::Vec3Array* positionSrc = dynamic_cast(source.getVertexArray()); - osg::Vec3Array* positionDst = dynamic_cast(destination.getVertexArray()); - if (positionSrc ) - { - if (!positionDst || (positionDst->size() != positionSrc->size()) ) - { - if (!positionDst) - { - positionDst = new osg::Vec3Array; - positionDst->setDataVariance(osg::Object::DYNAMIC); - destination.setVertexArray(positionDst); - } - *positionDst = *positionSrc; - } - if (!positionDst->empty()) - { - compute(geom.getMatrixFromSkeletonToGeometry(), - geom.getInvMatrixFromSkeletonToGeometry(), - &positionSrc->front(), - &positionDst->front()); - positionDst->dirty(); - } - - } - + osg::Vec3Array* positionSrc = static_cast(source.getVertexArray()); + osg::Vec3Array* positionDst = static_cast(destination.getVertexArray()); osg::Vec3Array* normalSrc = dynamic_cast(source.getNormalArray()); - osg::Vec3Array* normalDst = dynamic_cast(destination.getNormalArray()); + osg::Vec3Array* normalDst = static_cast(destination.getNormalArray()); + + + compute(geom.getMatrixFromSkeletonToGeometry(), + geom.getInvMatrixFromSkeletonToGeometry(), + &positionSrc->front(), + &positionDst->front()); + positionDst->dirty(); + + + if (normalSrc ) { - if (!normalDst || (normalDst->size() != normalSrc->size()) ) - { - if (!normalDst) - { - normalDst = new osg::Vec3Array; - normalDst->setDataVariance(osg::Object::DYNAMIC); - destination.setNormalArray(normalDst, osg::Array::BIND_PER_VERTEX); - } - *normalDst = *normalSrc; - } - if (!normalDst->empty()) - { computeNormal(geom.getMatrixFromSkeletonToGeometry(), geom.getInvMatrixFromSkeletonToGeometry(), &normalSrc->front(), &normalDst->front()); normalDst->dirty(); - } } } -void RigTransformSoftware::initVertexSetFromBones(const BoneMap& map, const VertexInfluenceSet::UniqVertexSetToBoneSetList& influence) +///convert BoneWeight to BonePtrWeight using bonemap +void RigTransformSoftware::initVertexSetFromBones(const BoneMap& map, const VertexInfluenceSet::UniqVertexGroupList& vertexgroups) { - _boneSetVertexSet.clear(); + _uniqInfluenceSet2VertIDList.clear(); - int size = influence.size(); - _boneSetVertexSet.resize(size); - for (int i = 0; i < size; i++) + int size = vertexgroups.size(); + _uniqInfluenceSet2VertIDList.resize(size); + //for (VertexInfluenceSet::UniqVertexGroupList::const_iterator vgit=vertexgroups.begin(); vgit!=vertexgroups.end();vgit++) + for(int i = 0; i < size; i++) { - const VertexInfluenceSet::UniqVertexSetToBoneSet& inf = influence[i]; - int nbBones = inf.getBones().size(); - BoneWeightList& boneList = _boneSetVertexSet[i].getBones(); + const VertexInfluenceSet::VertexGroup& vg = vertexgroups[i]; + int nbBones = vg.getBones().size(); + BonePtrWeightList& boneList = _uniqInfluenceSet2VertIDList[i].getBoneWeights(); double sumOfWeight = 0; for (int b = 0; b < nbBones; b++) { - const std::string& bname = inf.getBones()[b].getBoneName(); - float weight = inf.getBones()[b].getWeight(); + const std::string& bname = vg.getBones()[b].getBoneName(); + float weight = vg.getBones()[b].getWeight(); BoneMap::const_iterator it = map.find(bname); if (it == map.end() ) { @@ -143,18 +181,18 @@ void RigTransformSoftware::initVertexSetFromBones(const BoneMap& map, const Vert continue; } Bone* bone = it->second.get(); - boneList.push_back(BoneWeight(bone, weight)); + boneList.push_back(BonePtrWeight(bone, weight)); sumOfWeight += weight; } // if a bone referenced by a vertexinfluence is missed it can make the sum less than 1.0 // so we check it and renormalize the all weight bone - const double threshold = 1e-4; + /*const double threshold = 1e-4; if (!_boneSetVertexSet[i].getBones().empty() && (sumOfWeight < 1.0 - threshold || sumOfWeight > 1.0 + threshold)) { for (int b = 0; b < (int)boneList.size(); b++) boneList[b].setWeight(boneList[b].getWeight() / sumOfWeight); - } - _boneSetVertexSet[i].getVertexes() = inf.getVertexes(); + }*/ + _uniqInfluenceSet2VertIDList[i].getVertexes() = vg.getVertexes(); } } diff --git a/src/osgAnimation/VertexInfluence.cpp b/src/osgAnimation/VertexInfluence.cpp index ad1686277..f5a983234 100644 --- a/src/osgAnimation/VertexInfluence.cpp +++ b/src/osgAnimation/VertexInfluence.cpp @@ -16,16 +16,21 @@ #include #include #include +#include using namespace osgAnimation; void VertexInfluenceSet::addVertexInfluence(const VertexInfluence& v) { _bone2Vertexes.push_back(v); } -const VertexInfluenceSet::VertexIndexToBoneWeightMap& VertexInfluenceSet::getVertexToBoneList() const { return _vertex2Bones;} +const VertexInfluenceSet::VertIDToBoneWeightList& VertexInfluenceSet::getVertexToBoneList() const { return _vertex2Bones;} // this class manage VertexInfluence database by mesh // reference bones per vertex ... -void VertexInfluenceSet::buildVertex2BoneList() + +void VertexInfluenceSet::buildVertex2BoneList(unsigned int numvertices) { _vertex2Bones.clear(); + _vertex2Bones.reserve(numvertices); + _vertex2Bones.resize(numvertices); + for (BoneToVertexList::const_iterator it = _bone2Vertexes.begin(); it != _bone2Vertexes.end(); ++it) { const VertexInfluence& vi = (*it); @@ -35,23 +40,25 @@ void VertexInfluenceSet::buildVertex2BoneList() VertexIndexWeight viw = vi[i]; int index = viw.first; float weight = viw.second; - if (vi.getName().empty()) + if (vi.getName().empty()){ OSG_WARN << "VertexInfluenceSet::buildVertex2BoneList warning vertex " << index << " is not assigned to a bone" << std::endl; + } _vertex2Bones[index].push_back(BoneWeight(vi.getName(), weight)); } } // normalize weight per vertex - for (VertexIndexToBoneWeightMap::iterator it = _vertex2Bones.begin(); it != _vertex2Bones.end(); ++it) + unsigned int vertid=0; + for (VertIDToBoneWeightList::iterator it = _vertex2Bones.begin(); it != _vertex2Bones.end(); ++it,++vertid) { - BoneWeightList& bones = it->second; + BoneWeightList& bones =*it; int size = bones.size(); float sum = 0; for (int i = 0; i < size; i++) sum += bones[i].getWeight(); if (sum < 1e-4) { - OSG_WARN << "VertexInfluenceSet::buildVertex2BoneList warning the vertex " << it->first << " seems to have 0 weight, skip normalize for this vertex" << std::endl; + OSG_WARN << "VertexInfluenceSet::buildVertex2BoneList warning the vertex " < UnifyBoneGroup; + typedef std::map UnifyBoneGroup; UnifyBoneGroup unifyBuffer; - for (VertexIndexToBoneWeightMap::iterator it = _vertex2Bones.begin(); it != _vertex2Bones.end(); ++it) + unsigned int vertexID=0; + for (VertIDToBoneWeightList::iterator it = _vertex2Bones.begin(); it != _vertex2Bones.end(); ++it,++vertexID) { - BoneWeightList bones = it->second; - int vertexIndex = it->first; + BoneWeightList bones = *it; // sort the vector to have a consistent key std::sort(bones.begin(), bones.end(), SortByNameAndWeight()); @@ -128,10 +135,12 @@ void VertexInfluenceSet::buildUniqVertexSetToBoneSetList() UnifyBoneGroup::iterator result = unifyBuffer.find(bones); if (result == unifyBuffer.end()) unifyBuffer[bones].setBones(bones); - unifyBuffer[bones].getVertexes().push_back(vertexIndex); + unifyBuffer[bones].getVertexes().push_back(vertexID); } _uniqVertexSetToBoneSet.reserve(unifyBuffer.size()); + + for (UnifyBoneGroup::iterator it = unifyBuffer.begin(); it != unifyBuffer.end(); ++it) { _uniqVertexSetToBoneSet.push_back(it->second); From 0729e883d843e78ae280e7533b72e073f087f024 Mon Sep 17 00:00:00 2001 From: Julien Valentin Date: Sat, 26 Aug 2017 23:05:52 +0200 Subject: [PATCH 002/327] update serializers --- .../osgAnimation/AnimationManagerBase.cpp | 47 +++++++++++++-- .../osgAnimation/BasicAnimationManager.cpp | 59 +++++++++++++++++++ .../osgAnimation/MorphGeometry.cpp | 49 ++++++++++++++- .../serializers/osgAnimation/RigGeometry.cpp | 3 +- .../serializers/osgAnimation/RigTransform.cpp | 14 +++++ 5 files changed, 165 insertions(+), 7 deletions(-) diff --git a/src/osgWrappers/serializers/osgAnimation/AnimationManagerBase.cpp b/src/osgWrappers/serializers/osgAnimation/AnimationManagerBase.cpp index 06d2e353b..49a788fc5 100644 --- a/src/osgWrappers/serializers/osgAnimation/AnimationManagerBase.cpp +++ b/src/osgWrappers/serializers/osgAnimation/AnimationManagerBase.cpp @@ -5,7 +5,8 @@ #include #include #include - +namespace osgAnimation_AnimationManagerBaseWrapper +{ static bool checkAnimations( const osgAnimation::AnimationManagerBase& manager ) { return manager.getAnimationList().size()>0; @@ -13,7 +14,8 @@ static bool checkAnimations( const osgAnimation::AnimationManagerBase& manager ) static bool readAnimations( osgDB::InputStream& is, osgAnimation::AnimationManagerBase& manager ) { - unsigned int size = is.readSize(); is >> is.BEGIN_BRACKET; + unsigned int size = is.readSize(); + is >> is.BEGIN_BRACKET; for ( unsigned int i=0; i ani = is.readObjectOfType(); @@ -26,16 +28,48 @@ static bool readAnimations( osgDB::InputStream& is, osgAnimation::AnimationManag static bool writeAnimations( osgDB::OutputStream& os, const osgAnimation::AnimationManagerBase& manager ) { const osgAnimation::AnimationList& animations = manager.getAnimationList(); - os.writeSize(animations.size()); os << os.BEGIN_BRACKET << std::endl; + os.writeSize(animations.size()); + os << os.BEGIN_BRACKET << std::endl; for ( osgAnimation::AnimationList::const_iterator itr=animations.begin(); - itr!=animations.end(); ++itr ) + itr!=animations.end(); ++itr ) { os << itr->get(); } os << os.END_BRACKET << std::endl; return true; } +struct osgAnimation_AnimationManagerBasegetnumAnimations : public osgDB::MethodObject +{ + virtual bool run(void* objectPtr, osg::Parameters& inputParameters, osg::Parameters& outputParameters) const + { + osgAnimation::AnimationManagerBase* group = dynamic_cast(reinterpret_cast(objectPtr)); + outputParameters.push_back(new osg::UIntValueObject("return",group->getNumRegisteredAnimations())); + return true; + } +}; +struct osgAnimation_AnimationManagerBasegetAnimation : public osgDB::MethodObject +{ + virtual bool run(void* objectPtr, osg::Parameters& inputParameters, osg::Parameters& outputParameters) const + { + if (inputParameters.empty()) return false; + osg::Object* indexObject = inputParameters[0].get(); + + unsigned int index = 0; + osg::DoubleValueObject* dvo = dynamic_cast(indexObject); + if (dvo) index = static_cast(dvo->getValue()); + else + { + osg::UIntValueObject* uivo = dynamic_cast(indexObject); + if (uivo) index = uivo->getValue(); + } + osgAnimation::AnimationManagerBase* group = dynamic_cast(reinterpret_cast(objectPtr)); + outputParameters.push_back(group->getRegisteredAnimation(index)); + + + return true; + } +}; REGISTER_OBJECT_WRAPPER( osgAnimation_AnimationManagerBase, /*new osgAnimation::AnimationManagerBase*/NULL, osgAnimation::AnimationManagerBase, @@ -43,7 +77,10 @@ REGISTER_OBJECT_WRAPPER( osgAnimation_AnimationManagerBase, { ADD_USER_SERIALIZER( Animations ); // _animations ADD_BOOL_SERIALIZER( AutomaticLink, true ); // _automaticLink -} + ADD_METHOD_OBJECT( "getRegisteredAnimation", osgAnimation_AnimationManagerBasegetAnimation ); + ADD_METHOD_OBJECT( "getNumRegisteredAnimations", osgAnimation_AnimationManagerBasegetnumAnimations ); +} +} #undef OBJECT_CAST #define OBJECT_CAST static_cast diff --git a/src/osgWrappers/serializers/osgAnimation/BasicAnimationManager.cpp b/src/osgWrappers/serializers/osgAnimation/BasicAnimationManager.cpp index 22b913a0c..8aef704c8 100644 --- a/src/osgWrappers/serializers/osgAnimation/BasicAnimationManager.cpp +++ b/src/osgWrappers/serializers/osgAnimation/BasicAnimationManager.cpp @@ -5,12 +5,71 @@ #include #include #include +namespace osgAnimation_BasicAnimationManagerWrapper{ +struct BasicAnimationManagerIsplaying : public osgDB::MethodObject +{ + virtual bool run(void* objectPtr, osg::Parameters& inputParameters, osg::Parameters& outputParameters) const + { + if (inputParameters.empty()) return false; + osgAnimation::Animation* child = dynamic_cast(inputParameters[0].get()); + if (!child) return false; + osgAnimation::BasicAnimationManager* group = dynamic_cast(reinterpret_cast(objectPtr)); + outputParameters.push_back(new osg::BoolValueObject("return", group->isPlaying(child))); + return true; + } +}; +struct BasicAnimationManagerfindAnimation : public osgDB::MethodObject +{ + virtual bool run(void* objectPtr, osg::Parameters& inputParameters, osg::Parameters& outputParameters) const + { + if (inputParameters.empty()) return false; + + osgAnimation::Animation* child = dynamic_cast(inputParameters[0].get()); + if (!child) return false; + osgAnimation::BasicAnimationManager* group = dynamic_cast(reinterpret_cast(objectPtr)); + outputParameters.push_back(new osg::BoolValueObject("return",group->findAnimation(child))); + return true; + } +}; +struct BasicAnimationManagerPlayanimation : public osgDB::MethodObject +{ + virtual bool run(void* objectPtr, osg::Parameters& inputParameters, osg::Parameters& outputParameters) const + { + if (inputParameters.empty()) return false; + + osgAnimation::Animation* child = dynamic_cast(inputParameters[0].get()); + if (!child) return false; + osgAnimation::BasicAnimationManager* group = dynamic_cast(reinterpret_cast(objectPtr)); + group->playAnimation(child); + return true; + } +}; +struct BasicAnimationManagerStopanimation : public osgDB::MethodObject +{ + virtual bool run(void* objectPtr, osg::Parameters& inputParameters, osg::Parameters& outputParameters) const + { + if (inputParameters.empty()) return false; + + osgAnimation::Animation* child = dynamic_cast(inputParameters[0].get()); + if (!child) return false; + osgAnimation::BasicAnimationManager* group = dynamic_cast(reinterpret_cast(objectPtr)); + group->stopAnimation(child); + return true; + } +}; REGISTER_OBJECT_WRAPPER( osgAnimation_BasicAnimationManager, new osgAnimation::BasicAnimationManager, osgAnimation::BasicAnimationManager, "osg::Object osg::NodeCallback osgAnimation::AnimationManagerBase osgAnimation::BasicAnimationManager" ) { + + ADD_METHOD_OBJECT( "isPlaying", BasicAnimationManagerIsplaying ); + ADD_METHOD_OBJECT( "findAnimation", BasicAnimationManagerfindAnimation ); + ADD_METHOD_OBJECT( "playAnimation", BasicAnimationManagerPlayanimation ); + ADD_METHOD_OBJECT( "stopAnimation", BasicAnimationManagerStopanimation ); + +} } #undef OBJECT_CAST diff --git a/src/osgWrappers/serializers/osgAnimation/MorphGeometry.cpp b/src/osgWrappers/serializers/osgAnimation/MorphGeometry.cpp index 8d3d3c58b..5479ebaf5 100644 --- a/src/osgWrappers/serializers/osgAnimation/MorphGeometry.cpp +++ b/src/osgWrappers/serializers/osgAnimation/MorphGeometry.cpp @@ -36,10 +36,47 @@ static bool writeMorphTargets( osgDB::OutputStream& os, const osgAnimation::Morp return true; } +#define ADD_ARRAYDATA_FUNCTIONS( ORIGINAL_PROP, PROP ) \ + static bool check##ORIGINAL_PROP( const osgAnimation::MorphGeometry& geom ) \ + { return geom.get##PROP()!=0; } \ + static bool read##ORIGINAL_PROP( osgDB::InputStream& is, osgAnimation::MorphGeometry& geom ) { \ + is >> is.BEGIN_BRACKET; \ + osg::Array* array =is.readArray(); \ + geom.set##PROP((osg::Vec3Array*)array); \ + is >> is.END_BRACKET; \ + return true; \ + } \ + static bool write##ORIGINAL_PROP( osgDB::OutputStream& os, const osgAnimation::MorphGeometry& geom ) { \ + os << os.BEGIN_BRACKET << std::endl; \ + os.writeArray( geom.get##PROP()); \ + os << os.END_BRACKET << std::endl; \ + return true; \ + } +ADD_ARRAYDATA_FUNCTIONS( VertexData, VertexSource ) +ADD_ARRAYDATA_FUNCTIONS( NormalData, NormalSource ) + +struct FinishedObjectReadFillSourceIfRequiredCallback : public osgDB::FinishedObjectReadCallback +{ + virtual void objectRead(osgDB::InputStream&, osg::Object& obj) + { + + osgAnimation::MorphGeometry& geometry = static_cast(obj); + if((!geometry.getVertexSource() ||geometry.getVertexSource()->getNumElements()==0) + && dynamic_cast(geometry.getVertexArray())){ + geometry.setVertexSource((osg::Vec3Array* )geometry.getVertexArray()->clone(osg::CopyOp::DEEP_COPY_ALL)); + } + if((!geometry.getNormalSource() ||geometry.getNormalSource()->getNumElements()==0) + && geometry.getNormalArray()){ + geometry.setNormalSource((osg::Vec3Array* )geometry.getNormalArray()->clone(osg::CopyOp::DEEP_COPY_ALL)); + } +} + +}; + REGISTER_OBJECT_WRAPPER( osgAnimation_MorphGeometry, new osgAnimation::MorphGeometry, osgAnimation::MorphGeometry, - "osg::Object osg::Drawable osg::Geometry osgAnimation::MorphGeometry" ) + "osg::Object osg::Node osg::Drawable osg::Geometry osgAnimation::MorphGeometry" ) { BEGIN_ENUM_SERIALIZER( Method, NORMALIZED ); ADD_ENUM_VALUE( NORMALIZED ); @@ -48,4 +85,14 @@ REGISTER_OBJECT_WRAPPER( osgAnimation_MorphGeometry, ADD_USER_SERIALIZER( MorphTargets ); // _morphTargets ADD_BOOL_SERIALIZER( MorphNormals, true ); // _morphNormals + ADD_USER_SERIALIZER( VertexData ); // VertexSource + ADD_USER_SERIALIZER( NormalData ); // NormalSource + + + { + UPDATE_TO_VERSION_SCOPED( 147 ) + ADD_OBJECT_SERIALIZER( MorphTransformImplementation, osgAnimation::MorphTransform, NULL ); // _geometry + } + + wrapper->addFinishedObjectReadCallback( new FinishedObjectReadFillSourceIfRequiredCallback() ); } diff --git a/src/osgWrappers/serializers/osgAnimation/RigGeometry.cpp b/src/osgWrappers/serializers/osgAnimation/RigGeometry.cpp index 2787ec91c..7c25e0376 100644 --- a/src/osgWrappers/serializers/osgAnimation/RigGeometry.cpp +++ b/src/osgWrappers/serializers/osgAnimation/RigGeometry.cpp @@ -2,7 +2,7 @@ #include #include #include - +namespace wrap_osgAnimationRigGeometry{ static bool checkInfluenceMap( const osgAnimation::RigGeometry& geom ) { return geom.getInfluenceMap()->size()>0; @@ -78,3 +78,4 @@ REGISTER_OBJECT_WRAPPER( osgAnimation_RigGeometry, ADD_OBJECT_SERIALIZER( RigTransformImplementation, osgAnimation::RigTransform, NULL ); // _geometry } } +} diff --git a/src/osgWrappers/serializers/osgAnimation/RigTransform.cpp b/src/osgWrappers/serializers/osgAnimation/RigTransform.cpp index 82ba7b05d..8b1197f83 100644 --- a/src/osgWrappers/serializers/osgAnimation/RigTransform.cpp +++ b/src/osgWrappers/serializers/osgAnimation/RigTransform.cpp @@ -1,6 +1,7 @@ #include #include +#include #include #include #include @@ -23,3 +24,16 @@ namespace wrap_osgAnimationRigTransformHardWare{ osgAnimation::RigTransformHardware, "osg::Object osgAnimation::RigTransform osgAnimation::RigTransformHardware" ){} } + +namespace wrap_osgAnimationMorphTransform{ + REGISTER_OBJECT_WRAPPER( osgAnimation_MorphTransform, + NULL, + osgAnimation::MorphTransform, + "osg::Object osgAnimation::MorphTransform" ){} +} +namespace wrap_osgAnimationMorphTransformSoftWare{ + REGISTER_OBJECT_WRAPPER( osgAnimation_MorphTransformSoftware, + new osgAnimation::MorphTransformSoftware, + osgAnimation::MorphTransformSoftware, + "osg::Object osgAnimation::MorphTransform osgAnimation::MorphTransformSoftware" ){} +} From 4f0256bcc38e9a54b218b5c68bbab3b17c3f06ca Mon Sep 17 00:00:00 2001 From: Julien Valentin Date: Sun, 27 Aug 2017 00:10:52 +0200 Subject: [PATCH 003/327] remove unused code and remove a commented section --- src/osgAnimation/RigTransformSoftware.cpp | 45 ++--------------------- 1 file changed, 3 insertions(+), 42 deletions(-) diff --git a/src/osgAnimation/RigTransformSoftware.cpp b/src/osgAnimation/RigTransformSoftware.cpp index 79224cdd1..4ab524cdb 100644 --- a/src/osgAnimation/RigTransformSoftware.cpp +++ b/src/osgAnimation/RigTransformSoftware.cpp @@ -34,45 +34,6 @@ RigTransformSoftware::RigTransformSoftware(const RigTransformSoftware& rts,const } -// sort by name and weight -struct SortByNameAndWeight : public std::less -{ - bool operator()(const VertexInfluenceSet::BoneWeight& b0, - const VertexInfluenceSet::BoneWeight& 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 VertexInfluenceSet::BoneWeightList& b0, - const VertexInfluenceSet::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()) @@ -186,13 +147,13 @@ void RigTransformSoftware::initVertexSetFromBones(const BoneMap& map, const Vert } // if a bone referenced by a vertexinfluence is missed it can make the sum less than 1.0 // so we check it and renormalize the all weight bone - /*const double threshold = 1e-4; - if (!_boneSetVertexSet[i].getBones().empty() && + const double threshold = 1e-4; + if (!vg.getBones().empty() && (sumOfWeight < 1.0 - threshold || sumOfWeight > 1.0 + threshold)) { for (int b = 0; b < (int)boneList.size(); b++) boneList[b].setWeight(boneList[b].getWeight() / sumOfWeight); - }*/ + } _uniqInfluenceSet2VertIDList[i].getVertexes() = vg.getVertexes(); } } From ca224c81dd9fb238d011efbcdee932b874cc0320 Mon Sep 17 00:00:00 2001 From: Julien Valentin Date: Sun, 27 Aug 2017 02:14:12 +0200 Subject: [PATCH 004/327] replace VertexInfluence to BoneInfluenceList and VertexIndexWeight to IndexWeight fix in example --- .../osganimationhardware/osganimationhardware.cpp | 2 +- .../osganimationskinning/osganimationskinning.cpp | 6 +++--- include/osgAnimation/VertexInfluence | 14 +++++++------- src/osgAnimation/VertexInfluence.cpp | 6 +++--- src/osgPlugins/gles/AABBonBoneVisitor.cpp | 2 +- src/osgPlugins/gles/MostInfluencedGeometryByBone | 4 ++-- .../osgAnimation/ReaderWriter.cpp | 8 ++++---- .../serializers/osgAnimation/RigGeometry.cpp | 8 ++++---- 8 files changed, 25 insertions(+), 25 deletions(-) diff --git a/examples/osganimationhardware/osganimationhardware.cpp b/examples/osganimationhardware/osganimationhardware.cpp index afd56015c..74aacb7ba 100644 --- a/examples/osganimationhardware/osganimationhardware.cpp +++ b/examples/osganimationhardware/osganimationhardware.cpp @@ -145,7 +145,7 @@ struct SetupRigGeometry : public osg::NodeVisitor if (_hardware) { osgAnimation::RigGeometry* rig = dynamic_cast(&geom); if (rig) - rig->setRigTransformImplementation(new MyRigTransformHardware); + rig->setRigTransformImplementation(new osgAnimation::RigTransformHardware); } #if 0 diff --git a/examples/osganimationskinning/osganimationskinning.cpp b/examples/osganimationskinning/osganimationskinning.cpp index 7bfa9b017..bbf4614fb 100644 --- a/examples/osganimationskinning/osganimationskinning.cpp +++ b/examples/osganimationskinning/osganimationskinning.cpp @@ -146,11 +146,11 @@ void initVertexMap(osgAnimation::Bone* b0, float val = (*array)[i][0]; std::cout << val << std::endl; if (val >= -1.0f && val <= 0.0f) - (*vim)[b0->getName()].push_back(osgAnimation::VertexIndexWeight(i,1.0f)); + (*vim)[b0->getName()].push_back(osgAnimation::IndexWeight(i,1.0f)); else if ( val > 0.0f && val <= 1.0f) - (*vim)[b1->getName()].push_back(osgAnimation::VertexIndexWeight(i,1.0f)); + (*vim)[b1->getName()].push_back(osgAnimation::IndexWeight(i,1.0f)); else if ( val > 1.0f) - (*vim)[b2->getName()].push_back(osgAnimation::VertexIndexWeight(i,1.0f)); + (*vim)[b2->getName()].push_back(osgAnimation::IndexWeight(i,1.0f)); } geom->setInfluenceMap(vim); diff --git a/include/osgAnimation/VertexInfluence b/include/osgAnimation/VertexInfluence index 345b25db4..0b777e283 100644 --- a/include/osgAnimation/VertexInfluence +++ b/include/osgAnimation/VertexInfluence @@ -25,9 +25,9 @@ namespace osgAnimation { // first is vertex index, and second the weight, the - typedef std::pair VertexIndexWeight; - typedef std::vector VertexList; - class OSGANIMATION_EXPORT VertexInfluence : public VertexList + typedef std::pair IndexWeight; + typedef std::vector VertexList; + class OSGANIMATION_EXPORT BoneInfluenceList : public VertexList { public: const std::string& getName() const { return _name;} @@ -38,14 +38,14 @@ namespace osgAnimation std::string _name; }; - class VertexInfluenceMap : public std::map , public osg::Object + class VertexInfluenceMap : public std::map , public osg::Object { public: META_Object(osgAnimation, VertexInfluenceMap); VertexInfluenceMap() {} VertexInfluenceMap(const osgAnimation::VertexInfluenceMap& org, const osg::CopyOp& copyop): - std::map(org), + std::map(org), osg::Object(org, copyop) {} }; @@ -56,7 +56,7 @@ namespace osgAnimation class OSGANIMATION_EXPORT VertexInfluenceSet { public: - typedef std::vector BoneToVertexList; + typedef std::vector BoneToVertexList; class BoneWeight { @@ -95,7 +95,7 @@ namespace osgAnimation void buildUniqVertexGroupList(); /** return a list of unique VertexGroups and their influences**/ const UniqVertexGroupList& getUniqVertexGroupList() const { return _uniqVertexSetToBoneSet;} - void addVertexInfluence(const VertexInfluence& v); + void addVertexInfluence(const BoneInfluenceList& v); void buildVertex2BoneList(unsigned int numvertices); void clear(); diff --git a/src/osgAnimation/VertexInfluence.cpp b/src/osgAnimation/VertexInfluence.cpp index f5a983234..b1b10fa26 100644 --- a/src/osgAnimation/VertexInfluence.cpp +++ b/src/osgAnimation/VertexInfluence.cpp @@ -20,7 +20,7 @@ using namespace osgAnimation; -void VertexInfluenceSet::addVertexInfluence(const VertexInfluence& v) { _bone2Vertexes.push_back(v); } +void VertexInfluenceSet::addVertexInfluence(const BoneInfluenceList& v) { _bone2Vertexes.push_back(v); } const VertexInfluenceSet::VertIDToBoneWeightList& VertexInfluenceSet::getVertexToBoneList() const { return _vertex2Bones;} // this class manage VertexInfluence database by mesh // reference bones per vertex ... @@ -33,11 +33,11 @@ void VertexInfluenceSet::buildVertex2BoneList(unsigned int numvertices) for (BoneToVertexList::const_iterator it = _bone2Vertexes.begin(); it != _bone2Vertexes.end(); ++it) { - const VertexInfluence& vi = (*it); + const BoneInfluenceList& vi = (*it); int size = vi.size(); for (int i = 0; i < size; i++) { - VertexIndexWeight viw = vi[i]; + IndexWeight viw = vi[i]; int index = viw.first; float weight = viw.second; if (vi.getName().empty()){ diff --git a/src/osgPlugins/gles/AABBonBoneVisitor.cpp b/src/osgPlugins/gles/AABBonBoneVisitor.cpp index 0ea5302f7..5b3fc99dd 100644 --- a/src/osgPlugins/gles/AABBonBoneVisitor.cpp +++ b/src/osgPlugins/gles/AABBonBoneVisitor.cpp @@ -51,7 +51,7 @@ void ComputeAABBOnBoneVisitor::computeBoundingBoxOnBones() { osg::Vec3Array *vertices = dynamic_cast(rigGeometry->getVertexArray()); if(!vertices) continue; - osgAnimation::VertexInfluence vxtInf = (*itMap).second; + osgAnimation::BoneInfluenceList vxtInf = (*itMap).second; //Expand the boundingBox with each vertex for(unsigned int j = 0; j < vxtInf.size(); j++) { diff --git a/src/osgPlugins/gles/MostInfluencedGeometryByBone b/src/osgPlugins/gles/MostInfluencedGeometryByBone index 024d87ddb..a5e8c5e97 100644 --- a/src/osgPlugins/gles/MostInfluencedGeometryByBone +++ b/src/osgPlugins/gles/MostInfluencedGeometryByBone @@ -200,9 +200,9 @@ protected: BoneNameBoneMap::iterator bone_it = boneMap.find(vertexInfluencePair->first); if(bone_it == boneMap.end()) continue; osg::ref_ptr bone = bone_it->second; - const osgAnimation::VertexInfluence& vertexInfluence = (*vertexInfluencePair).second; + const osgAnimation::BoneInfluenceList& vertexInfluence = (*vertexInfluencePair).second; - for(osgAnimation::VertexInfluence::const_iterator vertexIndexWeight = vertexInfluence.begin(); vertexIndexWeight != vertexInfluence.end(); ++vertexIndexWeight) { + for(osgAnimation::BoneInfluenceList::const_iterator vertexIndexWeight = vertexInfluence.begin(); vertexIndexWeight != vertexInfluence.end(); ++vertexIndexWeight) { rigGeometryInfluenceByBoneMap[bone.get()][*rigGeometry].addWeight((*vertexIndexWeight).second); } } diff --git a/src/osgWrappers/deprecated-dotosg/osgAnimation/ReaderWriter.cpp b/src/osgWrappers/deprecated-dotosg/osgAnimation/ReaderWriter.cpp index add7f50fd..78824ad7c 100644 --- a/src/osgWrappers/deprecated-dotosg/osgAnimation/ReaderWriter.cpp +++ b/src/osgWrappers/deprecated-dotosg/osgAnimation/ReaderWriter.cpp @@ -813,7 +813,7 @@ bool RigGeometry_readLocalData(Object& obj, Input& fr) iteratorAdvanced = true; } - osgAnimation::VertexInfluence vi; + osgAnimation::BoneInfluenceList vi; vi.setName(name); vi.reserve(nbVertexes); for (int j = 0; j < nbVertexes; j++) @@ -827,7 +827,7 @@ bool RigGeometry_readLocalData(Object& obj, Input& fr) fr += 2; iteratorAdvanced = true; } - vi.push_back(osgAnimation::VertexIndexWeight(index, weight)); + vi.push_back(osgAnimation::IndexWeight(index, weight)); } if (fr.matchSequence("}")) { @@ -863,8 +863,8 @@ bool RigGeometry_writeLocalData(const Object& obj, Output& fw) name = "Empty"; fw.indent() << "osgAnimation::VertexInfluence \"" << name << "\" " << it->second.size() << " {" << std::endl; fw.moveIn(); - const osgAnimation::VertexInfluence& vi = it->second; - for (osgAnimation::VertexInfluence::const_iterator itv = vi.begin(); itv != vi.end(); itv++) + const osgAnimation::BoneInfluenceList& vi = it->second; + for (osgAnimation::BoneInfluenceList::const_iterator itv = vi.begin(); itv != vi.end(); itv++) { fw.indent() << itv->first << " " << itv->second << std::endl; } diff --git a/src/osgWrappers/serializers/osgAnimation/RigGeometry.cpp b/src/osgWrappers/serializers/osgAnimation/RigGeometry.cpp index 7c25e0376..5259d1e95 100644 --- a/src/osgWrappers/serializers/osgAnimation/RigGeometry.cpp +++ b/src/osgWrappers/serializers/osgAnimation/RigGeometry.cpp @@ -20,7 +20,7 @@ static bool readInfluenceMap( osgDB::InputStream& is, osgAnimation::RigGeometry& is.readWrappedString(name); viSize = is.readSize(); is >> is.BEGIN_BRACKET; - osgAnimation::VertexInfluence vi; + osgAnimation::BoneInfluenceList vi; vi.setName( name ); vi.reserve( viSize ); for ( unsigned int j=0; j> index >> weight; - vi.push_back( osgAnimation::VertexIndexWeight(index, weight) ); + vi.push_back( osgAnimation::IndexWeight(index, weight) ); } (*map)[name] = vi; is >> is.END_BRACKET; @@ -47,14 +47,14 @@ static bool writeInfluenceMap( osgDB::OutputStream& os, const osgAnimation::RigG itr!=map->end(); ++itr ) { std::string name = itr->first; - const osgAnimation::VertexInfluence& vi = itr->second; + const osgAnimation::BoneInfluenceList& vi = itr->second; if ( name.empty() ) name = "Empty"; os << os.PROPERTY("VertexInfluence"); os.writeWrappedString(name); os.writeSize(vi.size()) ; os << os.BEGIN_BRACKET << std::endl; - for ( osgAnimation::VertexInfluence::const_iterator vitr=vi.begin(); + for ( osgAnimation::BoneInfluenceList::const_iterator vitr=vi.begin(); vitr != vi.end(); ++vitr ) { os << vitr->first << vitr->second << std::endl; From ed04e2735e1d3772640cc5bfbb733cb6126e792e Mon Sep 17 00:00:00 2001 From: Julien Valentin Date: Mon, 28 Aug 2017 04:42:51 +0200 Subject: [PATCH 005/327] readd virtual void transformSoftwareMethod() for retrocompatibity --- include/osgAnimation/MorphGeometry | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/include/osgAnimation/MorphGeometry b/include/osgAnimation/MorphGeometry index e8c89d22d..57d54ebfb 100644 --- a/include/osgAnimation/MorphGeometry +++ b/include/osgAnimation/MorphGeometry @@ -89,7 +89,7 @@ namespace osgAnimation /** Set source of vertices for this morph geometry */ inline void setVertexSource(osg::Vec3Array *v){ _positionSource=v;} - + /** Get source of vertices for this morph geometry */ inline osg::Vec3Array * getVertexSource()const{return _positionSource;} @@ -143,6 +143,8 @@ namespace osgAnimation inline void dirty(bool b=true) { _dirty = b; } inline bool isDirty()const { return _dirty; } + /** for retrocompatibility */ + virtual void transformSoftwareMethod(){ if (!_rigTransformImplementation.valid()_rigTransformImplementation = new MorphTransformSoftware();_rigTransformImplementation(*this);} protected: osg::ref_ptr _rigTransformImplementation; From 2b2a8f3d2e4c1df988b16550b2be9d6aa171d825 Mon Sep 17 00:00:00 2001 From: Julien Valentin Date: Mon, 28 Aug 2017 04:51:52 +0200 Subject: [PATCH 006/327] MorphTransformHardware using TBO added --- include/osgAnimation/MorphTransformHardware | 60 ++++++ src/osgAnimation/CMakeLists.txt | 2 + src/osgAnimation/MorphTransformHardware.cpp | 197 ++++++++++++++++++++ 3 files changed, 259 insertions(+) create mode 100644 include/osgAnimation/MorphTransformHardware create mode 100644 src/osgAnimation/MorphTransformHardware.cpp diff --git a/include/osgAnimation/MorphTransformHardware b/include/osgAnimation/MorphTransformHardware new file mode 100644 index 000000000..e75114a74 --- /dev/null +++ b/include/osgAnimation/MorphTransformHardware @@ -0,0 +1,60 @@ +/* -*-c++-*- + * Copyright (C) 2009 Cedric Pinson + * + * This library is open source and may be redistributed and/or modified under + * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or + * (at your option) any later version. The full license is in LICENSE file + * included with this distribution, and on the openscenegraph.org website. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * OpenSceneGraph Public License for more details. + */ + +#ifndef OSGANIMATION_MORPH_TRANSFORM_HARDWARE +#define OSGANIMATION_MORPH_TRANSFORM_HARDWARE 1 + +#include +#include +#include +#include +#include +#include + +namespace osgAnimation +{ + class MorphGeometry; + + /// This class manage format for hardware morphing + class OSGANIMATION_EXPORT MorphTransformHardware : public MorphTransform + { + public: + + MorphTransformHardware(); + + MorphTransformHardware(const MorphTransformHardware& rth, const osg::CopyOp& copyop); + + META_Object(osgAnimation,MorphTransformHardware); + + + + + virtual void operator()(MorphGeometry&); + void setShader(osg::Shader*); + + + + protected: + + bool init(MorphGeometry&); + + + osg::ref_ptr _uniformTargetsWeight; + osg::ref_ptr _shader; + + bool _needInit; + }; +} + +#endif diff --git a/src/osgAnimation/CMakeLists.txt b/src/osgAnimation/CMakeLists.txt index dc199ef9c..7a79b914d 100644 --- a/src/osgAnimation/CMakeLists.txt +++ b/src/osgAnimation/CMakeLists.txt @@ -34,6 +34,7 @@ SET(TARGET_H ${HEADER_PATH}/RigTransform ${HEADER_PATH}/RigTransformHardware ${HEADER_PATH}/RigTransformSoftware + ${HEADER_PATH}/MorphTransformHardware ${HEADER_PATH}/MorphTransformSoftware ${HEADER_PATH}/Sampler ${HEADER_PATH}/Skeleton @@ -76,6 +77,7 @@ SET(TARGET_SRC RigGeometry.cpp RigTransformHardware.cpp RigTransformSoftware.cpp + MorphTransformHardware.cpp MorphTransformSoftware.cpp Skeleton.cpp StackedMatrixElement.cpp diff --git a/src/osgAnimation/MorphTransformHardware.cpp b/src/osgAnimation/MorphTransformHardware.cpp new file mode 100644 index 000000000..be37a470a --- /dev/null +++ b/src/osgAnimation/MorphTransformHardware.cpp @@ -0,0 +1,197 @@ +/* -*-c++-*- + * Copyleft 2016 Valentin Julien + * + * This library is open source and may be redistributed and/or modified under + * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or + * (at your option) any later version. The full license is in LICENSE file + * included with this distribution, and on the openscenegraph.org website. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * OpenSceneGraph Public License for more details. + */ + +#include +#include +#include +#include +#include + +///texture unit reserved for morphtarget TBO +#define MORPHTEXTUREUNIT 7 + +using namespace osgAnimation; + +MorphTransformHardware::MorphTransformHardware() +{ + _needInit = true; + +} + +MorphTransformHardware::MorphTransformHardware(const MorphTransformHardware& rth, const osg::CopyOp& copyop): + MorphTransform(rth, copyop), + _uniformTargetsWeight(rth._uniformTargetsWeight), + _shader(rth._shader), + _needInit(rth._needInit) +{ +} + +void MorphTransformHardware::setShader(osg::Shader* shader) +{ + _shader = shader; +} + +bool MorphTransformHardware::init(MorphGeometry& morphGeometry) +{ + osg::Vec3Array* pos = dynamic_cast(morphGeometry.getVertexArray()); + + osg::Vec3Array * vertexSource = (morphGeometry.getVertexSource()); + osg::Vec3Array * normalSource = (morphGeometry.getNormalSource()); + morphGeometry.setDataVariance(osg::Object::STATIC); + ///check for correct morph configuration + ///(blender osgexport doesn't set sources so assume morphgeom arrays are sources) + if(pos) + { + ///check if source is setted correctly + if (!vertexSource|| vertexSource->size() != pos->size()) + { + vertexSource =(static_cast( pos->clone(osg::CopyOp::DEEP_COPY_ARRAYS)));//osg::Vec3Array(pos->begin(),pos->end()); + pos->setDataVariance(osg::Object::DYNAMIC); + } + osg::Vec3Array* normal = dynamic_cast(morphGeometry.getNormalArray()); + bool normalmorphable = morphGeometry.getMorphNormals() && normal; + if(!normalmorphable) { + OSG_WARN << "MorphTransformHardware::morph geometry "<size() != normal->size())) + { + normalSource =(static_cast( normal->clone(osg::CopyOp::DEEP_COPY_ARRAYS)));//osg::Vec3Array(normal->begin(),normal->end()); + normal->setDataVariance(osg::Object::DYNAMIC); + } + } + ///end check + morphGeometry.setVertexArray(morphGeometry.getVertexSource()); + morphGeometry.setNormalArray(morphGeometry.getNormalSource(),osg::Array::BIND_PER_VERTEX); + morphGeometry.setDataVariance(osg::Object::STATIC); + + //create one TBO for all morphtargets (pack vertex/normal) + osg::Vec3Array * morphTargets=new osg::Vec3Array ; + MorphGeometry::MorphTargetList & morphlist=morphGeometry.getMorphTargetList(); + for(MorphGeometry::MorphTargetList::const_iterator curmorph=morphlist.begin(); curmorph!=morphlist.end(); ++curmorph) { + const osg::Geometry * morphtargetgeom= curmorph->getGeometry() ; + const osg::Vec3Array *varray=(osg::Vec3Array*)morphtargetgeom->getVertexArray(); + const osg::Vec3Array *narray=(osg::Vec3Array*)morphtargetgeom->getNormalArray(); + if(morphGeometry.getMethod()==MorphGeometry::RELATIVE){ + for(unsigned int i=0; igetNumElements(); ++i) { + morphTargets->push_back( (*varray)[i]); + morphTargets->push_back( (*narray)[i]); + } + }else{ + //convert to RELATIVE as it involve less math in the VS than NORMALIZED + const osg::Vec3Array *ovarray=(osg::Vec3Array*)morphGeometry.getVertexArray(); + const osg::Vec3Array *onarray=(osg::Vec3Array*)morphGeometry.getNormalArray(); + for(unsigned int i=0; igetNumElements(); ++i) { + morphTargets->push_back( (*varray)[i]- (*ovarray)[i] ); + morphTargets->push_back( (*narray)[i]- (*onarray)[i] ); + } + } + } + osg::TextureBuffer * morphTargetsTBO=new osg::TextureBuffer(); + morphTargetsTBO->setBufferData(morphTargets); + morphTargetsTBO->setInternalFormat( GL_RGB32F_ARB ); + + //create TBO Texture handle + osg::Uniform * morphTBOHandle=new osg::Uniform(osg::Uniform::SAMPLER_BUFFER,"morphTargets"); + morphTBOHandle->set(MORPHTEXTUREUNIT); + + //create dynamic uniform for morphtargets animation weights + _uniformTargetsWeight=new osg::Uniform(osg::Uniform::FLOAT,"morphWeights",morphlist.size()); + + + osg::ref_ptr program ; + osg::ref_ptr vertexshader; + osg::ref_ptr stateset = morphGeometry.getOrCreateStateSet(); + //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("HardwareMorphing"); + //set default source if _shader is not user setted + if (!vertexshader.valid()){ + if (!_shader.valid()) + vertexshader = osg::Shader::readShaderFile(osg::Shader::VERTEX,"morphing.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_MORPHWEIGHT"); + std::size_t start = str.find(toreplace); + if (std::string::npos == start){ + ///perhaps remanance from previous init (if saved after init) so reload shader + + vertexshader = osg::Shader::readShaderFile(osg::Shader::VERTEX,"morphing.vert"); + if (!vertexshader.valid()) { + OSG_WARN << "RigTransformHardware can't load VertexShader" << std::endl; + return false; + } + str = vertexshader->getShaderSource(); + start = str.find(toreplace); + } + if (std::string::npos != start) { + std::stringstream ss; + ss << _uniformTargetsWeight->getNumElements(); + str.replace(start, toreplace.size(), ss.str()); + vertexshader->setShaderSource(str); + } + else + { + OSG_WARN << "MAX_MORPHWEIGHT not found in Shader! " << str << std::endl; + } + OSG_INFO << "Shader " << str << std::endl; + } + + + + program->addShader(vertexshader.get()); + //morphGeometry.setStateSet((osg::StateSet *) osg::CopyOp()(source.getOrCreateStateSet())); + + osg::ref_ptr ss = morphGeometry.getOrCreateStateSet(); + ss->addUniform(_uniformTargetsWeight); + ss->setTextureAttribute(MORPHTEXTUREUNIT,morphTargetsTBO); + ss->addUniform( morphTBOHandle); + ss->addUniform(new osg::Uniform("nbMorphVertex", morphGeometry.getVertexArray()->getNumElements())); + + ss->setAttributeAndModes(program.get()); + _needInit = false; + return true; +} +void MorphTransformHardware::operator()(MorphGeometry& geom) +{ + if (_needInit) + if (!init(geom)) + return; + + ///upload new morph weights each update via uniform + int curimorph=0; + MorphGeometry::MorphTargetList & morphlist=geom.getMorphTargetList(); + for(MorphGeometry::MorphTargetList::const_iterator curmorph=morphlist.begin(); curmorph!=morphlist.end(); ++curmorph) + _uniformTargetsWeight->setElement(curimorph++, curmorph->getWeight()); + _uniformTargetsWeight->dirty(); +} From f46fdb4d4ec06f58fbeb038c62d9cfc64860e0aa Mon Sep 17 00:00:00 2001 From: Julien Valentin Date: Mon, 28 Aug 2017 05:17:17 +0200 Subject: [PATCH 007/327] add a new prepareData method to the interface --- include/osgAnimation/RigTransform | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/include/osgAnimation/RigTransform b/include/osgAnimation/RigTransform index 184cdae0c..7be592035 100644 --- a/include/osgAnimation/RigTransform +++ b/include/osgAnimation/RigTransform @@ -33,6 +33,10 @@ namespace osgAnimation virtual void operator()(RigGeometry&) {} + /// to call manually when a skeleton is reacheable from the rig + /// in order to prepare technic data before rendering + virtual bool prepareData(RigGeometry&){} + protected: virtual ~RigTransform() {} From 6dc6bd5b922079c385d2333c6e186c095d72aeb4 Mon Sep 17 00:00:00 2001 From: Julien Valentin Date: Mon, 28 Aug 2017 05:22:14 +0200 Subject: [PATCH 008/327] fix a bug introduced when readding transformsoftwareMethod --- include/osgAnimation/MorphGeometry | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/osgAnimation/MorphGeometry b/include/osgAnimation/MorphGeometry index 57d54ebfb..f74fdff85 100644 --- a/include/osgAnimation/MorphGeometry +++ b/include/osgAnimation/MorphGeometry @@ -144,7 +144,7 @@ namespace osgAnimation inline bool isDirty()const { return _dirty; } /** for retrocompatibility */ - virtual void transformSoftwareMethod(){ if (!_rigTransformImplementation.valid()_rigTransformImplementation = new MorphTransformSoftware();_rigTransformImplementation(*this);} + virtual void transformSoftwareMethod(){ if (!_rigTransformImplementation.valid())_rigTransformImplementation = new MorphTransformSoftware();_rigTransformImplementation(*this);} protected: osg::ref_ptr _rigTransformImplementation; From 66aedbb0b365616659480fb32c167cf812adea48 Mon Sep 17 00:00:00 2001 From: Julien Valentin Date: Mon, 28 Aug 2017 05:22:14 +0200 Subject: [PATCH 009/327] fix a bug introduced when readding transformsoftwareMethod --- include/osgAnimation/MorphGeometry | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/osgAnimation/MorphGeometry b/include/osgAnimation/MorphGeometry index 57d54ebfb..a1ec3f697 100644 --- a/include/osgAnimation/MorphGeometry +++ b/include/osgAnimation/MorphGeometry @@ -144,7 +144,7 @@ namespace osgAnimation inline bool isDirty()const { return _dirty; } /** for retrocompatibility */ - virtual void transformSoftwareMethod(){ if (!_rigTransformImplementation.valid()_rigTransformImplementation = new MorphTransformSoftware();_rigTransformImplementation(*this);} + virtual void transformSoftwareMethod(){ if (!_rigTransformImplementation.valid())_rigTransformImplementation = new MorphTransformSoftware();(*_rigTransformImplementation.get())(*this);} protected: osg::ref_ptr _rigTransformImplementation; From e2168332864742cf4455c34e6f9efaadf4aadb85 Mon Sep 17 00:00:00 2001 From: Julien Valentin Date: Mon, 28 Aug 2017 14:23:15 +0200 Subject: [PATCH 010/327] 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 Date: Mon, 28 Aug 2017 14:25:12 +0200 Subject: [PATCH 011/327] add prepareData for rigttransform software --- include/osgAnimation/RigTransformSoftware | 3 + src/osgAnimation/RigTransformSoftware.cpp | 138 ++++++++++++++++++++++ 2 files changed, 141 insertions(+) diff --git a/include/osgAnimation/RigTransformSoftware b/include/osgAnimation/RigTransformSoftware index 677f5e619..c468322cb 100644 --- a/include/osgAnimation/RigTransformSoftware +++ b/include/osgAnimation/RigTransformSoftware @@ -36,6 +36,8 @@ namespace osgAnimation META_Object(osgAnimation,RigTransformSoftware) virtual void operator()(RigGeometry&); + //to call when a skeleton is reacheable from the rig to prepare technic data + virtual bool prepareData(RigGeometry&); class BonePtrWeight: public BoneWeight { @@ -172,6 +174,7 @@ namespace osgAnimation std::map _invalidInfluence; + void buildMinimumUpdateSet(const BoneMap&boneMap,const RigGeometry&rig ); }; } diff --git a/src/osgAnimation/RigTransformSoftware.cpp b/src/osgAnimation/RigTransformSoftware.cpp index 455fddb2b..ca13a71a7 100644 --- a/src/osgAnimation/RigTransformSoftware.cpp +++ b/src/osgAnimation/RigTransformSoftware.cpp @@ -115,6 +115,144 @@ bool RigTransformSoftware::init(RigGeometry& geom) return true; } +void RigTransformSoftware::buildMinimumUpdateSet(const BoneMap&boneMap,const RigGeometry&rig ){ + + ///1 Create Index2Vec + typedef std::vector BoneWeightList; + typedef std::vector VertIDToBoneWeightList; + + VertIDToBoneWeightList _vertex2Bones; + _vertex2Bones.clear(); + _vertex2Bones.resize(rig.getSourceGeometry()->getVertexArray()->getNumElements()); + + const VertexInfluenceMap *_vertexInfluenceMap=rig.getInfluenceMap(); + for (osgAnimation::VertexInfluenceMap::const_iterator it = _vertexInfluenceMap->begin(); + it != _vertexInfluenceMap->end(); + ++it) + { + const BoneInfluenceList& inflist = it->second; + for(BoneInfluenceList::const_iterator infit=inflist.begin(); infit!=inflist.end(); ++infit) + { + const IndexWeight &iw = *infit; + const unsigned int &index = iw.getIndex(); + float weight = iw.getWeight(); + if (inflist.getBoneName().empty()) { + OSG_WARN << "VertexInfluenceSet::buildVertex2BoneList warning vertex " << index << " is not assigned to a bone" << std::endl; + } + BoneMap::const_iterator it = boneMap.find(inflist.getBoneName()); + if (it == boneMap.end() ) + { + if (_invalidInfluence.find(inflist.getBoneName()) != _invalidInfluence.end()) { + _invalidInfluence[inflist.getBoneName()] = true; + OSG_WARN << "RigTransformSoftware Bone " << inflist.getBoneName() << " not found, skip the influence group " << std::endl; + } + continue; + } + Bone* bone = it->second.get(); + _vertex2Bones[index].push_back(BonePtrWeight(inflist.getBoneName(), weight,bone));; + } + } + + // normalize _vertex2Bones weight per vertex + unsigned vertexID=0; + for (VertIDToBoneWeightList::iterator it = _vertex2Bones.begin(); it != _vertex2Bones.end(); ++it, ++vertexID) + { + BoneWeightList& bones = *it; + float sum = 0; + for(BoneWeightList::iterator bwit=bones.begin();bwit!=bones.end();++bwit) + sum += bwit->getWeight(); + if (sum < 1e-4) + { + OSG_WARN << "VertexInfluenceSet::buildVertex2BoneList warning the vertex " << vertexID << " seems to have 0 weight, skip normalize for this vertex" << std::endl; + } + else + { + float mult = 1.0/sum; + for(BoneWeightList::iterator bwit=bones.begin();bwit!=bones.end();++bwit) + bwit->setWeight(bwit->getWeight() * mult); + } + } + + ///2 Create inverse mapping Vec2Vec from previous built Index2Vec + ///in order to minimize weighted matrices computation on update + typedef std::map UnifyBoneGroup; + UnifyBoneGroup unifyBuffer; + vertexID=0; + for (VertIDToBoneWeightList::iterator it = _vertex2Bones.begin(); it != _vertex2Bones.end(); ++it,++vertexID) + { + BoneWeightList& bones = *it; + // sort the vector to have a consistent key + std::sort(bones.begin(), bones.end(), SortByNameAndWeight()); + // we use the vector as key to differentiate group + UnifyBoneGroup::iterator result = unifyBuffer.find(bones); + if (result == unifyBuffer.end()) + unifyBuffer[bones].getBoneWeights()=bones; + unifyBuffer[bones].getVertexes().push_back(vertexID); + } + if(_vertex2Bones.size()==unifyBuffer.size()) { + OSG_WARN << "RigTransformSoftware::build mapping is useless no duplicate VertexGroup : too much " <<_vertex2Bones.size()<<"=="<second); + + + OSG_DEBUG << "uniq groups " << _uniqInfluenceSet2VertIDList.size() << " for " << rig.getName() << std::endl; +} + +bool RigTransformSoftware::prepareData(RigGeometry&rig) { + 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()); + } + BoneMapVisitor mapVisitor; + rig.getSkeleton()->accept(mapVisitor); + BoneMap boneMap = mapVisitor.getBoneMap(); + + buildMinimumUpdateSet(boneMap,rig); + + if (rig.getSourceGeometry()) + rig.copyFrom(*rig.getSourceGeometry()); + + + osg::Vec3Array* normalSrc = dynamic_cast(rig.getSourceGeometry()->getNormalArray()); + osg::Vec3Array* positionSrc = dynamic_cast(rig.getSourceGeometry()->getVertexArray()); + + if(!(positionSrc) || positionSrc->empty() ) + return false; + if(normalSrc&& normalSrc->size()!=positionSrc->size()) + return false; + + + rig.setVertexArray(new osg::Vec3Array); + osg::Vec3Array* positionDst =new osg::Vec3Array; + rig.setVertexArray(positionDst); + *positionDst=*positionSrc; + positionDst->setDataVariance(osg::Object::DYNAMIC); + + + 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; + return true; +} void RigTransformSoftware::operator()(RigGeometry& geom) { if (_needInit) From 2b5ac5b4dbc78e1fa4b15fb1a84df0759d4c9de2 Mon Sep 17 00:00:00 2001 From: Julien Valentin Date: Mon, 28 Aug 2017 15:27:46 +0200 Subject: [PATCH 012/327] add default constructor for IndexWeight with invalid indices --- include/osgAnimation/VertexInfluence | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/osgAnimation/VertexInfluence b/include/osgAnimation/VertexInfluence index 4b2adb347..bf3a9b2be 100644 --- a/include/osgAnimation/VertexInfluence +++ b/include/osgAnimation/VertexInfluence @@ -36,7 +36,7 @@ namespace osgAnimation // first is vertex index, and second the weight struct IndexWeight: public std::pair { - IndexWeight( unsigned int f,float s): std::pair(f,s){} + IndexWeight( unsigned int f = 0xffffffff,float s = 0.0f): 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;} From 4b56a4d3be874f0e27472ddca48d7ad77e374402 Mon Sep 17 00:00:00 2001 From: Julien Valentin Date: Mon, 28 Aug 2017 15:40:04 +0200 Subject: [PATCH 013/327] minor changes+fix --- src/osgAnimation/RigTransformSoftware.cpp | 50 ++++++++++++----------- 1 file changed, 27 insertions(+), 23 deletions(-) diff --git a/src/osgAnimation/RigTransformSoftware.cpp b/src/osgAnimation/RigTransformSoftware.cpp index ca13a71a7..512e0a407 100644 --- a/src/osgAnimation/RigTransformSoftware.cpp +++ b/src/osgAnimation/RigTransformSoftware.cpp @@ -118,44 +118,45 @@ bool RigTransformSoftware::init(RigGeometry& geom) void RigTransformSoftware::buildMinimumUpdateSet(const BoneMap&boneMap,const RigGeometry&rig ){ ///1 Create Index2Vec - typedef std::vector BoneWeightList; - typedef std::vector VertIDToBoneWeightList; - - VertIDToBoneWeightList _vertex2Bones; - _vertex2Bones.clear(); + std::vector _vertex2Bones; _vertex2Bones.resize(rig.getSourceGeometry()->getVertexArray()->getNumElements()); + typedef std::pair FloatInt; + std::vector< FloatInt > sums;///stat totalweight nbref + sums.resize(rig.getSourceGeometry()->getVertexArray()->getNumElements() + ); const VertexInfluenceMap *_vertexInfluenceMap=rig.getInfluenceMap(); for (osgAnimation::VertexInfluenceMap::const_iterator it = _vertexInfluenceMap->begin(); it != _vertexInfluenceMap->end(); ++it) { const BoneInfluenceList& inflist = it->second; + if (inflist.getBoneName().empty()) { + OSG_WARN << "RigTransformSoftware::VertexInfluenceMap contains unamed bone BoneInfluenceList" << std::endl; + } + BoneMap::const_iterator bmit = boneMap.find(inflist.getBoneName()); + if (bmit == boneMap.end() ) + { + if (_invalidInfluence.find(inflist.getBoneName()) != _invalidInfluence.end()) { + _invalidInfluence[inflist.getBoneName()] = true; + OSG_WARN << "RigTransformSoftware Bone " << inflist.getBoneName() << " not found, skip the influence group " << std::endl; + } + continue; + } + Bone* bone = bmit->second.get(); for(BoneInfluenceList::const_iterator infit=inflist.begin(); infit!=inflist.end(); ++infit) { const IndexWeight &iw = *infit; const unsigned int &index = iw.getIndex(); float weight = iw.getWeight(); - if (inflist.getBoneName().empty()) { - OSG_WARN << "VertexInfluenceSet::buildVertex2BoneList warning vertex " << index << " is not assigned to a bone" << std::endl; - } - BoneMap::const_iterator it = boneMap.find(inflist.getBoneName()); - if (it == boneMap.end() ) - { - if (_invalidInfluence.find(inflist.getBoneName()) != _invalidInfluence.end()) { - _invalidInfluence[inflist.getBoneName()] = true; - OSG_WARN << "RigTransformSoftware Bone " << inflist.getBoneName() << " not found, skip the influence group " << std::endl; - } - continue; - } - Bone* bone = it->second.get(); + _vertex2Bones[index].push_back(BonePtrWeight(inflist.getBoneName(), weight,bone));; } } // normalize _vertex2Bones weight per vertex unsigned vertexID=0; - for (VertIDToBoneWeightList::iterator it = _vertex2Bones.begin(); it != _vertex2Bones.end(); ++it, ++vertexID) + for (std::vector::iterator it = _vertex2Bones.begin(); it != _vertex2Bones.end(); ++it, ++vertexID) { BoneWeightList& bones = *it; float sum = 0; @@ -178,7 +179,7 @@ void RigTransformSoftware::buildMinimumUpdateSet(const BoneMap&boneMap,const Rig typedef std::map UnifyBoneGroup; UnifyBoneGroup unifyBuffer; vertexID=0; - for (VertIDToBoneWeightList::iterator it = _vertex2Bones.begin(); it != _vertex2Bones.end(); ++it,++vertexID) + for (std::vector::iterator it = _vertex2Bones.begin(); it != _vertex2Bones.end(); ++it,++vertexID) { BoneWeightList& bones = *it; // sort the vector to have a consistent key @@ -198,11 +199,11 @@ void RigTransformSoftware::buildMinimumUpdateSet(const BoneMap&boneMap,const Rig for (UnifyBoneGroup::iterator it = unifyBuffer.begin(); it != unifyBuffer.end(); ++it) _uniqInfluenceSet2VertIDList.push_back(it->second); - OSG_DEBUG << "uniq groups " << _uniqInfluenceSet2VertIDList.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; @@ -217,12 +218,15 @@ bool RigTransformSoftware::prepareData(RigGeometry&rig) { } rig.setSkeleton(finder._root.get()); } + ///get bonemap from skeleton BoneMapVisitor mapVisitor; rig.getSkeleton()->accept(mapVisitor); BoneMap boneMap = mapVisitor.getBoneMap(); + /// build minimal set of VertexGroup buildMinimumUpdateSet(boneMap,rig); + ///set geom as it source if (rig.getSourceGeometry()) rig.copyFrom(*rig.getSourceGeometry()); @@ -235,14 +239,13 @@ bool RigTransformSoftware::prepareData(RigGeometry&rig) { 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; rig.setVertexArray(positionDst); *positionDst=*positionSrc; positionDst->setDataVariance(osg::Object::DYNAMIC); - if(normalSrc) { osg::Vec3Array* normalDst =new osg::Vec3Array; *normalDst=*normalSrc; @@ -253,6 +256,7 @@ bool RigTransformSoftware::prepareData(RigGeometry&rig) { _needInit = false; return true; } + void RigTransformSoftware::operator()(RigGeometry& geom) { if (_needInit) From 3efaccb2980eeb7302f403d63b17e11f570ddb11 Mon Sep 17 00:00:00 2001 From: Julien Valentin Date: Mon, 28 Aug 2017 15:41:14 +0200 Subject: [PATCH 014/327] add prepareData for RigTransformHW --- include/osgAnimation/RigTransformHardware | 9 +- src/osgAnimation/RigTransformHardware.cpp | 284 +++++++++++++++++++++- 2 files changed, 285 insertions(+), 8 deletions(-) diff --git a/include/osgAnimation/RigTransformHardware b/include/osgAnimation/RigTransformHardware index 28330e87e..4c2aa1875 100644 --- a/include/osgAnimation/RigTransformHardware +++ b/include/osgAnimation/RigTransformHardware @@ -43,7 +43,7 @@ namespace osgAnimation typedef std::map BoneNamePaletteIndex; typedef std::vector MatrixPalette; - struct IndexWeightEntry + /*struct IndexWeightEntry { IndexWeightEntry(unsigned int index=0, float weight=0.0f): _boneIndex(index), _boneWeight(weight){} IndexWeightEntry(const IndexWeightEntry&o): _boneIndex(o._boneIndex), _boneWeight(o._boneWeight){} @@ -52,7 +52,7 @@ namespace osgAnimation const float &getWeight() const { return _boneWeight; } unsigned int _boneIndex; float _boneWeight; - }; + };*/ osg::Vec4Array* getVertexAttrib(unsigned int index); @@ -68,6 +68,8 @@ namespace osgAnimation virtual void operator()(RigGeometry&); + virtual bool prepareData(RigGeometry& ); + void setShader(osg::Shader*); const BoneNamePaletteIndex& getBoneNameToPalette() { @@ -89,6 +91,9 @@ namespace osgAnimation osg::ref_ptr _shader; bool _needInit; + + bool buildPalette(BoneMap&boneMap ,RigGeometry&rig); + }; } diff --git a/src/osgAnimation/RigTransformHardware.cpp b/src/osgAnimation/RigTransformHardware.cpp index ad15c31e6..dc67533ae 100644 --- a/src/osgAnimation/RigTransformHardware.cpp +++ b/src/osgAnimation/RigTransformHardware.cpp @@ -76,7 +76,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; +typedef std::vector > VertexIndexWeightList; void createVertexAttribList(RigTransformHardware& rig,const VertexIndexWeightList&_vertexIndexMatrixWeightList,RigTransformHardware::BoneWeightAttribList & boneWeightAttribArrays); bool RigTransformHardware::createPalette(unsigned int nbVertexes, const BoneMap &boneMap, const VertexInfluenceSet::VertIDToBoneWeightList& vertexIndexToBoneWeightMap) @@ -111,7 +111,7 @@ bool RigTransformHardware::createPalette(unsigned int nbVertexes, const BoneMap { boneNameCountMap[bw.getBoneName()]++; bonesForThisVertex++; // count max number of bones per vertexes - vertexIndexWeight[vertexID].push_back(IndexWeightEntry(boneName2PaletteIndex->second,bw.getWeight())); + vertexIndexWeight[vertexID].push_back(IndexWeight(boneName2PaletteIndex->second,bw.getWeight())); } else { @@ -125,7 +125,7 @@ bool RigTransformHardware::createPalette(unsigned int nbVertexes, const BoneMap bonesForThisVertex++; _boneNameToPalette[bw.getBoneName()] = _bonePalette.size() ; - vertexIndexWeight[vertexID].push_back(IndexWeightEntry(_bonePalette.size(),bw.getWeight())); + vertexIndexWeight[vertexID].push_back(IndexWeight(_bonePalette.size(),bw.getWeight())); _bonePalette.push_back(bonebyname->second); } } @@ -168,8 +168,12 @@ bool RigTransformHardware::createPalette(unsigned int nbVertexes, const BoneMap // the idea is to use this format to have a granularity smaller // than the 4 bones using two vertex attributes // + void createVertexAttribList(RigTransformHardware& rig,const VertexIndexWeightList& _vertexIndexMatrixWeightList, RigTransformHardware::BoneWeightAttribList& boneWeightAttribArrays) { + +//void createVertexAttribList(RigTransformHardware& rig,const VertexIndexWeightList& _vertexIndexMatrixWeightList, RigTransformHardware::BoneWeightAttribList& boneWeightAttribArrays) +//{ unsigned int nbVertices= rig.getNumVertexes(); unsigned int maxbonepervertex=rig.getNumBonesPerVertex(); unsigned int nbArray = static_cast(ceilf( ((float)maxbonepervertex) * 0.5f)); @@ -195,7 +199,7 @@ void createVertexAttribList(RigTransformHardware& rig,const VertexIndexWeightLis (*array)[j][1 + boneIndexInVec4] = 0; if (boneIndexInList < maxbonepervertex) { - float boneIndex = static_cast(_vertexIndexMatrixWeightList[j][boneIndexInList].getBoneIndex()); + float boneIndex = static_cast(_vertexIndexMatrixWeightList[j][boneIndexInList].getIndex()); float boneWeight = _vertexIndexMatrixWeightList[j][boneIndexInList].getWeight(); // fill the vec4 (*array)[j][0 + boneIndexInVec4] = boneIndex; @@ -219,6 +223,274 @@ void RigTransformHardware::setShader(osg::Shader* shader) _shader = shader; } +bool RigTransformHardware::prepareData(RigGeometry& rig) +{ + 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()); + } + BoneMapVisitor mapVisitor; + rig.getSkeleton()->accept(mapVisitor); + BoneMap boneMap = mapVisitor.getBoneMap(); + + if (!buildPalette(boneMap,rig) ) + return false; + + 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; + return false; + } + + // copy shallow from source geometry to rig + rig.copyFrom(source); + + //if (!createPalette(positionSrc->size(),bm,geom.getVertexInfluenceSet().getVertexToBoneWeightList())) return false; + + osg::ref_ptr program ; + osg::ref_ptr vertexshader; + osg::ref_ptr stateset = rig.getOrCreateStateSet(); + + //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) { + ///perhaps remanance from previous init (if saved after init) so reload shader + /* OSG_WARN << str << std::endl; + vertexshader = osg::Shader::readShaderFile(osg::Shader::VERTEX,"skinning.vert"); + if (!vertexshader.valid()) { + OSG_WARN << "RigTransformHardware can't load VertexShader" << std::endl; + return false; + } + str = vertexshader->getShaderSource(); + start = str.find(toreplace); + // _uniformMatrixPalette=stateset->getUniform("matrixPalette"); + unsigned int attribIndex = 11; + unsigned int nbAttribs = getNumVertexAttrib(); + if(nbAttribs==0) + OSG_WARN << "nbAttribs== " << nbAttribs << std::endl; + for (unsigned int i = 0; i < nbAttribs; i++) + { + std::stringstream ss; + ss << "boneWeight" << i; + program->addBindAttribLocation(ss.str(), attribIndex + i); + + if(getVertexAttrib(i)->getNumElements()!=_nbVertexes) + OSG_WARN << "getVertexAttrib== " << getVertexAttrib(i)->getNumElements() << std::endl; + geom.setVertexAttribArray(attribIndex + i, getVertexAttrib(i)); + OSG_INFO << "set vertex attrib " << ss.str() << std::endl; + } + _needInit = false; + return true;*/ + } + if (std::string::npos != start) { + std::stringstream ss; + ss << getMatrixPaletteUniform()->getNumElements(); + str.replace(start, toreplace.size(), ss.str()); + vertexshader->setShaderSource(str); + } + else + { + OSG_INFO<< "MAX_MATRIX not found in Shader! " << str << std::endl; + } + OSG_INFO << "Shader " << str << std::endl; + } + + unsigned int attribIndex = 11; + unsigned int nbAttribs = getNumVertexAttrib(); + if(nbAttribs==0) + OSG_WARN << "nbAttribs== " << nbAttribs << std::endl; + for (unsigned int i = 0; i < nbAttribs; i++) + { + std::stringstream ss; + ss << "boneWeight" << i; + program->addBindAttribLocation(ss.str(), attribIndex + i); + + if(getVertexAttrib(i)->getNumElements()!=_nbVertexes) + OSG_WARN << "getVertexAttrib== " << getVertexAttrib(i)->getNumElements() << std::endl; + rig.setVertexAttribArray(attribIndex + 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(getMatrixPaletteUniform()); + + stateset->removeAttribute(osg::StateAttribute::PROGRAM); + if(!stateset->getAttribute(osg::StateAttribute::PROGRAM)) + stateset->setAttributeAndModes(program.get()); + + _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(); + unsigned int maxBonePerVertex=0; + + typedef std::pair FloatInt; + std::vector< FloatInt > sums;///stat totalweight nbref + sums.resize(_nbVertexes); + + typedef std::map BoneNameCountMap; + _bonePalette.clear(); + _boneNameToPalette.clear(); + BoneNameCountMap boneNameCountMap; + + VertexInfluenceMap *vertexInfluenceMap=rig.getInfluenceMap(); + BoneNamePaletteIndex::iterator boneName2PaletteIndex; + _boneWeightAttribArrays.resize(0); + + // init temp vertex attribute data + VertexIndexWeightList vertexIndexWeight; + vertexIndexWeight.resize(_nbVertexes); + + for (osgAnimation::VertexInfluenceMap::iterator it = vertexInfluenceMap->begin(); + it != vertexInfluenceMap->end(); + ++it) + { + const BoneInfluenceList& boneinflist = it->second; + for(BoneInfluenceList::const_iterator infit = boneinflist.begin(); infit!=boneinflist.end(); ++infit) + { + const IndexWeight& iw = *infit; + const unsigned int &index = iw.getIndex(); + const float &weight = iw.getWeight(); + + FloatInt &sum=sums[index]; + unsigned int arrayid=sum.second/2; + unsigned short inx=2*(sum.second&1); + + if (boneinflist.getBoneName().empty()) { + OSG_WARN << "VertexInfluenceSet::buildVertex2BoneList warning vertex " << index << " is not assigned to a bone" << std::endl; + } + + //_vertex2Bones[index].push_back(VertexInfluenceSet::BoneWeight(vi.getName(), weight));; + + if(fabs(weight) > 1e-4) // don't use bone with weight too small + { + if ((boneName2PaletteIndex= _boneNameToPalette.find(boneinflist.getBoneName())) != _boneNameToPalette.end()) + { + boneNameCountMap[boneinflist.getBoneName()]++; + vertexIndexWeight[index].push_back(IndexWeight(boneName2PaletteIndex->second,weight)); + } + else + { + BoneMap::const_iterator bonebyname; + if ((bonebyname=boneMap.find(boneinflist.getBoneName())) == boneMap.end()) + { + OSG_WARN << "RigTransformHardware::createPalette can't find bone " << boneinflist.getBoneName() << "in skeleton bonemap: skip this influence" << std::endl; + continue; + } + boneNameCountMap[boneinflist.getBoneName()] = 1; // for stats + + _boneNameToPalette[boneinflist.getBoneName()] = _bonePalette.size() ; + vertexIndexWeight[index].push_back(IndexWeight(_bonePalette.size(),weight)); + _bonePalette.push_back(bonebyname->second); + sum.first+=weight; + ++sum.second; + } + } + else + { + OSG_WARN << "RigTransformHardware::createPalette Bone " << boneinflist.getBoneName() << " has a weight " << weight << " for vertex " << index << " this bone will not be in the palette" << std::endl; + } + maxBonePerVertex = osg::maximum(maxBonePerVertex, sum.second); + + } + OSG_INFO << "RigTransformHardware::createPalette maximum number of bone per vertex is " << maxBonePerVertex << std::endl; + OSG_INFO << "RigTransformHardware::createPalette matrix palette has " << boneNameCountMap.size() << " entries" << std::endl; + + for (BoneNameCountMap::iterator it = boneNameCountMap.begin(); it != boneNameCountMap.end(); ++it) + { + OSG_INFO << "RigTransformHardware::createPalette Bone " << it->first << " is used " << it->second << " times" << std::endl; + } + + OSG_INFO << "RigTransformHardware::createPalette will use " << boneNameCountMap.size() * 4 << " uniforms" << std::endl; + + + } + + _bonesPerVertex = maxBonePerVertex; + _uniformMatrixPalette = new osg::Uniform(osg::Uniform::FLOAT_MAT4, "matrixPalette", _bonePalette.size()); + + createVertexAttribList(*this,vertexIndexWeight,this->_boneWeightAttribArrays); + // normalize weight per vertex +///..assume not sum=0 + + /* for(BoneWeightAttribList::iterator attribit=_boneWeightAttribArrays.begin();attribit!=_boneWeightAttribArrays.end();++attribit){ + std::vector< std::pair >::iterator countit=sums.begin(); + for(osg::Vec4Array::iterator vert=attribit->get()->begin();vert!=attribit->get()->end();++vert,++countit){ + osg::Vec4& v=*vert; + v[1]/=countit->first; + v[3]/=countit->first; + } + + } + */ + /* unsigned int vertexID=0; + for (VertIDToBoneWeightList::iterator it = _vertex2Bones.begin(); it != _vertex2Bones.end(); ++it,++vertexID) + { + BoneWeightList& bones = *it; + int size = bones.size(); + if (sums[vertexID].first < 1e-4) + { + OSG_WARN << "VertexInfluenceSet::buildVertex2BoneList warning the vertex " << it->first << " seems to have 0 weight, skip normalize for this vertex" << std::endl; + } + else + { + float mult = 1.0/sums[vertexID].first ; + for (int i = 0; i < size; i++) + bones[i].setWeight(bones[i].getWeight() * mult); + } + } + */ +return true; +} bool RigTransformHardware::init(RigGeometry& geom) { if (!geom.getSkeleton()) @@ -310,13 +582,13 @@ bool RigTransformHardware::init(RigGeometry& geom) } program->addShader(vertexshader.get()); - + stateset->removeUniform("matrixPalette"); stateset->addUniform(getMatrixPaletteUniform()); stateset->removeUniform("nbBonesPerVertex"); stateset->addUniform(new osg::Uniform("nbBonesPerVertex",_bonesPerVertex)); - + stateset->removeAttribute(osg::StateAttribute::PROGRAM); if(!stateset->getAttribute(osg::StateAttribute::PROGRAM)) stateset->setAttributeAndModes(program.get()); From 7659b23f3836c5c7d985582db6e15a07e5bcf67a Mon Sep 17 00:00:00 2001 From: Julien Valentin Date: Mon, 28 Aug 2017 15:44:09 +0200 Subject: [PATCH 015/327] remove unused --- src/osgAnimation/RigTransformSoftware.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/osgAnimation/RigTransformSoftware.cpp b/src/osgAnimation/RigTransformSoftware.cpp index 512e0a407..c1bc46560 100644 --- a/src/osgAnimation/RigTransformSoftware.cpp +++ b/src/osgAnimation/RigTransformSoftware.cpp @@ -121,10 +121,6 @@ void RigTransformSoftware::buildMinimumUpdateSet(const BoneMap&boneMap,const Rig std::vector _vertex2Bones; _vertex2Bones.resize(rig.getSourceGeometry()->getVertexArray()->getNumElements()); - typedef std::pair FloatInt; - std::vector< FloatInt > sums;///stat totalweight nbref - sums.resize(rig.getSourceGeometry()->getVertexArray()->getNumElements() - ); const VertexInfluenceMap *_vertexInfluenceMap=rig.getInfluenceMap(); for (osgAnimation::VertexInfluenceMap::const_iterator it = _vertexInfluenceMap->begin(); it != _vertexInfluenceMap->end(); From 2aab28149fbbdc65cceeb516fe8f8aab47a25b7b Mon Sep 17 00:00:00 2001 From: Julien Valentin Date: Mon, 28 Aug 2017 15:59:13 +0200 Subject: [PATCH 016/327] reroot to rigtransform::prepareData old path to rig::buildvertexinfluence --- include/osgAnimation/RigGeometry | 9 +++++++-- src/osgAnimation/RigGeometry.cpp | 5 ----- src/osgAnimation/RigTransformHardware.cpp | 2 +- src/osgAnimation/RigTransformSoftware.cpp | 2 +- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/include/osgAnimation/RigGeometry b/include/osgAnimation/RigGeometry index 31cda0179..a636f7717 100644 --- a/include/osgAnimation/RigGeometry +++ b/include/osgAnimation/RigGeometry @@ -17,7 +17,7 @@ #include #include -#include +#include #include #include @@ -151,8 +151,13 @@ namespace osgAnimation osg::notify(osg::WARN) << "A RigGeometry did not find a parent skeleton for RigGeometry ( " << geom->getName() << " )" << std::endl; return; } - geom->buildVertexInfluenceSet(); geom->setSkeleton(finder._root.get()); + + if(!geom->getRigTransformImplementation()) + { + geom->setRigTransformImplementation(new RigTransformSoftware); + } + geom->getRigTransformImplementation()->prepareData(*geom); } if(!geom->getSkeleton()) diff --git a/src/osgAnimation/RigGeometry.cpp b/src/osgAnimation/RigGeometry.cpp index b09c61966..bb5a9c8ee 100644 --- a/src/osgAnimation/RigGeometry.cpp +++ b/src/osgAnimation/RigGeometry.cpp @@ -118,11 +118,6 @@ void RigGeometry::computeMatrixFromRootSkeleton() void RigGeometry::update() { - if (!getRigTransformImplementation()) - { - _rigTransformImplementation = new RigTransformSoftware; - } - RigTransform& implementation = *getRigTransformImplementation(); (implementation)(*this); } diff --git a/src/osgAnimation/RigTransformHardware.cpp b/src/osgAnimation/RigTransformHardware.cpp index dc67533ae..90c684669 100644 --- a/src/osgAnimation/RigTransformHardware.cpp +++ b/src/osgAnimation/RigTransformHardware.cpp @@ -600,7 +600,7 @@ bool RigTransformHardware::init(RigGeometry& geom) void RigTransformHardware::operator()(RigGeometry& geom) { if (_needInit) - if (!init(geom)) + if (!prepareData(geom)) return; computeMatrixPaletteUniform(geom.getMatrixFromSkeletonToGeometry(), geom.getInvMatrixFromSkeletonToGeometry()); } diff --git a/src/osgAnimation/RigTransformSoftware.cpp b/src/osgAnimation/RigTransformSoftware.cpp index c1bc46560..69920cd71 100644 --- a/src/osgAnimation/RigTransformSoftware.cpp +++ b/src/osgAnimation/RigTransformSoftware.cpp @@ -256,7 +256,7 @@ bool RigTransformSoftware::prepareData(RigGeometry&rig) { void RigTransformSoftware::operator()(RigGeometry& geom) { if (_needInit) - if (!init(geom)) + if (!prepareData(geom)) return; if (!geom.getSourceGeometry()) { From 6d55d8d341fac5d71d65cfd49e7f1fc4ed0dd48d Mon Sep 17 00:00:00 2001 From: Julien Valentin Date: Mon, 28 Aug 2017 16:02:00 +0200 Subject: [PATCH 017/327] minor fixes removed unused --- include/osgAnimation/RigTransform | 2 +- src/osgAnimation/RigTransformHardware.cpp | 10 ++++------ 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/include/osgAnimation/RigTransform b/include/osgAnimation/RigTransform index 7be592035..9a6a0e367 100644 --- a/include/osgAnimation/RigTransform +++ b/include/osgAnimation/RigTransform @@ -35,7 +35,7 @@ namespace osgAnimation /// to call manually when a skeleton is reacheable from the rig /// in order to prepare technic data before rendering - virtual bool prepareData(RigGeometry&){} + virtual bool prepareData(RigGeometry&){return true;} protected: virtual ~RigTransform() {} diff --git a/src/osgAnimation/RigTransformHardware.cpp b/src/osgAnimation/RigTransformHardware.cpp index 90c684669..8751455e5 100644 --- a/src/osgAnimation/RigTransformHardware.cpp +++ b/src/osgAnimation/RigTransformHardware.cpp @@ -390,11 +390,11 @@ bool RigTransformHardware::buildPalette(BoneMap&boneMap ,RigGeometry&rig) { VertexIndexWeightList vertexIndexWeight; vertexIndexWeight.resize(_nbVertexes); - for (osgAnimation::VertexInfluenceMap::iterator it = vertexInfluenceMap->begin(); - it != vertexInfluenceMap->end(); - ++it) + for (osgAnimation::VertexInfluenceMap::iterator mapit = vertexInfluenceMap->begin(); + mapit != vertexInfluenceMap->end(); + ++mapit) { - const BoneInfluenceList& boneinflist = it->second; + const BoneInfluenceList& boneinflist = mapit->second; for(BoneInfluenceList::const_iterator infit = boneinflist.begin(); infit!=boneinflist.end(); ++infit) { const IndexWeight& iw = *infit; @@ -402,8 +402,6 @@ bool RigTransformHardware::buildPalette(BoneMap&boneMap ,RigGeometry&rig) { const float &weight = iw.getWeight(); FloatInt &sum=sums[index]; - unsigned int arrayid=sum.second/2; - unsigned short inx=2*(sum.second&1); if (boneinflist.getBoneName().empty()) { OSG_WARN << "VertexInfluenceSet::buildVertex2BoneList warning vertex " << index << " is not assigned to a bone" << std::endl; From da1d2b67f7b21ce976538acd49f129da805ea74a Mon Sep 17 00:00:00 2001 From: Julien Valentin Date: Mon, 28 Aug 2017 16:46:01 +0200 Subject: [PATCH 018/327] remove old path and add few fixes --- include/osgAnimation/RigTransformHardware | 17 +- include/osgAnimation/RigTransformSoftware | 18 +- include/osgAnimation/VertexInfluence | 5 + src/osgAnimation/RigTransformHardware.cpp | 221 +--------------------- src/osgAnimation/RigTransformSoftware.cpp | 149 +-------------- 5 files changed, 25 insertions(+), 385 deletions(-) diff --git a/include/osgAnimation/RigTransformHardware b/include/osgAnimation/RigTransformHardware index 4c2aa1875..fd10eeec6 100644 --- a/include/osgAnimation/RigTransformHardware +++ b/include/osgAnimation/RigTransformHardware @@ -1,5 +1,6 @@ /* -*-c++-*- * Copyright (C) 2009 Cedric Pinson + * Copyright (C) 2017 Julien Valentin * * This library is open source and may be redistributed and/or modified under * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or @@ -43,17 +44,6 @@ namespace osgAnimation typedef std::map BoneNamePaletteIndex; typedef std::vector MatrixPalette; - /*struct IndexWeightEntry - { - IndexWeightEntry(unsigned int index=0, float weight=0.0f): _boneIndex(index), _boneWeight(weight){} - IndexWeightEntry(const IndexWeightEntry&o): _boneIndex(o._boneIndex), _boneWeight(o._boneWeight){} - bool operator <(const IndexWeightEntry &o)const{return (_boneIndex + * Copyright (C) 2017 Julien Valentin * * This library is open source and may be redistributed and/or modified under * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or @@ -132,9 +133,9 @@ namespace osgAnimation template 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(std::vector::iterator itvg=_uniqInfluenceSet2VertIDList.begin(); itvg!=_uniqInfluenceSet2VertIDList.end(); ++itvg) + for(VertexGroupSet::iterator itvg=_uniqInfluenceSet2VertIDList.begin(); itvg!=_uniqInfluenceSet2VertIDList.end(); ++itvg) { - VertexGroup& uniq = *itvg; + VertexGroup& uniq = itvg->second; uniq.computeMatrixForVertexSet(); osg::Matrix matrix = transform * uniq.getMatrix() * invTransform; @@ -150,9 +151,9 @@ namespace osgAnimation template void computeNormal(const osg::Matrix& transform, const osg::Matrix& invTransform, const V* src, V* dst) { - for(std::vector::iterator itvg=_uniqInfluenceSet2VertIDList.begin(); itvg!=_uniqInfluenceSet2VertIDList.end(); ++itvg) + for(VertexGroupSet::iterator itvg=_uniqInfluenceSet2VertIDList.begin(); itvg!=_uniqInfluenceSet2VertIDList.end(); ++itvg) { - VertexGroup& uniq = *itvg; + VertexGroup& uniq = itvg->second; uniq.computeMatrixForVertexSet(); osg::Matrix matrix = transform * uniq.getMatrix() * invTransform; @@ -166,15 +167,16 @@ namespace osgAnimation protected: - bool init(RigGeometry&); - void initVertexSetFromBones(const BoneMap& map, const VertexInfluenceSet::UniqVertexGroupList& influence); - std::vector _uniqInfluenceSet2VertIDList; - bool _needInit; std::map _invalidInfluence; + typedef std::vector BoneWeightList; + typedef std::map VertexGroupSet; + + VertexGroupSet _uniqInfluenceSet2VertIDList; void buildMinimumUpdateSet(const BoneMap&boneMap,const RigGeometry&rig ); + }; } diff --git a/include/osgAnimation/VertexInfluence b/include/osgAnimation/VertexInfluence index bf3a9b2be..3060aa8c3 100644 --- a/include/osgAnimation/VertexInfluence +++ b/include/osgAnimation/VertexInfluence @@ -32,6 +32,11 @@ namespace osgAnimation inline void setBoneName(const std::string&s){first=s;} inline const float &getWeight()const{return second;} inline void setWeight(float i){second=i;} + ///default invweight ordered + bool operator <(const BoneWeight&o)const{ + if(getWeight()>o.getWeight()) return true; + if(getWeight() diff --git a/src/osgAnimation/RigTransformHardware.cpp b/src/osgAnimation/RigTransformHardware.cpp index 8751455e5..b4640df4c 100644 --- a/src/osgAnimation/RigTransformHardware.cpp +++ b/src/osgAnimation/RigTransformHardware.cpp @@ -1,5 +1,6 @@ /* -*-c++-*- * Copyright (C) 2009 Cedric Pinson + * Copyright (C) 2017 Julien Valentin * * This library is open source and may be redistributed and/or modified under * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or @@ -79,87 +80,6 @@ unsigned int RigTransformHardware::getNumVertexes() const { return _nbVertexes;} typedef std::vector > VertexIndexWeightList; void createVertexAttribList(RigTransformHardware& rig,const VertexIndexWeightList&_vertexIndexMatrixWeightList,RigTransformHardware::BoneWeightAttribList & boneWeightAttribArrays); -bool RigTransformHardware::createPalette(unsigned int nbVertexes, const BoneMap &boneMap, const VertexInfluenceSet::VertIDToBoneWeightList& vertexIndexToBoneWeightMap) -{ - _nbVertexes = nbVertexes; - typedef std::map BoneNameCountMap; - _bonePalette.clear(); - _boneNameToPalette.clear(); - BoneNameCountMap boneNameCountMap; - // init vertex attribute data - VertexIndexWeightList vertexIndexWeight; - vertexIndexWeight.resize(nbVertexes); - - unsigned int maxBonePerVertex = 0; - if(vertexIndexToBoneWeightMap.size()!=nbVertexes) { - OSG_WARN << "RigTransformHardware::some vertex has no transform " < 1e-4) // don't use bone with weight too small - { - if ((boneName2PaletteIndex= _boneNameToPalette.find(bw.getBoneName())) != _boneNameToPalette.end()) - { - boneNameCountMap[bw.getBoneName()]++; - bonesForThisVertex++; // count max number of bones per vertexes - vertexIndexWeight[vertexID].push_back(IndexWeight(boneName2PaletteIndex->second,bw.getWeight())); - } - else - { - BoneMap::const_iterator bonebyname; - if ((bonebyname=boneMap.find(bw.getBoneName())) == boneMap.end()) - { - OSG_WARN << "RigTransformHardware::createPalette can't find bone " << bw.getBoneName() << "in skeleton bonemap: skip this influence" << std::endl; - continue; - } - boneNameCountMap[bw.getBoneName()] = 1; // for stats - bonesForThisVertex++; - - _boneNameToPalette[bw.getBoneName()] = _bonePalette.size() ; - vertexIndexWeight[vertexID].push_back(IndexWeight(_bonePalette.size(),bw.getWeight())); - _bonePalette.push_back(bonebyname->second); - } - } - else - { - OSG_WARN << "RigTransformHardware::createPalette Bone " << bw.getBoneName() << " has a weight " << bw.getWeight() << " for vertex " << vertexID << " this bone will not be in the palette" << std::endl; - } - } - if(bonesForThisVertex==0) { - OSG_WARN << "RigTransformHardware::no transform for vertex " << vertexID << " this will induce a bug in vertex shader" << std::endl; - } - maxBonePerVertex = osg::maximum(maxBonePerVertex, bonesForThisVertex); - } - OSG_INFO << "RigTransformHardware::createPalette maximum number of bone per vertex is " << maxBonePerVertex << std::endl; - OSG_INFO << "RigTransformHardware::createPalette matrix palette has " << boneNameCountMap.size() << " entries" << std::endl; - - for (BoneNameCountMap::iterator it = boneNameCountMap.begin(); it != boneNameCountMap.end(); ++it) - { - OSG_INFO << "RigTransformHardware::createPalette Bone " << it->first << " is used " << it->second << " times" << std::endl; - } - - OSG_INFO << "RigTransformHardware::createPalette will use " << boneNameCountMap.size() * 4 << " uniforms" << std::endl; - - - _bonesPerVertex = maxBonePerVertex; - for (int i = 0 ; i < (int)vertexIndexWeight.size(); i++) - vertexIndexWeight[i].resize(maxBonePerVertex); - - _uniformMatrixPalette = createVertexUniform(); - createVertexAttribList(*this,vertexIndexWeight,this->_boneWeightAttribArrays); - return true; -} - - // // create vertex attribute by 2 bones // vec4(boneIndex0, weight0, boneIndex1, weight1) @@ -171,9 +91,6 @@ bool RigTransformHardware::createPalette(unsigned int nbVertexes, const BoneMap void createVertexAttribList(RigTransformHardware& rig,const VertexIndexWeightList& _vertexIndexMatrixWeightList, RigTransformHardware::BoneWeightAttribList& boneWeightAttribArrays) { - -//void createVertexAttribList(RigTransformHardware& rig,const VertexIndexWeightList& _vertexIndexMatrixWeightList, RigTransformHardware::BoneWeightAttribList& boneWeightAttribArrays) -//{ unsigned int nbVertices= rig.getNumVertexes(); unsigned int maxbonepervertex=rig.getNumBonesPerVertex(); unsigned int nbArray = static_cast(ceilf( ((float)maxbonepervertex) * 0.5f)); @@ -257,8 +174,6 @@ bool RigTransformHardware::prepareData(RigGeometry& rig) // copy shallow from source geometry to rig rig.copyFrom(source); - //if (!createPalette(positionSrc->size(),bm,geom.getVertexInfluenceSet().getVertexToBoneWeightList())) return false; - osg::ref_ptr program ; osg::ref_ptr vertexshader; osg::ref_ptr stateset = rig.getOrCreateStateSet(); @@ -294,35 +209,6 @@ bool RigTransformHardware::prepareData(RigGeometry& rig) std::string str = vertexshader->getShaderSource(); std::string toreplace = std::string("MAX_MATRIX"); std::size_t start = str.find(toreplace); - if (std::string::npos == start) { - ///perhaps remanance from previous init (if saved after init) so reload shader - /* OSG_WARN << str << std::endl; - vertexshader = osg::Shader::readShaderFile(osg::Shader::VERTEX,"skinning.vert"); - if (!vertexshader.valid()) { - OSG_WARN << "RigTransformHardware can't load VertexShader" << std::endl; - return false; - } - str = vertexshader->getShaderSource(); - start = str.find(toreplace); - // _uniformMatrixPalette=stateset->getUniform("matrixPalette"); - unsigned int attribIndex = 11; - unsigned int nbAttribs = getNumVertexAttrib(); - if(nbAttribs==0) - OSG_WARN << "nbAttribs== " << nbAttribs << std::endl; - for (unsigned int i = 0; i < nbAttribs; i++) - { - std::stringstream ss; - ss << "boneWeight" << i; - program->addBindAttribLocation(ss.str(), attribIndex + i); - - if(getVertexAttrib(i)->getNumElements()!=_nbVertexes) - OSG_WARN << "getVertexAttrib== " << getVertexAttrib(i)->getNumElements() << std::endl; - geom.setVertexAttribArray(attribIndex + i, getVertexAttrib(i)); - OSG_INFO << "set vertex attrib " << ss.str() << std::endl; - } - _needInit = false; - return true;*/ - } if (std::string::npos != start) { std::stringstream ss; ss << getMatrixPaletteUniform()->getNumElements(); @@ -489,111 +375,6 @@ bool RigTransformHardware::buildPalette(BoneMap&boneMap ,RigGeometry&rig) { */ return true; } -bool RigTransformHardware::init(RigGeometry& geom) -{ - if (!geom.getSkeleton()) - { - OSG_WARN << "RigTransformHardware no skeleton set in geometry " << geom.getName() << std::endl; - return false; - } - BoneMapVisitor mapVisitor; - geom.getSkeleton()->accept(mapVisitor); - BoneMap bm = mapVisitor.getBoneMap(); - - osg::Geometry& source = *geom.getSourceGeometry(); - osg::Vec3Array* positionSrc = dynamic_cast(source.getVertexArray()); - if (!positionSrc) - { - OSG_WARN << "RigTransformHardware no vertex array in the geometry " << geom.getName() << std::endl; - return false; - } - - // copy shallow from source geometry to rig - geom.copyFrom(source); - - if (!createPalette(positionSrc->size(),bm,geom.getVertexInfluenceSet().getVertexToBoneList())) - return false; - - osg::ref_ptr program ; - osg::ref_ptr vertexshader; - osg::ref_ptr stateset = geom.getOrCreateStateSet(); - - //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_INFO<< "MAX_MATRIX not found in Shader! " << str << std::endl; - } - OSG_INFO << "Shader " << str << std::endl; - } - - unsigned int attribIndex = 11; - unsigned int nbAttribs = getNumVertexAttrib(); - if(nbAttribs==0) - OSG_WARN << "nbAttribs== " << nbAttribs << std::endl; - for (unsigned int i = 0; i < nbAttribs; i++) - { - std::stringstream ss; - ss << "boneWeight" << i; - program->addBindAttribLocation(ss.str(), attribIndex + i); - - if(getVertexAttrib(i)->getNumElements()!=_nbVertexes) - OSG_WARN << "getVertexAttrib== " << getVertexAttrib(i)->getNumElements() << std::endl; - geom.setVertexAttribArray(attribIndex + i, getVertexAttrib(i)); - OSG_INFO << "set vertex attrib " << ss.str() << std::endl; - } - - program->addShader(vertexshader.get()); - - stateset->removeUniform("matrixPalette"); - stateset->addUniform(getMatrixPaletteUniform()); - - stateset->removeUniform("nbBonesPerVertex"); - stateset->addUniform(new osg::Uniform("nbBonesPerVertex",_bonesPerVertex)); - - stateset->removeAttribute(osg::StateAttribute::PROGRAM); - if(!stateset->getAttribute(osg::StateAttribute::PROGRAM)) - stateset->setAttributeAndModes(program.get()); - - _needInit = false; - return true; -} void RigTransformHardware::operator()(RigGeometry& geom) { diff --git a/src/osgAnimation/RigTransformSoftware.cpp b/src/osgAnimation/RigTransformSoftware.cpp index 69920cd71..60a9c9476 100644 --- a/src/osgAnimation/RigTransformSoftware.cpp +++ b/src/osgAnimation/RigTransformSoftware.cpp @@ -1,5 +1,6 @@ /* -*-c++-*- * Copyright (C) 2009 Cedric Pinson + * Copyright (C) 2017 Julien Valentin * * This library is open source and may be redistributed and/or modified under * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or @@ -34,87 +35,6 @@ 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()) - return false; - - BoneMapVisitor mapVisitor; - geom.getSkeleton()->accept(mapVisitor); - BoneMap bm = mapVisitor.getBoneMap(); - initVertexSetFromBones(bm, geom.getVertexInfluenceSet().getUniqVertexGroupList()); - - if (geom.getSourceGeometry()) - geom.copyFrom(*geom.getSourceGeometry()); - - - osg::Vec3Array* normalSrc = dynamic_cast(geom.getSourceGeometry()->getNormalArray()); - osg::Vec3Array* positionSrc = dynamic_cast(geom.getSourceGeometry()->getVertexArray()); - - if(!(positionSrc) || positionSrc->empty() ) - return false; - if(normalSrc&& normalSrc->size()!=positionSrc->size()) - return false; - - - geom.setVertexArray(new osg::Vec3Array); - osg::Vec3Array* positionDst =new osg::Vec3Array; - geom.setVertexArray(positionDst); - *positionDst=*positionSrc; - positionDst->setDataVariance(osg::Object::DYNAMIC); - - - if(normalSrc){ - osg::Vec3Array* normalDst =new osg::Vec3Array; - *normalDst=*normalSrc; - geom.setNormalArray(normalDst, osg::Array::BIND_PER_VERTEX); - normalDst->setDataVariance(osg::Object::DYNAMIC); - } - - _needInit = false; - return true; -} - void RigTransformSoftware::buildMinimumUpdateSet(const BoneMap&boneMap,const RigGeometry&rig ){ ///1 Create Index2Vec @@ -172,29 +92,19 @@ 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 - typedef std::map UnifyBoneGroup; - UnifyBoneGroup unifyBuffer; + _uniqInfluenceSet2VertIDList.clear(); vertexID=0; for (std::vector::iterator it = _vertex2Bones.begin(); it != _vertex2Bones.end(); ++it,++vertexID) { BoneWeightList& bones = *it; // sort the vector to have a consistent key - std::sort(bones.begin(), bones.end(), SortByNameAndWeight()); + std::sort(bones.begin(), bones.end()); // we use the vector as key to differentiate group - UnifyBoneGroup::iterator result = unifyBuffer.find(bones); - if (result == unifyBuffer.end()) - unifyBuffer[bones].getBoneWeights()=bones; - unifyBuffer[bones].getVertexes().push_back(vertexID); + VertexGroupSet::iterator result = _uniqInfluenceSet2VertIDList.find(bones); + if (result == _uniqInfluenceSet2VertIDList.end()) + _uniqInfluenceSet2VertIDList[bones].getBoneWeights()=bones; + _uniqInfluenceSet2VertIDList[bones].getVertexes().push_back(vertexID); } - if(_vertex2Bones.size()==unifyBuffer.size()) { - OSG_WARN << "RigTransformSoftware::build mapping is useless no duplicate VertexGroup : too much " <<_vertex2Bones.size()<<"=="<second); - OSG_DEBUG << "uniq groups " << _uniqInfluenceSet2VertIDList.size() << " for " << rig.getName() << std::endl; } @@ -290,48 +200,3 @@ void RigTransformSoftware::operator()(RigGeometry& geom) } } - -///convert BoneWeight to BonePtrWeight using bonemap -void RigTransformSoftware::initVertexSetFromBones(const BoneMap& map, const VertexInfluenceSet::UniqVertexGroupList& vertexgroups) -{ - _uniqInfluenceSet2VertIDList.clear(); - - int size = vertexgroups.size(); - _uniqInfluenceSet2VertIDList.resize(size); - //for (VertexInfluenceSet::UniqVertexGroupList::const_iterator vgit=vertexgroups.begin(); vgit!=vertexgroups.end();vgit++) - for(int i = 0; i < size; i++) - { - const VertexInfluenceSet::VertexGroup& vg = vertexgroups[i]; - int nbBones = vg.getBones().size(); - BonePtrWeightList& boneList = _uniqInfluenceSet2VertIDList[i].getBoneWeights(); - - double sumOfWeight = 0; - for (int b = 0; b < nbBones; b++) - { - const std::string& bname = vg.getBones()[b].getBoneName(); - float weight = vg.getBones()[b].getWeight(); - BoneMap::const_iterator it = map.find(bname); - if (it == map.end() ) - { - if (_invalidInfluence.find(bname) != _invalidInfluence.end()) { - _invalidInfluence[bname] = true; - OSG_WARN << "RigTransformSoftware Bone " << bname << " not found, skip the influence group " <second.get(); - 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 - // so we check it and renormalize the all weight bone - const double threshold = 1e-4; - if (!vg.getBones().empty() && - (sumOfWeight < 1.0 - threshold || sumOfWeight > 1.0 + threshold)) - { - for (int b = 0; b < (int)boneList.size(); b++) - boneList[b].setWeight(boneList[b].getWeight() / sumOfWeight); - } - _uniqInfluenceSet2VertIDList[i].getVertexes() = vg.getVertexes(); - } -} From 87070869147515ac648e33a3c1dc0944ce200178 Mon Sep 17 00:00:00 2001 From: Julien Valentin Date: Mon, 28 Aug 2017 17:13:23 +0200 Subject: [PATCH 019/327] fix the example --- .../osganimationhardware.cpp | 176 +++++++++++------- 1 file changed, 110 insertions(+), 66 deletions(-) diff --git a/examples/osganimationhardware/osganimationhardware.cpp b/examples/osganimationhardware/osganimationhardware.cpp index 74aacb7ba..eb7d8b3ea 100644 --- a/examples/osganimationhardware/osganimationhardware.cpp +++ b/examples/osganimationhardware/osganimationhardware.cpp @@ -45,84 +45,121 @@ osg::ref_ptr program; struct MyRigTransformHardware : public osgAnimation::RigTransformHardware { - void operator()(osgAnimation::RigGeometry& geom) + virtual bool prepareData(osgAnimation::RigGeometry& rig) { - if (_needInit) - if (!init(geom)) - return; - computeMatrixPaletteUniform(geom.getMatrixFromSkeletonToGeometry(), geom.getInvMatrixFromSkeletonToGeometry()); - } + if(!rig.getSkeleton() && !rig.getParents().empty()) + { + osgAnimation::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); - bool init(osgAnimation::RigGeometry& geom) - { - osg::Vec3Array* pos = dynamic_cast(geom.getVertexArray()); - if (!pos) { - osg::notify(osg::WARN) << "RigTransformHardware no vertex array in the geometry " << geom.getName() << std::endl; - return false; - } - - if (!geom.getSkeleton()) { - osg::notify(osg::WARN) << "RigTransformHardware no skeleting set in geometry " << geom.getName() << std::endl; - return false; - } - - osgAnimation::BoneMapVisitor mapVisitor; - geom.getSkeleton()->accept(mapVisitor); - osgAnimation::BoneMap bm = mapVisitor.getBoneMap(); - - if (!createPalette(pos->size(),bm, geom.getVertexInfluenceSet().getVertexToBoneList())) - return false; - - int attribIndex = 11; - int nbAttribs = getNumVertexAttrib(); - - // use a global program for all avatar - if (!program.valid()) { - program = new osg::Program; - program->setName("HardwareSkinning"); - if (!_shader.valid()) - _shader = osg::Shader::readShaderFile(osg::Shader::VERTEX,"shaders/skinning.vert"); - - if (!_shader.valid()) { - osg::notify(osg::WARN) << "RigTransformHardware can't load VertexShader" << std::endl; + 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()); + } + osgAnimation::BoneMapVisitor mapVisitor; + rig.getSkeleton()->accept(mapVisitor); + osgAnimation::BoneMap boneMap = mapVisitor.getBoneMap(); - // replace max matrix by the value from uniform + if (!buildPalette(boneMap,rig) ) + return false; + + 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; + return false; + } + + // copy shallow from source geometry to rig + rig.copyFrom(source); + + // osg::ref_ptr program ; + osg::ref_ptr vertexshader; + osg::ref_ptr stateset = rig.getOrCreateStateSet(); + + //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,"shaders/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::string str = _shader->getShaderSource(); - std::string toreplace = std::string("MAX_MATRIX"); - std::size_t start = str.find(toreplace); std::stringstream ss; ss << getMatrixPaletteUniform()->getNumElements(); str.replace(start, toreplace.size(), ss.str()); - _shader->setShaderSource(str); - osg::notify(osg::INFO) << "Shader " << str << std::endl; + vertexshader->setShaderSource(str); } - - program->addShader(_shader.get()); - - for (int i = 0; i < nbAttribs; i++) + else { - std::stringstream ss; - ss << "boneWeight" << i; - program->addBindAttribLocation(ss.str(), attribIndex + i); - - osg::notify(osg::INFO) << "set vertex attrib " << ss.str() << std::endl; + OSG_INFO<< "MAX_MATRIX not found in Shader! " << str << std::endl; } + OSG_INFO << "Shader " << str << std::endl; } - for (int i = 0; i < nbAttribs; i++) + + unsigned int attribIndex = 11; + unsigned int nbAttribs = getNumVertexAttrib(); + if(nbAttribs==0) + OSG_WARN << "nbAttribs== " << nbAttribs << std::endl; + for (unsigned int i = 0; i < nbAttribs; i++) { std::stringstream ss; ss << "boneWeight" << i; - geom.setVertexAttribArray(attribIndex + i, getVertexAttrib(i)); + program->addBindAttribLocation(ss.str(), attribIndex + i); + + if(getVertexAttrib(i)->getNumElements()!=_nbVertexes) + OSG_WARN << "getVertexAttrib== " << getVertexAttrib(i)->getNumElements() << std::endl; + rig.setVertexAttribArray(attribIndex + i, getVertexAttrib(i)); + OSG_INFO << "set vertex attrib " << ss.str() << std::endl; } - osg::ref_ptr ss = new osg::StateSet; - ss->addUniform(getMatrixPaletteUniform()); - ss->addUniform(new osg::Uniform("nbBonesPerVertex", getNumBonesPerVertex())); - ss->setAttributeAndModes(program.get()); - geom.setStateSet(ss.get()); + + program->addShader(vertexshader.get()); + stateset->removeUniform("nbBonesPerVertex"); + stateset->addUniform(new osg::Uniform("nbBonesPerVertex",_bonesPerVertex)); + stateset->removeUniform("matrixPalette"); + stateset->addUniform(getMatrixPaletteUniform()); + + stateset->removeAttribute(osg::StateAttribute::PROGRAM); + if(!stateset->getAttribute(osg::StateAttribute::PROGRAM)) + stateset->setAttributeAndModes(program.get()); + _needInit = false; return true; } @@ -142,10 +179,11 @@ struct SetupRigGeometry : public osg::NodeVisitor } void apply(osg::Drawable& geom) { - if (_hardware) { + if (_hardware) + { osgAnimation::RigGeometry* rig = dynamic_cast(&geom); if (rig) - rig->setRigTransformImplementation(new osgAnimation::RigTransformHardware); + rig->setRigTransformImplementation(new MyRigTransformHardware); } #if 0 @@ -169,7 +207,8 @@ osg::Group* createCharacterInstance(osg::Group* character, bool hardware) osgAnimation::BasicAnimationManager* anim = dynamic_cast(animationManager); const osgAnimation::AnimationList& list = animationManager->getAnimationList(); int v = getRandomValueinRange(list.size()); - if (list[v]->getName() == std::string("MatIpo_ipo")) { + if (list[v]->getName() == std::string("MatIpo_ipo")) + { anim->playAnimation(list[v].get()); v = (v + 1)%list.size(); } @@ -193,7 +232,10 @@ int main (int argc, char* argv[]) bool hardware = true; int maxChar = 10; - while (psr.read("--software")) { hardware = false; } + while (psr.read("--software")) + { + hardware = false; + } while (psr.read("--number", maxChar)) {} osg::ref_ptr node = osgDB::readRefNodeFiles(psr); @@ -243,8 +285,10 @@ int main (int argc, char* argv[]) double xChar = maxChar; double yChar = xChar * 9.0/16; - for (double i = 0.0; i < xChar; i++) { - for (double j = 0.0; j < yChar; j++) { + for (double i = 0.0; i < xChar; i++) + { + for (double j = 0.0; j < yChar; j++) + { osg::ref_ptr c = createCharacterInstance(root.get(), hardware); osg::MatrixTransform* tr = new osg::MatrixTransform; From ad550acc604ff2b468cb9c9b6469f8943ca55a8c Mon Sep 17 00:00:00 2001 From: Julien Valentin Date: Mon, 28 Aug 2017 17:13:48 +0200 Subject: [PATCH 020/327] clean unused --- include/osgAnimation/RigTransformSoftware | 6 ------ 1 file changed, 6 deletions(-) diff --git a/include/osgAnimation/RigTransformSoftware b/include/osgAnimation/RigTransformSoftware index eca71eba8..a8d817e64 100644 --- a/include/osgAnimation/RigTransformSoftware +++ b/include/osgAnimation/RigTransformSoftware @@ -49,12 +49,6 @@ namespace osgAnimation 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 _boneptr; }; From 28bb88a0386638994de17f123af67cc549fd9a91 Mon Sep 17 00:00:00 2001 From: Julien Valentin Date: Mon, 28 Aug 2017 18:02:52 +0200 Subject: [PATCH 021/327] remove default order for BoneWeight and restore old sort func (behaviors differs) --- include/osgAnimation/RigTransformSoftware | 13 +++--- include/osgAnimation/VertexInfluence | 5 -- src/osgAnimation/RigTransformSoftware.cpp | 56 +++++++++++++++++++++-- 3 files changed, 57 insertions(+), 17 deletions(-) diff --git a/include/osgAnimation/RigTransformSoftware b/include/osgAnimation/RigTransformSoftware index a8d817e64..9d2a014dc 100644 --- a/include/osgAnimation/RigTransformSoftware +++ b/include/osgAnimation/RigTransformSoftware @@ -127,9 +127,9 @@ namespace osgAnimation template 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(VertexGroupSet::iterator itvg=_uniqInfluenceSet2VertIDList.begin(); itvg!=_uniqInfluenceSet2VertIDList.end(); ++itvg) + for(VertexGroupList::iterator itvg=_uniqInfluenceSet2VertIDList.begin(); itvg!=_uniqInfluenceSet2VertIDList.end(); ++itvg) { - VertexGroup& uniq = itvg->second; + VertexGroup& uniq = *itvg; uniq.computeMatrixForVertexSet(); osg::Matrix matrix = transform * uniq.getMatrix() * invTransform; @@ -145,9 +145,9 @@ namespace osgAnimation template void computeNormal(const osg::Matrix& transform, const osg::Matrix& invTransform, const V* src, V* dst) { - for(VertexGroupSet::iterator itvg=_uniqInfluenceSet2VertIDList.begin(); itvg!=_uniqInfluenceSet2VertIDList.end(); ++itvg) + for(VertexGroupList::iterator itvg=_uniqInfluenceSet2VertIDList.begin(); itvg!=_uniqInfluenceSet2VertIDList.end(); ++itvg) { - VertexGroup& uniq = itvg->second; + VertexGroup& uniq = *itvg; uniq.computeMatrixForVertexSet(); osg::Matrix matrix = transform * uniq.getMatrix() * invTransform; @@ -165,10 +165,9 @@ namespace osgAnimation std::map _invalidInfluence; - typedef std::vector BoneWeightList; - typedef std::map VertexGroupSet; + typedef std::vector VertexGroupList; - VertexGroupSet _uniqInfluenceSet2VertIDList; + VertexGroupList _uniqInfluenceSet2VertIDList; void buildMinimumUpdateSet(const BoneMap&boneMap,const RigGeometry&rig ); }; diff --git a/include/osgAnimation/VertexInfluence b/include/osgAnimation/VertexInfluence index 3060aa8c3..bf3a9b2be 100644 --- a/include/osgAnimation/VertexInfluence +++ b/include/osgAnimation/VertexInfluence @@ -32,11 +32,6 @@ namespace osgAnimation inline void setBoneName(const std::string&s){first=s;} inline const float &getWeight()const{return second;} inline void setWeight(float i){second=i;} - ///default invweight ordered - bool operator <(const BoneWeight&o)const{ - if(getWeight()>o.getWeight()) return true; - if(getWeight() diff --git a/src/osgAnimation/RigTransformSoftware.cpp b/src/osgAnimation/RigTransformSoftware.cpp index 60a9c9476..31de573b3 100644 --- a/src/osgAnimation/RigTransformSoftware.cpp +++ b/src/osgAnimation/RigTransformSoftware.cpp @@ -35,6 +35,46 @@ RigTransformSoftware::RigTransformSoftware(const RigTransformSoftware& rts,const } + +// 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; + } +}; +typedef std::vector BoneWeightList; + +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++) + { + if (SortByNameAndWeight()(b0[i], b1[i])) + return true; + else if (SortByNameAndWeight()(b1[i], b0[i])) + return false; + } + return false; + } +}; + void RigTransformSoftware::buildMinimumUpdateSet(const BoneMap&boneMap,const RigGeometry&rig ){ ///1 Create Index2Vec @@ -93,18 +133,24 @@ 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(); + + typedef std::map UnifyBoneGroup; + UnifyBoneGroup unifyBuffer; vertexID=0; for (std::vector::iterator it = _vertex2Bones.begin(); it != _vertex2Bones.end(); ++it,++vertexID) { BoneWeightList& bones = *it; // sort the vector to have a consistent key - std::sort(bones.begin(), bones.end()); + std::sort(bones.begin(), bones.end(), SortByNameAndWeight() ); // we use the vector as key to differentiate group - VertexGroupSet::iterator result = _uniqInfluenceSet2VertIDList.find(bones); - if (result == _uniqInfluenceSet2VertIDList.end()) - _uniqInfluenceSet2VertIDList[bones].getBoneWeights()=bones; - _uniqInfluenceSet2VertIDList[bones].getVertexes().push_back(vertexID); + UnifyBoneGroup::iterator result = unifyBuffer.find(bones); + if (result == unifyBuffer.end()) + unifyBuffer[bones].getBoneWeights()=bones; + unifyBuffer[bones].getVertexes().push_back(vertexID); } + _uniqInfluenceSet2VertIDList.reserve(unifyBuffer.size()); + for (UnifyBoneGroup::iterator it = unifyBuffer.begin(); it != unifyBuffer.end(); ++it) + _uniqInfluenceSet2VertIDList.push_back(it->second); OSG_DEBUG << "uniq groups " << _uniqInfluenceSet2VertIDList.size() << " for " << rig.getName() << std::endl; } From 925f1524cffae2045d7c6175e45940a175cf498e Mon Sep 17 00:00:00 2001 From: Julien Valentin Date: Mon, 28 Aug 2017 18:16:30 +0200 Subject: [PATCH 022/327] total removal of the old path --- include/osgAnimation/RigGeometry | 8 -- include/osgAnimation/VertexInfluence | 56 ------------ src/osgAnimation/RigGeometry.cpp | 18 ---- src/osgAnimation/VertexInfluence.cpp | 127 --------------------------- 4 files changed, 209 deletions(-) diff --git a/include/osgAnimation/RigGeometry b/include/osgAnimation/RigGeometry index a636f7717..a2a096b51 100644 --- a/include/osgAnimation/RigGeometry +++ b/include/osgAnimation/RigGeometry @@ -69,14 +69,8 @@ namespace osgAnimation void setNeedToComputeMatrix(bool state) { _needToComputeMatrix = state;} bool getNeedToComputeMatrix() const { return _needToComputeMatrix;} - - // this build the internal database about vertex influence and bones - void buildVertexInfluenceSet(); - inline const VertexInfluenceSet& getVertexInfluenceSet() const { return _vertexInfluenceSet;} - void computeMatrixFromRootSkeleton(); - // set implementation of rig method inline RigTransform* getRigTransformImplementation() { return _rigTransformImplementation.get(); } inline void setRigTransformImplementation(RigTransform* rig) { _rigTransformImplementation = rig; } @@ -87,7 +81,6 @@ namespace osgAnimation const osg::Matrix& getMatrixFromSkeletonToGeometry() const; const osg::Matrix& getInvMatrixFromSkeletonToGeometry() const; - inline osg::Geometry* getSourceGeometry() { return _geometry.get(); } inline const osg::Geometry* getSourceGeometry() const { return _geometry.get(); } inline void setSourceGeometry(osg::Geometry* geometry) { _geometry = geometry; } @@ -112,7 +105,6 @@ namespace osgAnimation osg::ref_ptr _geometry; osg::ref_ptr _rigTransformImplementation; - VertexInfluenceSet _vertexInfluenceSet; osg::ref_ptr _vertexInfluenceMap; osg::Matrix _matrixFromSkeletonToGeometry; diff --git a/include/osgAnimation/VertexInfluence b/include/osgAnimation/VertexInfluence index bf3a9b2be..9c9e38738 100644 --- a/include/osgAnimation/VertexInfluence +++ b/include/osgAnimation/VertexInfluence @@ -67,62 +67,6 @@ namespace osgAnimation {} }; - - // this class manage VertexInfluence database by mesh - // reference bones per vertex ... - class OSGANIMATION_EXPORT VertexInfluenceSet - { - public: - typedef std::vector BoneToVertexList; - - class BoneWeight - { - public: - BoneWeight(const std::string& name, float weight) : _boneName(name), _weight(weight) {} - BoneWeight(const BoneWeight &bw2) : _boneName(bw2._boneName), _weight(bw2._weight) {} - const std::string& getBoneName() const { return _boneName; } - float getWeight() const { return _weight; } - void setWeight(float weight) { _weight = weight; } - bool operator==(const BoneWeight& b) const { return (_boneName == b.getBoneName() && _weight == b.getWeight()); } - - protected: - std::string _boneName; - float _weight; - }; - - typedef std::vector BoneWeightList; - typedef std::vector VertIDToBoneWeightList; - - class VertexGroup - { - public: - // set Influences of the VertexGroup - void setBones(BoneWeightList& bones) { _bones = bones;} - const BoneWeightList& getBones() const { return _bones;} - // set Vertex Indices of the VertexGroup - std::vector& getVertexes() { return _vertexes;} - const std::vector& getVertexes() const { return _vertexes;} - protected: - std::vector _vertexes; - BoneWeightList _bones; // here we could limit matrix operation by caching (weight * matrix) - }; - - typedef std::vector UniqVertexGroupList; - /** construct a vector of unique VertexGroups and their influences**/ - void buildUniqVertexGroupList(); - /** return a list of unique VertexGroups and their influences**/ - const UniqVertexGroupList& getUniqVertexGroupList() const { return _uniqVertexSetToBoneSet;} - void addVertexInfluence(const BoneInfluenceList& v); - void buildVertex2BoneList(unsigned int numvertices); - void clear(); - - const VertIDToBoneWeightList& getVertexToBoneList() const; - protected: - BoneToVertexList _bone2Vertexes; - VertIDToBoneWeightList _vertex2Bones; - UniqVertexGroupList _uniqVertexSetToBoneSet; - }; - } #endif diff --git a/src/osgAnimation/RigGeometry.cpp b/src/osgAnimation/RigGeometry.cpp index bb5a9c8ee..057625876 100644 --- a/src/osgAnimation/RigGeometry.cpp +++ b/src/osgAnimation/RigGeometry.cpp @@ -66,7 +66,6 @@ RigGeometry::RigGeometry() RigGeometry::RigGeometry(const RigGeometry& b, const osg::CopyOp& copyop) : osg::Geometry(b,copyop), _geometry(b._geometry), - _vertexInfluenceSet(b._vertexInfluenceSet), _vertexInfluenceMap(b._vertexInfluenceMap), _needToComputeMatrix(b._needToComputeMatrix) { @@ -84,23 +83,6 @@ RigGeometry::RigGeometry(const RigGeometry& b, const osg::CopyOp& copyop) : const osg::Matrix& RigGeometry::getMatrixFromSkeletonToGeometry() const { return _matrixFromSkeletonToGeometry; } const osg::Matrix& RigGeometry::getInvMatrixFromSkeletonToGeometry() const { return _invMatrixFromSkeletonToGeometry;} -void RigGeometry::buildVertexInfluenceSet() -{ - if (!_vertexInfluenceMap.valid()) - { - OSG_WARN << "buildVertexInfluenceSet can't be called without VertexInfluence already set to the RigGeometry ( " << getName() << " ) " << std::endl; - return; - } - _vertexInfluenceSet.clear(); - for (osgAnimation::VertexInfluenceMap::iterator it = _vertexInfluenceMap->begin(); - it != _vertexInfluenceMap->end(); - ++it){ - _vertexInfluenceSet.addVertexInfluence(it->second); - } - _vertexInfluenceSet.buildVertex2BoneList(getSourceGeometry()->getVertexArray()->getNumElements()); - _vertexInfluenceSet.buildUniqVertexGroupList(); - OSG_DEBUG << "uniq groups " << _vertexInfluenceSet.getUniqVertexGroupList().size() << " for " << getName() << std::endl; -} void RigGeometry::computeMatrixFromRootSkeleton() { diff --git a/src/osgAnimation/VertexInfluence.cpp b/src/osgAnimation/VertexInfluence.cpp index bcb626190..9c9e178ba 100644 --- a/src/osgAnimation/VertexInfluence.cpp +++ b/src/osgAnimation/VertexInfluence.cpp @@ -20,130 +20,3 @@ using namespace osgAnimation; -void VertexInfluenceSet::addVertexInfluence(const BoneInfluenceList& v) { _bone2Vertexes.push_back(v); } -const VertexInfluenceSet::VertIDToBoneWeightList& VertexInfluenceSet::getVertexToBoneList() const { return _vertex2Bones;} -// this class manage VertexInfluence database by mesh -// reference bones per vertex ... - -void VertexInfluenceSet::buildVertex2BoneList(unsigned int numvertices) -{ - _vertex2Bones.clear(); - _vertex2Bones.reserve(numvertices); - _vertex2Bones.resize(numvertices); - - for (BoneToVertexList::const_iterator it = _bone2Vertexes.begin(); it != _bone2Vertexes.end(); ++it) - { - const BoneInfluenceList& vi = (*it); - int size = vi.size(); - for (int i = 0; i < size; i++) - { - IndexWeight viw = vi[i]; - int index = viw.first; - float weight = viw.second; - 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.getBoneName(), weight)); - } - } - - // normalize weight per vertex - unsigned int vertid=0; - for (VertIDToBoneWeightList::iterator it = _vertex2Bones.begin(); it != _vertex2Bones.end(); ++it,++vertid) - { - BoneWeightList& bones =*it; - int size = bones.size(); - float sum = 0; - for (int i = 0; i < size; i++) - sum += bones[i].getWeight(); - if (sum < 1e-4) - { - OSG_WARN << "VertexInfluenceSet::buildVertex2BoneList warning the vertex " < -{ - bool operator()(const VertexInfluenceSet::BoneWeight& b0, - const VertexInfluenceSet::BoneWeight& 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 VertexInfluenceSet::BoneWeightList& b0, - const VertexInfluenceSet::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; - } -}; - -void VertexInfluenceSet::clear() -{ - _bone2Vertexes.clear(); - _uniqVertexSetToBoneSet.clear(); -} - -void VertexInfluenceSet::buildUniqVertexGroupList() -{ - _uniqVertexSetToBoneSet.clear(); - - typedef std::map UnifyBoneGroup; - UnifyBoneGroup unifyBuffer; - - unsigned int vertexID=0; - for (VertIDToBoneWeightList::iterator it = _vertex2Bones.begin(); it != _vertex2Bones.end(); ++it,++vertexID) - { - BoneWeightList bones = *it; - - // sort the vector to have a consistent key - std::sort(bones.begin(), bones.end(), SortByNameAndWeight()); - - // we use the vector as key to differentiate group - UnifyBoneGroup::iterator result = unifyBuffer.find(bones); - if (result == unifyBuffer.end()) - unifyBuffer[bones].setBones(bones); - unifyBuffer[bones].getVertexes().push_back(vertexID); - } - - _uniqVertexSetToBoneSet.reserve(unifyBuffer.size()); - - - for (UnifyBoneGroup::iterator it = unifyBuffer.begin(); it != unifyBuffer.end(); ++it) - { - _uniqVertexSetToBoneSet.push_back(it->second); - } -} - From 5123614f892680253c8ef40b27de890f79dcc3d3 Mon Sep 17 00:00:00 2001 From: Julien Valentin Date: Mon, 28 Aug 2017 18:27:23 +0200 Subject: [PATCH 023/327] comply with refactoring --- src/osgWrappers/deprecated-dotosg/osgAnimation/ReaderWriter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/osgWrappers/deprecated-dotosg/osgAnimation/ReaderWriter.cpp b/src/osgWrappers/deprecated-dotosg/osgAnimation/ReaderWriter.cpp index 78824ad7c..b8813ae70 100644 --- a/src/osgWrappers/deprecated-dotosg/osgAnimation/ReaderWriter.cpp +++ b/src/osgWrappers/deprecated-dotosg/osgAnimation/ReaderWriter.cpp @@ -814,7 +814,7 @@ bool RigGeometry_readLocalData(Object& obj, Input& fr) } osgAnimation::BoneInfluenceList vi; - vi.setName(name); + vi.setBoneName(name); vi.reserve(nbVertexes); for (int j = 0; j < nbVertexes; j++) { From 350756e7381868abac8505143916477ab0e36c80 Mon Sep 17 00:00:00 2001 From: Julien Valentin Date: Mon, 28 Aug 2017 18:42:22 +0200 Subject: [PATCH 024/327] add 2 method to VertexInfluenceMap: normalize and cullInfluenceCountPerVertex --- include/osgAnimation/VertexInfluence | 6 ++ src/osgAnimation/VertexInfluence.cpp | 82 ++++++++++++++++++++++++++++ 2 files changed, 88 insertions(+) diff --git a/include/osgAnimation/VertexInfluence b/include/osgAnimation/VertexInfluence index 9c9e38738..ff0403134 100644 --- a/include/osgAnimation/VertexInfluence +++ b/include/osgAnimation/VertexInfluence @@ -65,6 +65,12 @@ namespace osgAnimation std::map(org), osg::Object(org, copyop) {} + ///normalize per vertex weights given numvert of the attached mesh + void normalize(unsigned int numvert); + + ///remove weakest influences in order to fit targetted numbonepervertex + void cullInfluenceCountPerVertex(unsigned int maxnumbonepervertex, float minweight=0, bool renormalize=true); + }; } diff --git a/src/osgAnimation/VertexInfluence.cpp b/src/osgAnimation/VertexInfluence.cpp index 9c9e178ba..3038e8374 100644 --- a/src/osgAnimation/VertexInfluence.cpp +++ b/src/osgAnimation/VertexInfluence.cpp @@ -20,3 +20,85 @@ using namespace osgAnimation; +struct invweight_ordered +{ + inline bool operator() (const BoneWeight& bw1, const BoneWeight& bw2) + { + if (bw1.getWeight() > bw2.getWeight())return true; + if (bw1.getWeight() < bw2.getWeight())return false; + return(bw1.getBoneName() > PerVertWeights; + std::vector localstore; + localstore.resize(numvert); + for(VertexInfluenceMap::iterator mapit=this->begin(); mapit!=this->end(); ++mapit) { + BoneInfluenceList &curvecinf=mapit->second; + for(BoneInfluenceList::iterator curinf=curvecinf.begin(); curinf!=curvecinf.end(); ++curinf) { + IndexWeight& 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) { + 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; + } + } + +} +///remove weakest influences in order to fit targetted numbonepervertex +void VertexInfluenceMap::cullInfluenceCountPerVertex(unsigned int numbonepervertex,float minweight, bool renormalize) { + + typedef std::set BoneWeightOrdered; + std::map tempVec2Bones; + for(VertexInfluenceMap::iterator mapit=this->begin(); mapit!=this->end(); ++mapit) { + BoneInfluenceList &curvecinf=mapit->second; + for(BoneInfluenceList::iterator curinf=curvecinf.begin(); curinf!=curvecinf.end(); ++curinf) { + IndexWeight& inf=*curinf; + if( curvecinf.getBoneName().empty()) { + OSG_WARN << "VertexInfluenceSet::buildVertex2BoneList warning vertex " << inf.first << " is not assigned to a bone" << std::endl; + } + else if(inf.second>minweight)tempVec2Bones[inf.first].insert(BoneWeight(curvecinf.getBoneName(), inf.second)); + } + } + this->clear(); + 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){ + for(BoneWeightOrdered::iterator bwit=bwset.begin(); bwit!=bwset.end(); ++bwit) + sum+=bwit->getWeight(); + if(sum>1e-4){ + sum=1.0f/sum; + for(BoneWeightOrdered::iterator bwit=bwset.begin(); bwit!=bwset.end(); ++bwit) { + BoneInfluenceList & inf= (*this)[bwit->getBoneName()]; + inf.setBoneName(bwit->getBoneName()); + inf.push_back(IndexWeight(mapit->first, bwit->getWeight()*sum)); + } + } + }else{ + for(BoneWeightOrdered::iterator bwit=bwset.begin(); bwit!=bwset.end(); ++bwit) { + BoneInfluenceList & inf= (*this)[bwit->getBoneName()]; + inf.setBoneName(bwit->getBoneName()); + inf.push_back(IndexWeight(mapit->first,bwit->getWeight())); + } + + } + } +} From 4a626cea2071a63b00de2b6f4e0c5a855c4e6b30 Mon Sep 17 00:00:00 2001 From: Julien Valentin Date: Tue, 29 Aug 2017 00:07:07 +0200 Subject: [PATCH 025/327] remove VertexInfluenceSet --- examples/osganimationskinning/osganimationskinning.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/examples/osganimationskinning/osganimationskinning.cpp b/examples/osganimationskinning/osganimationskinning.cpp index bbf4614fb..c28a2b15d 100644 --- a/examples/osganimationskinning/osganimationskinning.cpp +++ b/examples/osganimationskinning/osganimationskinning.cpp @@ -134,12 +134,11 @@ void initVertexMap(osgAnimation::Bone* b0, osgAnimation::RigGeometry* geom, osg::Vec3Array* array) { - osgAnimation::VertexInfluenceSet vertexesInfluences; osgAnimation::VertexInfluenceMap* vim = new osgAnimation::VertexInfluenceMap; - (*vim)[b0->getName()].setName(b0->getName()); - (*vim)[b1->getName()].setName(b1->getName()); - (*vim)[b2->getName()].setName(b2->getName()); + (*vim)[b0->getName()].setBoneName(b0->getName()); + (*vim)[b1->getName()].setBoneName(b1->getName()); + (*vim)[b2->getName()].setBoneName(b2->getName()); for (int i = 0; i < (int)array->size(); i++) { From 9856cecb71b68e38bd57294772eef0c1fb869a83 Mon Sep 17 00:00:00 2001 From: Julien Valentin Date: Tue, 29 Aug 2017 00:09:38 +0200 Subject: [PATCH 026/327] cleanup --- include/osgAnimation/VertexInfluence | 14 ++++++++++-- src/osgAnimation/RigTransformSoftware.cpp | 28 +++++++++++------------ 2 files changed, 25 insertions(+), 17 deletions(-) diff --git a/include/osgAnimation/VertexInfluence b/include/osgAnimation/VertexInfluence index ff0403134..317a45e87 100644 --- a/include/osgAnimation/VertexInfluence +++ b/include/osgAnimation/VertexInfluence @@ -42,9 +42,19 @@ namespace osgAnimation inline const float &getWeight()const{return second;} inline void setWeight(float i){second=i;} }; + typedef std::vector IndexWeightList; + typedef std::vector BoneWeightList; + typedef std::vector IndexList; - typedef std::vector VertexList; - class OSGANIMATION_EXPORT BoneInfluenceList : public VertexList + /// map a set of boneinfluence to a list of vertex indices sharing this set + class VertexGroup: public std::pair + { + public: + inline const BoneWeightList& getBoneWeights()const { return first; } + inline void setBoneWeights(BoneWeightList&o) { first=o; } + inline IndexList& vertIDs() { return second; } + }; + class OSGANIMATION_EXPORT BoneInfluenceList : public IndexWeightList { public: const std::string& getBoneName() const { return _name;} diff --git a/src/osgAnimation/RigTransformSoftware.cpp b/src/osgAnimation/RigTransformSoftware.cpp index 31de573b3..d7d1515df 100644 --- a/src/osgAnimation/RigTransformSoftware.cpp +++ b/src/osgAnimation/RigTransformSoftware.cpp @@ -46,17 +46,15 @@ struct SortByNameAndWeight : public std::less b1.getBoneName()) return false; - if (b0.getWeight() < b1.getWeight()) - return true; - return false; + return (b0.getWeight() < b1.getWeight()); } }; -typedef std::vector BoneWeightList; +typedef std::vector BonePtrWeightList; -struct SortByBoneWeightList : public std::less +struct SortByBoneWeightList : public std::less { - bool operator()(const BoneWeightList& b0, - const BoneWeightList& b1) const + bool operator()(const BonePtrWeightList& b0, + const BonePtrWeightList& b1) const { if (b0.size() < b1.size()) return true; @@ -78,7 +76,7 @@ struct SortByBoneWeightList : public std::less void RigTransformSoftware::buildMinimumUpdateSet(const BoneMap&boneMap,const RigGeometry&rig ){ ///1 Create Index2Vec - std::vector _vertex2Bones; + std::vector _vertex2Bones; _vertex2Bones.resize(rig.getSourceGeometry()->getVertexArray()->getNumElements()); const VertexInfluenceMap *_vertexInfluenceMap=rig.getInfluenceMap(); @@ -112,11 +110,11 @@ void RigTransformSoftware::buildMinimumUpdateSet(const BoneMap&boneMap,const Rig // 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 = _vertex2Bones.begin(); it != _vertex2Bones.end(); ++it, ++vertexID) { - BoneWeightList& bones = *it; + BonePtrWeightList& bones = *it; float sum = 0; - for(BoneWeightList::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) { @@ -125,7 +123,7 @@ void RigTransformSoftware::buildMinimumUpdateSet(const BoneMap&boneMap,const Rig else { float mult = 1.0/sum; - for(BoneWeightList::iterator bwit=bones.begin();bwit!=bones.end();++bwit) + for(BonePtrWeightList::iterator bwit=bones.begin();bwit!=bones.end();++bwit) bwit->setWeight(bwit->getWeight() * mult); } } @@ -134,12 +132,12 @@ void RigTransformSoftware::buildMinimumUpdateSet(const BoneMap&boneMap,const Rig ///in order to minimize weighted matrices computation on update _uniqInfluenceSet2VertIDList.clear(); - typedef std::map UnifyBoneGroup; + typedef std::map UnifyBoneGroup; UnifyBoneGroup unifyBuffer; vertexID=0; - for (std::vector::iterator it = _vertex2Bones.begin(); it != _vertex2Bones.end(); ++it,++vertexID) + for (std::vector::iterator it = _vertex2Bones.begin(); it != _vertex2Bones.end(); ++it,++vertexID) { - BoneWeightList& bones = *it; + BonePtrWeightList& bones = *it; // sort the vector to have a consistent key std::sort(bones.begin(), bones.end(), SortByNameAndWeight() ); // we use the vector as key to differentiate group From b3402d9344f9fd877cbc27cdc43ce4d60ad082ad Mon Sep 17 00:00:00 2001 From: Julien Valentin Date: Tue, 29 Aug 2017 00:34:26 +0200 Subject: [PATCH 027/327] readd the 2 methods in InfluenceMap just in case --- include/osgAnimation/VertexInfluence | 4 ++ src/osgAnimation/VertexInfluence.cpp | 90 ++++++++++++++++++++++++++++ 2 files changed, 94 insertions(+) diff --git a/include/osgAnimation/VertexInfluence b/include/osgAnimation/VertexInfluence index 317a45e87..1b35b2c0f 100644 --- a/include/osgAnimation/VertexInfluence +++ b/include/osgAnimation/VertexInfluence @@ -81,6 +81,10 @@ namespace osgAnimation ///remove weakest influences in order to fit targetted numbonepervertex void cullInfluenceCountPerVertex(unsigned int maxnumbonepervertex, float minweight=0, bool renormalize=true); + //compute PerVertexInfluenceList + void computePerVertexInfluenceList(std::vector& vertex2Bones,unsigned int numvert)const; + //create the minimal VertexGroup set + void computeMinimalVertexGroupList(std::vector&uniqVertexGroupList,unsigned int numvert)const; }; } diff --git a/src/osgAnimation/VertexInfluence.cpp b/src/osgAnimation/VertexInfluence.cpp index 3038e8374..dabaca32f 100644 --- a/src/osgAnimation/VertexInfluence.cpp +++ b/src/osgAnimation/VertexInfluence.cpp @@ -102,3 +102,93 @@ 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) + { + const BoneInfluenceList& inflist = it->second; + if (inflist.getBoneName().empty()) { + OSG_WARN << "RigTransformSoftware::VertexInfluenceMap contains unamed bone BoneInfluenceList" << std::endl; + } + for(BoneInfluenceList::const_iterator infit=inflist.begin(); infit!=inflist.end(); ++infit) + { + const IndexWeight &iw = *infit; + const unsigned int &index = iw.getIndex(); + float weight = iw.getWeight(); + + vertex2Bones[index].push_back(BoneWeight(inflist.getBoneName(), weight));; + } + } +} + +// sort by name and weight +struct SortByNameAndWeight : public std::less +{ + bool operator()(const BoneWeight& b0, + const BoneWeight& b1) const + { + if (b0.getBoneName() < b1.getBoneName()) + return true; + else if (b0.getBoneName() > b1.getBoneName()) + return false; + return (b0.getWeight() < b1.getWeight()); + } +}; + +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++) + { + if (SortByNameAndWeight()(b0[i], b1[i])) + return true; + else if (SortByNameAndWeight()(b1[i], b0[i])) + return false; + } + return false; + } +}; +void VertexInfluenceMap::computeMinimalVertexGroupList(std::vector&uniqVertexGroupList,unsigned int numvert)const +{ + uniqVertexGroupList.clear(); + std::vector vertex2Bones; + computePerVertexInfluenceList(vertex2Bones,numvert); + typedef std::map UnifyBoneGroup; + UnifyBoneGroup unifyBuffer; + + unsigned int vertexID=0; + for (std::vector::iterator it = vertex2Bones.begin(); it != vertex2Bones.end(); ++it,++vertexID) + { + BoneWeightList &boneweightlist = *it;//->second; + //int vertexIndex = it->first; + + // sort the vector to have a consistent key + std::sort(boneweightlist.begin(), boneweightlist.end(), SortByNameAndWeight()); + + // we use the vector as key to differentiate group + UnifyBoneGroup::iterator result = unifyBuffer.find(boneweightlist); + if (result == unifyBuffer.end()) + unifyBuffer[boneweightlist].setBoneWeights(boneweightlist); + unifyBuffer[boneweightlist].vertIDs().push_back(vertexID); + } + if(vertex2Bones.size()==unifyBuffer.size()) { + OSG_WARN << "VertexInfluenceSet::buildmap is useless no duplicate VertexGroup" << std::endl; + } + uniqVertexGroupList.reserve(unifyBuffer.size()); + for (UnifyBoneGroup::iterator it = unifyBuffer.begin(); it != unifyBuffer.end(); ++it) + { + uniqVertexGroupList.push_back(it->second); + } +} From 0c9a624026ad7eedad77cc187983d6761c77f4cb Mon Sep 17 00:00:00 2001 From: Julien Valentin Date: Tue, 29 Aug 2017 02:55:40 +0200 Subject: [PATCH 028/327] few refactoring and fixes --- include/osgAnimation/RigTransformSoftware | 15 +++++++------- include/osgAnimation/VertexInfluence | 24 ++++++++++++----------- src/osgAnimation/RigTransformSoftware.cpp | 20 ++++++++++++------- 3 files changed, 33 insertions(+), 26 deletions(-) diff --git a/include/osgAnimation/RigTransformSoftware b/include/osgAnimation/RigTransformSoftware index 9d2a014dc..fa8aabcb9 100644 --- a/include/osgAnimation/RigTransformSoftware +++ b/include/osgAnimation/RigTransformSoftware @@ -53,7 +53,6 @@ namespace osgAnimation osg::observer_ptr< Bone > _boneptr; }; typedef std::vector BonePtrWeightList; - typedef std::vector IndexList; /// map a set of boneinfluence to a list of vertex indices sharing this set class VertexGroup @@ -61,7 +60,7 @@ namespace osgAnimation public: inline BonePtrWeightList& getBoneWeights() { return _boneweights; } - inline IndexList& getVertexes() { return _vertexes; } + inline IndexList& getVertices() { return _vertexes; } inline void resetMatrix() { @@ -122,9 +121,8 @@ namespace osgAnimation osg::Matrix _result; }; - - - template void compute(const osg::Matrix& transform, const osg::Matrix& invTransform, const V* src, V* dst) + template + 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) @@ -133,7 +131,7 @@ namespace osgAnimation uniq.computeMatrixForVertexSet(); osg::Matrix matrix = transform * uniq.getMatrix() * invTransform; - const IndexList& vertexes = uniq.getVertexes(); + const IndexList& vertexes = uniq.getVertices(); for(IndexList::const_iterator vertIDit=vertexes.begin(); vertIDit!=vertexes.end(); ++vertIDit) { dst[*vertIDit] = src[*vertIDit] * matrix; @@ -143,7 +141,8 @@ namespace osgAnimation } - template void computeNormal(const osg::Matrix& transform, const osg::Matrix& invTransform, const V* src, V* dst) + 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) { @@ -151,7 +150,7 @@ namespace osgAnimation uniq.computeMatrixForVertexSet(); osg::Matrix matrix = transform * uniq.getMatrix() * invTransform; - const IndexList& vertexes = uniq.getVertexes(); + const IndexList& vertexes = uniq.getVertices(); for(IndexList::const_iterator vertIDit=vertexes.begin(); vertIDit!=vertexes.end(); ++vertIDit) { dst[*vertIDit] = osg::Matrix::transform3x3(src[*vertIDit],matrix); diff --git a/include/osgAnimation/VertexInfluence b/include/osgAnimation/VertexInfluence index 1b35b2c0f..4bb42b105 100644 --- a/include/osgAnimation/VertexInfluence +++ b/include/osgAnimation/VertexInfluence @@ -46,14 +46,6 @@ namespace osgAnimation typedef std::vector BoneWeightList; typedef std::vector IndexList; - /// map a set of boneinfluence to a list of vertex indices sharing this set - class VertexGroup: public std::pair - { - public: - inline const BoneWeightList& getBoneWeights()const { return first; } - inline void setBoneWeights(BoneWeightList&o) { first=o; } - inline IndexList& vertIDs() { return second; } - }; class OSGANIMATION_EXPORT BoneInfluenceList : public IndexWeightList { public: @@ -82,9 +74,19 @@ namespace osgAnimation void cullInfluenceCountPerVertex(unsigned int maxnumbonepervertex, float minweight=0, bool renormalize=true); //compute PerVertexInfluenceList - void computePerVertexInfluenceList(std::vector& vertex2Bones,unsigned int numvert)const; - //create the minimal VertexGroup set - void computeMinimalVertexGroupList(std::vector&uniqVertexGroupList,unsigned int numvert)const; + void computePerVertexInfluenceList(std::vector& perVertexInfluenceList, unsigned int numvert)const; + + /// map a set of boneinfluence to a list of vertex indices sharing this set + class VertexGroup: public std::pair + { + public: + inline const BoneWeightList& getBoneWeights()const { return first; } + inline void setBoneWeights( BoneWeightList& o ) { first=o; } + inline IndexList& vertIDs() { return second; } + }; + + /// compute the minimal VertexGroup Set in which vertices shares the same influence set + void computeMinimalVertexGroupList(std::vector&uniqVertexGroupList, unsigned int numvert)const; }; } diff --git a/src/osgAnimation/RigTransformSoftware.cpp b/src/osgAnimation/RigTransformSoftware.cpp index d7d1515df..ff241bc91 100644 --- a/src/osgAnimation/RigTransformSoftware.cpp +++ b/src/osgAnimation/RigTransformSoftware.cpp @@ -20,6 +20,7 @@ #include #include + using namespace osgAnimation; RigTransformSoftware::RigTransformSoftware() @@ -35,7 +36,6 @@ RigTransformSoftware::RigTransformSoftware(const RigTransformSoftware& rts,const } - // sort by name and weight struct SortByNameAndWeight : public std::less { @@ -104,7 +104,7 @@ void RigTransformSoftware::buildMinimumUpdateSet(const BoneMap&boneMap,const Rig const unsigned int &index = iw.getIndex(); float weight = iw.getWeight(); - _vertex2Bones[index].push_back(BonePtrWeight(inflist.getBoneName(), weight,bone));; + _vertex2Bones[index].push_back(BonePtrWeight(inflist.getBoneName(), weight,bone)); } } @@ -135,19 +135,25 @@ void RigTransformSoftware::buildMinimumUpdateSet(const BoneMap&boneMap,const Rig typedef std::map UnifyBoneGroup; UnifyBoneGroup unifyBuffer; vertexID=0; + ; for (std::vector::iterator it = _vertex2Bones.begin(); it != _vertex2Bones.end(); ++it,++vertexID) { - BonePtrWeightList& bones = *it; + BonePtrWeightList bones = *it; // sort the vector to have a consistent key std::sort(bones.begin(), bones.end(), SortByNameAndWeight() ); // we use the vector as key to differentiate group UnifyBoneGroup::iterator result = unifyBuffer.find(bones); - if (result == unifyBuffer.end()) - unifyBuffer[bones].getBoneWeights()=bones; - unifyBuffer[bones].getVertexes().push_back(vertexID); + if (result != unifyBuffer.end()) + result->second.getVertices().push_back(vertexID); + else + { + VertexGroup& vg = unifyBuffer[bones]; + vg.getBoneWeights() = bones; + vg.getVertices().push_back(vertexID); + } } _uniqInfluenceSet2VertIDList.reserve(unifyBuffer.size()); - for (UnifyBoneGroup::iterator it = unifyBuffer.begin(); it != unifyBuffer.end(); ++it) + for (UnifyBoneGroup::const_iterator it = unifyBuffer.begin(); it != unifyBuffer.end(); ++it) _uniqInfluenceSet2VertIDList.push_back(it->second); OSG_DEBUG << "uniq groups " << _uniqInfluenceSet2VertIDList.size() << " for " << rig.getName() << std::endl; } From c36e47188b4ca951b6cb587e15345e57640fc9f1 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Tue, 29 Aug 2017 12:21:14 +0100 Subject: [PATCH 029/327] Added argument parsing to viewer constructor --- examples/osgfont/osgfont.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/osgfont/osgfont.cpp b/examples/osgfont/osgfont.cpp index 9255bea0c..5f3eb9bee 100644 --- a/examples/osgfont/osgfont.cpp +++ b/examples/osgfont/osgfont.cpp @@ -84,8 +84,8 @@ typedef std::list Sizes; int main(int argc, char** argv) { - osgViewer::Viewer viewer; osg::ArgumentParser args(&argc, argv); + osgViewer::Viewer viewer(args); // Make sure we have the minimum args... if(argc <= 2) From 37487b0c0b7c299f8a710c1f151e5eebb098f90c Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Tue, 29 Aug 2017 13:48:06 +0100 Subject: [PATCH 030/327] Added --ortho command line option to toggle use of orthographic camera or default perspective one --- examples/osgfont/osgfont.cpp | 36 +++++++++++++++++++++++++++--------- 1 file changed, 27 insertions(+), 9 deletions(-) diff --git a/examples/osgfont/osgfont.cpp b/examples/osgfont/osgfont.cpp index 5f3eb9bee..5090422ce 100644 --- a/examples/osgfont/osgfont.cpp +++ b/examples/osgfont/osgfont.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #include @@ -56,12 +57,12 @@ osg::Camera* createOrthoCamera(double width, double height) return camera; } -osgText::Text* createLabel(const std::string& l, const char* f, unsigned int size) +osgText::Text* createLabel(const std::string& l, const std::string& fontfile, unsigned int size) { static osg::Vec3 pos(10.0f, 10.0f, 0.0f); osgText::Text* label = new osgText::Text(); - osg::ref_ptr font = osgText::readRefFontFile(f); + osg::ref_ptr font = osgText::readRefFontFile(fontfile); label->setFont(font); label->setCharacterSize(size); @@ -100,8 +101,27 @@ int main(int argc, char** argv) viewer.addEventHandler(new osgViewer::StatsHandler()); viewer.addEventHandler(new osgViewer::WindowSizeHandler()); - osg::Group* group = new osg::Group(); - osg::Camera* camera = createOrthoCamera(1280.0f, 1024.0f); + + osg::ref_ptr root = new osg::Group; + + bool ortho = args.read("--ortho"); + if (ortho) + { + osg::ref_ptr camera = createOrthoCamera(1280.0f, 1024.0f); + root->addChild(camera.get()); + root = camera; + } + else + { + osg::ref_ptr transform = new osg::MatrixTransform; + transform->setMatrix(osg::Matrixd::rotate(osg::DegreesToRadians(90.0), 1.0, 0.0, 0.0)); + root->addChild(transform.get()); + root = transform; + } + + std::string fontfile("arial.ttf"); + + fontfile = argv[1]; // Create the list of desired sizes. Sizes sizes; @@ -122,14 +142,12 @@ int main(int argc, char** argv) ss << *i << " 1234567890 abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ"; - geode->addDrawable(createLabel(ss.str(), args[1], *i)); + geode->addDrawable(createLabel(ss.str(), fontfile, *i)); } - camera->addChild(geode); + root->addChild(geode); - group->addChild(camera); - - viewer.setSceneData(group); + viewer.setSceneData(root.get()); return viewer.run(); } From 059fc703379f54c60fbe7004d3de6af5db53d9a3 Mon Sep 17 00:00:00 2001 From: Julien Valentin Date: Tue, 29 Aug 2017 14:11:44 +0200 Subject: [PATCH 031/327] set defaut implementation at creation --- include/osgAnimation/MorphGeometry | 20 ++++++++++---------- include/osgAnimation/MorphTransformHardware | 2 +- include/osgAnimation/RigGeometry | 4 ---- src/osgAnimation/MorphGeometry.cpp | 6 +++--- src/osgAnimation/MorphTransformHardware.cpp | 2 +- src/osgAnimation/RigGeometry.cpp | 4 +++- 6 files changed, 18 insertions(+), 20 deletions(-) diff --git a/include/osgAnimation/MorphGeometry b/include/osgAnimation/MorphGeometry index a1ec3f697..9c87ac681 100644 --- a/include/osgAnimation/MorphGeometry +++ b/include/osgAnimation/MorphGeometry @@ -61,25 +61,25 @@ namespace osgAnimation virtual const char* className() const { return "MorphGeometry"; } // set implementation of rig method - void setMorphTransformImplementation(MorphTransform*); - MorphTransform* getMorphTransformImplementation(); - const MorphTransform* getMorphTransformImplementation() const { return _rigTransformImplementation.get(); } + inline void setMorphTransformImplementation(MorphTransform*mt) { _morphTransformImplementation=mt; } + inline MorphTransform* getMorphTransformImplementation() { return _morphTransformImplementation.get(); } + inline const MorphTransform* getMorphTransformImplementation() const { return _morphTransformImplementation.get(); } /** Set the morphing method. */ - void setMethod(Method method) { _method = method; } + inline void setMethod(Method method) { _method = method; } /** Get the morphing method. */ inline Method getMethod() const { return _method; } /** Set flag for morphing normals. */ - void setMorphNormals(bool morphNormals) { _morphNormals = morphNormals; } + inline void setMorphNormals(bool morphNormals) { _morphNormals = morphNormals; } /** Get the flag for morphing normals. */ inline bool getMorphNormals() const { return _morphNormals; } /** Get the list of MorphTargets.*/ - const MorphTargetList& getMorphTargetList() const { return _morphTargets; } + inline const MorphTargetList& getMorphTargetList() const { return _morphTargets; } /** Get the list of MorphTargets. Warning if you modify this array you will have to call dirty() */ - MorphTargetList& getMorphTargetList() { return _morphTargets; } + inline MorphTargetList& getMorphTargetList() { return _morphTargets; } /** Return the \c MorphTarget at position \c i.*/ inline const MorphTarget& getMorphTarget( unsigned int i ) const { return _morphTargets[i]; } @@ -130,7 +130,7 @@ namespace osgAnimation } /** update a morph target at index setting its current weight to morphWeight */ - void setWeight(unsigned int index, float morphWeight) + inline void setWeight(unsigned int index, float morphWeight) { if (index < _morphTargets.size()) { @@ -144,10 +144,10 @@ namespace osgAnimation inline bool isDirty()const { return _dirty; } /** for retrocompatibility */ - virtual void transformSoftwareMethod(){ if (!_rigTransformImplementation.valid())_rigTransformImplementation = new MorphTransformSoftware();(*_rigTransformImplementation.get())(*this);} + virtual void transformSoftwareMethod(){(*_morphTransformImplementation.get())(*this);} protected: - osg::ref_ptr _rigTransformImplementation; + osg::ref_ptr _morphTransformImplementation; /// Do we need to recalculate the morphed geometry? bool _dirty; diff --git a/include/osgAnimation/MorphTransformHardware b/include/osgAnimation/MorphTransformHardware index e75114a74..9b5e5239b 100644 --- a/include/osgAnimation/MorphTransformHardware +++ b/include/osgAnimation/MorphTransformHardware @@ -1,5 +1,5 @@ /* -*-c++-*- - * Copyright (C) 2009 Cedric Pinson + * Copyright (C) 2017 Julien Valentin * * This library is open source and may be redistributed and/or modified under * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or diff --git a/include/osgAnimation/RigGeometry b/include/osgAnimation/RigGeometry index a2a096b51..e3b3c4a46 100644 --- a/include/osgAnimation/RigGeometry +++ b/include/osgAnimation/RigGeometry @@ -145,10 +145,6 @@ namespace osgAnimation } geom->setSkeleton(finder._root.get()); - if(!geom->getRigTransformImplementation()) - { - geom->setRigTransformImplementation(new RigTransformSoftware); - } geom->getRigTransformImplementation()->prepareData(*geom); } diff --git a/src/osgAnimation/MorphGeometry.cpp b/src/osgAnimation/MorphGeometry.cpp index f52c04c3a..07a86d1a6 100644 --- a/src/osgAnimation/MorphGeometry.cpp +++ b/src/osgAnimation/MorphGeometry.cpp @@ -29,6 +29,7 @@ MorphGeometry::MorphGeometry() : setUseDisplayList(false); setUpdateCallback(new UpdateMorphGeometry); setUseVertexBufferObjects(true); + _morphTransformImplementation = new MorphTransformSoftware(); } MorphGeometry::MorphGeometry(const osg::Geometry& g) : @@ -41,10 +42,12 @@ MorphGeometry::MorphGeometry(const osg::Geometry& g) : setUseDisplayList(false); setUpdateCallback(new UpdateMorphGeometry); setUseVertexBufferObjects(true); + _morphTransformImplementation = new MorphTransformSoftware(); } MorphGeometry::MorphGeometry(const MorphGeometry& b, const osg::CopyOp& copyop) : osg::Geometry(b,copyop), + _morphTransformImplementation((MorphTransform*)copyop(b._morphTransformImplementation)), _dirty(b._dirty), _method(b._method), _morphTargets(b._morphTargets), @@ -56,9 +59,6 @@ MorphGeometry::MorphGeometry(const MorphGeometry& b, const osg::CopyOp& copyop) setUseVertexBufferObjects(true); } -MorphTransform* MorphGeometry::getMorphTransformImplementation() { return _rigTransformImplementation.get(); } -void MorphGeometry::setMorphTransformImplementation(MorphTransform* rig) { _rigTransformImplementation = rig; } - UpdateMorph::UpdateMorph(const UpdateMorph& apc,const osg::CopyOp& copyop) : osg::Object(apc, copyop), osg::Callback(apc, copyop), diff --git a/src/osgAnimation/MorphTransformHardware.cpp b/src/osgAnimation/MorphTransformHardware.cpp index be37a470a..8b5351cea 100644 --- a/src/osgAnimation/MorphTransformHardware.cpp +++ b/src/osgAnimation/MorphTransformHardware.cpp @@ -1,5 +1,5 @@ /* -*-c++-*- - * Copyleft 2016 Valentin Julien + * Copyright (C) 2017 Julien Valentin * * This library is open source and may be redistributed and/or modified under * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or diff --git a/src/osgAnimation/RigGeometry.cpp b/src/osgAnimation/RigGeometry.cpp index 057625876..c176cf9df 100644 --- a/src/osgAnimation/RigGeometry.cpp +++ b/src/osgAnimation/RigGeometry.cpp @@ -59,6 +59,7 @@ RigGeometry::RigGeometry() _matrixFromSkeletonToGeometry = _invMatrixFromSkeletonToGeometry = osg::Matrix::identity(); // disable the computation of boundingbox for the rig mesh setComputeBoundingBoxCallback(new RigComputeBoundingBoxCallback()); + _rigTransformImplementation = new osgAnimation::RigTransformSoftware; } @@ -66,6 +67,7 @@ RigGeometry::RigGeometry() RigGeometry::RigGeometry(const RigGeometry& b, const osg::CopyOp& copyop) : osg::Geometry(b,copyop), _geometry(b._geometry), + _rigTransformImplementation((RigTransform*)copyop(b._rigTransformImplementation)), _vertexInfluenceMap(b._vertexInfluenceMap), _needToComputeMatrix(b._needToComputeMatrix) { @@ -100,7 +102,7 @@ void RigGeometry::computeMatrixFromRootSkeleton() void RigGeometry::update() { - RigTransform& implementation = *getRigTransformImplementation(); + RigTransform& implementation = *_rigTransformImplementation; (implementation)(*this); } From 21bcd61c92c3af8e4ee7f576d404e23868d4a9af Mon Sep 17 00:00:00 2001 From: Julien Valentin Date: Tue, 29 Aug 2017 14:47:56 +0200 Subject: [PATCH 032/327] add MorphTransformHW for RigGeometry sources that are MorphGeometry --- examples/osganimationhardware/osganimationhardware.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/examples/osganimationhardware/osganimationhardware.cpp b/examples/osganimationhardware/osganimationhardware.cpp index eb7d8b3ea..4c65644a8 100644 --- a/examples/osganimationhardware/osganimationhardware.cpp +++ b/examples/osganimationhardware/osganimationhardware.cpp @@ -28,6 +28,8 @@ #include #include #include +#include +#include #include #include @@ -182,8 +184,11 @@ struct SetupRigGeometry : public osg::NodeVisitor if (_hardware) { osgAnimation::RigGeometry* rig = dynamic_cast(&geom); - if (rig) + if (rig){ rig->setRigTransformImplementation(new MyRigTransformHardware); + osgAnimation::MorphGeometry *morph=dynamic_cast(rig->getSourceGeometry()); + if(morph)morph->setMorphTransformImplementation(new osgAnimation::MorphTransformHardware); + } } #if 0 From 186691a9db084ec971ca8b78872e1b12faf6c759 Mon Sep 17 00:00:00 2001 From: Julien Valentin Date: Tue, 29 Aug 2017 15:10:05 +0200 Subject: [PATCH 033/327] remove virtual qualifier for deprecated method --- include/osgAnimation/MorphGeometry | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/osgAnimation/MorphGeometry b/include/osgAnimation/MorphGeometry index 9c87ac681..cf4b06228 100644 --- a/include/osgAnimation/MorphGeometry +++ b/include/osgAnimation/MorphGeometry @@ -144,7 +144,7 @@ namespace osgAnimation inline bool isDirty()const { return _dirty; } /** for retrocompatibility */ - virtual void transformSoftwareMethod(){(*_morphTransformImplementation.get())(*this);} + void transformSoftwareMethod(){(*_morphTransformImplementation.get())(*this);} protected: osg::ref_ptr _morphTransformImplementation; From ce6a316bde97e9fb84566a9e572d4768a036d8b0 Mon Sep 17 00:00:00 2001 From: Julien Valentin Date: Tue, 29 Aug 2017 17:24:35 +0200 Subject: [PATCH 034/327] cleanup --- include/osgAnimation/RigTransformSoftware | 22 +++++++----- src/osgAnimation/RigTransformSoftware.cpp | 43 +++-------------------- 2 files changed, 18 insertions(+), 47 deletions(-) diff --git a/include/osgAnimation/RigTransformSoftware b/include/osgAnimation/RigTransformSoftware index fa8aabcb9..1632eff96 100644 --- a/include/osgAnimation/RigTransformSoftware +++ b/include/osgAnimation/RigTransformSoftware @@ -40,17 +40,23 @@ namespace osgAnimation //to call when a skeleton is reacheable from the rig to prepare technic data virtual bool prepareData(RigGeometry&); - class BonePtrWeight: public BoneWeight + class BonePtrWeight: std::pair< osg::observer_ptr< Bone >, float> { public: - BonePtrWeight(const std::string& name, float weight, Bone *bptr=0) :BoneWeight(name,weight), _boneptr(bptr) {} - BonePtrWeight(const BonePtrWeight &bw2) : BoneWeight(bw2), _boneptr(bw2._boneptr) {} + 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()) {} - const Bone * getBonePtr()const{return _boneptr.get();} - void setBonePtr(Bone*b){_boneptr=b;} - - protected: - osg::observer_ptr< Bone > _boneptr; + inline const Bone * getBonePtr() const {return first.get();} + inline void setBonePtr(Bone*b){first=b;} + inline const float & getWeight() const {return second;} + inline void setWeight(float b) {second=b;} + inline bool operator<(const BonePtrWeight &b1) const{ + if (getBonePtr() < b1.getBonePtr()) + return true; + else if (getBonePtr() > b1.getBonePtr()) + return false; + return (getWeight() < b1.getWeight()); + } }; typedef std::vector BonePtrWeightList; diff --git a/src/osgAnimation/RigTransformSoftware.cpp b/src/osgAnimation/RigTransformSoftware.cpp index ff241bc91..676cad8ea 100644 --- a/src/osgAnimation/RigTransformSoftware.cpp +++ b/src/osgAnimation/RigTransformSoftware.cpp @@ -36,43 +36,8 @@ RigTransformSoftware::RigTransformSoftware(const RigTransformSoftware& rts,const } -// 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; - return (b0.getWeight() < b1.getWeight()); - } -}; typedef std::vector BonePtrWeightList; -struct SortByBoneWeightList : public std::less -{ - bool operator()(const BonePtrWeightList& b0, - const BonePtrWeightList& 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++) - { - if (SortByNameAndWeight()(b0[i], b1[i])) - return true; - else if (SortByNameAndWeight()(b1[i], b0[i])) - return false; - } - return false; - } -}; - void RigTransformSoftware::buildMinimumUpdateSet(const BoneMap&boneMap,const RigGeometry&rig ){ ///1 Create Index2Vec @@ -104,7 +69,7 @@ void RigTransformSoftware::buildMinimumUpdateSet(const BoneMap&boneMap,const Rig const unsigned int &index = iw.getIndex(); float weight = iw.getWeight(); - _vertex2Bones[index].push_back(BonePtrWeight(inflist.getBoneName(), weight,bone)); + _vertex2Bones[index].push_back(BonePtrWeight(bone, weight)); } } @@ -132,15 +97,15 @@ void RigTransformSoftware::buildMinimumUpdateSet(const BoneMap&boneMap,const Rig ///in order to minimize weighted matrices computation on update _uniqInfluenceSet2VertIDList.clear(); - typedef std::map UnifyBoneGroup; + typedef std::map UnifyBoneGroup; UnifyBoneGroup unifyBuffer; vertexID=0; ; for (std::vector::iterator it = _vertex2Bones.begin(); it != _vertex2Bones.end(); ++it,++vertexID) { - BonePtrWeightList bones = *it; + BonePtrWeightList &bones = *it; // sort the vector to have a consistent key - std::sort(bones.begin(), bones.end(), SortByNameAndWeight() ); + std::sort(bones.begin(), bones.end() ); // we use the vector as key to differentiate group UnifyBoneGroup::iterator result = unifyBuffer.find(bones); if (result != unifyBuffer.end()) From fae9729560193aa4b9c3e5b171e90bfa14bf68af Mon Sep 17 00:00:00 2001 From: Julien Valentin Date: Tue, 29 Aug 2017 17:32:19 +0200 Subject: [PATCH 035/327] swap priority in BonePtrWeight comparator< yeild the same VG set --- include/osgAnimation/RigTransformSoftware | 8 +++----- src/osgAnimation/RigTransformSoftware.cpp | 2 +- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/include/osgAnimation/RigTransformSoftware b/include/osgAnimation/RigTransformSoftware index 1632eff96..2a9f28c86 100644 --- a/include/osgAnimation/RigTransformSoftware +++ b/include/osgAnimation/RigTransformSoftware @@ -51,11 +51,9 @@ namespace osgAnimation inline const float & getWeight() const {return second;} inline void setWeight(float b) {second=b;} inline bool operator<(const BonePtrWeight &b1) const{ - if (getBonePtr() < b1.getBonePtr()) - return true; - else if (getBonePtr() > b1.getBonePtr()) - return false; - return (getWeight() < b1.getWeight()); + if (second > b1.second)return true; + if (second < b1.second)return false; + return (first.get() > b1.first.get()); } }; typedef std::vector BonePtrWeightList; diff --git a/src/osgAnimation/RigTransformSoftware.cpp b/src/osgAnimation/RigTransformSoftware.cpp index 676cad8ea..6e54b2cd6 100644 --- a/src/osgAnimation/RigTransformSoftware.cpp +++ b/src/osgAnimation/RigTransformSoftware.cpp @@ -120,7 +120,7 @@ void RigTransformSoftware::buildMinimumUpdateSet(const BoneMap&boneMap,const Rig _uniqInfluenceSet2VertIDList.reserve(unifyBuffer.size()); for (UnifyBoneGroup::const_iterator it = unifyBuffer.begin(); it != unifyBuffer.end(); ++it) _uniqInfluenceSet2VertIDList.push_back(it->second); - OSG_DEBUG << "uniq groups " << _uniqInfluenceSet2VertIDList.size() << " for " << rig.getName() << std::endl; + OSG_WARN << "uniq groups " << _uniqInfluenceSet2VertIDList.size() << " for " << rig.getName() << std::endl; } bool RigTransformSoftware::prepareData(RigGeometry&rig) { From 5566a025b53ef57133c282c75d489927d78c5e9a Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Tue, 29 Aug 2017 17:19:26 +0100 Subject: [PATCH 036/327] Added TextSettings struct to manage values used to set up the text. with the addition of following command line parameters: --outline // enable outlne --shadow // enable shadow --offset ratio // set the backdrop offset --text-color r g b a // set the text body color --bd-color r g b a // set the shadow/outline color --bg-color r g b a // window background color -o filename // write create subgraph to disk using specified filename --- examples/osgfont/osgfont.cpp | 74 ++++++++++++++++++++++++++++++++---- src/osgText/Text.cpp | 9 +++++ 2 files changed, 75 insertions(+), 8 deletions(-) diff --git a/examples/osgfont/osgfont.cpp b/examples/osgfont/osgfont.cpp index 5090422ce..f7c068acd 100644 --- a/examples/osgfont/osgfont.cpp +++ b/examples/osgfont/osgfont.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -57,30 +58,74 @@ osg::Camera* createOrthoCamera(double width, double height) return camera; } -osgText::Text* createLabel(const std::string& l, const std::string& fontfile, unsigned int size) +struct TextSettings +{ + TextSettings(): + fontFilename("fonts/arial.ttf"), + textColor(1.0f, 1.0f, 1.0f, 1.0f), + backdropType(osgText::Text::NONE), + backdropOffset(0.04f, 0.04f), + backdropColor(0.0f, 0.0f, 0.0f, 1.0f) + { + } + + void read(osg::ArgumentParser& arguments) + { + if (arguments.read("--outline")) backdropType = osgText::Text::OUTLINE; + if (arguments.read("--shadow")) backdropType = osgText::Text::DROP_SHADOW_BOTTOM_RIGHT; + + float offset; + if (arguments.read("--offset", offset)) backdropOffset.set(offset, offset); + + if (arguments.read("--text-color", textColor.r(), textColor.g(), textColor.b(), textColor.a())) {} + if (arguments.read("--bd-color", backdropColor.r(), backdropColor.g(), backdropColor.b(), backdropColor.a())) {} + } + + void setText(osgText::Text& text) + { + OSG_NOTICE<<"Settings::setText()"< font = osgText::readRefFontFile(fontfile); + osg::ref_ptr font = osgText::readRefFontFile(settings.fontFilename); + + settings.setText(*label); - label->setFont(font); label->setCharacterSize(size); label->setFontResolution(size, size); - label->setColor(osg::Vec4(1.0f, 1.0f, 1.0f, 1.0f)); label->setPosition(pos); label->setAlignment(osgText::Text::LEFT_BOTTOM); + // It seems to be important we do this last to get best results? label->setText(l); - textInfo(label); + + // textInfo(label); pos.y() += size + 10.0f; return label; } + + typedef std::list Sizes; int main(int argc, char** argv) @@ -101,6 +146,11 @@ int main(int argc, char** argv) viewer.addEventHandler(new osgViewer::StatsHandler()); viewer.addEventHandler(new osgViewer::WindowSizeHandler()); + osg::Vec4d backgroudColor = viewer.getCamera()->getClearColor(); + if (args.read("--bg-color", backgroudColor.r(), backgroudColor.g(), backgroudColor.b(), backgroudColor.a())) + { + viewer.getCamera()->setClearColor(backgroudColor); + } osg::ref_ptr root = new osg::Group; @@ -119,9 +169,10 @@ int main(int argc, char** argv) root = transform; } - std::string fontfile("arial.ttf"); + TextSettings settings; + settings.fontFilename = argv[1]; + settings.read(args); - fontfile = argv[1]; // Create the list of desired sizes. Sizes sizes; @@ -142,11 +193,18 @@ int main(int argc, char** argv) ss << *i << " 1234567890 abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ"; - geode->addDrawable(createLabel(ss.str(), fontfile, *i)); + geode->addDrawable(createLabel(ss.str(), settings, *i)); } root->addChild(geode); + std::string filename; + if (args.read("-o", filename)) + { + osgDB::writeNodeFile(*root, filename); + return 0; + } + viewer.setSceneData(root.get()); return viewer.run(); diff --git a/src/osgText/Text.cpp b/src/osgText/Text.cpp index 53a5d3b1a..af9b4eccc 100644 --- a/src/osgText/Text.cpp +++ b/src/osgText/Text.cpp @@ -1131,6 +1131,8 @@ void Text::drawImplementationSinglePass(osg::State& state, const osg::Vec4& colo #if 1 if(_backdropType != NONE) { + OSG_NOTICE<<"Text::drawImplementationSinglePass() Drawing backdrop"<draw(state, usingVertexBufferObjects); } } From f3bbb686d2765dd4df1a95d8d0b6bc1ec4426630 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Tue, 29 Aug 2017 17:32:14 +0100 Subject: [PATCH 037/327] Removed debug messages --- src/osgText/Text.cpp | 9 --------- 1 file changed, 9 deletions(-) diff --git a/src/osgText/Text.cpp b/src/osgText/Text.cpp index af9b4eccc..53a5d3b1a 100644 --- a/src/osgText/Text.cpp +++ b/src/osgText/Text.cpp @@ -1131,8 +1131,6 @@ void Text::drawImplementationSinglePass(osg::State& state, const osg::Vec4& colo #if 1 if(_backdropType != NONE) { - OSG_NOTICE<<"Text::drawImplementationSinglePass() Drawing backdrop"<draw(state, usingVertexBufferObjects); } } From fe99b568a0dc7dfdc3903a211ab636689fb88552 Mon Sep 17 00:00:00 2001 From: Julien Valentin Date: Wed, 30 Aug 2017 11:12:17 +0200 Subject: [PATCH 038/327] refactor: remove totally VertexInfluence (renamed BoneInfluenceList) everywhere --- .../osganimationskinning.cpp | 4 --- include/osgAnimation/VertexInfluence | 14 ++------ src/osgAnimation/RigTransformHardware.cpp | 25 ++++++--------- src/osgAnimation/RigTransformSoftware.cpp | 18 ++++++----- src/osgAnimation/VertexInfluence.cpp | 32 +++++++++---------- src/osgPlugins/gles/AABBonBoneVisitor.cpp | 2 +- .../gles/MostInfluencedGeometryByBone | 4 +-- .../osgAnimation/ReaderWriter.cpp | 13 ++++---- .../serializers/osgAnimation/RigGeometry.cpp | 13 ++++---- 9 files changed, 53 insertions(+), 72 deletions(-) diff --git a/examples/osganimationskinning/osganimationskinning.cpp b/examples/osganimationskinning/osganimationskinning.cpp index c28a2b15d..340868460 100644 --- a/examples/osganimationskinning/osganimationskinning.cpp +++ b/examples/osganimationskinning/osganimationskinning.cpp @@ -136,10 +136,6 @@ void initVertexMap(osgAnimation::Bone* b0, { osgAnimation::VertexInfluenceMap* vim = new osgAnimation::VertexInfluenceMap; - (*vim)[b0->getName()].setBoneName(b0->getName()); - (*vim)[b1->getName()].setBoneName(b1->getName()); - (*vim)[b2->getName()].setBoneName(b2->getName()); - for (int i = 0; i < (int)array->size(); i++) { float val = (*array)[i][0]; diff --git a/include/osgAnimation/VertexInfluence b/include/osgAnimation/VertexInfluence index 4bb42b105..09bdf4c6b 100644 --- a/include/osgAnimation/VertexInfluence +++ b/include/osgAnimation/VertexInfluence @@ -46,25 +46,15 @@ namespace osgAnimation typedef std::vector BoneWeightList; typedef std::vector IndexList; - class OSGANIMATION_EXPORT BoneInfluenceList : public IndexWeightList - { - public: - const std::string& getBoneName() const { return _name;} - void setBoneName(const std::string& name) { _name = name;} - protected: - // the name is the bone to link to - std::string _name; - }; - - class VertexInfluenceMap : public std::map , public osg::Object + class VertexInfluenceMap : public std::map , public osg::Object { public: META_Object(osgAnimation, VertexInfluenceMap); VertexInfluenceMap() {} VertexInfluenceMap(const osgAnimation::VertexInfluenceMap& org, const osg::CopyOp& copyop): - std::map(org), + std::map(org), osg::Object(org, copyop) {} ///normalize per vertex weights given numvert of the attached mesh diff --git a/src/osgAnimation/RigTransformHardware.cpp b/src/osgAnimation/RigTransformHardware.cpp index b4640df4c..bc7fc16d7 100644 --- a/src/osgAnimation/RigTransformHardware.cpp +++ b/src/osgAnimation/RigTransformHardware.cpp @@ -280,8 +280,9 @@ bool RigTransformHardware::buildPalette(BoneMap&boneMap ,RigGeometry&rig) { mapit != vertexInfluenceMap->end(); ++mapit) { - const BoneInfluenceList& boneinflist = mapit->second; - for(BoneInfluenceList::const_iterator infit = boneinflist.begin(); infit!=boneinflist.end(); ++infit) + const IndexWeightList& boneinflist = mapit->second; + const std::string& bonename = mapit->first; + for(IndexWeightList::const_iterator infit = boneinflist.begin(); infit!=boneinflist.end(); ++infit) { const IndexWeight& iw = *infit; const unsigned int &index = iw.getIndex(); @@ -289,30 +290,24 @@ bool RigTransformHardware::buildPalette(BoneMap&boneMap ,RigGeometry&rig) { FloatInt &sum=sums[index]; - if (boneinflist.getBoneName().empty()) { - OSG_WARN << "VertexInfluenceSet::buildVertex2BoneList warning vertex " << index << " is not assigned to a bone" << std::endl; - } - - //_vertex2Bones[index].push_back(VertexInfluenceSet::BoneWeight(vi.getName(), weight));; - if(fabs(weight) > 1e-4) // don't use bone with weight too small { - if ((boneName2PaletteIndex= _boneNameToPalette.find(boneinflist.getBoneName())) != _boneNameToPalette.end()) + if ((boneName2PaletteIndex= _boneNameToPalette.find(bonename)) != _boneNameToPalette.end()) { - boneNameCountMap[boneinflist.getBoneName()]++; + boneNameCountMap[bonename]++; vertexIndexWeight[index].push_back(IndexWeight(boneName2PaletteIndex->second,weight)); } else { BoneMap::const_iterator bonebyname; - if ((bonebyname=boneMap.find(boneinflist.getBoneName())) == boneMap.end()) + if ((bonebyname=boneMap.find(bonename)) == boneMap.end()) { - OSG_WARN << "RigTransformHardware::createPalette can't find bone " << boneinflist.getBoneName() << "in skeleton bonemap: skip this influence" << std::endl; + OSG_WARN << "RigTransformHardware::createPalette can't find bone " << bonename << "in skeleton bonemap: skip this influence" << std::endl; continue; } - boneNameCountMap[boneinflist.getBoneName()] = 1; // for stats + boneNameCountMap[bonename] = 1; // for stats - _boneNameToPalette[boneinflist.getBoneName()] = _bonePalette.size() ; + _boneNameToPalette[bonename] = _bonePalette.size() ; vertexIndexWeight[index].push_back(IndexWeight(_bonePalette.size(),weight)); _bonePalette.push_back(bonebyname->second); sum.first+=weight; @@ -321,7 +316,7 @@ bool RigTransformHardware::buildPalette(BoneMap&boneMap ,RigGeometry&rig) { } else { - OSG_WARN << "RigTransformHardware::createPalette Bone " << boneinflist.getBoneName() << " has a weight " << weight << " for vertex " << index << " this bone will not be in the palette" << std::endl; + OSG_WARN << "RigTransformHardware::createPalette Bone " << bonename << " has a weight " << weight << " for vertex " << index << " this bone will not be in the palette" << std::endl; } maxBonePerVertex = osg::maximum(maxBonePerVertex, sum.second); diff --git a/src/osgAnimation/RigTransformSoftware.cpp b/src/osgAnimation/RigTransformSoftware.cpp index 6e54b2cd6..c36b1aa5a 100644 --- a/src/osgAnimation/RigTransformSoftware.cpp +++ b/src/osgAnimation/RigTransformSoftware.cpp @@ -49,21 +49,23 @@ void RigTransformSoftware::buildMinimumUpdateSet(const BoneMap&boneMap,const Rig it != _vertexInfluenceMap->end(); ++it) { - const BoneInfluenceList& inflist = it->second; - if (inflist.getBoneName().empty()) { - OSG_WARN << "RigTransformSoftware::VertexInfluenceMap contains unamed bone BoneInfluenceList" << std::endl; + const IndexWeightList& inflist = it->second; + const std::string& bonename = it->first; + + if (bonename.empty()) { + OSG_WARN << "RigTransformSoftware::VertexInfluenceMap contains unamed bone IndexWeightList" << std::endl; } - BoneMap::const_iterator bmit = boneMap.find(inflist.getBoneName()); + BoneMap::const_iterator bmit = boneMap.find(bonename); if (bmit == boneMap.end() ) { - if (_invalidInfluence.find(inflist.getBoneName()) != _invalidInfluence.end()) { - _invalidInfluence[inflist.getBoneName()] = true; - OSG_WARN << "RigTransformSoftware Bone " << inflist.getBoneName() << " not found, skip the influence group " << std::endl; + 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(BoneInfluenceList::const_iterator infit=inflist.begin(); infit!=inflist.end(); ++infit) + for(IndexWeightList::const_iterator infit=inflist.begin(); infit!=inflist.end(); ++infit) { const IndexWeight &iw = *infit; const unsigned int &index = iw.getIndex(); diff --git a/src/osgAnimation/VertexInfluence.cpp b/src/osgAnimation/VertexInfluence.cpp index dabaca32f..4dc433ff2 100644 --- a/src/osgAnimation/VertexInfluence.cpp +++ b/src/osgAnimation/VertexInfluence.cpp @@ -36,8 +36,8 @@ void VertexInfluenceMap::normalize(unsigned int numvert) { std::vector localstore; localstore.resize(numvert); for(VertexInfluenceMap::iterator mapit=this->begin(); mapit!=this->end(); ++mapit) { - BoneInfluenceList &curvecinf=mapit->second; - for(BoneInfluenceList::iterator curinf=curvecinf.begin(); curinf!=curvecinf.end(); ++curinf) { + IndexWeightList &curvecinf=mapit->second; + for(IndexWeightList::iterator curinf=curvecinf.begin(); curinf!=curvecinf.end(); ++curinf) { IndexWeight& inf=*curinf; localstore[inf.first].first+=inf.second; localstore[inf.first].second.push_back(&inf.second); @@ -65,14 +65,16 @@ void VertexInfluenceMap::cullInfluenceCountPerVertex(unsigned int numbonepervert typedef std::set BoneWeightOrdered; std::map tempVec2Bones; - for(VertexInfluenceMap::iterator mapit=this->begin(); mapit!=this->end(); ++mapit) { - BoneInfluenceList &curvecinf=mapit->second; - for(BoneInfluenceList::iterator curinf=curvecinf.begin(); curinf!=curvecinf.end(); ++curinf) { + 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) { IndexWeight& inf=*curinf; - if( curvecinf.getBoneName().empty()) { + if( bonename.empty()) { OSG_WARN << "VertexInfluenceSet::buildVertex2BoneList warning vertex " << inf.first << " is not assigned to a bone" << std::endl; } - else if(inf.second>minweight)tempVec2Bones[inf.first].insert(BoneWeight(curvecinf.getBoneName(), inf.second)); + else if(inf.second>minweight)tempVec2Bones[inf.first].insert(BoneWeight(bonename, inf.second)); } } this->clear(); @@ -87,15 +89,13 @@ void VertexInfluenceMap::cullInfluenceCountPerVertex(unsigned int numbonepervert if(sum>1e-4){ sum=1.0f/sum; for(BoneWeightOrdered::iterator bwit=bwset.begin(); bwit!=bwset.end(); ++bwit) { - BoneInfluenceList & inf= (*this)[bwit->getBoneName()]; - inf.setBoneName(bwit->getBoneName()); + IndexWeightList & inf= (*this)[bwit->getBoneName()]; inf.push_back(IndexWeight(mapit->first, bwit->getWeight()*sum)); } } }else{ for(BoneWeightOrdered::iterator bwit=bwset.begin(); bwit!=bwset.end(); ++bwit) { - BoneInfluenceList & inf= (*this)[bwit->getBoneName()]; - inf.setBoneName(bwit->getBoneName()); + IndexWeightList & inf= (*this)[bwit->getBoneName()]; inf.push_back(IndexWeight(mapit->first,bwit->getWeight())); } @@ -110,17 +110,17 @@ void VertexInfluenceMap::computePerVertexInfluenceList(std::vectorsecond; - if (inflist.getBoneName().empty()) { - OSG_WARN << "RigTransformSoftware::VertexInfluenceMap contains unamed bone BoneInfluenceList" << std::endl; + const IndexWeightList& inflist = it->second; + if (it->first.empty()) { + OSG_WARN << "RigTransformSoftware::VertexInfluenceMap contains unamed bone IndexWeightList" << std::endl; } - for(BoneInfluenceList::const_iterator infit=inflist.begin(); infit!=inflist.end(); ++infit) + for(IndexWeightList::const_iterator infit=inflist.begin(); infit!=inflist.end(); ++infit) { const IndexWeight &iw = *infit; const unsigned int &index = iw.getIndex(); float weight = iw.getWeight(); - vertex2Bones[index].push_back(BoneWeight(inflist.getBoneName(), weight));; + vertex2Bones[index].push_back(BoneWeight(it->first, weight));; } } } diff --git a/src/osgPlugins/gles/AABBonBoneVisitor.cpp b/src/osgPlugins/gles/AABBonBoneVisitor.cpp index 5b3fc99dd..ec0bc7e46 100644 --- a/src/osgPlugins/gles/AABBonBoneVisitor.cpp +++ b/src/osgPlugins/gles/AABBonBoneVisitor.cpp @@ -51,7 +51,7 @@ void ComputeAABBOnBoneVisitor::computeBoundingBoxOnBones() { osg::Vec3Array *vertices = dynamic_cast(rigGeometry->getVertexArray()); if(!vertices) continue; - osgAnimation::BoneInfluenceList vxtInf = (*itMap).second; + osgAnimation::IndexWeightList vxtInf = (*itMap).second; //Expand the boundingBox with each vertex for(unsigned int j = 0; j < vxtInf.size(); j++) { diff --git a/src/osgPlugins/gles/MostInfluencedGeometryByBone b/src/osgPlugins/gles/MostInfluencedGeometryByBone index a5e8c5e97..000b9930f 100644 --- a/src/osgPlugins/gles/MostInfluencedGeometryByBone +++ b/src/osgPlugins/gles/MostInfluencedGeometryByBone @@ -200,9 +200,9 @@ protected: BoneNameBoneMap::iterator bone_it = boneMap.find(vertexInfluencePair->first); if(bone_it == boneMap.end()) continue; osg::ref_ptr bone = bone_it->second; - const osgAnimation::BoneInfluenceList& vertexInfluence = (*vertexInfluencePair).second; + const osgAnimation::IndexWeightList& vertexInfluence = (*vertexInfluencePair).second; - for(osgAnimation::BoneInfluenceList::const_iterator vertexIndexWeight = vertexInfluence.begin(); vertexIndexWeight != vertexInfluence.end(); ++vertexIndexWeight) { + for(osgAnimation::IndexWeightList::const_iterator vertexIndexWeight = vertexInfluence.begin(); vertexIndexWeight != vertexInfluence.end(); ++vertexIndexWeight) { rigGeometryInfluenceByBoneMap[bone.get()][*rigGeometry].addWeight((*vertexIndexWeight).second); } } diff --git a/src/osgWrappers/deprecated-dotosg/osgAnimation/ReaderWriter.cpp b/src/osgWrappers/deprecated-dotosg/osgAnimation/ReaderWriter.cpp index b8813ae70..57796375b 100644 --- a/src/osgWrappers/deprecated-dotosg/osgAnimation/ReaderWriter.cpp +++ b/src/osgWrappers/deprecated-dotosg/osgAnimation/ReaderWriter.cpp @@ -804,17 +804,16 @@ bool RigGeometry_readLocalData(Object& obj, Input& fr) for (int i = 0; i < nbGroups; i++) { int nbVertexes = 0; - std::string name; + std::string bonename; if (fr.matchSequence("osgAnimation::VertexInfluence %s %i {")) { - name = fr[1].getStr(); + bonename = fr[1].getStr(); fr[2].getInt(nbVertexes); fr += 4; iteratorAdvanced = true; } - osgAnimation::BoneInfluenceList vi; - vi.setBoneName(name); + osgAnimation::IndexWeightList vi; vi.reserve(nbVertexes); for (int j = 0; j < nbVertexes; j++) { @@ -833,7 +832,7 @@ bool RigGeometry_readLocalData(Object& obj, Input& fr) { fr+=1; } - (*vmap)[name] = vi; + (*vmap)[bonename] = vi; } if (!vmap->empty()) geom.setInfluenceMap(vmap.get()); @@ -863,8 +862,8 @@ bool RigGeometry_writeLocalData(const Object& obj, Output& fw) name = "Empty"; fw.indent() << "osgAnimation::VertexInfluence \"" << name << "\" " << it->second.size() << " {" << std::endl; fw.moveIn(); - const osgAnimation::BoneInfluenceList& vi = it->second; - for (osgAnimation::BoneInfluenceList::const_iterator itv = vi.begin(); itv != vi.end(); itv++) + const osgAnimation::IndexWeightList& vi = it->second; + for (osgAnimation::IndexWeightList::const_iterator itv = vi.begin(); itv != vi.end(); itv++) { fw.indent() << itv->first << " " << itv->second << std::endl; } diff --git a/src/osgWrappers/serializers/osgAnimation/RigGeometry.cpp b/src/osgWrappers/serializers/osgAnimation/RigGeometry.cpp index 0d88de08d..1403bd648 100644 --- a/src/osgWrappers/serializers/osgAnimation/RigGeometry.cpp +++ b/src/osgWrappers/serializers/osgAnimation/RigGeometry.cpp @@ -14,14 +14,13 @@ static bool readInfluenceMap( osgDB::InputStream& is, osgAnimation::RigGeometry& unsigned int size = is.readSize(); is >> is.BEGIN_BRACKET; for ( unsigned int i=0; i> is.PROPERTY("VertexInfluence"); - is.readWrappedString(name); + is.readWrappedString(bonename); viSize = is.readSize(); is >> is.BEGIN_BRACKET; - osgAnimation::BoneInfluenceList vi; - vi.setBoneName( name ); + osgAnimation::IndexWeightList vi; vi.reserve( viSize ); for ( unsigned int j=0; j> index >> weight; vi.push_back( osgAnimation::IndexWeight(index, weight) ); } - (*map)[name] = vi; + (*map)[bonename] = vi; is >> is.END_BRACKET; } is >> is.END_BRACKET; @@ -47,14 +46,14 @@ static bool writeInfluenceMap( osgDB::OutputStream& os, const osgAnimation::RigG itr!=map->end(); ++itr ) { std::string name = itr->first; - const osgAnimation::BoneInfluenceList& vi = itr->second; + const osgAnimation::IndexWeightList& vi = itr->second; if ( name.empty() ) name = "Empty"; os << os.PROPERTY("VertexInfluence"); os.writeWrappedString(name); os.writeSize(vi.size()) ; os << os.BEGIN_BRACKET << std::endl; - for ( osgAnimation::BoneInfluenceList::const_iterator vitr=vi.begin(); + for ( osgAnimation::IndexWeightList::const_iterator vitr=vi.begin(); vitr != vi.end(); ++vitr ) { os << vitr->first << vitr->second << std::endl; From 20ecd5c60dc8e30e4ab2a2d7047c5951a44fbb21 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 30 Aug 2017 10:16:18 +0100 Subject: [PATCH 039/327] Added --test command line option that sets up all the sizes and font settings required for a useufl unit test. --- examples/osgfont/osgfont.cpp | 73 +++++++++++++++++++++++------------- 1 file changed, 47 insertions(+), 26 deletions(-) diff --git a/examples/osgfont/osgfont.cpp b/examples/osgfont/osgfont.cpp index f7c068acd..6b8ca7c80 100644 --- a/examples/osgfont/osgfont.cpp +++ b/examples/osgfont/osgfont.cpp @@ -58,6 +58,8 @@ osg::Camera* createOrthoCamera(double width, double height) return camera; } +typedef std::list Sizes; + struct TextSettings { TextSettings(): @@ -71,6 +73,23 @@ struct TextSettings void read(osg::ArgumentParser& arguments) { + if (arguments.read("--test")) + { + backgroundColor = osg::Vec4(1.0, 1.0, 1.0, 1.0); + + fontFilename = "fonts/arialbd.ttf"; + backdropType = osgText::Text::OUTLINE; + + sizes.clear(); + sizes.push_back(8); + sizes.push_back(16); + sizes.push_back(32); + sizes.push_back(64); + sizes.push_back(128); + } + + if (arguments.read("--font",fontFilename)) {} + if (arguments.read("--outline")) backdropType = osgText::Text::OUTLINE; if (arguments.read("--shadow")) backdropType = osgText::Text::DROP_SHADOW_BOTTOM_RIGHT; @@ -79,6 +98,8 @@ struct TextSettings if (arguments.read("--text-color", textColor.r(), textColor.g(), textColor.b(), textColor.a())) {} if (arguments.read("--bd-color", backdropColor.r(), backdropColor.g(), backdropColor.b(), backdropColor.a())) {} + if (arguments.read("--bg-color", backgroundColor.r(), backgroundColor.g(), backgroundColor.b(), backgroundColor.a())) {} + } void setText(osgText::Text& text) @@ -96,6 +117,8 @@ struct TextSettings osgText::Text::BackdropType backdropType; osg::Vec2 backdropOffset; osg::Vec4 backdropColor; + osg::Vec4 backgroundColor; + Sizes sizes; }; osgText::Text* createLabel(const std::string& l, TextSettings& settings, unsigned int size) @@ -126,31 +149,23 @@ osgText::Text* createLabel(const std::string& l, TextSettings& settings, unsigne -typedef std::list Sizes; int main(int argc, char** argv) { osg::ArgumentParser args(&argc, argv); osgViewer::Viewer viewer(args); - // Make sure we have the minimum args... - if(argc <= 2) - { - osg::notify(osg::FATAL) << "usage: " << args[0] << " fontfile size1 [size2 ...]" << std::endl; - - return 1; - } - viewer.addEventHandler( new osgGA::StateSetManipulator(viewer.getCamera()->getOrCreateStateSet()) ); viewer.addEventHandler(new osgViewer::StatsHandler()); viewer.addEventHandler(new osgViewer::WindowSizeHandler()); - osg::Vec4d backgroudColor = viewer.getCamera()->getClearColor(); - if (args.read("--bg-color", backgroudColor.r(), backgroudColor.g(), backgroudColor.b(), backgroudColor.a())) - { - viewer.getCamera()->setClearColor(backgroudColor); - } + TextSettings settings; + settings.backgroundColor = viewer.getCamera()->getClearColor(); + + settings.read(args); + + viewer.getCamera()->setClearColor(settings.backgroundColor); osg::ref_ptr root = new osg::Group; @@ -169,25 +184,31 @@ int main(int argc, char** argv) root = transform; } - TextSettings settings; - settings.fontFilename = argv[1]; - settings.read(args); - - - // Create the list of desired sizes. - Sizes sizes; - - for(int i = 2; i < argc; i++) + if (args.argc() > 1) { - if(!args.isNumber(i)) continue; + settings.fontFilename = argv[1]; - sizes.push_back(std::atoi(args[i])); + // Create the list of desired sizes. + for(int i = 2; i < args.argc(); i++) + { + if(!args.isNumber(i)) continue; + + settings.sizes.push_back(std::atoi(args[i])); + } + } + + if (settings.sizes.empty()) + { + settings.sizes.push_back(8); + settings.sizes.push_back(16); + settings.sizes.push_back(32); + settings.sizes.push_back(64); } osg::Geode* geode = new osg::Geode(); // Add all of our osgText drawables. - for(Sizes::const_iterator i = sizes.begin(); i != sizes.end(); i++) + for(Sizes::const_iterator i = settings.sizes.begin(); i != settings.sizes.end(); i++) { std::stringstream ss; From 7323bb776bf83f789b567f802f442a56a0eccee3 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 30 Aug 2017 10:50:26 +0100 Subject: [PATCH 040/327] Added --margin texel_width and --margin-ration ratio to control the spacing between glyphs in the font. --- examples/osgfont/osgfont.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/examples/osgfont/osgfont.cpp b/examples/osgfont/osgfont.cpp index 6b8ca7c80..5da7e495c 100644 --- a/examples/osgfont/osgfont.cpp +++ b/examples/osgfont/osgfont.cpp @@ -64,6 +64,8 @@ struct TextSettings { TextSettings(): fontFilename("fonts/arial.ttf"), + glyphImageMargin(1), + glyphImageMarginRatio(0.02), textColor(1.0f, 1.0f, 1.0f, 1.0f), backdropType(osgText::Text::NONE), backdropOffset(0.04f, 0.04f), @@ -90,6 +92,11 @@ struct TextSettings if (arguments.read("--font",fontFilename)) {} + + if (arguments.read("--margin", glyphImageMargin)) {} + if (arguments.read("--margin-ratio", glyphImageMarginRatio)) {} + + if (arguments.read("--outline")) backdropType = osgText::Text::OUTLINE; if (arguments.read("--shadow")) backdropType = osgText::Text::DROP_SHADOW_BOTTOM_RIGHT; @@ -113,6 +120,9 @@ struct TextSettings } std::string fontFilename; + unsigned int glyphImageMargin; + float glyphImageMarginRatio; + osg::Vec4 textColor; osgText::Text::BackdropType backdropType; osg::Vec2 backdropOffset; @@ -128,6 +138,9 @@ osgText::Text* createLabel(const std::string& l, TextSettings& settings, unsigne osgText::Text* label = new osgText::Text(); osg::ref_ptr font = osgText::readRefFontFile(settings.fontFilename); + font->setGlyphImageMargin(settings.glyphImageMargin); + font->setGlyphImageMarginRatio(settings.glyphImageMarginRatio); + settings.setText(*label); label->setCharacterSize(size); From 0ebf540d655dee3bc7121d837a4ff8aac90e213f Mon Sep 17 00:00:00 2001 From: Julien Valentin Date: Wed, 30 Aug 2017 12:09:54 +0200 Subject: [PATCH 041/327] add and comment out normlization in rigtransformXXX --- src/osgAnimation/RigTransformHardware.cpp | 107 ++++++++++------------ src/osgAnimation/RigTransformSoftware.cpp | 4 +- 2 files changed, 50 insertions(+), 61 deletions(-) diff --git a/src/osgAnimation/RigTransformHardware.cpp b/src/osgAnimation/RigTransformHardware.cpp index bc7fc16d7..262d99c9a 100644 --- a/src/osgAnimation/RigTransformHardware.cpp +++ b/src/osgAnimation/RigTransformHardware.cpp @@ -257,7 +257,7 @@ void createVertexAttribList(RigTransformHardware& rig,const VertexIndexWeightLis bool RigTransformHardware::buildPalette(BoneMap&boneMap ,RigGeometry&rig) { _nbVertexes = rig.getVertexArray()->getNumElements(); - unsigned int maxBonePerVertex=0; + IndexWeightList::size_type maxBonePerVertex=0; typedef std::pair FloatInt; std::vector< FloatInt > sums;///stat totalweight nbref @@ -276,98 +276,87 @@ bool RigTransformHardware::buildPalette(BoneMap&boneMap ,RigGeometry&rig) { VertexIndexWeightList vertexIndexWeight; vertexIndexWeight.resize(_nbVertexes); + unsigned int paletteindex; for (osgAnimation::VertexInfluenceMap::iterator mapit = vertexInfluenceMap->begin(); mapit != vertexInfluenceMap->end(); ++mapit) { const IndexWeightList& boneinflist = mapit->second; const std::string& bonename = mapit->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 IndexWeight& iw = *infit; const unsigned int &index = iw.getIndex(); const float &weight = iw.getWeight(); - - FloatInt &sum=sums[index]; + IndexWeightList & iwlist=vertexIndexWeight[index]; if(fabs(weight) > 1e-4) // don't use bone with weight too small { - if ((boneName2PaletteIndex= _boneNameToPalette.find(bonename)) != _boneNameToPalette.end()) - { - boneNameCountMap[bonename]++; - vertexIndexWeight[index].push_back(IndexWeight(boneName2PaletteIndex->second,weight)); - } - else - { - BoneMap::const_iterator bonebyname; - if ((bonebyname=boneMap.find(bonename)) == boneMap.end()) - { - OSG_WARN << "RigTransformHardware::createPalette can't find bone " << bonename << "in skeleton bonemap: skip this influence" << std::endl; - continue; - } - boneNameCountMap[bonename] = 1; // for stats - - _boneNameToPalette[bonename] = _bonePalette.size() ; - vertexIndexWeight[index].push_back(IndexWeight(_bonePalette.size(),weight)); - _bonePalette.push_back(bonebyname->second); - sum.first+=weight; - ++sum.second; - } + iwlist.push_back(IndexWeight(paletteindex,weight)); } else { - OSG_WARN << "RigTransformHardware::createPalette Bone " << bonename << " has a weight " << weight << " for vertex " << index << " this bone will not be in the palette" << std::endl; + OSG_WARN << "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, sum.second); + maxBonePerVertex = osg::maximum(maxBonePerVertex, iwlist.size()); } - OSG_INFO << "RigTransformHardware::createPalette maximum number of bone per vertex is " << maxBonePerVertex << std::endl; - OSG_INFO << "RigTransformHardware::createPalette matrix palette has " << boneNameCountMap.size() << " entries" << std::endl; + OSG_INFO << "RigTransformHardware::buildPalette maximum number of bone per vertex is " << maxBonePerVertex << 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::createPalette Bone " << it->first << " is used " << it->second << " times" << std::endl; + OSG_INFO << "RigTransformHardware::buildPalette Bone " << it->first << " is used " << it->second << " times" << std::endl; } - OSG_INFO << "RigTransformHardware::createPalette will use " << boneNameCountMap.size() * 4 << " uniforms" << std::endl; + OSG_INFO << "RigTransformHardware::buildPalette will use " << boneNameCountMap.size() * 4 << " uniforms" << std::endl; } + ///normalize + /*unsigned int vertid=0; + for(VertexIndexWeightList::iterator it=vertexIndexWeight.begin();it!=vertexIndexWeight.end();++it,++vertid) + { + float sum=0; + for(IndexWeightList::iterator iwit=it->begin();iwit!=it->end();++iwit) + sum+=iwit->second; + + if(sum< 1e-4){ + OSG_WARN << "RigTransformHardware::buildPalette Warning: vertex with zero sum weights: " <begin();iwit!=it->end();++iwit) + iwit->second*=sum; + } + }*/ + _bonesPerVertex = maxBonePerVertex; _uniformMatrixPalette = new osg::Uniform(osg::Uniform::FLOAT_MAT4, "matrixPalette", _bonePalette.size()); createVertexAttribList(*this,vertexIndexWeight,this->_boneWeightAttribArrays); - // normalize weight per vertex -///..assume not sum=0 - /* for(BoneWeightAttribList::iterator attribit=_boneWeightAttribArrays.begin();attribit!=_boneWeightAttribArrays.end();++attribit){ - std::vector< std::pair >::iterator countit=sums.begin(); - for(osg::Vec4Array::iterator vert=attribit->get()->begin();vert!=attribit->get()->end();++vert,++countit){ - osg::Vec4& v=*vert; - v[1]/=countit->first; - v[3]/=countit->first; - } - - } - */ - /* unsigned int vertexID=0; - for (VertIDToBoneWeightList::iterator it = _vertex2Bones.begin(); it != _vertex2Bones.end(); ++it,++vertexID) - { - BoneWeightList& bones = *it; - int size = bones.size(); - if (sums[vertexID].first < 1e-4) - { - OSG_WARN << "VertexInfluenceSet::buildVertex2BoneList warning the vertex " << it->first << " seems to have 0 weight, skip normalize for this vertex" << std::endl; - } - else - { - float mult = 1.0/sums[vertexID].first ; - for (int i = 0; i < size; i++) - bones[i].setWeight(bones[i].getWeight() * mult); - } - } - */ return true; } diff --git a/src/osgAnimation/RigTransformSoftware.cpp b/src/osgAnimation/RigTransformSoftware.cpp index c36b1aa5a..a2ef47abf 100644 --- a/src/osgAnimation/RigTransformSoftware.cpp +++ b/src/osgAnimation/RigTransformSoftware.cpp @@ -77,7 +77,7 @@ void RigTransformSoftware::buildMinimumUpdateSet(const BoneMap&boneMap,const Rig // 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 = _vertex2Bones.begin(); it != _vertex2Bones.end(); ++it, ++vertexID) { BonePtrWeightList& bones = *it; float sum = 0; @@ -93,7 +93,7 @@ void RigTransformSoftware::buildMinimumUpdateSet(const BoneMap&boneMap,const Rig for(BonePtrWeightList::iterator bwit=bones.begin();bwit!=bones.end();++bwit) bwit->setWeight(bwit->getWeight() * mult); } - } + }*/ ///2 Create inverse mapping Vec2Vec from previous built Index2Vec ///in order to minimize weighted matrices computation on update From 985d766f058114380d6ed5730e3419d19dc8af75 Mon Sep 17 00:00:00 2001 From: Julien Valentin Date: Wed, 30 Aug 2017 12:55:45 +0200 Subject: [PATCH 042/327] uncomment normalization in rigtransformxxx --- include/osgAnimation/MorphTransformHardware | 5 ----- src/osgAnimation/RigTransformSoftware.cpp | 4 ++-- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/include/osgAnimation/MorphTransformHardware b/include/osgAnimation/MorphTransformHardware index 9b5e5239b..fde644a96 100644 --- a/include/osgAnimation/MorphTransformHardware +++ b/include/osgAnimation/MorphTransformHardware @@ -37,14 +37,9 @@ namespace osgAnimation META_Object(osgAnimation,MorphTransformHardware); - - - virtual void operator()(MorphGeometry&); void setShader(osg::Shader*); - - protected: bool init(MorphGeometry&); diff --git a/src/osgAnimation/RigTransformSoftware.cpp b/src/osgAnimation/RigTransformSoftware.cpp index a2ef47abf..c36b1aa5a 100644 --- a/src/osgAnimation/RigTransformSoftware.cpp +++ b/src/osgAnimation/RigTransformSoftware.cpp @@ -77,7 +77,7 @@ void RigTransformSoftware::buildMinimumUpdateSet(const BoneMap&boneMap,const Rig // 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 = _vertex2Bones.begin(); it != _vertex2Bones.end(); ++it, ++vertexID) { BonePtrWeightList& bones = *it; float sum = 0; @@ -93,7 +93,7 @@ void RigTransformSoftware::buildMinimumUpdateSet(const BoneMap&boneMap,const Rig for(BonePtrWeightList::iterator bwit=bones.begin();bwit!=bones.end();++bwit) bwit->setWeight(bwit->getWeight() * mult); } - }*/ + } ///2 Create inverse mapping Vec2Vec from previous built Index2Vec ///in order to minimize weighted matrices computation on update From fd9b8f103e543d31b4a0b757a4406c0979bc9ecc Mon Sep 17 00:00:00 2001 From: Julien Valentin Date: Wed, 30 Aug 2017 13:21:32 +0200 Subject: [PATCH 043/327] cleanup --- include/osgAnimation/RigGeometry | 2 +- include/osgAnimation/RigTransformHardware | 28 +++---- include/osgAnimation/RigTransformSoftware | 6 +- src/osgAnimation/RigTransformHardware.cpp | 89 ++++++++--------------- src/osgAnimation/RigTransformSoftware.cpp | 43 ++++++----- 5 files changed, 67 insertions(+), 101 deletions(-) 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) { From 6d1193ee70855467546a324d3f0d2f143815b5d6 Mon Sep 17 00:00:00 2001 From: Julien Valentin Date: Wed, 30 Aug 2017 14:59:31 +0200 Subject: [PATCH 044/327] readd buildVertexInfluenceSet for backward compat --- include/osgAnimation/RigGeometry | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/osgAnimation/RigGeometry b/include/osgAnimation/RigGeometry index 5319b4e0a..805e9c779 100644 --- a/include/osgAnimation/RigGeometry +++ b/include/osgAnimation/RigGeometry @@ -78,6 +78,8 @@ namespace osgAnimation void update(); + void buildVertexInfluenceSet(){_rigTransformImplementation->prepareData(*this);} + const osg::Matrix& getMatrixFromSkeletonToGeometry() const; const osg::Matrix& getInvMatrixFromSkeletonToGeometry() const; From 8fad310ce12cfb0a602e3c2ca129cfe6620e307d Mon Sep 17 00:00:00 2001 From: Julien Valentin Date: Wed, 30 Aug 2017 15:13:54 +0200 Subject: [PATCH 045/327] readd VertexInfluence whenever it's bad named and kinda useless --- .../osganimationskinning/osganimationskinning.cpp | 4 +++- include/osgAnimation/VertexInfluence | 15 +++++++++++++-- src/osgAnimation/VertexInfluence.cpp | 6 ++++-- src/osgPlugins/gles/AABBonBoneVisitor.cpp | 2 +- src/osgPlugins/gles/MostInfluencedGeometryByBone | 4 ++-- .../osgAnimation/ReaderWriter.cpp | 13 +++++++------ .../serializers/osgAnimation/RigGeometry.cpp | 8 ++++---- 7 files changed, 34 insertions(+), 18 deletions(-) diff --git a/examples/osganimationskinning/osganimationskinning.cpp b/examples/osganimationskinning/osganimationskinning.cpp index 340868460..485276e03 100644 --- a/examples/osganimationskinning/osganimationskinning.cpp +++ b/examples/osganimationskinning/osganimationskinning.cpp @@ -135,7 +135,9 @@ void initVertexMap(osgAnimation::Bone* b0, osg::Vec3Array* array) { osgAnimation::VertexInfluenceMap* vim = new osgAnimation::VertexInfluenceMap; - + (*vim)[b0->getName()].setName(b0->getName()); + (*vim)[b1->getName()].setName(b1->getName()); + (*vim)[b2->getName()].setName(b2->getName()); for (int i = 0; i < (int)array->size(); i++) { float val = (*array)[i][0]; diff --git a/include/osgAnimation/VertexInfluence b/include/osgAnimation/VertexInfluence index 09bdf4c6b..94c12b0e4 100644 --- a/include/osgAnimation/VertexInfluence +++ b/include/osgAnimation/VertexInfluence @@ -46,15 +46,26 @@ namespace osgAnimation typedef std::vector BoneWeightList; typedef std::vector IndexList; + //Bone influence list + class OSGANIMATION_EXPORT VertexInfluence : public IndexWeightList + { + public: + const std::string& getName() const { return _name;} + void setName(const std::string& name) { _name = name;} - class VertexInfluenceMap : public std::map , public osg::Object + protected: + // the name is the bone to link to + std::string _name; + }; + + class VertexInfluenceMap : public std::map , public osg::Object { public: META_Object(osgAnimation, VertexInfluenceMap); VertexInfluenceMap() {} VertexInfluenceMap(const osgAnimation::VertexInfluenceMap& org, const osg::CopyOp& copyop): - std::map(org), + std::map(org), osg::Object(org, copyop) {} ///normalize per vertex weights given numvert of the attached mesh diff --git a/src/osgAnimation/VertexInfluence.cpp b/src/osgAnimation/VertexInfluence.cpp index 4dc433ff2..2fffc7559 100644 --- a/src/osgAnimation/VertexInfluence.cpp +++ b/src/osgAnimation/VertexInfluence.cpp @@ -89,14 +89,16 @@ void VertexInfluenceMap::cullInfluenceCountPerVertex(unsigned int numbonepervert if(sum>1e-4){ sum=1.0f/sum; for(BoneWeightOrdered::iterator bwit=bwset.begin(); bwit!=bwset.end(); ++bwit) { - IndexWeightList & inf= (*this)[bwit->getBoneName()]; + VertexInfluence & inf= (*this)[bwit->getBoneName()]; inf.push_back(IndexWeight(mapit->first, bwit->getWeight()*sum)); + inf.setName(bwit->getBoneName()); } } }else{ for(BoneWeightOrdered::iterator bwit=bwset.begin(); bwit!=bwset.end(); ++bwit) { - IndexWeightList & inf= (*this)[bwit->getBoneName()]; + VertexInfluence & inf= (*this)[bwit->getBoneName()]; inf.push_back(IndexWeight(mapit->first,bwit->getWeight())); + inf.setName(bwit->getBoneName()); } } diff --git a/src/osgPlugins/gles/AABBonBoneVisitor.cpp b/src/osgPlugins/gles/AABBonBoneVisitor.cpp index ec0bc7e46..0ea5302f7 100644 --- a/src/osgPlugins/gles/AABBonBoneVisitor.cpp +++ b/src/osgPlugins/gles/AABBonBoneVisitor.cpp @@ -51,7 +51,7 @@ void ComputeAABBOnBoneVisitor::computeBoundingBoxOnBones() { osg::Vec3Array *vertices = dynamic_cast(rigGeometry->getVertexArray()); if(!vertices) continue; - osgAnimation::IndexWeightList vxtInf = (*itMap).second; + osgAnimation::VertexInfluence vxtInf = (*itMap).second; //Expand the boundingBox with each vertex for(unsigned int j = 0; j < vxtInf.size(); j++) { diff --git a/src/osgPlugins/gles/MostInfluencedGeometryByBone b/src/osgPlugins/gles/MostInfluencedGeometryByBone index 000b9930f..024d87ddb 100644 --- a/src/osgPlugins/gles/MostInfluencedGeometryByBone +++ b/src/osgPlugins/gles/MostInfluencedGeometryByBone @@ -200,9 +200,9 @@ protected: BoneNameBoneMap::iterator bone_it = boneMap.find(vertexInfluencePair->first); if(bone_it == boneMap.end()) continue; osg::ref_ptr bone = bone_it->second; - const osgAnimation::IndexWeightList& vertexInfluence = (*vertexInfluencePair).second; + const osgAnimation::VertexInfluence& vertexInfluence = (*vertexInfluencePair).second; - for(osgAnimation::IndexWeightList::const_iterator vertexIndexWeight = vertexInfluence.begin(); vertexIndexWeight != vertexInfluence.end(); ++vertexIndexWeight) { + for(osgAnimation::VertexInfluence::const_iterator vertexIndexWeight = vertexInfluence.begin(); vertexIndexWeight != vertexInfluence.end(); ++vertexIndexWeight) { rigGeometryInfluenceByBoneMap[bone.get()][*rigGeometry].addWeight((*vertexIndexWeight).second); } } diff --git a/src/osgWrappers/deprecated-dotosg/osgAnimation/ReaderWriter.cpp b/src/osgWrappers/deprecated-dotosg/osgAnimation/ReaderWriter.cpp index 57796375b..4dbf949dc 100644 --- a/src/osgWrappers/deprecated-dotosg/osgAnimation/ReaderWriter.cpp +++ b/src/osgWrappers/deprecated-dotosg/osgAnimation/ReaderWriter.cpp @@ -804,16 +804,17 @@ bool RigGeometry_readLocalData(Object& obj, Input& fr) for (int i = 0; i < nbGroups; i++) { int nbVertexes = 0; - std::string bonename; + std::string name; if (fr.matchSequence("osgAnimation::VertexInfluence %s %i {")) { - bonename = fr[1].getStr(); + name = fr[1].getStr(); fr[2].getInt(nbVertexes); fr += 4; iteratorAdvanced = true; } - osgAnimation::IndexWeightList vi; + osgAnimation::VertexInfluence vi; + vi.setName(name); vi.reserve(nbVertexes); for (int j = 0; j < nbVertexes; j++) { @@ -832,7 +833,7 @@ bool RigGeometry_readLocalData(Object& obj, Input& fr) { fr+=1; } - (*vmap)[bonename] = vi; + (*vmap)[name] = vi; } if (!vmap->empty()) geom.setInfluenceMap(vmap.get()); @@ -862,8 +863,8 @@ bool RigGeometry_writeLocalData(const Object& obj, Output& fw) name = "Empty"; fw.indent() << "osgAnimation::VertexInfluence \"" << name << "\" " << it->second.size() << " {" << std::endl; fw.moveIn(); - const osgAnimation::IndexWeightList& vi = it->second; - for (osgAnimation::IndexWeightList::const_iterator itv = vi.begin(); itv != vi.end(); itv++) + const osgAnimation::VertexInfluence& vi = it->second; + for (osgAnimation::VertexInfluence::const_iterator itv = vi.begin(); itv != vi.end(); itv++) { fw.indent() << itv->first << " " << itv->second << std::endl; } diff --git a/src/osgWrappers/serializers/osgAnimation/RigGeometry.cpp b/src/osgWrappers/serializers/osgAnimation/RigGeometry.cpp index 1403bd648..2ea4b9551 100644 --- a/src/osgWrappers/serializers/osgAnimation/RigGeometry.cpp +++ b/src/osgWrappers/serializers/osgAnimation/RigGeometry.cpp @@ -19,8 +19,8 @@ static bool readInfluenceMap( osgDB::InputStream& is, osgAnimation::RigGeometry& is >> is.PROPERTY("VertexInfluence"); is.readWrappedString(bonename); viSize = is.readSize(); is >> is.BEGIN_BRACKET; - - osgAnimation::IndexWeightList vi; + osgAnimation::VertexInfluence vi; + vi.setName( bonename ); vi.reserve( viSize ); for ( unsigned int j=0; jend(); ++itr ) { std::string name = itr->first; - const osgAnimation::IndexWeightList& vi = itr->second; + const osgAnimation::VertexInfluence& vi = itr->second; if ( name.empty() ) name = "Empty"; os << os.PROPERTY("VertexInfluence"); os.writeWrappedString(name); os.writeSize(vi.size()) ; os << os.BEGIN_BRACKET << std::endl; - for ( osgAnimation::IndexWeightList::const_iterator vitr=vi.begin(); + for ( osgAnimation::VertexInfluence::const_iterator vitr=vi.begin(); vitr != vi.end(); ++vitr ) { os << vitr->first << vitr->second << std::endl; From 705695b41da7c76db13f496c301b7135343856ba Mon Sep 17 00:00:00 2001 From: Julien Valentin Date: Wed, 30 Aug 2017 15:46:19 +0200 Subject: [PATCH 046/327] add a guard (if dirty) on uniform update --- src/osgAnimation/MorphTransformHardware.cpp | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/osgAnimation/MorphTransformHardware.cpp b/src/osgAnimation/MorphTransformHardware.cpp index 8b5351cea..86df7b465 100644 --- a/src/osgAnimation/MorphTransformHardware.cpp +++ b/src/osgAnimation/MorphTransformHardware.cpp @@ -187,11 +187,14 @@ void MorphTransformHardware::operator()(MorphGeometry& geom) if (_needInit) if (!init(geom)) return; - - ///upload new morph weights each update via uniform - int curimorph=0; - MorphGeometry::MorphTargetList & morphlist=geom.getMorphTargetList(); - for(MorphGeometry::MorphTargetList::const_iterator curmorph=morphlist.begin(); curmorph!=morphlist.end(); ++curmorph) - _uniformTargetsWeight->setElement(curimorph++, curmorph->getWeight()); - _uniformTargetsWeight->dirty(); + if (geom.isDirty()) + { + ///upload new morph weights each update via uniform + int curimorph=0; + MorphGeometry::MorphTargetList & morphlist=geom.getMorphTargetList(); + for(MorphGeometry::MorphTargetList::const_iterator curmorph=morphlist.begin(); curmorph!=morphlist.end(); ++curmorph) + _uniformTargetsWeight->setElement(curimorph++, curmorph->getWeight()); + _uniformTargetsWeight->dirty(); + geom.dirty(false); + } } From 86ad54f67102e32b7d07213f8adeb3d1549d2dda Mon Sep 17 00:00:00 2001 From: Julien Valentin Date: Wed, 30 Aug 2017 17:07:11 +0200 Subject: [PATCH 047/327] add parameter to XXXTranformHW to customize reserved texture attribs and vertex attribs --- include/osgAnimation/MorphTransformHardware | 9 ++++++++- include/osgAnimation/RigTransformHardware | 10 +++++++--- src/osgAnimation/MorphTransformHardware.cpp | 18 ++++++------------ src/osgAnimation/RigTransformHardware.cpp | 8 +++++--- 4 files changed, 26 insertions(+), 19 deletions(-) diff --git a/include/osgAnimation/MorphTransformHardware b/include/osgAnimation/MorphTransformHardware index fde644a96..b061cccae 100644 --- a/include/osgAnimation/MorphTransformHardware +++ b/include/osgAnimation/MorphTransformHardware @@ -38,7 +38,13 @@ namespace osgAnimation META_Object(osgAnimation,MorphTransformHardware); virtual void operator()(MorphGeometry&); - void setShader(osg::Shader*); + + inline void setShader(osg::Shader*s){_shader=s;} + inline osg::Shader * getShader()const{return _shader;} + + ///texture unit reserved for morphtarget TBO default is 7 + void setReservedTextureUnit(unsigned int t){_reservedTextureUnit=t;} + unsigned int getReservedTextureUnit() const {return _reservedTextureUnit;} protected: @@ -49,6 +55,7 @@ namespace osgAnimation osg::ref_ptr _shader; bool _needInit; + unsigned int _reservedTextureUnit; }; } diff --git a/include/osgAnimation/RigTransformHardware b/include/osgAnimation/RigTransformHardware index cbb825e16..91c586d33 100644 --- a/include/osgAnimation/RigTransformHardware +++ b/include/osgAnimation/RigTransformHardware @@ -43,12 +43,16 @@ namespace osgAnimation typedef std::map BoneNamePaletteIndex; typedef std::vector MatrixPalette; - osg::Vec4Array* getVertexAttrib(unsigned int index); - unsigned int getNumVertexAttrib() const {return _boneWeightAttribArrays.size();} + ///set the first Vertex Attribute Array index of the rig generated by this technic (default:11) + void setFirstVertexAttributeTarget(unsigned int i){ _minAttribIndex=i;} + unsigned int getFirstVertexAttributeTarget()const { return _minAttribIndex;} void setShader(osg::Shader* shader) { _shader = shader; } osg::Shader* getShader() const { return _shader; } + osg::Vec4Array* getVertexAttrib(unsigned int index); + unsigned int getNumVertexAttrib() const {return _boneWeightAttribArrays.size();} + const unsigned int &getNumBonesPerVertex() const{ return _bonesPerVertex; } const unsigned int &getNumVertexes() const { return _nbVertexes; } @@ -74,7 +78,7 @@ namespace osgAnimation osg::ref_ptr _shader; bool _needInit; - + unsigned int _minAttribIndex; bool buildPalette(const BoneMap& boneMap ,const RigGeometry& rig); }; diff --git a/src/osgAnimation/MorphTransformHardware.cpp b/src/osgAnimation/MorphTransformHardware.cpp index 86df7b465..f0915bbf1 100644 --- a/src/osgAnimation/MorphTransformHardware.cpp +++ b/src/osgAnimation/MorphTransformHardware.cpp @@ -19,29 +19,23 @@ #include ///texture unit reserved for morphtarget TBO -#define MORPHTEXTUREUNIT 7 +#define DEFAULTMORPHTEXTUREUNIT 7 using namespace osgAnimation; -MorphTransformHardware::MorphTransformHardware() +MorphTransformHardware::MorphTransformHardware():_needInit(true),_reservedTextureUnit(DEFAULTMORPHTEXTUREUNIT) { - _needInit = true; - } MorphTransformHardware::MorphTransformHardware(const MorphTransformHardware& rth, const osg::CopyOp& copyop): MorphTransform(rth, copyop), _uniformTargetsWeight(rth._uniformTargetsWeight), _shader(rth._shader), - _needInit(rth._needInit) + _needInit(rth._needInit), + _reservedTextureUnit(rth._reservedTextureUnit) { } -void MorphTransformHardware::setShader(osg::Shader* shader) -{ - _shader = shader; -} - bool MorphTransformHardware::init(MorphGeometry& morphGeometry) { osg::Vec3Array* pos = dynamic_cast(morphGeometry.getVertexArray()); @@ -104,7 +98,7 @@ bool MorphTransformHardware::init(MorphGeometry& morphGeometry) //create TBO Texture handle osg::Uniform * morphTBOHandle=new osg::Uniform(osg::Uniform::SAMPLER_BUFFER,"morphTargets"); - morphTBOHandle->set(MORPHTEXTUREUNIT); + morphTBOHandle->set(_reservedTextureUnit); //create dynamic uniform for morphtargets animation weights _uniformTargetsWeight=new osg::Uniform(osg::Uniform::FLOAT,"morphWeights",morphlist.size()); @@ -174,7 +168,7 @@ bool MorphTransformHardware::init(MorphGeometry& morphGeometry) osg::ref_ptr ss = morphGeometry.getOrCreateStateSet(); ss->addUniform(_uniformTargetsWeight); - ss->setTextureAttribute(MORPHTEXTUREUNIT,morphTargetsTBO); + ss->setTextureAttribute(_reservedTextureUnit,morphTargetsTBO); ss->addUniform( morphTBOHandle); ss->addUniform(new osg::Uniform("nbMorphVertex", morphGeometry.getVertexArray()->getNumElements())); diff --git a/src/osgAnimation/RigTransformHardware.cpp b/src/osgAnimation/RigTransformHardware.cpp index fb51cb177..ae2e0dfa6 100644 --- a/src/osgAnimation/RigTransformHardware.cpp +++ b/src/osgAnimation/RigTransformHardware.cpp @@ -20,12 +20,13 @@ using namespace osgAnimation; - +#define DEFAULT_FIRST_VERTATTRIB_TARGETTED 11 RigTransformHardware::RigTransformHardware() { _needInit = true; _bonesPerVertex = 0; _nbVertexes = 0; + _minAttribIndex = DEFAULT_FIRST_VERTATTRIB_TARGETTED; } RigTransformHardware::RigTransformHardware(const RigTransformHardware& rth, const osg::CopyOp& copyop): @@ -37,7 +38,8 @@ RigTransformHardware::RigTransformHardware(const RigTransformHardware& rth, cons _boneWeightAttribArrays(rth._boneWeightAttribArrays), _uniformMatrixPalette(rth._uniformMatrixPalette), _shader(rth._shader), - _needInit(rth._needInit) + _needInit(rth._needInit), + _minAttribIndex(rth._minAttribIndex) { } @@ -198,7 +200,7 @@ bool RigTransformHardware::prepareData(RigGeometry& rig) OSG_INFO << "Shader " << str << std::endl; } - unsigned int attribIndex = 11; + unsigned int attribIndex = _minAttribIndex; unsigned int nbAttribs = getNumVertexAttrib(); if(nbAttribs==0) OSG_WARN << "nbAttribs== " << nbAttribs << std::endl; From 1289c4ee41288299509ef91ede05285a5beae734 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 30 Aug 2017 16:21:03 +0100 Subject: [PATCH 048/327] Added osgText::Font::s/getGlyphInterval(int) and GlyphTexture::s/getGlyphInterval(int) and internal support for clmapping positions of glyph images an defined intervals, defaults to 1. --- include/osgText/Font | 6 ++++++ include/osgText/Glyph | 5 +++++ src/osgText/Font.cpp | 2 ++ src/osgText/Glyph.cpp | 23 ++++++++++++++--------- 4 files changed, 27 insertions(+), 9 deletions(-) diff --git a/include/osgText/Font b/include/osgText/Font index 952a6fda4..369493891 100644 --- a/include/osgText/Font +++ b/include/osgText/Font @@ -122,6 +122,11 @@ public: void setGlyphImageMarginRatio(float margin); float getGlyphImageMarginRatio() const; + /** Set the interval that glyph positions are clamped to. + * Default interval is 1 texels.*/ + void setGlyphInterval(int interval); + int getGlyphInterval() const; + /** Set the size of texture to create to store the glyph images when rendering. * Note, this doesn't affect already created Texture Glhph's.*/ @@ -197,6 +202,7 @@ protected: FontResolution _fontSize; unsigned int _margin; float _marginRatio; + int _glyphInterval; unsigned int _textureWidthHint; unsigned int _textureHeightHint; diff --git a/include/osgText/Glyph b/include/osgText/Glyph index f08686841..bb7d5192a 100644 --- a/include/osgText/Glyph +++ b/include/osgText/Glyph @@ -260,6 +260,9 @@ public: void setGlyphImageMarginRatio(float margin) { _marginRatio = margin; } float getGlyphImageMarginRatio() const { return _marginRatio; } + void setGlyphInterval(int interval) { _interval = interval; } + int getGlyphInterval() const { return _interval; } + bool getSpaceForGlyph(Glyph* glyph, int& posX, int& posY); void addGlyph(Glyph* glyph,int posX, int posY); @@ -282,6 +285,8 @@ protected: // in the texture which could accommodate new glyphs. int _margin; float _marginRatio; + int _interval; + int _usedY; int _partUsedX; int _partUsedY; diff --git a/src/osgText/Font.cpp b/src/osgText/Font.cpp index c06392640..155acadff 100644 --- a/src/osgText/Font.cpp +++ b/src/osgText/Font.cpp @@ -301,6 +301,7 @@ Font::Font(FontImplementation* implementation): osg::Object(true), _margin(1), _marginRatio(0.02), + _glyphInterval(1), _textureWidthHint(1024), _textureHeightHint(1024), _minFilterHint(osg::Texture::LINEAR_MIPMAP_LINEAR), @@ -604,6 +605,7 @@ void Font::addGlyph(const FontResolution& fontRes, unsigned int charcode, Glyph* // reserve enough space for the glyphs. glyphTexture->setGlyphImageMargin(_margin); glyphTexture->setGlyphImageMarginRatio(_marginRatio); + glyphTexture->setGlyphInterval(_glyphInterval); glyphTexture->setTextureSize(_textureWidthHint,_textureHeightHint); glyphTexture->setFilter(osg::Texture::MIN_FILTER,_minFilterHint); glyphTexture->setFilter(osg::Texture::MAG_FILTER,_magFilterHint); diff --git a/src/osgText/Glyph.cpp b/src/osgText/Glyph.cpp index 3bc346c8f..2699b0627 100644 --- a/src/osgText/Glyph.cpp +++ b/src/osgText/Glyph.cpp @@ -31,6 +31,7 @@ using namespace std; GlyphTexture::GlyphTexture(): _margin(1), _marginRatio(0.02f), + _interval(1), _usedY(0), _partUsedX(0), _partUsedY(0) @@ -60,18 +61,22 @@ bool GlyphTexture::getSpaceForGlyph(Glyph* glyph, int& posX, int& posY) int width = glyph->s()+2*margin; int height = glyph->t()+2*margin; - // first check box (_partUsedX,_usedY) to (width,height) - if (width <= (getTextureWidth()-_partUsedX) && - height <= (getTextureHeight()-_usedY)) + int partUsedX = ((_partUsedX % _interval) == 0) ? _partUsedX : (((_partUsedX/_interval)+1)*_interval); + int partUsedY = ((_partUsedY % _interval) == 0) ? _partUsedY : (((_partUsedY/_interval)+1)*_interval); + int usedY = ((_usedY % _interval) == 0) ? _usedY : (((_usedY/_interval)+1)*_interval); + + // first check box (partUsedX, usedY) to (width,height) + if (width <= (getTextureWidth()-partUsedX) && + height <= (getTextureHeight()-usedY)) { // can fit in existing row. // record the position in which the texture will be stored. - posX = _partUsedX+margin; - posY = _usedY+margin; + posX = partUsedX+margin; + posY = usedY+margin; // move used markers on. - _partUsedX += width; + _partUsedX = posX+width; if (_usedY+height>_partUsedY) _partUsedY = _usedY+height; return true; @@ -83,14 +88,14 @@ bool GlyphTexture::getSpaceForGlyph(Glyph* glyph, int& posX, int& posY) { // can fit next row. _partUsedX = 0; - _usedY = _partUsedY; + _usedY = partUsedY; posX = _partUsedX+margin; posY = _usedY+margin; // move used markers on. - _partUsedX += width; - if (_usedY+height>_partUsedY) _partUsedY = _usedY+height; + _partUsedX = posX+width; + _partUsedY = _usedY+height; return true; } From 81f93e34b82ded6e0c51c57f61e4cf132ef86294 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 30 Aug 2017 16:22:25 +0100 Subject: [PATCH 049/327] Added --interval value commnad line option for setting the Font::setGlyphInterval() to experimentation of clamping of glyph images to user specified intervals in the glyph texture --- examples/osgfont/osgfont.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/examples/osgfont/osgfont.cpp b/examples/osgfont/osgfont.cpp index 5da7e495c..43a8653d5 100644 --- a/examples/osgfont/osgfont.cpp +++ b/examples/osgfont/osgfont.cpp @@ -66,6 +66,7 @@ struct TextSettings fontFilename("fonts/arial.ttf"), glyphImageMargin(1), glyphImageMarginRatio(0.02), + glyphInterval(1), textColor(1.0f, 1.0f, 1.0f, 1.0f), backdropType(osgText::Text::NONE), backdropOffset(0.04f, 0.04f), @@ -95,6 +96,7 @@ struct TextSettings if (arguments.read("--margin", glyphImageMargin)) {} if (arguments.read("--margin-ratio", glyphImageMarginRatio)) {} + if (arguments.read("--interval", glyphInterval)) {} if (arguments.read("--outline")) backdropType = osgText::Text::OUTLINE; @@ -122,6 +124,7 @@ struct TextSettings std::string fontFilename; unsigned int glyphImageMargin; float glyphImageMarginRatio; + int glyphInterval; osg::Vec4 textColor; osgText::Text::BackdropType backdropType; From 07a8d082e414c21182aeecb9096da78153e34862 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 30 Aug 2017 17:43:29 +0100 Subject: [PATCH 050/327] Added --shader filename command line parsing and associated set up of osg::Program to allow shaders to be passed into example to customize rendering --- examples/osgfont/osgfont.cpp | 29 ++++++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/examples/osgfont/osgfont.cpp b/examples/osgfont/osgfont.cpp index 43a8653d5..823e7ae24 100644 --- a/examples/osgfont/osgfont.cpp +++ b/examples/osgfont/osgfont.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -200,6 +201,29 @@ int main(int argc, char** argv) root = transform; } + osg::ref_ptr program = new osg::Program; + std::string shaderFilename; + while(args.read("--shader", shaderFilename)) + { + osg::ref_ptr shader = osgDB::readRefShaderFile(shaderFilename); + if (shader.get()) + { + OSG_NOTICE<<"Loading shader "<addShader(shader.get()); + } + } + + if (program->getNumShaders()>0) + { + OSG_NOTICE<<"Using shaders"<getOrCreateStateSet()->setAttribute(program.get(), osg::StateAttribute::OVERRIDE | osg::StateAttribute::ON); + root->getOrCreateStateSet()->addUniform(new osg::Uniform("glyphTexture", 0)); + } + + + std::string outputFilename; + if (args.read("-o", outputFilename)) {} + if (args.argc() > 1) { settings.fontFilename = argv[1]; @@ -235,10 +259,9 @@ int main(int argc, char** argv) root->addChild(geode); - std::string filename; - if (args.read("-o", filename)) + if (!outputFilename.empty()) { - osgDB::writeNodeFile(*root, filename); + osgDB::writeNodeFile(*root, outputFilename); return 0; } From 1f628235d469eea1c6613cc2e4011857490b2f12 Mon Sep 17 00:00:00 2001 From: Julien Valentin Date: Wed, 30 Aug 2017 20:36:34 +0200 Subject: [PATCH 051/327] rehabilit an init method to ensure morphing po setted before skinning po in case of rigeom source that are morphgeom --- include/osgAnimation/RigTransformHardware | 2 + src/osgAnimation/RigTransformHardware.cpp | 159 ++++++++++++---------- 2 files changed, 86 insertions(+), 75 deletions(-) diff --git a/include/osgAnimation/RigTransformHardware b/include/osgAnimation/RigTransformHardware index 91c586d33..9e2cb23f1 100644 --- a/include/osgAnimation/RigTransformHardware +++ b/include/osgAnimation/RigTransformHardware @@ -81,6 +81,8 @@ namespace osgAnimation unsigned int _minAttribIndex; bool buildPalette(const BoneMap& boneMap ,const RigGeometry& rig); + bool init(RigGeometry& ); + }; } diff --git a/src/osgAnimation/RigTransformHardware.cpp b/src/osgAnimation/RigTransformHardware.cpp index ae2e0dfa6..ef690d5fb 100644 --- a/src/osgAnimation/RigTransformHardware.cpp +++ b/src/osgAnimation/RigTransformHardware.cpp @@ -152,82 +152,8 @@ bool RigTransformHardware::prepareData(RigGeometry& rig) // copy shallow from source geometry to rig rig.copyFrom(source); - osg::ref_ptr program ; - osg::ref_ptr vertexshader; - osg::ref_ptr stateset = rig.getOrCreateStateSet(); - - //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_INFO<< "MAX_MATRIX not found in Shader! " << str << std::endl; - } - OSG_INFO << "Shader " << str << std::endl; - } - - unsigned int attribIndex = _minAttribIndex; - unsigned int nbAttribs = getNumVertexAttrib(); - if(nbAttribs==0) - OSG_WARN << "nbAttribs== " << nbAttribs << std::endl; - for (unsigned int i = 0; i < nbAttribs; i++) - { - std::stringstream ss; - ss << "boneWeight" << i; - program->addBindAttribLocation(ss.str(), attribIndex + i); - - if(getVertexAttrib(i)->getNumElements()!=_nbVertexes) - OSG_WARN << "getVertexAttrib== " << getVertexAttrib(i)->getNumElements() << std::endl; - rig.setVertexAttribArray(attribIndex + 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(getMatrixPaletteUniform()); - - stateset->removeAttribute(osg::StateAttribute::PROGRAM); - if(!stateset->getAttribute(osg::StateAttribute::PROGRAM)) - stateset->setAttributeAndModes(program.get()); - - _needInit = false; return true; } @@ -333,10 +259,93 @@ bool RigTransformHardware::buildPalette(const BoneMap&boneMap ,const RigGeometry return true; } +bool RigTransformHardware::init(RigGeometry& rig){ + if(_uniformMatrixPalette.valid()){ + ///data seams prepared + osg::ref_ptr program ; + osg::ref_ptr vertexshader; + osg::ref_ptr stateset = rig.getOrCreateStateSet(); + + //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_INFO<< "MAX_MATRIX not found in Shader! " << str << std::endl; + } + OSG_INFO << "Shader " << str << std::endl; + } + + unsigned int attribIndex = _minAttribIndex; + unsigned int nbAttribs = getNumVertexAttrib(); + if(nbAttribs==0) + OSG_WARN << "nbAttribs== " << nbAttribs << std::endl; + for (unsigned int i = 0; i < nbAttribs; i++) + { + std::stringstream ss; + ss << "boneWeight" << i; + program->addBindAttribLocation(ss.str(), attribIndex + i); + + if(getVertexAttrib(i)->getNumElements()!=_nbVertexes) + OSG_WARN << "getVertexAttrib== " << getVertexAttrib(i)->getNumElements() << std::endl; + rig.setVertexAttribArray(attribIndex + 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(getMatrixPaletteUniform()); + + stateset->removeAttribute(osg::StateAttribute::PROGRAM); + if(!stateset->getAttribute(osg::StateAttribute::PROGRAM)) + stateset->setAttributeAndModes(program.get()); + _needInit = false; + return false; + } + else prepareData(rig); + return false; +} void RigTransformHardware::operator()(RigGeometry& geom) { if (_needInit) - if (!prepareData(geom)) + if (!init(geom)) return; computeMatrixPaletteUniform(geom.getMatrixFromSkeletonToGeometry(), geom.getInvMatrixFromSkeletonToGeometry()); } From f4675a56482eeea6d9663adbf3b711c354be86fb Mon Sep 17 00:00:00 2001 From: Julien Valentin Date: Wed, 30 Aug 2017 23:01:21 +0200 Subject: [PATCH 052/327] I found the damn bug in RigTransformHW --- src/osgAnimation/RigTransformHardware.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/osgAnimation/RigTransformHardware.cpp b/src/osgAnimation/RigTransformHardware.cpp index ef690d5fb..f2fac8c43 100644 --- a/src/osgAnimation/RigTransformHardware.cpp +++ b/src/osgAnimation/RigTransformHardware.cpp @@ -104,7 +104,7 @@ void createVertexAttribList(RigTransformHardware& rig, unsigned int boneIndexInVec4 = b*2; (*array)[j][0 + boneIndexInVec4] = 0; (*array)[j][1 + boneIndexInVec4] = 0; - if (boneIndexInList < maxbonepervertex) + if (boneIndexInList < perVertexInfluences[j].size()) { float boneIndex = static_cast(perVertexInfluences[j][boneIndexInList].getIndex()); float boneWeight = perVertexInfluences[j][boneIndexInList].getWeight(); @@ -214,7 +214,7 @@ bool RigTransformHardware::buildPalette(const BoneMap&boneMap ,const RigGeometry } else { - OSG_INFO << "RigTransformHardware::buildPalette Bone " << bonename << " has a weight " << weight << " for vertex " << index << " this bone will not be in the palette" << std::endl; + OSG_WARN << "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()); From 0926bb783d208bf84b1a8130d620dd2d39cc65d8 Mon Sep 17 00:00:00 2001 From: Julien Valentin Date: Thu, 31 Aug 2017 13:29:42 +0200 Subject: [PATCH 053/327] fix example --- examples/osganimationhardware/osganimationhardware.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/osganimationhardware/osganimationhardware.cpp b/examples/osganimationhardware/osganimationhardware.cpp index 4c65644a8..acc2bf2f8 100644 --- a/examples/osganimationhardware/osganimationhardware.cpp +++ b/examples/osganimationhardware/osganimationhardware.cpp @@ -42,12 +42,12 @@ static unsigned int getRandomValueinRange(unsigned int v) } -osg::ref_ptr program; +//osg::ref_ptr program; // show how to override the default RigTransformHardware for customized usage struct MyRigTransformHardware : public osgAnimation::RigTransformHardware { - virtual bool prepareData(osgAnimation::RigGeometry& rig) + virtual bool init(osgAnimation::RigGeometry& rig) { if(!rig.getSkeleton() && !rig.getParents().empty()) { @@ -81,7 +81,7 @@ struct MyRigTransformHardware : public osgAnimation::RigTransformHardware // copy shallow from source geometry to rig rig.copyFrom(source); - // osg::ref_ptr program ; + osg::ref_ptr program ; osg::ref_ptr vertexshader; osg::ref_ptr stateset = rig.getOrCreateStateSet(); From 068a032dacfbfb7b1157f7504f5db0a9da4d72c3 Mon Sep 17 00:00:00 2001 From: Julien Valentin Date: Thu, 31 Aug 2017 13:30:24 +0200 Subject: [PATCH 054/327] revert s/VertexIndexWeight/IndexWeight/ --- .../osganimationskinning.cpp | 6 +++--- include/osgAnimation/RigTransformHardware | 2 +- include/osgAnimation/VertexInfluence | 6 +++--- src/osgAnimation/RigTransformHardware.cpp | 10 +++++----- src/osgAnimation/RigTransformSoftware.cpp | 2 +- src/osgAnimation/VertexInfluence.cpp | 18 +++++++----------- .../osgAnimation/ReaderWriter.cpp | 2 +- .../serializers/osgAnimation/RigGeometry.cpp | 2 +- 8 files changed, 22 insertions(+), 26 deletions(-) diff --git a/examples/osganimationskinning/osganimationskinning.cpp b/examples/osganimationskinning/osganimationskinning.cpp index 485276e03..2536353a6 100644 --- a/examples/osganimationskinning/osganimationskinning.cpp +++ b/examples/osganimationskinning/osganimationskinning.cpp @@ -143,11 +143,11 @@ void initVertexMap(osgAnimation::Bone* b0, float val = (*array)[i][0]; std::cout << val << std::endl; if (val >= -1.0f && val <= 0.0f) - (*vim)[b0->getName()].push_back(osgAnimation::IndexWeight(i,1.0f)); + (*vim)[b0->getName()].push_back(osgAnimation::VertexIndexWeight(i,1.0f)); else if ( val > 0.0f && val <= 1.0f) - (*vim)[b1->getName()].push_back(osgAnimation::IndexWeight(i,1.0f)); + (*vim)[b1->getName()].push_back(osgAnimation::VertexIndexWeight(i,1.0f)); else if ( val > 1.0f) - (*vim)[b2->getName()].push_back(osgAnimation::IndexWeight(i,1.0f)); + (*vim)[b2->getName()].push_back(osgAnimation::VertexIndexWeight(i,1.0f)); } geom->setInfluenceMap(vim); diff --git a/include/osgAnimation/RigTransformHardware b/include/osgAnimation/RigTransformHardware index 9e2cb23f1..eeefa0030 100644 --- a/include/osgAnimation/RigTransformHardware +++ b/include/osgAnimation/RigTransformHardware @@ -81,7 +81,7 @@ namespace osgAnimation unsigned int _minAttribIndex; bool buildPalette(const BoneMap& boneMap ,const RigGeometry& rig); - bool init(RigGeometry& ); + virtual bool init(RigGeometry& ); }; } diff --git a/include/osgAnimation/VertexInfluence b/include/osgAnimation/VertexInfluence index 94c12b0e4..a521f13d7 100644 --- a/include/osgAnimation/VertexInfluence +++ b/include/osgAnimation/VertexInfluence @@ -34,15 +34,15 @@ namespace osgAnimation inline void setWeight(float i){second=i;} }; // first is vertex index, and second the weight - struct IndexWeight: public std::pair + struct VertexIndexWeight: public std::pair { - IndexWeight( unsigned int f = 0xffffffff,float s = 0.0f): std::pair(f,s){} + VertexIndexWeight( unsigned int f = 0xffffffff,float s = 0.0f): 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;} }; - typedef std::vector IndexWeightList; + typedef std::vector IndexWeightList; typedef std::vector BoneWeightList; typedef std::vector IndexList; diff --git a/src/osgAnimation/RigTransformHardware.cpp b/src/osgAnimation/RigTransformHardware.cpp index f2fac8c43..8713b5cef 100644 --- a/src/osgAnimation/RigTransformHardware.cpp +++ b/src/osgAnimation/RigTransformHardware.cpp @@ -65,7 +65,7 @@ void RigTransformHardware::computeMatrixPaletteUniform(const osg::Matrix& transf } -void createVertexAttribList(RigTransformHardware& rig,const std::vector > &perVertexInfluences,RigTransformHardware::BoneWeightAttribList & boneWeightAttribArrays); +void createVertexAttribList(RigTransformHardware& rig,const std::vector > &perVertexInfluences,RigTransformHardware::BoneWeightAttribList & boneWeightAttribArrays); // // create vertex attribute by 2 bones @@ -76,7 +76,7 @@ void createVertexAttribList(RigTransformHardware& rig,const std::vector > PerVertexInfList; +typedef std::vector > PerVertexInfList; void createVertexAttribList(RigTransformHardware& rig, const PerVertexInfList & perVertexInfluences, RigTransformHardware::BoneWeightAttribList& boneWeightAttribArrays) @@ -172,7 +172,7 @@ bool RigTransformHardware::buildPalette(const BoneMap&boneMap ,const RigGeometry BoneNamePaletteIndex::iterator boneName2PaletteIndex; // init temp vertex attribute data - std::vector > perVertexInfluences; + std::vector perVertexInfluences; perVertexInfluences.resize(_nbVertexes); unsigned int paletteindex; @@ -203,14 +203,14 @@ bool RigTransformHardware::buildPalette(const BoneMap&boneMap ,const RigGeometry } for(IndexWeightList::const_iterator infit = boneinflist.begin(); infit!=boneinflist.end(); ++infit) { - const IndexWeight& iw = *infit; + const VertexIndexWeight& iw = *infit; const unsigned int &index = iw.getIndex(); const float &weight = iw.getWeight(); IndexWeightList & iwlist=perVertexInfluences[index]; if(fabs(weight) > 1e-4) // don't use bone with weight too small { - iwlist.push_back(IndexWeight(paletteindex,weight)); + iwlist.push_back(VertexIndexWeight(paletteindex,weight)); } else { diff --git a/src/osgAnimation/RigTransformSoftware.cpp b/src/osgAnimation/RigTransformSoftware.cpp index 35bea4823..3e858647a 100644 --- a/src/osgAnimation/RigTransformSoftware.cpp +++ b/src/osgAnimation/RigTransformSoftware.cpp @@ -67,7 +67,7 @@ void RigTransformSoftware::buildMinimumUpdateSet( const BoneMap&boneMap, const R Bone* bone = bmit->second.get(); for(IndexWeightList::const_iterator infit=inflist.begin(); infit!=inflist.end(); ++infit) { - const IndexWeight &iw = *infit; + const VertexIndexWeight &iw = *infit; const unsigned int &index = iw.getIndex(); float weight = iw.getWeight(); diff --git a/src/osgAnimation/VertexInfluence.cpp b/src/osgAnimation/VertexInfluence.cpp index 2fffc7559..d0bba7599 100644 --- a/src/osgAnimation/VertexInfluence.cpp +++ b/src/osgAnimation/VertexInfluence.cpp @@ -38,7 +38,7 @@ void VertexInfluenceMap::normalize(unsigned int numvert) { for(VertexInfluenceMap::iterator mapit=this->begin(); mapit!=this->end(); ++mapit) { IndexWeightList &curvecinf=mapit->second; for(IndexWeightList::iterator curinf=curvecinf.begin(); curinf!=curvecinf.end(); ++curinf) { - IndexWeight& inf=*curinf; + VertexIndexWeight& inf=*curinf; localstore[inf.first].first+=inf.second; localstore[inf.first].second.push_back(&inf.second); @@ -70,7 +70,7 @@ void VertexInfluenceMap::cullInfluenceCountPerVertex(unsigned int numbonepervert const std::string& bonename=mapit->first; IndexWeightList &curvecinf=mapit->second; for(IndexWeightList::iterator curinf=curvecinf.begin(); curinf!=curvecinf.end(); ++curinf) { - IndexWeight& inf=*curinf; + VertexIndexWeight& inf=*curinf; if( bonename.empty()) { OSG_WARN << "VertexInfluenceSet::buildVertex2BoneList warning vertex " << inf.first << " is not assigned to a bone" << std::endl; } @@ -90,14 +90,14 @@ void VertexInfluenceMap::cullInfluenceCountPerVertex(unsigned int numbonepervert sum=1.0f/sum; for(BoneWeightOrdered::iterator bwit=bwset.begin(); bwit!=bwset.end(); ++bwit) { VertexInfluence & inf= (*this)[bwit->getBoneName()]; - inf.push_back(IndexWeight(mapit->first, bwit->getWeight()*sum)); + inf.push_back(VertexIndexWeight(mapit->first, bwit->getWeight()*sum)); inf.setName(bwit->getBoneName()); } } }else{ for(BoneWeightOrdered::iterator bwit=bwset.begin(); bwit!=bwset.end(); ++bwit) { VertexInfluence & inf= (*this)[bwit->getBoneName()]; - inf.push_back(IndexWeight(mapit->first,bwit->getWeight())); + inf.push_back(VertexIndexWeight(mapit->first,bwit->getWeight())); inf.setName(bwit->getBoneName()); } @@ -114,14 +114,13 @@ void VertexInfluenceMap::computePerVertexInfluenceList(std::vectorsecond; if (it->first.empty()) { - OSG_WARN << "RigTransformSoftware::VertexInfluenceMap contains unamed bone IndexWeightList" << std::endl; + OSG_WARN << "VertexInfluenceMap::computePerVertexInfluenceList contains unamed bone IndexWeightList" << std::endl; } for(IndexWeightList::const_iterator infit=inflist.begin(); infit!=inflist.end(); ++infit) { - const IndexWeight &iw = *infit; + const VertexIndexWeight &iw = *infit; const unsigned int &index = iw.getIndex(); float weight = iw.getWeight(); - vertex2Bones[index].push_back(BoneWeight(it->first, weight));; } } @@ -173,12 +172,9 @@ void VertexInfluenceMap::computeMinimalVertexGroupList(std::vector& unsigned int vertexID=0; for (std::vector::iterator it = vertex2Bones.begin(); it != vertex2Bones.end(); ++it,++vertexID) { - BoneWeightList &boneweightlist = *it;//->second; - //int vertexIndex = it->first; - + BoneWeightList &boneweightlist = *it; // sort the vector to have a consistent key std::sort(boneweightlist.begin(), boneweightlist.end(), SortByNameAndWeight()); - // we use the vector as key to differentiate group UnifyBoneGroup::iterator result = unifyBuffer.find(boneweightlist); if (result == unifyBuffer.end()) diff --git a/src/osgWrappers/deprecated-dotosg/osgAnimation/ReaderWriter.cpp b/src/osgWrappers/deprecated-dotosg/osgAnimation/ReaderWriter.cpp index 4dbf949dc..add7f50fd 100644 --- a/src/osgWrappers/deprecated-dotosg/osgAnimation/ReaderWriter.cpp +++ b/src/osgWrappers/deprecated-dotosg/osgAnimation/ReaderWriter.cpp @@ -827,7 +827,7 @@ bool RigGeometry_readLocalData(Object& obj, Input& fr) fr += 2; iteratorAdvanced = true; } - vi.push_back(osgAnimation::IndexWeight(index, weight)); + vi.push_back(osgAnimation::VertexIndexWeight(index, weight)); } if (fr.matchSequence("}")) { diff --git a/src/osgWrappers/serializers/osgAnimation/RigGeometry.cpp b/src/osgWrappers/serializers/osgAnimation/RigGeometry.cpp index 2ea4b9551..10b14d0f1 100644 --- a/src/osgWrappers/serializers/osgAnimation/RigGeometry.cpp +++ b/src/osgWrappers/serializers/osgAnimation/RigGeometry.cpp @@ -27,7 +27,7 @@ static bool readInfluenceMap( osgDB::InputStream& is, osgAnimation::RigGeometry& int index = 0; float weight = 0.0f; is >> index >> weight; - vi.push_back( osgAnimation::IndexWeight(index, weight) ); + vi.push_back( osgAnimation::VertexIndexWeight(index, weight) ); } (*map)[bonename] = vi; is >> is.END_BRACKET; From b790986f3739db204dfdc1326ce426f34f6b0cc5 Mon Sep 17 00:00:00 2001 From: Julien Valentin Date: Thu, 31 Aug 2017 13:49:27 +0200 Subject: [PATCH 055/327] few cleanup --- include/osgAnimation/RigTransformHardware | 3 +++ src/osgAnimation/RigTransformHardware.cpp | 26 +++++++++++------------ src/osgAnimation/RigTransformSoftware.cpp | 1 - 3 files changed, 16 insertions(+), 14 deletions(-) diff --git a/include/osgAnimation/RigTransformHardware b/include/osgAnimation/RigTransformHardware index eeefa0030..5469fb299 100644 --- a/include/osgAnimation/RigTransformHardware +++ b/include/osgAnimation/RigTransformHardware @@ -62,8 +62,10 @@ namespace osgAnimation void computeMatrixPaletteUniform(const osg::Matrix& transformFromSkeletonToGeometry, const osg::Matrix& invTransformFromSkeletonToGeometry); + // update rig if needed virtual void operator()(RigGeometry&); + // init animations data virtual bool prepareData(RigGeometry& ); protected: @@ -81,6 +83,7 @@ namespace osgAnimation unsigned int _minAttribIndex; bool buildPalette(const BoneMap& boneMap ,const RigGeometry& rig); + //on first update virtual bool init(RigGeometry& ); }; diff --git a/src/osgAnimation/RigTransformHardware.cpp b/src/osgAnimation/RigTransformHardware.cpp index 8713b5cef..85a32bdaa 100644 --- a/src/osgAnimation/RigTransformHardware.cpp +++ b/src/osgAnimation/RigTransformHardware.cpp @@ -21,13 +21,12 @@ using namespace osgAnimation; #define DEFAULT_FIRST_VERTATTRIB_TARGETTED 11 -RigTransformHardware::RigTransformHardware() -{ - _needInit = true; - _bonesPerVertex = 0; - _nbVertexes = 0; - _minAttribIndex = DEFAULT_FIRST_VERTATTRIB_TARGETTED; -} +RigTransformHardware::RigTransformHardware(): + _bonesPerVertex (0), + _nbVertexes (0), + _needInit (true), + _minAttribIndex(DEFAULT_FIRST_VERTATTRIB_TARGETTED) + {} RigTransformHardware::RigTransformHardware(const RigTransformHardware& rth, const osg::CopyOp& copyop): RigTransform(rth, copyop), @@ -152,8 +151,6 @@ bool RigTransformHardware::prepareData(RigGeometry& rig) // copy shallow from source geometry to rig rig.copyFrom(source); - - return true; } @@ -229,7 +226,6 @@ bool RigTransformHardware::buildPalette(const BoneMap&boneMap ,const RigGeometry OSG_INFO << "RigTransformHardware::buildPalette will use " << boneNameCountMap.size() * 4 << " uniforms" << std::endl; - } ///normalize @@ -251,16 +247,17 @@ bool RigTransformHardware::buildPalette(const BoneMap&boneMap ,const RigGeometry } } - _bonesPerVertex = maxBonePerVertex; _uniformMatrixPalette = new osg::Uniform(osg::Uniform::FLOAT_MAT4, "matrixPalette", _bonePalette.size()); + _bonesPerVertex = maxBonePerVertex; + createVertexAttribList(*this,perVertexInfluences,this->_boneWeightAttribArrays); return true; } bool RigTransformHardware::init(RigGeometry& rig){ - if(_uniformMatrixPalette.valid()){ + if(_bonesPerVertex>0){ ///data seams prepared osg::ref_ptr program ; osg::ref_ptr vertexshader; @@ -328,14 +325,17 @@ bool RigTransformHardware::init(RigGeometry& rig){ program->addShader(vertexshader.get()); + stateset->removeUniform("nbBonesPerVertex"); stateset->addUniform(new osg::Uniform("nbBonesPerVertex",_bonesPerVertex)); + stateset->removeUniform("matrixPalette"); - stateset->addUniform(getMatrixPaletteUniform()); + stateset->addUniform(_uniformMatrixPalette); stateset->removeAttribute(osg::StateAttribute::PROGRAM); if(!stateset->getAttribute(osg::StateAttribute::PROGRAM)) stateset->setAttributeAndModes(program.get()); + _needInit = false; return false; } diff --git a/src/osgAnimation/RigTransformSoftware.cpp b/src/osgAnimation/RigTransformSoftware.cpp index 3e858647a..403033da3 100644 --- a/src/osgAnimation/RigTransformSoftware.cpp +++ b/src/osgAnimation/RigTransformSoftware.cpp @@ -70,7 +70,6 @@ void RigTransformSoftware::buildMinimumUpdateSet( const BoneMap&boneMap, const R const VertexIndexWeight &iw = *infit; const unsigned int &index = iw.getIndex(); float weight = iw.getWeight(); - perVertexInfluences[index].push_back(BonePtrWeight(bone, weight)); } } From 5aa96727e90b54daee5e07c0c4b2ad7ee627220b Mon Sep 17 00:00:00 2001 From: Julien Valentin Date: Thu, 31 Aug 2017 16:35:05 +0200 Subject: [PATCH 056/327] clean and bugfixes --- include/osgAnimation/RigTransformHardware | 2 +- include/osgAnimation/VertexInfluence | 1 + src/osgAnimation/MorphTransformHardware.cpp | 20 ++--- src/osgAnimation/MorphTransformSoftware.cpp | 1 - src/osgAnimation/RigTransformHardware.cpp | 83 ++++++++++--------- src/osgAnimation/RigTransformSoftware.cpp | 2 + src/osgAnimation/VertexInfluence.cpp | 7 +- .../serializers/osgAnimation/RigGeometry.cpp | 1 + 8 files changed, 63 insertions(+), 54 deletions(-) diff --git a/include/osgAnimation/RigTransformHardware b/include/osgAnimation/RigTransformHardware index 5469fb299..674a6a66e 100644 --- a/include/osgAnimation/RigTransformHardware +++ b/include/osgAnimation/RigTransformHardware @@ -65,7 +65,7 @@ namespace osgAnimation // update rig if needed virtual void operator()(RigGeometry&); - // init animations data + // init/reset animations data virtual bool prepareData(RigGeometry& ); protected: diff --git a/include/osgAnimation/VertexInfluence b/include/osgAnimation/VertexInfluence index a521f13d7..bff9a11d9 100644 --- a/include/osgAnimation/VertexInfluence +++ b/include/osgAnimation/VertexInfluence @@ -1,5 +1,6 @@ /* -*-c++-*- * Copyright (C) 2008 Cedric Pinson + * Copyright (C) 2017 Julien Valentin * * This library is open source and may be redistributed and/or modified under * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or diff --git a/src/osgAnimation/MorphTransformHardware.cpp b/src/osgAnimation/MorphTransformHardware.cpp index f0915bbf1..40ae94007 100644 --- a/src/osgAnimation/MorphTransformHardware.cpp +++ b/src/osgAnimation/MorphTransformHardware.cpp @@ -23,7 +23,9 @@ using namespace osgAnimation; -MorphTransformHardware::MorphTransformHardware():_needInit(true),_reservedTextureUnit(DEFAULTMORPHTEXTUREUNIT) +MorphTransformHardware::MorphTransformHardware(): + _needInit(true), + _reservedTextureUnit(DEFAULTMORPHTEXTUREUNIT) { } @@ -46,23 +48,22 @@ bool MorphTransformHardware::init(MorphGeometry& morphGeometry) ///check for correct morph configuration ///(blender osgexport doesn't set sources so assume morphgeom arrays are sources) if(pos) - { + { pos->setDataVariance(osg::Object::STATIC); ///check if source is setted correctly if (!vertexSource|| vertexSource->size() != pos->size()) { - vertexSource =(static_cast( pos->clone(osg::CopyOp::DEEP_COPY_ARRAYS)));//osg::Vec3Array(pos->begin(),pos->end()); - pos->setDataVariance(osg::Object::DYNAMIC); + vertexSource =(static_cast( pos->clone(osg::CopyOp::DEEP_COPY_ARRAYS))); } osg::Vec3Array* normal = dynamic_cast(morphGeometry.getNormalArray()); - bool normalmorphable = morphGeometry.getMorphNormals() && normal; + bool normalmorphable = morphGeometry.getMorphNormals() && normal&&(normal->getBinding()==osg::Array::BIND_PER_VERTEX); if(!normalmorphable) { - OSG_WARN << "MorphTransformHardware::morph geometry "<setDataVariance(osg::Object::STATIC); if (normalmorphable && (!normalSource || normalSource->size() != normal->size())) { - normalSource =(static_cast( normal->clone(osg::CopyOp::DEEP_COPY_ARRAYS)));//osg::Vec3Array(normal->begin(),normal->end()); - normal->setDataVariance(osg::Object::DYNAMIC); + normalSource =(static_cast( normal->clone(osg::CopyOp::DEEP_COPY_ARRAYS))); } } ///end check @@ -98,7 +99,7 @@ bool MorphTransformHardware::init(MorphGeometry& morphGeometry) //create TBO Texture handle osg::Uniform * morphTBOHandle=new osg::Uniform(osg::Uniform::SAMPLER_BUFFER,"morphTargets"); - morphTBOHandle->set(_reservedTextureUnit); + morphTBOHandle->set((int)_reservedTextureUnit); //create dynamic uniform for morphtargets animation weights _uniformTargetsWeight=new osg::Uniform(osg::Uniform::FLOAT,"morphWeights",morphlist.size()); @@ -139,7 +140,6 @@ bool MorphTransformHardware::init(MorphGeometry& morphGeometry) std::size_t start = str.find(toreplace); if (std::string::npos == start){ ///perhaps remanance from previous init (if saved after init) so reload shader - vertexshader = osg::Shader::readShaderFile(osg::Shader::VERTEX,"morphing.vert"); if (!vertexshader.valid()) { OSG_WARN << "RigTransformHardware can't load VertexShader" << std::endl; diff --git a/src/osgAnimation/MorphTransformSoftware.cpp b/src/osgAnimation/MorphTransformSoftware.cpp index 7080d8a4d..1965a5ed1 100644 --- a/src/osgAnimation/MorphTransformSoftware.cpp +++ b/src/osgAnimation/MorphTransformSoftware.cpp @@ -23,7 +23,6 @@ using namespace osgAnimation; bool MorphTransformSoftware::init(MorphGeometry& morphGeometry){ - morphGeometry.setDataVariance(osg::Object::DYNAMIC); osg::Vec3Array* pos = dynamic_cast(morphGeometry.getVertexArray()); osg::Vec3Array * vertexSource = (morphGeometry.getVertexSource()); diff --git a/src/osgAnimation/RigTransformHardware.cpp b/src/osgAnimation/RigTransformHardware.cpp index 85a32bdaa..b4eb7cdf1 100644 --- a/src/osgAnimation/RigTransformHardware.cpp +++ b/src/osgAnimation/RigTransformHardware.cpp @@ -21,12 +21,13 @@ using namespace osgAnimation; #define DEFAULT_FIRST_VERTATTRIB_TARGETTED 11 + RigTransformHardware::RigTransformHardware(): _bonesPerVertex (0), _nbVertexes (0), _needInit (true), _minAttribIndex(DEFAULT_FIRST_VERTATTRIB_TARGETTED) - {} +{} RigTransformHardware::RigTransformHardware(const RigTransformHardware& rth, const osg::CopyOp& copyop): RigTransform(rth, copyop), @@ -51,7 +52,7 @@ osg::Vec4Array* RigTransformHardware::getVertexAttrib(unsigned int index) void RigTransformHardware::computeMatrixPaletteUniform(const osg::Matrix& transformFromSkeletonToGeometry, const osg::Matrix& invTransformFromSkeletonToGeometry) { - for (unsigned int i = 0; i < _bonePalette.size(); i++) + for (unsigned int i = 0; i < _bonePalette.size(); ++i) { osg::ref_ptr bone = _bonePalette[i].get(); const osg::Matrixf& invBindMatrix = bone->getInvBindMatrixInSkeletonSpace(); @@ -63,9 +64,6 @@ void RigTransformHardware::computeMatrixPaletteUniform(const osg::Matrix& transf } } - -void createVertexAttribList(RigTransformHardware& rig,const std::vector > &perVertexInfluences,RigTransformHardware::BoneWeightAttribList & boneWeightAttribArrays); - // // create vertex attribute by 2 bones // vec4(boneIndex0, weight0, boneIndex1, weight1) @@ -76,12 +74,12 @@ void createVertexAttribList(RigTransformHardware& rig,const std::vector > PerVertexInfList; -void createVertexAttribList(RigTransformHardware& rig, +void createVertexAttribList(const RigTransformHardware& rig, const PerVertexInfList & perVertexInfluences, RigTransformHardware::BoneWeightAttribList& boneWeightAttribArrays) { - unsigned int nbVertices= rig.getNumVertexes(); - unsigned int maxbonepervertex=rig.getNumBonesPerVertex(); + unsigned int nbVertices = rig.getNumVertexes(); + unsigned int maxbonepervertex = rig.getNumBonesPerVertex(); unsigned int nbArray = static_cast(ceilf( ((float)maxbonepervertex) * 0.5f)); if (!nbArray) @@ -101,8 +99,6 @@ void createVertexAttribList(RigTransformHardware& rig, // it's convenient to init the second with a weight 0 unsigned int boneIndexInList = i*2 + b; unsigned int boneIndexInVec4 = b*2; - (*array)[j][0 + boneIndexInVec4] = 0; - (*array)[j][1 + boneIndexInVec4] = 0; if (boneIndexInList < perVertexInfluences[j].size()) { float boneIndex = static_cast(perVertexInfluences[j][boneIndexInList].getIndex()); @@ -110,6 +106,9 @@ void createVertexAttribList(RigTransformHardware& rig, // fill the vec4 (*array)[j][0 + boneIndexInVec4] = boneIndex; (*array)[j][1 + boneIndexInVec4] = boneWeight; + }else{ + (*array)[j][0 + boneIndexInVec4] = 0; + (*array)[j][1 + boneIndexInVec4] = 0; } } } @@ -133,6 +132,8 @@ bool RigTransformHardware::prepareData(RigGeometry& rig) } rig.setSkeleton(finder._root.get()); } + if(!rig.getSkeleton()) + return false; BoneMapVisitor mapVisitor; rig.getSkeleton()->accept(mapVisitor); BoneMap boneMap = mapVisitor.getBoneMap(); @@ -154,7 +155,8 @@ bool RigTransformHardware::prepareData(RigGeometry& rig) return true; } -bool RigTransformHardware::buildPalette(const BoneMap&boneMap ,const RigGeometry&rig) { +bool RigTransformHardware::buildPalette(const BoneMap&boneMap,const RigGeometry&rig) +{ typedef std::map BoneNameCountMap; _nbVertexes = rig.getVertexArray()->getNumElements(); @@ -165,7 +167,7 @@ bool RigTransformHardware::buildPalette(const BoneMap&boneMap ,const RigGeometry IndexWeightList::size_type maxBonePerVertex=0; BoneNameCountMap boneNameCountMap; - const VertexInfluenceMap &vertexInfluenceMap=*rig.getInfluenceMap(); + const VertexInfluenceMap &vertexInfluenceMap = *rig.getInfluenceMap(); BoneNamePaletteIndex::iterator boneName2PaletteIndex; // init temp vertex attribute data @@ -173,14 +175,14 @@ bool RigTransformHardware::buildPalette(const BoneMap&boneMap ,const RigGeometry perVertexInfluences.resize(_nbVertexes); unsigned int paletteindex; - for (osgAnimation::VertexInfluenceMap::const_iterator boneinflistit = vertexInfluenceMap.begin(); + for (VertexInfluenceMap::const_iterator boneinflistit = vertexInfluenceMap.begin(); boneinflistit != vertexInfluenceMap.end(); ++boneinflistit) { const IndexWeightList& boneinflist = boneinflistit->second; const std::string& bonename = boneinflistit->first; BoneMap::const_iterator bonebyname; - if ((bonebyname=boneMap.find(bonename)) == boneMap.end()) + 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; @@ -213,10 +215,8 @@ bool RigTransformHardware::buildPalette(const BoneMap&boneMap ,const RigGeometry { OSG_WARN << "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()); } - OSG_INFO << "RigTransformHardware::buildPalette maximum number of bone per vertex is " << maxBonePerVertex << std::endl; OSG_INFO << "RigTransformHardware::buildPalette matrix palette has " << boneNameCountMap.size() << " entries" << std::endl; for (BoneNameCountMap::iterator it = boneNameCountMap.begin(); it != boneNameCountMap.end(); ++it) @@ -228,24 +228,27 @@ bool RigTransformHardware::buildPalette(const BoneMap&boneMap ,const RigGeometry } - ///normalize + ///normalize and get maxBonePerVertex unsigned int vertid=0; for(PerVertexInfList::iterator vertinfit=perVertexInfluences.begin(); vertinfit != perVertexInfluences.end(); ++vertinfit,++vertid) { + maxBonePerVertex = osg::maximum(maxBonePerVertex, vertinfit->size()); float sum=0; for(IndexWeightList::iterator iwit = vertinfit->begin(); iwit != vertinfit->end(); ++iwit) sum+=iwit->second; - if(sum< 1e-4){ + if(sum< 1e-4) + { OSG_WARN << "RigTransformHardware::buildPalette Warning: vertex with zero sum weights: " <begin();iwit!=vertinfit->end();++iwit) + for(IndexWeightList::iterator iwit=vertinfit->begin(); iwit!=vertinfit->end(); ++iwit) iwit->second*=sum; } } + OSG_INFO << "RigTransformHardware::buildPalette maximum number of bone per vertex is " << maxBonePerVertex << std::endl; _uniformMatrixPalette = new osg::Uniform(osg::Uniform::FLOAT_MAT4, "matrixPalette", _bonePalette.size()); @@ -253,12 +256,16 @@ bool RigTransformHardware::buildPalette(const BoneMap&boneMap ,const RigGeometry createVertexAttribList(*this,perVertexInfluences,this->_boneWeightAttribArrays); -return true; + _needInit = true; + + return true; } -bool RigTransformHardware::init(RigGeometry& rig){ - if(_bonesPerVertex>0){ - ///data seams prepared +bool RigTransformHardware::init(RigGeometry& rig) +{ + //if animdata seams prepared + if(_uniformMatrixPalette.valid()) + { osg::ref_ptr program ; osg::ref_ptr vertexshader; osg::ref_ptr stateset = rig.getOrCreateStateSet(); @@ -267,24 +274,28 @@ bool RigTransformHardware::init(RigGeometry& rig){ 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) { + if(program->getShader(i)->getType()==osg::Shader::VERTEX) + { vertexshader=program->getShader(i); program->removeShader(vertexshader); - } - } else { + } + else + { program = new osg::Program; program->setName("HardwareSkinning"); } //set default source if _shader is not user setted - if (!vertexshader.valid()) { + if (!vertexshader.valid()) + { if (!_shader.valid()) vertexshader = osg::Shader::readShaderFile(osg::Shader::VERTEX,"skinning.vert"); else vertexshader=_shader; } - if (!vertexshader.valid()) { + if (!vertexshader.valid()) + { OSG_WARN << "RigTransformHardware can't load VertexShader" << std::endl; return false; } @@ -294,7 +305,8 @@ bool RigTransformHardware::init(RigGeometry& rig){ std::string str = vertexshader->getShaderSource(); std::string toreplace = std::string("MAX_MATRIX"); std::size_t start = str.find(toreplace); - if (std::string::npos != start) { + if (std::string::npos != start) + { std::stringstream ss; ss << getMatrixPaletteUniform()->getNumElements(); str.replace(start, toreplace.size(), ss.str()); @@ -302,28 +314,22 @@ bool RigTransformHardware::init(RigGeometry& rig){ } else { - OSG_INFO<< "MAX_MATRIX not found in Shader! " << str << std::endl; + OSG_WARN<< "MAX_MATRIX not found in Shader! " << str << std::endl; } OSG_INFO << "Shader " << str << std::endl; } unsigned int attribIndex = _minAttribIndex; unsigned int nbAttribs = getNumVertexAttrib(); - if(nbAttribs==0) - OSG_WARN << "nbAttribs== " << nbAttribs << std::endl; for (unsigned int i = 0; i < nbAttribs; i++) { std::stringstream ss; ss << "boneWeight" << i; program->addBindAttribLocation(ss.str(), attribIndex + i); - - if(getVertexAttrib(i)->getNumElements()!=_nbVertexes) - OSG_WARN << "getVertexAttrib== " << getVertexAttrib(i)->getNumElements() << std::endl; rig.setVertexAttribArray(attribIndex + i, getVertexAttrib(i)); OSG_INFO << "set vertex attrib " << ss.str() << std::endl; } - program->addShader(vertexshader.get()); stateset->removeUniform("nbBonesPerVertex"); @@ -333,11 +339,10 @@ bool RigTransformHardware::init(RigGeometry& rig){ stateset->addUniform(_uniformMatrixPalette); stateset->removeAttribute(osg::StateAttribute::PROGRAM); - if(!stateset->getAttribute(osg::StateAttribute::PROGRAM)) - stateset->setAttributeAndModes(program.get()); + stateset->setAttributeAndModes(program.get()); _needInit = false; - return false; + return true; } else prepareData(rig); return false; diff --git a/src/osgAnimation/RigTransformSoftware.cpp b/src/osgAnimation/RigTransformSoftware.cpp index 403033da3..4d8be913c 100644 --- a/src/osgAnimation/RigTransformSoftware.cpp +++ b/src/osgAnimation/RigTransformSoftware.cpp @@ -139,6 +139,8 @@ bool RigTransformSoftware::prepareData(RigGeometry&rig) { } rig.setSkeleton(finder._root.get()); } + if(!rig.getSkeleton()) + return false; ///get bonemap from skeleton BoneMapVisitor mapVisitor; rig.getSkeleton()->accept(mapVisitor); diff --git a/src/osgAnimation/VertexInfluence.cpp b/src/osgAnimation/VertexInfluence.cpp index d0bba7599..ee42b53c4 100644 --- a/src/osgAnimation/VertexInfluence.cpp +++ b/src/osgAnimation/VertexInfluence.cpp @@ -1,5 +1,6 @@ /* -*-c++-*- * Copyright (C) 2008 Cedric Pinson + * Copyright (C) 2017 Julien Valentin * * This library is open source and may be redistributed and/or modified under * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or @@ -72,7 +73,7 @@ void VertexInfluenceMap::cullInfluenceCountPerVertex(unsigned int numbonepervert for(IndexWeightList::iterator curinf=curvecinf.begin(); curinf!=curvecinf.end(); ++curinf) { VertexIndexWeight& inf=*curinf; if( bonename.empty()) { - OSG_WARN << "VertexInfluenceSet::buildVertex2BoneList warning vertex " << inf.first << " is not assigned to a bone" << std::endl; + 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)); } @@ -161,7 +162,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; @@ -182,7 +183,7 @@ void VertexInfluenceMap::computeMinimalVertexGroupList(std::vector& unifyBuffer[boneweightlist].vertIDs().push_back(vertexID); } if(vertex2Bones.size()==unifyBuffer.size()) { - OSG_WARN << "VertexInfluenceSet::buildmap is useless no duplicate VertexGroup" << std::endl; + OSG_WARN << "VertexInfluenceMap::computeMinimalVertexGroupList is useless no duplicate VertexGroup" << std::endl; } uniqVertexGroupList.reserve(unifyBuffer.size()); for (UnifyBoneGroup::iterator it = unifyBuffer.begin(); it != unifyBuffer.end(); ++it) diff --git a/src/osgWrappers/serializers/osgAnimation/RigGeometry.cpp b/src/osgWrappers/serializers/osgAnimation/RigGeometry.cpp index 10b14d0f1..be47b97b1 100644 --- a/src/osgWrappers/serializers/osgAnimation/RigGeometry.cpp +++ b/src/osgWrappers/serializers/osgAnimation/RigGeometry.cpp @@ -2,6 +2,7 @@ #include #include #include + namespace wrap_osgAnimationRigGeometry{ static bool checkInfluenceMap( const osgAnimation::RigGeometry& geom ) { From dee9dc216464a65456121cec0c81a109f1ee1bfb Mon Sep 17 00:00:00 2001 From: Julien Valentin Date: Fri, 1 Sep 2017 01:43:00 +0200 Subject: [PATCH 057/327] a functional cleanup --- .../osganimationhardware.cpp | 2 +- include/osgAnimation/RigTransformHardware | 4 +- src/osgAnimation/RigTransformHardware.cpp | 122 ++++++++++-------- 3 files changed, 68 insertions(+), 60 deletions(-) diff --git a/examples/osganimationhardware/osganimationhardware.cpp b/examples/osganimationhardware/osganimationhardware.cpp index acc2bf2f8..03735b2da 100644 --- a/examples/osganimationhardware/osganimationhardware.cpp +++ b/examples/osganimationhardware/osganimationhardware.cpp @@ -145,7 +145,7 @@ struct MyRigTransformHardware : public osgAnimation::RigTransformHardware ss << "boneWeight" << i; program->addBindAttribLocation(ss.str(), attribIndex + i); - if(getVertexAttrib(i)->getNumElements()!=_nbVertexes) + if(getVertexAttrib(i)->getNumElements()!=_nbVertices) OSG_WARN << "getVertexAttrib== " << getVertexAttrib(i)->getNumElements() << std::endl; rig.setVertexAttribArray(attribIndex + i, getVertexAttrib(i)); OSG_INFO << "set vertex attrib " << ss.str() << std::endl; diff --git a/include/osgAnimation/RigTransformHardware b/include/osgAnimation/RigTransformHardware index 674a6a66e..2f7ea868b 100644 --- a/include/osgAnimation/RigTransformHardware +++ b/include/osgAnimation/RigTransformHardware @@ -54,7 +54,7 @@ namespace osgAnimation unsigned int getNumVertexAttrib() const {return _boneWeightAttribArrays.size();} const unsigned int &getNumBonesPerVertex() const{ return _bonesPerVertex; } - const unsigned int &getNumVertexes() const { return _nbVertexes; } + const unsigned int &getNumVertexes() const { return _nbVertices; } const BoneNamePaletteIndex& getBoneNameToPalette(){ return _boneNameToPalette; } const BonePalette& getBonePalette() { return _bonePalette; } @@ -71,7 +71,7 @@ namespace osgAnimation protected: unsigned int _bonesPerVertex; - unsigned int _nbVertexes; + unsigned int _nbVertices; BonePalette _bonePalette; BoneNamePaletteIndex _boneNameToPalette; diff --git a/src/osgAnimation/RigTransformHardware.cpp b/src/osgAnimation/RigTransformHardware.cpp index b4eb7cdf1..427cd313d 100644 --- a/src/osgAnimation/RigTransformHardware.cpp +++ b/src/osgAnimation/RigTransformHardware.cpp @@ -24,7 +24,7 @@ using namespace osgAnimation; RigTransformHardware::RigTransformHardware(): _bonesPerVertex (0), - _nbVertexes (0), + _nbVertices (0), _needInit (true), _minAttribIndex(DEFAULT_FIRST_VERTATTRIB_TARGETTED) {} @@ -32,7 +32,7 @@ RigTransformHardware::RigTransformHardware(): RigTransformHardware::RigTransformHardware(const RigTransformHardware& rth, const osg::CopyOp& copyop): RigTransform(rth, copyop), _bonesPerVertex(rth._bonesPerVertex), - _nbVertexes(rth._nbVertexes), + _nbVertices(rth._nbVertices), _bonePalette(rth._bonePalette), _boneNameToPalette(rth._boneNameToPalette), _boneWeightAttribArrays(rth._boneWeightAttribArrays), @@ -74,46 +74,75 @@ void RigTransformHardware::computeMatrixPaletteUniform(const osg::Matrix& transf // typedef std::vector > PerVertexInfList; -void createVertexAttribList(const 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)); + +///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){ + short boneIndexInVec4; + unsigned int vertid = 0, + boneIndexInList; + IndexWeightList::size_type maxBonePerVertex = 0; + ///build vertex attrib arrays + //get maxBonePerVertex + for(PerVertexInfList::const_iterator vertinfit = perVertexInfluences.begin(); vertinfit != perVertexInfluences.end(); ++vertinfit) + maxBonePerVertex = osg::maximum(maxBonePerVertex, vertinfit->size()); + + OSG_INFO << "RigTransformHardware::createVertexAttribList maximum number of bone per vertex is " << maxBonePerVertex << std::endl; + + unsigned int nbArray = static_cast(ceilf( ((float)maxBonePerVertex) * 0.5f)); if (!nbArray) - return ; + return 0; + ///create vertex attrib arrays boneWeightAttribArrays.resize(nbArray); - for (unsigned int i = 0; i < nbArray; i++) + for(unsigned int j=0; j< nbArray; ++j) { - osg::ref_ptr array = new osg::Vec4Array(osg::Array::BIND_PER_VERTEX); - boneWeightAttribArrays[i] = array; - array->resize( nbVertices); - for (unsigned int j = 0; j < nbVertices; j++) + boneWeightAttribArrays[j] = new osg::Vec4Array(osg::Array::BIND_PER_VERTEX); + boneWeightAttribArrays[j]->resize(perVertexInfluences.size()); + } + + ///populate vertex attrib arrays + for(PerVertexInfList::const_iterator vertinfit=perVertexInfluences.begin(); vertinfit != perVertexInfluences.end(); ++vertinfit,++vertid) + { + //sum for normalization + float sum=0; + for(IndexWeightList::const_iterator iwit = vertinfit->begin(); iwit != vertinfit->end(); ++iwit) + sum+=iwit->second; + + if(sum< 1e-4) { - for (unsigned int b = 0; b < 2; b++) + OSG_WARN << "RigTransformHardware::buildPalette Warning: vertex with zero sum weights: " <(perVertexInfluences[j][boneIndexInList].getIndex()); - float boneWeight = perVertexInfluences[j][boneIndexInList].getWeight(); - // fill the vec4 - (*array)[j][0 + boneIndexInVec4] = boneIndex; - (*array)[j][1 + boneIndexInVec4] = boneWeight; - }else{ - (*array)[j][0 + boneIndexInVec4] = 0; - (*array)[j][1 + boneIndexInVec4] = 0; + boneIndexInVec4 = b*2; + boneIndexInList = j*2 + b; + if (boneIndexInList < (*vertinfit).size()) + { + float boneIndex = static_cast((*vertinfit)[boneIndexInList].getIndex()); + ///normalization here + float boneWeight = (*vertinfit)[boneIndexInList].getWeight()*sum; + dest[0 + boneIndexInVec4] = boneIndex; + dest[1 + boneIndexInVec4] = boneWeight; + } + else + { + dest[0 + boneIndexInVec4] = 0; + dest[1 + boneIndexInVec4] = 0; + } } } } } - return; + return maxBonePerVertex; } bool RigTransformHardware::prepareData(RigGeometry& rig) @@ -155,11 +184,12 @@ bool RigTransformHardware::prepareData(RigGeometry& rig) return true; } + bool RigTransformHardware::buildPalette(const BoneMap&boneMap,const RigGeometry&rig) { typedef std::map BoneNameCountMap; - _nbVertexes = rig.getVertexArray()->getNumElements(); + _nbVertices = rig.getVertexArray()->getNumElements(); _boneWeightAttribArrays.resize(0); _bonePalette.clear(); _boneNameToPalette.clear(); @@ -172,7 +202,7 @@ bool RigTransformHardware::buildPalette(const BoneMap&boneMap,const RigGeometry& // init temp vertex attribute data std::vector perVertexInfluences; - perVertexInfluences.resize(_nbVertexes); + perVertexInfluences.resize(_nbVertices); unsigned int paletteindex; for (VertexInfluenceMap::const_iterator boneinflistit = vertexInfluenceMap.begin(); @@ -205,7 +235,7 @@ bool RigTransformHardware::buildPalette(const BoneMap&boneMap,const RigGeometry& const VertexIndexWeight& iw = *infit; const unsigned int &index = iw.getIndex(); const float &weight = iw.getWeight(); - IndexWeightList & iwlist=perVertexInfluences[index]; + IndexWeightList & iwlist = perVertexInfluences[index]; if(fabs(weight) > 1e-4) // don't use bone with weight too small { @@ -228,34 +258,12 @@ bool RigTransformHardware::buildPalette(const BoneMap&boneMap,const RigGeometry& } - ///normalize and get maxBonePerVertex - unsigned int vertid=0; - for(PerVertexInfList::iterator vertinfit=perVertexInfluences.begin(); vertinfit != perVertexInfluences.end(); ++vertinfit,++vertid) - { - maxBonePerVertex = osg::maximum(maxBonePerVertex, vertinfit->size()); - float sum=0; - for(IndexWeightList::iterator iwit = vertinfit->begin(); iwit != vertinfit->end(); ++iwit) - sum+=iwit->second; - if(sum< 1e-4) - { - OSG_WARN << "RigTransformHardware::buildPalette Warning: vertex with zero sum weights: " <begin(); iwit!=vertinfit->end(); ++iwit) - iwit->second*=sum; - } - } - OSG_INFO << "RigTransformHardware::buildPalette maximum number of bone per vertex is " << maxBonePerVertex << std::endl; + if( (_bonesPerVertex = createVertexAttribList(perVertexInfluences, _boneWeightAttribArrays) ) < 1 ) + return false; _uniformMatrixPalette = new osg::Uniform(osg::Uniform::FLOAT_MAT4, "matrixPalette", _bonePalette.size()); - _bonesPerVertex = maxBonePerVertex; - - createVertexAttribList(*this,perVertexInfluences,this->_boneWeightAttribArrays); - _needInit = true; return true; From 8b74b04de0b59ef510037198bd33857126188d01 Mon Sep 17 00:00:00 2001 From: Julien Valentin Date: Fri, 1 Sep 2017 15:12:10 +0200 Subject: [PATCH 058/327] cleanup --- src/osgAnimation/MorphTransformHardware.cpp | 3 ++- src/osgAnimation/RigTransformHardware.cpp | 3 +-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/osgAnimation/MorphTransformHardware.cpp b/src/osgAnimation/MorphTransformHardware.cpp index 40ae94007..48119c813 100644 --- a/src/osgAnimation/MorphTransformHardware.cpp +++ b/src/osgAnimation/MorphTransformHardware.cpp @@ -48,7 +48,8 @@ bool MorphTransformHardware::init(MorphGeometry& morphGeometry) ///check for correct morph configuration ///(blender osgexport doesn't set sources so assume morphgeom arrays are sources) if(pos) - { pos->setDataVariance(osg::Object::STATIC); + { + pos->setDataVariance(osg::Object::STATIC); ///check if source is setted correctly if (!vertexSource|| vertexSource->size() != pos->size()) { diff --git a/src/osgAnimation/RigTransformHardware.cpp b/src/osgAnimation/RigTransformHardware.cpp index 427cd313d..e474cde00 100644 --- a/src/osgAnimation/RigTransformHardware.cpp +++ b/src/osgAnimation/RigTransformHardware.cpp @@ -346,8 +346,7 @@ bool RigTransformHardware::init(RigGeometry& rig) stateset->removeUniform("matrixPalette"); stateset->addUniform(_uniformMatrixPalette); - stateset->removeAttribute(osg::StateAttribute::PROGRAM); - stateset->setAttributeAndModes(program.get()); + stateset->setAttribute(program.get()); _needInit = false; return true; From 0d02dfbbbd95e2a23d325b866d8fa4b7e3fd54c8 Mon Sep 17 00:00:00 2001 From: Julien Valentin Date: Fri, 1 Sep 2017 16:23:49 +0200 Subject: [PATCH 059/327] remove utility classes BoneWeight and IndexWeight in order to avoid unnecessary symbols (but decrease a bit clarity of the code) --- include/osgAnimation/VertexInfluence | 22 ++++------------- src/osgAnimation/RigTransformHardware.cpp | 13 +++++----- src/osgAnimation/RigTransformSoftware.cpp | 4 +-- src/osgAnimation/VertexInfluence.cpp | 30 +++++++++++------------ 4 files changed, 28 insertions(+), 41 deletions(-) diff --git a/include/osgAnimation/VertexInfluence b/include/osgAnimation/VertexInfluence index bff9a11d9..2ddd39ebe 100644 --- a/include/osgAnimation/VertexInfluence +++ b/include/osgAnimation/VertexInfluence @@ -25,26 +25,14 @@ 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;} - }; + typedef std::pair BoneWeight; // first is vertex index, and second the weight - struct VertexIndexWeight: public std::pair - { - VertexIndexWeight( unsigned int f = 0xffffffff,float s = 0.0f): 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;} - }; + typedef std::pair VertexIndexWeight; + // list of IndexWeight typedef std::vector IndexWeightList; + // list of IndexWeight typedef std::vector BoneWeightList; + // list of Index typedef std::vector IndexList; //Bone influence list diff --git a/src/osgAnimation/RigTransformHardware.cpp b/src/osgAnimation/RigTransformHardware.cpp index e474cde00..c34ec2831 100644 --- a/src/osgAnimation/RigTransformHardware.cpp +++ b/src/osgAnimation/RigTransformHardware.cpp @@ -127,9 +127,9 @@ unsigned int createVertexAttribList(const PerVertexInfList & perVertexInfluences boneIndexInList = j*2 + b; if (boneIndexInList < (*vertinfit).size()) { - float boneIndex = static_cast((*vertinfit)[boneIndexInList].getIndex()); + float boneIndex = static_cast((*vertinfit)[boneIndexInList].first); ///normalization here - float boneWeight = (*vertinfit)[boneIndexInList].getWeight()*sum; + float boneWeight = (*vertinfit)[boneIndexInList].second*sum; dest[0 + boneIndexInVec4] = boneIndex; dest[1 + boneIndexInVec4] = boneWeight; } @@ -233,8 +233,8 @@ bool RigTransformHardware::buildPalette(const BoneMap&boneMap,const RigGeometry& for(IndexWeightList::const_iterator infit = boneinflist.begin(); infit!=boneinflist.end(); ++infit) { const VertexIndexWeight& iw = *infit; - const unsigned int &index = iw.getIndex(); - const float &weight = iw.getWeight(); + 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 @@ -327,14 +327,13 @@ bool RigTransformHardware::init(RigGeometry& rig) OSG_INFO << "Shader " << str << std::endl; } - unsigned int attribIndex = _minAttribIndex; unsigned int nbAttribs = getNumVertexAttrib(); for (unsigned int i = 0; i < nbAttribs; i++) { std::stringstream ss; ss << "boneWeight" << i; - program->addBindAttribLocation(ss.str(), attribIndex + i); - rig.setVertexAttribArray(attribIndex + i, getVertexAttrib(i)); + program->addBindAttribLocation(ss.str(), _minAttribIndex + i); + rig.setVertexAttribArray(_minAttribIndex + i, getVertexAttrib(i)); OSG_INFO << "set vertex attrib " << ss.str() << std::endl; } diff --git a/src/osgAnimation/RigTransformSoftware.cpp b/src/osgAnimation/RigTransformSoftware.cpp index 4d8be913c..ccb1a0a11 100644 --- a/src/osgAnimation/RigTransformSoftware.cpp +++ b/src/osgAnimation/RigTransformSoftware.cpp @@ -68,8 +68,8 @@ void RigTransformSoftware::buildMinimumUpdateSet( const BoneMap&boneMap, const R for(IndexWeightList::const_iterator infit=inflist.begin(); infit!=inflist.end(); ++infit) { const VertexIndexWeight &iw = *infit; - const unsigned int &index = iw.getIndex(); - float weight = iw.getWeight(); + const unsigned int &index = iw.first; + float weight = iw.second; perVertexInfluences[index].push_back(BonePtrWeight(bone, weight)); } } diff --git a/src/osgAnimation/VertexInfluence.cpp b/src/osgAnimation/VertexInfluence.cpp index ee42b53c4..3c2c50c42 100644 --- a/src/osgAnimation/VertexInfluence.cpp +++ b/src/osgAnimation/VertexInfluence.cpp @@ -25,9 +25,9 @@ struct invweight_ordered { inline bool operator() (const BoneWeight& bw1, const BoneWeight& bw2) { - if (bw1.getWeight() > bw2.getWeight())return true; - if (bw1.getWeight() < bw2.getWeight())return false; - return(bw1.getBoneName() bw2.second)return true; + if (bw1.second < bw2.second)return false; + return(bw1.firstnewsize)bwset.erase(*bwset.rbegin()); if(renormalize){ for(BoneWeightOrdered::iterator bwit=bwset.begin(); bwit!=bwset.end(); ++bwit) - sum+=bwit->getWeight(); + sum+=bwit->second; if(sum>1e-4){ sum=1.0f/sum; for(BoneWeightOrdered::iterator bwit=bwset.begin(); bwit!=bwset.end(); ++bwit) { - VertexInfluence & inf= (*this)[bwit->getBoneName()]; - inf.push_back(VertexIndexWeight(mapit->first, bwit->getWeight()*sum)); - inf.setName(bwit->getBoneName()); + 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) { - VertexInfluence & inf= (*this)[bwit->getBoneName()]; - inf.push_back(VertexIndexWeight(mapit->first,bwit->getWeight())); - inf.setName(bwit->getBoneName()); + VertexInfluence & inf= (*this)[bwit->first]; + inf.push_back(VertexIndexWeight(mapit->first,bwit->second)); + inf.setName(bwit->first); } } @@ -120,8 +120,8 @@ void VertexInfluenceMap::computePerVertexInfluenceList(std::vectorfirst, weight));; } } @@ -133,11 +133,11 @@ struct SortByNameAndWeight : public std::less bool operator()(const BoneWeight& b0, const BoneWeight& b1) const { - if (b0.getBoneName() < b1.getBoneName()) + if (b0.first < b1.first) return true; - else if (b0.getBoneName() > b1.getBoneName()) + else if (b0.first> b1.first) return false; - return (b0.getWeight() < b1.getWeight()); + return (b0.second < b1.second); } }; From 78dd81a8b4ffcd2e92125eb04d448c7d1c13647b Mon Sep 17 00:00:00 2001 From: Julien Valentin Date: Fri, 1 Sep 2017 17:48:28 +0200 Subject: [PATCH 060/327] 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 061/327] 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 062/327] 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 063/327] 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 064/327] 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 065/327] 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); + } } } From 20ee12e9866112f9d9dbf42132e665311683de03 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 6 Sep 2017 10:40:05 +0100 Subject: [PATCH 066/327] To control the GlyphTexture Min/MagFilter values Added --min and --mag filter with LINEAR, NEAREST and LINEAR_MIPMAP_LINER options for values --- examples/osgfont/osgfont.cpp | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/examples/osgfont/osgfont.cpp b/examples/osgfont/osgfont.cpp index 823e7ae24..55f893f36 100644 --- a/examples/osgfont/osgfont.cpp +++ b/examples/osgfont/osgfont.cpp @@ -65,6 +65,8 @@ struct TextSettings { TextSettings(): fontFilename("fonts/arial.ttf"), + minFilter(osg::Texture::LINEAR_MIPMAP_LINEAR), + magFilter(osg::Texture::LINEAR), glyphImageMargin(1), glyphImageMarginRatio(0.02), glyphInterval(1), @@ -75,6 +77,14 @@ struct TextSettings { } + + void readFilterMode(const std::string& value, osg::Texture::FilterMode& filterMode) + { + if (value=="LINEAR") filterMode = osg::Texture::LINEAR; + if (value=="NEAREST") filterMode = osg::Texture::NEAREST; + if (value=="LINEAR_MIPMAP_LINEAR") filterMode = osg::Texture::LINEAR_MIPMAP_LINEAR; + } + void read(osg::ArgumentParser& arguments) { if (arguments.read("--test")) @@ -94,6 +104,10 @@ struct TextSettings if (arguments.read("--font",fontFilename)) {} + std::string value; + if (arguments.read("--min", value)) { readFilterMode(value, minFilter); } + if (arguments.read("--mag", value)) { readFilterMode(value, magFilter); } + if (arguments.read("--margin", glyphImageMargin)) {} if (arguments.read("--margin-ratio", glyphImageMarginRatio)) {} @@ -123,6 +137,8 @@ struct TextSettings } std::string fontFilename; + osg::Texture::FilterMode minFilter; + osg::Texture::FilterMode magFilter; unsigned int glyphImageMargin; float glyphImageMarginRatio; int glyphInterval; @@ -144,6 +160,8 @@ osgText::Text* createLabel(const std::string& l, TextSettings& settings, unsigne font->setGlyphImageMargin(settings.glyphImageMargin); font->setGlyphImageMarginRatio(settings.glyphImageMarginRatio); + font->setMinFilterHint(settings.minFilter); + font->setMagFilterHint(settings.magFilter); settings.setText(*label); From 77d4705182a3fe89bb6195a3052f9f6836eba853 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 6 Sep 2017 16:53:54 +0100 Subject: [PATCH 067/327] Added KeyHandler for toggling "SIGNED_DISTANCE_FIELD" and "OUTLINE" #pragma(tic) shader defines to control the different shader paths. Keys to press are 'd' for toggle SIGNED_DISTANCE_FIELD and 'o' for OUTLINE. --- examples/osgfont/osgfont.cpp | 57 +++++++++++++++++++++++++++++++++++- 1 file changed, 56 insertions(+), 1 deletion(-) diff --git a/examples/osgfont/osgfont.cpp b/examples/osgfont/osgfont.cpp index 55f893f36..3e70be384 100644 --- a/examples/osgfont/osgfont.cpp +++ b/examples/osgfont/osgfont.cpp @@ -182,7 +182,61 @@ osgText::Text* createLabel(const std::string& l, TextSettings& settings, unsigne return label; } +class KeyHandler : public osgGA::GUIEventHandler +{ +public: + KeyHandler() {} + + ~KeyHandler() {} + + bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa) + { + osgViewer::View* view = dynamic_cast(&aa); + if (!view) return false; + +#if 1 + osg::StateSet* stateset = view->getSceneData()->getOrCreateStateSet(); +#else + osg::StateSet* stateset = view->getCamera()->getOrCreateStateSet(); +#endif + switch(ea.getEventType()) + { + case(osgGA::GUIEventAdapter::KEYUP): + { + if (ea.getKey()=='d') + { + toggleDefine(stateset, "SIGNED_DISTANCE_FIELD"); + return true; + } + else if (ea.getKey()=='o') + { + toggleDefine(stateset, "OUTLINE"); + return true; + } + break; + } + default: + break; + } + return false; + } + + void toggleDefine(osg::StateSet* stateset, const std::string& define) + { + osg::StateSet::DefinePair* dp = stateset->getDefinePair(define); + if (dp) + { + OSG_NOTICE<<"Disabling "<removeDefine(define); + } + else + { + OSG_NOTICE<<"Enabling "<setDefine(define); + } + } +}; int main(int argc, char** argv) @@ -191,9 +245,10 @@ int main(int argc, char** argv) osgViewer::Viewer viewer(args); - viewer.addEventHandler( new osgGA::StateSetManipulator(viewer.getCamera()->getOrCreateStateSet()) ); + viewer.addEventHandler(new osgGA::StateSetManipulator(viewer.getCamera()->getOrCreateStateSet())); viewer.addEventHandler(new osgViewer::StatsHandler()); viewer.addEventHandler(new osgViewer::WindowSizeHandler()); + viewer.addEventHandler(new KeyHandler()); TextSettings settings; settings.backgroundColor = viewer.getCamera()->getClearColor(); From de47eb3666cde64bc474115d8c81a21da413456d Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Fri, 8 Sep 2017 16:59:43 +0100 Subject: [PATCH 068/327] Add support for generating outline and signed distance field channels in a RGBA packed GlyphTexture Image. --- include/osgText/Font | 11 +- include/osgText/Glyph | 33 +++-- src/osgText/Font.cpp | 15 ++- src/osgText/Glyph.cpp | 291 ++++++++++++++++++++++++++++++++++-------- src/osgText/Text.cpp | 6 +- 5 files changed, 292 insertions(+), 64 deletions(-) diff --git a/include/osgText/Font b/include/osgText/Font index 369493891..e77a0e035 100644 --- a/include/osgText/Font +++ b/include/osgText/Font @@ -128,6 +128,10 @@ public: int getGlyphInterval() const; + void setGyphTextureFeatures(GlyphTexture::Features features) { _glyphTextureFeatures = features; } + GlyphTexture::Features getGlyphTextureFeatures() const { return _glyphTextureFeatures; } + + /** Set the size of texture to create to store the glyph images when rendering. * Note, this doesn't affect already created Texture Glhph's.*/ void setTextureSizeHint(unsigned int width,unsigned int height); @@ -145,6 +149,9 @@ public: void setMagFilterHint(osg::Texture::FilterMode mode); osg::Texture::FilterMode getMagFilterHint() const; + void setMaxAnisotropy(float anis) { _maxAnisotropy = anis; } + float getMaxAnisotropy() const { return _maxAnisotropy; } + unsigned int getFontDepth() const { return _depth; } void setNumberCurveSamples(unsigned int numSamples) { _numCurveSamples = numSamples; } @@ -203,11 +210,13 @@ protected: unsigned int _margin; float _marginRatio; int _glyphInterval; + GlyphTexture::Features _glyphTextureFeatures; unsigned int _textureWidthHint; unsigned int _textureHeightHint; osg::Texture::FilterMode _minFilterHint; osg::Texture::FilterMode _magFilterHint; + float _maxAnisotropy; unsigned int _depth; unsigned int _numCurveSamples; @@ -253,8 +262,6 @@ public: virtual bool getVerticalSize(float & /*ascender*/, float & /*descender*/) const { return false; } }; - - }; } diff --git a/include/osgText/Glyph b/include/osgText/Glyph index bb7d5192a..8dac38051 100644 --- a/include/osgText/Glyph +++ b/include/osgText/Glyph @@ -58,6 +58,9 @@ public: unsigned int getGlyphCode() const { return _glyphCode; } + void setFontResolution(const FontResolution& fontRes) { _fontResolution = fontRes; } + const FontResolution& getFontResolution() const { return _fontResolution; } + void setWidth(float width) { _width = width; } float getWidth() const { return _width; } @@ -90,8 +93,6 @@ public: void setMaxTexCoord(const osg::Vec2& coord); const osg::Vec2& getMaxTexCoord() const; - void subload() const; - protected: virtual ~Glyph(); @@ -99,6 +100,8 @@ protected: Font* _font; unsigned int _glyphCode; + FontResolution _fontResolution; + float _width; float _height; @@ -263,6 +266,17 @@ public: void setGlyphInterval(int interval) { _interval = interval; } int getGlyphInterval() const { return _interval; } + enum Features + { + GREYSCALE, + OUTLINE_GREYSCALE, + SIGNED_DISTANCE_FIELD, + ALL_FEATURES + }; + + void setGlyphTextureFeatures(Features features) { _glyphTextureFeatures = features; } + Features getGlyphTextureFeatures() const { return _glyphTextureFeatures; } + bool getSpaceForGlyph(Glyph* glyph, int& posX, int& posY); void addGlyph(Glyph* glyph,int posX, int posY); @@ -280,16 +294,19 @@ protected: virtual ~GlyphTexture(); + void copyGlyphImage(Glyph* glyph); + // parameter used to compute the size and position of empty space // in the texture which could accommodate new glyphs. - int _margin; - float _marginRatio; - int _interval; + int _margin; + float _marginRatio; + int _interval; + Features _glyphTextureFeatures; - int _usedY; - int _partUsedX; - int _partUsedY; + int _usedY; + int _partUsedX; + int _partUsedY; typedef std::vector< osg::ref_ptr > GlyphRefList; typedef std::vector< const Glyph* > GlyphPtrList; diff --git a/src/osgText/Font.cpp b/src/osgText/Font.cpp index 155acadff..c09285046 100644 --- a/src/osgText/Font.cpp +++ b/src/osgText/Font.cpp @@ -302,10 +302,16 @@ Font::Font(FontImplementation* implementation): _margin(1), _marginRatio(0.02), _glyphInterval(1), +#if 0 + _glyphTextureFeatures(GlyphTexture::ALL_FEATURES), +#else + _glyphTextureFeatures(GlyphTexture::GREYSCALE), +#endif _textureWidthHint(1024), _textureHeightHint(1024), _minFilterHint(osg::Texture::LINEAR_MIPMAP_LINEAR), _magFilterHint(osg::Texture::LINEAR), + _maxAnisotropy(16), _depth(1), _numCurveSamples(10) { @@ -411,6 +417,12 @@ float Font::getGlyphImageMarginRatio() const return _marginRatio; } +void Font::setGlyphInterval(int interval) +{ + _glyphInterval = interval; +} + + void Font::setTextureSizeHint(unsigned int width,unsigned int height) { _textureWidthHint = width; @@ -606,10 +618,11 @@ void Font::addGlyph(const FontResolution& fontRes, unsigned int charcode, Glyph* glyphTexture->setGlyphImageMargin(_margin); glyphTexture->setGlyphImageMarginRatio(_marginRatio); glyphTexture->setGlyphInterval(_glyphInterval); + glyphTexture->setGlyphTextureFeatures(_glyphTextureFeatures); glyphTexture->setTextureSize(_textureWidthHint,_textureHeightHint); glyphTexture->setFilter(osg::Texture::MIN_FILTER,_minFilterHint); glyphTexture->setFilter(osg::Texture::MAG_FILTER,_magFilterHint); - glyphTexture->setMaxAnisotropy(8); + glyphTexture->setMaxAnisotropy(_maxAnisotropy); _glyphTextureList.push_back(glyphTexture); diff --git a/src/osgText/Glyph.cpp b/src/osgText/Glyph.cpp index 2699b0627..fd6d61f9c 100644 --- a/src/osgText/Glyph.cpp +++ b/src/osgText/Glyph.cpp @@ -28,6 +28,14 @@ using namespace osgText; using namespace std; +#if 0 + #define TEXTURE_IMAGE_NUM_CHANNELS 1 + #define TEXTURE_IMAGE_FORMAT OSGTEXT_GLYPH_FORMAT +#else + #define TEXTURE_IMAGE_NUM_CHANNELS 4 + #define TEXTURE_IMAGE_FORMAT GL_RGBA +#endif + GlyphTexture::GlyphTexture(): _margin(1), _marginRatio(0.02f), @@ -121,8 +129,227 @@ void GlyphTexture::addGlyph(Glyph* glyph, int posX, int posY) glyph->setMaxTexCoord( osg::Vec2( static_cast(posX+glyph->s())/static_cast(getTextureWidth()), static_cast(posY+glyph->t())/static_cast(getTextureHeight()) ) ); - _image->copySubImage(glyph->getTexturePositionX(), glyph->getTexturePositionY(), 0, glyph); - _image->dirty(); + copyGlyphImage(glyph); +} + +void GlyphTexture::copyGlyphImage(Glyph* glyph) +{ + + if (_glyphTextureFeatures==GREYSCALE) + { + // OSG_NOTICE<<"GlyphTexture::copyGlyphImage() greyscale copy"<copySubImage(glyph->getTexturePositionX(), glyph->getTexturePositionY(), 0, glyph); + _image->dirty(); + return; + } + + // OSG_NOTICE<<"GlyphTexture::copyGlyphImage() generating signed distance field."<s(); + int src_rows = glyph->t(); + unsigned char* src_data = glyph->data(); + + int dest_columns = _image->s(); + int dest_rows = _image->t(); + unsigned char* dest_data = _image->data(glyph->getTexturePositionX(),glyph->getTexturePositionY()); + + int search_distance = glyph->getFontResolution().second/8; + + int left = -search_distance; + int right = glyph->s()+search_distance; + int lower = -search_distance; + int upper = glyph->t()+search_distance; + + float multiplier = 1.0/255.0f; + float max_distance = sqrtf(float(search_distance*search_distance)*2.0f); + + int num_channels = TEXTURE_IMAGE_NUM_CHANNELS; + + if ((left+glyph->getTexturePositionX())<0) left = -glyph->getTexturePositionX(); + if ((right+glyph->getTexturePositionX())>=dest_columns) right = dest_columns-glyph->getTexturePositionX()-1; + + if ((lower+glyph->getTexturePositionY())<0) lower = -glyph->getTexturePositionY(); + if ((upper+glyph->getTexturePositionY())>=dest_rows) upper = dest_rows-glyph->getTexturePositionY()-1; + + + for(int dr=lower; dr<=upper; ++dr) + { + for(int dc=left; dc<=right; ++dc) + { + unsigned char value = 0; + + unsigned char center_value = 0; + if (dr>=0 && dr=0 && dc0 && center_value<255) + { + if (center_value_f>=0.5f) + { + min_distance = center_value_f-0.5f; + value = 128+(min_distance/max_distance)*127; + } + else + { + min_distance = 0.5f-center_value_f; + value = 127-(min_distance/max_distance)*127; + } + } + else + { + for(int radius=1; radius=0 && r=0 && cabs(dy)) ? D/float(abs(dx)) : D/float(abs(dy)); + + float local_distance = sqrtf(float(radius*radius)+float(span*span)); + if (center_value==0) local_distance += (0.5f-local_value_f)*local_multiplier; + else local_distance += (local_value_f - 0.5f)*local_multiplier; + } + } + + { + // top + int dx = radius; + int dy = span; + + int c = dc+dx; + int r = dr+dy; + + unsigned char local_value = 0; + if (r>=0 && r=0 && cabs(dy)) ? D/float(abs(dx)) : D/float(abs(dy)); + + float local_distance = sqrtf(float(radius*radius)+float(span*span)); + if (center_value==0) local_distance += (0.5f-local_value_f)*local_multiplier; + else local_distance += (local_value_f - 0.5f)*local_multiplier; + } + } + + { + // right + int dx = radius; + int dy = -span; + + int c = dc+dx; + int r = dr+dy; + + unsigned char local_value = 0; + if (r>=0 && r=0 && cabs(dy)) ? D/float(abs(dx)) : D/float(abs(dy)); + + float local_distance = sqrtf(float(radius*radius)+float(span*span)); + if (center_value==0) local_distance += (0.5f-local_value_f)*local_multiplier; + else local_distance += (local_value_f - 0.5f)*local_multiplier; + if (local_distance=0 && r=0 && cabs(dy)) ? D/float(abs(dx)) : D/float(abs(dy)); + + float local_distance = sqrtf(float(radius*radius)+float(span*span)); + if (center_value==0) local_distance += (0.5f-local_value_f)*local_multiplier; + else local_distance += (local_value_f - 0.5f)*local_multiplier; + if (local_distance=0.5) + { + value = 128+(min_distance/max_distance)*127; + } + else + { + value = 127-(min_distance/max_distance)*127; + } + } + + + unsigned char* dest_ptr = dest_data + (dr*dest_columns + dc)*num_channels; + if (num_channels==4) + { + // signed distance field value + *(dest_ptr++) = value; + + float outline_distance = max_distance/4.0f; + + // compute the alpha value of outline, one texel thick + unsigned char outline = center_value; + if (center_value<255) + { + if (min_distanceallocateImage(getTextureWidth(), getTextureHeight(), 1, OSGTEXT_GLYPH_FORMAT, GL_UNSIGNED_BYTE); + + #if defined(OSG_GL3_AVAILABLE) && !defined(OSG_GL2_AVAILABLE) && !defined(OSG_GL1_AVAILABLE) + GLenum imageFormat = (_glyphTextureFeatures==GREYSCALE) ? GL_RED : GL_RGBA; + #else + GLenum imageFormat = (_glyphTextureFeatures==GREYSCALE) ? GL_ALPHA : GL_RGBA; + #endif + + _image->allocateImage(getTextureWidth(), getTextureHeight(), 1, imageFormat, GL_UNSIGNED_BYTE); memset(_image->data(), 0, _image->getTotalSizeInBytes()); for(GlyphRefList::iterator itr = _glyphs.begin(); @@ -161,7 +397,7 @@ osg::Image* GlyphTexture::createImage() ++itr) { Glyph* glyph = itr->get(); - _image->copySubImage(glyph->getTexturePositionX(), glyph->getTexturePositionY(), 0, glyph); + copyGlyphImage(glyph); } } @@ -217,53 +453,6 @@ const osg::Vec2& Glyph::getMinTexCoord() const { return _minTexCoord; } void Glyph::setMaxTexCoord(const osg::Vec2& coord) { _maxTexCoord=coord; } const osg::Vec2& Glyph::getMaxTexCoord() const { return _maxTexCoord; } -void Glyph::subload() const -{ - GLenum errorNo = glGetError(); - if (errorNo!=GL_NO_ERROR) - { - const GLubyte* msg = osg::gluErrorString(errorNo); - if (msg) { OSG_WARN<<"before Glyph::subload(): detected OpenGL error: "<(data())<<");"<getMaxTexCoord(); osg::Vec2 vDiff = maxtc - mintc; - float fHorizTCMargin = 1.0f / glyph->getTexture()->getTextureWidth(); - float fVertTCMargin = 1.0f / glyph->getTexture()->getTextureHeight(); + float texelMargin = 4.0f; + + float fHorizTCMargin = texelMargin / glyph->getTexture()->getTextureWidth(); + float fVertTCMargin = texelMargin / glyph->getTexture()->getTextureHeight(); float fHorizQuadMargin = vDiff.x() == 0.0f ? 0.0f : width * fHorizTCMargin / vDiff.x(); float fVertQuadMargin = vDiff.y() == 0.0f ? 0.0f : height * fVertTCMargin / vDiff.y(); From 2b010f019f28f65c13178f4701df74ba5d5cfb68 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Fri, 8 Sep 2017 17:02:38 +0100 Subject: [PATCH 069/327] Added setting of the original font reoslution to the created Glyph --- src/osgPlugins/freetype/FreeTypeFont.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/osgPlugins/freetype/FreeTypeFont.cpp b/src/osgPlugins/freetype/FreeTypeFont.cpp index c647e2cf9..5d7aee6e9 100644 --- a/src/osgPlugins/freetype/FreeTypeFont.cpp +++ b/src/osgPlugins/freetype/FreeTypeFont.cpp @@ -351,6 +351,8 @@ osgText::Glyph* FreeTypeFont::getGlyph(const osgText::FontResolution& fontRes, u osg::ref_ptr glyph = new osgText::Glyph(_facade, charcode); + glyph->setFontResolution(fontRes); + unsigned int dataSize = width*height; unsigned char* data = new unsigned char[dataSize]; From f98c23d4606ec50dd82a10cf26343803216b6085 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Fri, 8 Sep 2017 17:03:15 +0100 Subject: [PATCH 070/327] Added extra command line paramter and osgText::Font settings to add better control of osgText::GlyphTexture generation to support signed distance field and outline image data. --- examples/osgfont/osgfont.cpp | 59 +++++++++++++++++++++++------------- 1 file changed, 38 insertions(+), 21 deletions(-) diff --git a/examples/osgfont/osgfont.cpp b/examples/osgfont/osgfont.cpp index 3e70be384..2d37f4862 100644 --- a/examples/osgfont/osgfont.cpp +++ b/examples/osgfont/osgfont.cpp @@ -67,9 +67,11 @@ struct TextSettings fontFilename("fonts/arial.ttf"), minFilter(osg::Texture::LINEAR_MIPMAP_LINEAR), magFilter(osg::Texture::LINEAR), + maxAnisotropy(16.0f), glyphImageMargin(1), glyphImageMarginRatio(0.02), glyphInterval(1), + glyphTextureFeatures(osgText::GlyphTexture::GREYSCALE), textColor(1.0f, 1.0f, 1.0f, 1.0f), backdropType(osgText::Text::NONE), backdropOffset(0.04f, 0.04f), @@ -81,8 +83,8 @@ struct TextSettings void readFilterMode(const std::string& value, osg::Texture::FilterMode& filterMode) { if (value=="LINEAR") filterMode = osg::Texture::LINEAR; - if (value=="NEAREST") filterMode = osg::Texture::NEAREST; - if (value=="LINEAR_MIPMAP_LINEAR") filterMode = osg::Texture::LINEAR_MIPMAP_LINEAR; + else if (value=="NEAREST") filterMode = osg::Texture::NEAREST; + else if (value=="LINEAR_MIPMAP_LINEAR") filterMode = osg::Texture::LINEAR_MIPMAP_LINEAR; } void read(osg::ArgumentParser& arguments) @@ -102,12 +104,18 @@ struct TextSettings sizes.push_back(128); } + if (arguments.read("--GREYSCALE")) { glyphTextureFeatures = osgText::GlyphTexture::GREYSCALE; } + if (arguments.read("--OUTLINE_GREYSCALE")) { glyphTextureFeatures = osgText::GlyphTexture::OUTLINE_GREYSCALE; } + if (arguments.read("--SIGNED_DISTANCE_FIELD")) { glyphTextureFeatures = osgText::GlyphTexture::SIGNED_DISTANCE_FIELD; } + if (arguments.read("--ALL_FEATURES")) { glyphTextureFeatures = osgText::GlyphTexture::ALL_FEATURES; } + if (arguments.read("--font",fontFilename)) {} std::string value; if (arguments.read("--min", value)) { readFilterMode(value, minFilter); } if (arguments.read("--mag", value)) { readFilterMode(value, magFilter); } + if (arguments.read("--anisotropy",maxAnisotropy)) {} if (arguments.read("--margin", glyphImageMargin)) {} if (arguments.read("--margin-ratio", glyphImageMarginRatio)) {} @@ -129,26 +137,39 @@ struct TextSettings void setText(osgText::Text& text) { OSG_NOTICE<<"Settings::setText()"< font = osgText::readRefFontFile(fontFilename); + + font->setGlyphImageMargin(glyphImageMargin); + font->setGlyphImageMarginRatio(glyphImageMarginRatio); + font->setMinFilterHint(minFilter); + font->setMagFilterHint(magFilter); + font->setMaxAnisotropy(maxAnisotropy); + font->setGlyphInterval(glyphInterval); + font->setGyphTextureFeatures(glyphTextureFeatures); + text.setFont(font.get()); + text.setColor(textColor); text.setBackdropType(backdropType); text.setBackdropOffset(backdropOffset.x(), backdropOffset.y()); text.setBackdropColor(backdropColor); } - std::string fontFilename; - osg::Texture::FilterMode minFilter; - osg::Texture::FilterMode magFilter; - unsigned int glyphImageMargin; - float glyphImageMarginRatio; - int glyphInterval; + std::string fontFilename; + osg::Texture::FilterMode minFilter; + osg::Texture::FilterMode magFilter; + float maxAnisotropy; + unsigned int glyphImageMargin; + float glyphImageMarginRatio; + int glyphInterval; + osgText::GlyphTexture::Features glyphTextureFeatures; - osg::Vec4 textColor; - osgText::Text::BackdropType backdropType; - osg::Vec2 backdropOffset; - osg::Vec4 backdropColor; - osg::Vec4 backgroundColor; - Sizes sizes; + osg::Vec4 textColor; + osgText::Text::BackdropType backdropType; + osg::Vec2 backdropOffset; + osg::Vec4 backdropColor; + osg::Vec4 backgroundColor; + Sizes sizes; }; osgText::Text* createLabel(const std::string& l, TextSettings& settings, unsigned int size) @@ -156,12 +177,6 @@ osgText::Text* createLabel(const std::string& l, TextSettings& settings, unsigne static osg::Vec3 pos(10.0f, 10.0f, 0.0f); osgText::Text* label = new osgText::Text(); - osg::ref_ptr font = osgText::readRefFontFile(settings.fontFilename); - - font->setGlyphImageMargin(settings.glyphImageMargin); - font->setGlyphImageMarginRatio(settings.glyphImageMarginRatio); - font->setMinFilterHint(settings.minFilter); - font->setMagFilterHint(settings.magFilter); settings.setText(*label); @@ -291,6 +306,8 @@ int main(int argc, char** argv) OSG_NOTICE<<"Using shaders"<getOrCreateStateSet()->setAttribute(program.get(), osg::StateAttribute::OVERRIDE | osg::StateAttribute::ON); root->getOrCreateStateSet()->addUniform(new osg::Uniform("glyphTexture", 0)); + + settings.glyphTextureFeatures = osgText::GlyphTexture::ALL_FEATURES; } From 985b3a7206b2bee904c030b768883bc5ca2cc025 Mon Sep 17 00:00:00 2001 From: Laurens Voerman Date: Tue, 12 Sep 2017 09:19:33 +0200 Subject: [PATCH 071/327] removed las_c library from FindLIBLAS.cmake, it's not used by the osg plugin. --- CMakeModules/FindLIBLAS.cmake | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/CMakeModules/FindLIBLAS.cmake b/CMakeModules/FindLIBLAS.cmake index 5b2236cb4..1c9a7ee01 100644 --- a/CMakeModules/FindLIBLAS.cmake +++ b/CMakeModules/FindLIBLAS.cmake @@ -94,14 +94,12 @@ macro(FIND_LIBLAS_LIBRARY MYLIBRARY MYLIBRARYNAME) endmacro(FIND_LIBLAS_LIBRARY LIBRARY LIBRARYNAME) FIND_LIBLAS_LIBRARY(LIBLAS_LIBRARY las) -FIND_LIBLAS_LIBRARY(LIBLASC_LIBRARY las_c) set(LIBLAS_FOUND "NO") -if(LIBLAS_LIBRARY AND LIBLASC_LIBRARY AND LIBLAS_INCLUDE_DIR) - +if(LIBLAS_LIBRARY AND LIBLAS_INCLUDE_DIR) FIND_PACKAGE(Boost) # used by LIBLAS if(Boost_FOUND) - set(LIBLAS_LIBRARIES ${LIBLAS_LIBRARY} ${LIBLASC_LIBRARY} ) + set(LIBLAS_LIBRARIES ${LIBLAS_LIBRARY} ) set(LIBLAS_FOUND "YES") endif() endif() From 722ed6fc5ecc89620cc90a03317bf25e22d38a5e Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Tue, 12 Sep 2017 11:50:47 +0100 Subject: [PATCH 072/327] Shifted set up of osgText related StateSet from osgText::Font into into osg::TextBase/Text to enable grater control over state required for specific Text implementations --- include/osgText/Font | 15 ++-- include/osgText/Text | 16 ++-- include/osgText/TextBase | 4 + src/osgText/Font.cpp | 133 +++------------------------- src/osgText/Text.cpp | 184 +++++++++++++++++++++++++++++++++------ src/osgText/TextBase.cpp | 12 ++- 6 files changed, 193 insertions(+), 171 deletions(-) diff --git a/include/osgText/Font b/include/osgText/Font index e77a0e035..7b7fd0186 100644 --- a/include/osgText/Font +++ b/include/osgText/Font @@ -27,6 +27,7 @@ namespace osgText { // forward declare Font class Font; +class TextBase; #ifdef OSG_PROVIDE_READFILE /** Read a font from specified file. The filename may contain a path. @@ -84,13 +85,9 @@ public: static osg::ref_ptr& getDefaultFont(); - void setTexEnv(osg::TexEnv* texenv) { if (texenv) _texenv = texenv; } - inline osg::TexEnv* getTexEnv() { return _texenv.get(); } - inline const osg::TexEnv* getTexEnv() const { return _texenv.get(); } - - void setStateSet(osg::StateSet* stateset) { _stateset = stateset; } - osg::StateSet* getStateSet() { return _stateset.get(); } - const osg::StateSet* getStateSet() const { return _stateset.get(); } + typedef std::vector< osg::ref_ptr > StateSets; + StateSets& getCachedStateSets() { return _statesets; } + const StateSets& getCachedStateSets() const { return _statesets; } /** Get a kerning (adjustment of spacing of two adjacent character) for specified charcodes and a font resolution.*/ @@ -188,7 +185,6 @@ protected: void addGlyph(const FontResolution& fontRes, unsigned int charcode, Glyph* glyph); - typedef std::vector< osg::ref_ptr > StateSetList; typedef std::map< unsigned int, osg::ref_ptr > GlyphMap; typedef std::map< unsigned int, osg::ref_ptr > Glyph3DMap; @@ -197,8 +193,7 @@ protected: mutable OpenThreads::Mutex _glyphMapMutex; - osg::ref_ptr _texenv; - osg::ref_ptr _stateset; + StateSets _statesets; FontSizeGlyphMap _sizeGlyphMap; GlyphTextureList _glyphTextureList; diff --git a/include/osgText/Text b/include/osgText/Text index db497792f..fc6fbfc0f 100644 --- a/include/osgText/Text +++ b/include/osgText/Text @@ -36,16 +36,6 @@ public: virtual const char* className() const { return "Text"; } virtual const char* libraryName() const { return "osgText"; } - virtual void setFont(Font* font=0) { setFont(osg::ref_ptr(font)); }; - - /** Set the Font to use to render the text.*/ - virtual void setFont(osg::ref_ptr font); - - /** Set the font, loaded from the specified front file, to use to render the text, - * setFont("") sets the use of the default font. - * See the osgText::readFontFile function for how the font file will be located. */ - virtual void setFont(const std::string& fontfile) { TextBase::setFont(fontfile); } - /** * Turns off writing to the depth buffer when rendering text. This only affects text * with no backdrop or text using the DELAYED_DEPTH_WRITES implementation, since @@ -92,7 +82,9 @@ public: * buffer. But if you don't need the depth buffer updated for * your, this extra pass can be disabled by calling * enableDepthWrites(false).*/ - DELAYED_DEPTH_WRITES + DELAYED_DEPTH_WRITES, + + USE_SHADERS }; /** @@ -284,6 +276,8 @@ protected: virtual ~Text(); + virtual osg::StateSet* createStateSet(); + Font* getActiveFont(); const Font* getActiveFont() const; diff --git a/include/osgText/TextBase b/include/osgText/TextBase index 64fe785f1..dceac86b7 100644 --- a/include/osgText/TextBase +++ b/include/osgText/TextBase @@ -284,6 +284,10 @@ protected: virtual ~TextBase(); + virtual osg::StateSet* createStateSet(); + + virtual void assignStateSet(); + void initArraysAndBuffers(); osg::VertexArrayState* createVertexArrayState(osg::RenderInfo& renderInfo) const; diff --git a/src/osgText/Font.cpp b/src/osgText/Font.cpp index c09285046..c1aa0e077 100644 --- a/src/osgText/Font.cpp +++ b/src/osgText/Font.cpp @@ -32,81 +32,6 @@ using namespace osgText; using namespace std; -#if (!defined(OSG_GLES2_AVAILABLE) && !defined(OSG_GLES3_AVAILABLE)) - #define GLSL_VERSION_STR "330 core" - #define GLYPH_CMP "r" -#else - #define GLSL_VERSION_STR "300 es" - #define GLYPH_CMP "a" -#endif - -static const char* gl3_TextVertexShader = { - "#version " GLSL_VERSION_STR "\n" - "// gl3_TextVertexShader\n" - "#ifdef GL_ES\n" - " precision highp float;\n" - "#endif\n" - "in vec4 osg_Vertex;\n" - "in vec4 osg_Color;\n" - "in vec4 osg_MultiTexCoord0;\n" - "uniform mat4 osg_ModelViewProjectionMatrix;\n" - "out vec2 texCoord;\n" - "out vec4 vertexColor;\n" - "void main(void)\n" - "{\n" - " gl_Position = osg_ModelViewProjectionMatrix * osg_Vertex;\n" - " texCoord = osg_MultiTexCoord0.xy;\n" - " vertexColor = osg_Color; \n" - "}\n" -}; - -static const char* gl3_TextFragmentShader = { - "#version " GLSL_VERSION_STR "\n" - "// gl3_TextFragmentShader\n" - "#ifdef GL_ES\n" - " precision highp float;\n" - "#endif\n" - "uniform sampler2D glyphTexture;\n" - "in vec2 texCoord;\n" - "in vec4 vertexColor;\n" - "out vec4 color;\n" - "void main(void)\n" - "{\n" - " if (texCoord.x>=0.0) color = vertexColor * vec4(1.0, 1.0, 1.0, texture(glyphTexture, texCoord)." GLYPH_CMP ");\n" - " else color = vertexColor;\n" - "}\n" -}; - -static const char* gl2_TextVertexShader = { - "// gl2_TextVertexShader\n" - "#ifdef GL_ES\n" - " precision highp float;\n" - "#endif\n" - "varying vec2 texCoord;\n" - "varying vec4 vertexColor;\n" - "void main(void)\n" - "{\n" - " gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;\n" - " texCoord = gl_MultiTexCoord0.xy;\n" - " vertexColor = gl_Color; \n" - "}\n" -}; - -static const char* gl2_TextFragmentShader = { - "// gl2_TextFragmentShader\n" - "#ifdef GL_ES\n" - " precision highp float;\n" - "#endif\n" - "uniform sampler2D glyphTexture;\n" - "varying vec2 texCoord;\n" - "varying vec4 vertexColor;\n" - "void main(void)\n" - "{\n" - " if (texCoord.x>=0.0) gl_FragColor = vertexColor * vec4(1.0, 1.0, 1.0, texture2D(glyphTexture, texCoord).a);\n" - " else gl_FragColor = vertexColor;\n" - "}\n" -}; - osg::ref_ptr& Font::getDefaultFont() { static OpenThreads::Mutex s_DefaultFontMutex; @@ -317,47 +242,6 @@ Font::Font(FontImplementation* implementation): { setImplementation(implementation); - _texenv = new osg::TexEnv; - _stateset = new osg::StateSet; - - _stateset->setRenderingHint(osg::StateSet::TRANSPARENT_BIN); - _stateset->setMode(GL_LIGHTING, osg::StateAttribute::OFF); - _stateset->setMode(GL_BLEND, osg::StateAttribute::ON); - -#if defined(OSG_GL_FIXED_FUNCTION_AVAILABLE) - - OSG_INFO<<"Font::Font() Fixed function pipeline"<setTextureMode(0, GL_TEXTURE_2D, osg::StateAttribute::ON); -#endif - - osg::DisplaySettings::ShaderHint shaderHint = osg::DisplaySettings::instance()->getShaderHint(); - if (shaderHint==osg::DisplaySettings::SHADER_GL3 || shaderHint==osg::DisplaySettings::SHADER_GLES3) - { - - OSG_INFO<<"Font::Font() Setting up GL3 compatible shaders"< program = new osg::Program; - program->addShader(new osg::Shader(osg::Shader::VERTEX, gl3_TextVertexShader)); - program->addShader(new osg::Shader(osg::Shader::FRAGMENT, gl3_TextFragmentShader)); - _stateset->setAttributeAndModes(program.get()); - _stateset->addUniform(new osg::Uniform("glyphTexture", 0)); - - } - else if (shaderHint==osg::DisplaySettings::SHADER_GL2 || shaderHint==osg::DisplaySettings::SHADER_GLES2) - { - - - OSG_INFO<<"Font::Font() Setting up GL2 compatible shaders"< program = new osg::Program; - program->addShader(new osg::Shader(osg::Shader::VERTEX, gl2_TextVertexShader)); - program->addShader(new osg::Shader(osg::Shader::FRAGMENT, gl2_TextFragmentShader)); - _stateset->setAttributeAndModes(program.get()); - _stateset->addUniform(new osg::Uniform("glyphTexture", 0)); - - } - char *ptr; if( (ptr = getenv("OSG_MAX_TEXTURE_SIZE")) != 0) { @@ -531,9 +415,6 @@ void Font::setThreadSafeRefUnref(bool threadSafe) { osg::Object::setThreadSafeRefUnref(threadSafe); - if (_texenv.valid()) _texenv->setThreadSafeRefUnref(threadSafe); - if (_stateset.valid()) _stateset->setThreadSafeRefUnref(threadSafe); - for(GlyphTextureList::const_iterator itr=_glyphTextureList.begin(); itr!=_glyphTextureList.end(); ++itr) @@ -544,7 +425,12 @@ void Font::setThreadSafeRefUnref(bool threadSafe) void Font::resizeGLObjectBuffers(unsigned int maxSize) { - if (_stateset.valid()) _stateset->resizeGLObjectBuffers(maxSize); + for(StateSets::iterator itr = _statesets.begin(); + itr != _statesets.end(); + ++itr) + { + (*itr)->resizeGLObjectBuffers(maxSize); + } for(GlyphTextureList::const_iterator itr=_glyphTextureList.begin(); itr!=_glyphTextureList.end(); @@ -556,7 +442,12 @@ void Font::resizeGLObjectBuffers(unsigned int maxSize) void Font::releaseGLObjects(osg::State* state) const { - if (_stateset.valid()) _stateset->releaseGLObjects(state); + for(StateSets::const_iterator itr = _statesets.begin(); + itr != _statesets.end(); + ++itr) + { + (*itr)->releaseGLObjects(state); + } for(GlyphTextureList::const_iterator itr=_glyphTextureList.begin(); itr!=_glyphTextureList.end(); diff --git a/src/osgText/Text.cpp b/src/osgText/Text.cpp index 7cac3d0a9..f4cb94bd7 100644 --- a/src/osgText/Text.cpp +++ b/src/osgText/Text.cpp @@ -28,10 +28,92 @@ using namespace osg; using namespace osgText; +#if (!defined(OSG_GLES2_AVAILABLE) && !defined(OSG_GLES3_AVAILABLE)) + #define GLSL_VERSION_STR "330 core" + #define GLYPH_CMP "r" +#else + #define GLSL_VERSION_STR "300 es" + #define GLYPH_CMP "a" +#endif + +static const char* gl3_TextVertexShader = { + "#version " GLSL_VERSION_STR "\n" + "// gl3_TextVertexShader\n" + "#ifdef GL_ES\n" + " precision highp float;\n" + "#endif\n" + "in vec4 osg_Vertex;\n" + "in vec4 osg_Color;\n" + "in vec4 osg_MultiTexCoord0;\n" + "uniform mat4 osg_ModelViewProjectionMatrix;\n" + "out vec2 texCoord;\n" + "out vec4 vertexColor;\n" + "void main(void)\n" + "{\n" + " gl_Position = osg_ModelViewProjectionMatrix * osg_Vertex;\n" + " texCoord = osg_MultiTexCoord0.xy;\n" + " vertexColor = osg_Color; \n" + "}\n" +}; + +static const char* gl3_TextFragmentShader = { + "#version " GLSL_VERSION_STR "\n" + "// gl3_TextFragmentShader\n" + "#ifdef GL_ES\n" + " precision highp float;\n" + "#endif\n" + "uniform sampler2D glyphTexture;\n" + "in vec2 texCoord;\n" + "in vec4 vertexColor;\n" + "out vec4 color;\n" + "void main(void)\n" + "{\n" + " if (texCoord.x>=0.0) color = vertexColor * vec4(1.0, 1.0, 1.0, texture(glyphTexture, texCoord)." GLYPH_CMP ");\n" + " else color = vertexColor;\n" + "}\n" +}; + +static const char* gl2_TextVertexShader = { + "// gl2_TextVertexShader\n" + "#ifdef GL_ES\n" + " precision highp float;\n" + "#endif\n" + "varying vec2 texCoord;\n" + "varying vec4 vertexColor;\n" + "void main(void)\n" + "{\n" + " gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;\n" + " texCoord = gl_MultiTexCoord0.xy;\n" + " vertexColor = gl_Color; \n" + "}\n" +}; + +static const char* gl2_TextFragmentShader = { + "// gl2_TextFragmentShader\n" + "#ifdef GL_ES\n" + " precision highp float;\n" + "#endif\n" + "uniform sampler2D glyphTexture;\n" + "varying vec2 texCoord;\n" + "varying vec4 vertexColor;\n" + "void main(void)\n" + "{\n" + " if (texCoord.x>=0.0) gl_FragColor = vertexColor * vec4(1.0, 1.0, 1.0, texture2D(glyphTexture, texCoord).a);\n" + " else gl_FragColor = vertexColor;\n" + "}\n" +}; + + + + Text::Text(): _enableDepthWrites(true), _backdropType(NONE), +#if 1 _backdropImplementation(DELAYED_DEPTH_WRITES), +#else + _backdropImplementation(USE_SHADERS), +#endif _backdropHorizontalOffset(0.07f), _backdropVerticalOffset(0.07f), _backdropColor(0.0f, 0.0f, 0.0f, 1.0f), @@ -42,6 +124,8 @@ Text::Text(): _colorGradientTopRight(1.0f, 1.0f, 1.0f, 1.0f) { _supportsVertexBufferObjects = true; + + assignStateSet(); } Text::Text(const Text& text,const osg::CopyOp& copyop): @@ -65,21 +149,59 @@ Text::~Text() { } -void Text::setFont(osg::ref_ptr font) +osg::StateSet* Text::createStateSet() { - if (_font==font) return; + Font* activeFont = getActiveFont(); + if (!activeFont) return 0; - osg::StateSet* previousFontStateSet = _font.valid() ? _font->getStateSet() : Font::getDefaultFont()->getStateSet(); - osg::StateSet* newFontStateSet = font.valid() ? font->getStateSet() : Font::getDefaultFont()->getStateSet(); + Font::StateSets& statesets = activeFont->getCachedStateSets(); - if (getStateSet() == previousFontStateSet) + if (!statesets.empty()) { - setStateSet( newFontStateSet ); + return statesets.front().get(); } - TextBase::setFont(font); -} + osg::ref_ptr stateset = new osg::StateSet; + statesets.push_back(stateset.get()); + + stateset->setRenderingHint(osg::StateSet::TRANSPARENT_BIN); + stateset->setMode(GL_LIGHTING, osg::StateAttribute::OFF); + stateset->setMode(GL_BLEND, osg::StateAttribute::ON); + +#if defined(OSG_GL_FIXED_FUNCTION_AVAILABLE) + + OSG_INFO<<"Font::Font() Fixed function pipeline"<setTextureMode(0, GL_TEXTURE_2D, osg::StateAttribute::ON); +#endif + + osg::DisplaySettings::ShaderHint shaderHint = osg::DisplaySettings::instance()->getShaderHint(); + if (shaderHint==osg::DisplaySettings::SHADER_GL3 || shaderHint==osg::DisplaySettings::SHADER_GLES3) + { + OSG_INFO<<"Font::Font() Setting up GL3 compatible shaders"< program = new osg::Program; + program->addShader(new osg::Shader(osg::Shader::VERTEX, gl3_TextVertexShader)); + program->addShader(new osg::Shader(osg::Shader::FRAGMENT, gl3_TextFragmentShader)); + stateset->setAttributeAndModes(program.get()); + stateset->addUniform(new osg::Uniform("glyphTexture", 0)); + + } + else if (shaderHint==osg::DisplaySettings::SHADER_GL2 || shaderHint==osg::DisplaySettings::SHADER_GLES2) + { + OSG_INFO<<"Font::Font() Setting up GL2 compatible shaders"< program = new osg::Program; + program->addShader(new osg::Shader(osg::Shader::VERTEX, gl2_TextVertexShader)); + program->addShader(new osg::Shader(osg::Shader::FRAGMENT, gl2_TextFragmentShader)); + stateset->setAttributeAndModes(program.get()); + stateset->addUniform(new osg::Uniform("glyphTexture", 0)); + + } + + return stateset.release(); +} Font* Text::getActiveFont() { @@ -632,7 +754,7 @@ void Text::computePositionsImplementation() // Presumes the atc matrix is already up-to-date void Text::computeBackdropPositions() { - if(_backdropType == NONE) + if(_backdropType == NONE || _backdropImplementation == USE_SHADERS) { return; } @@ -1130,33 +1252,39 @@ void Text::drawImplementationSinglePass(osg::State& state, const osg::Vec4& colo const GlyphQuads& glyphquad = titr->second; -#if 1 if(_backdropType != NONE) { - unsigned int backdrop_index; - unsigned int max_backdrop_index; - if(_backdropType == OUTLINE) + if (_backdropImplementation != USE_SHADERS) { - backdrop_index = 1; - max_backdrop_index = 8; + unsigned int backdrop_index; + unsigned int max_backdrop_index; + if(_backdropType == OUTLINE) + { + backdrop_index = 1; + max_backdrop_index = 8; + } + else + { + backdrop_index = _backdropType+1; + max_backdrop_index = backdrop_index+1; + } + + if (max_backdrop_index>glyphquad._primitives.size()) max_backdrop_index=glyphquad._primitives.size(); + + state.disableColorPointer(); + state.Color(_backdropColor.r(),_backdropColor.g(),_backdropColor.b(),_backdropColor.a()); + + for( ; backdrop_index < max_backdrop_index; backdrop_index++) + { + glyphquad._primitives[backdrop_index]->draw(state, usingVertexBufferObjects); + } } else { - backdrop_index = _backdropType+1; - max_backdrop_index = backdrop_index+1; - } - - if (max_backdrop_index>glyphquad._primitives.size()) max_backdrop_index=glyphquad._primitives.size(); - - state.disableColorPointer(); - state.Color(_backdropColor.r(),_backdropColor.g(),_backdropColor.b(),_backdropColor.a()); - - for( ; backdrop_index < max_backdrop_index; backdrop_index++) - { - glyphquad._primitives[backdrop_index]->draw(state, usingVertexBufferObjects); + OSG_NOTICE<<"Using shaders for backdrop"<disableColorArray(state); diff --git a/src/osgText/TextBase.cpp b/src/osgText/TextBase.cpp index 5c5e5460e..c0da7b679 100644 --- a/src/osgText/TextBase.cpp +++ b/src/osgText/TextBase.cpp @@ -50,7 +50,6 @@ TextBase::TextBase(): _lineCount(0), _glyphNormalized(false) { - setStateSet(Font::getDefaultFont()->getStateSet()); setUseDisplayList(false); setSupportsDisplayList(false); @@ -89,6 +88,11 @@ TextBase::~TextBase() { } +osg::StateSet* TextBase::createStateSet() +{ + return 0; +} + void TextBase::initArraysAndBuffers() { _vbo = new osg::VertexBufferObject; @@ -182,6 +186,10 @@ void TextBase::setColor(const osg::Vec4& color) _color = color; } +void TextBase::assignStateSet() +{ + setStateSet(createStateSet()); +} void TextBase::setFont(osg::ref_ptr font) { @@ -189,6 +197,8 @@ void TextBase::setFont(osg::ref_ptr font) _font = font; + assignStateSet(); + computeGlyphRepresentation(); } From 7a50bdafe38b3c538ae3ce085b4c270652a49f5e Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Tue, 12 Sep 2017 16:03:35 +0100 Subject: [PATCH 073/327] Changed the margin computation to properly account of the Signed Distance Function data --- src/osgText/Glyph.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/osgText/Glyph.cpp b/src/osgText/Glyph.cpp index fd6d61f9c..efdf1cfb0 100644 --- a/src/osgText/Glyph.cpp +++ b/src/osgText/Glyph.cpp @@ -64,7 +64,10 @@ int GlyphTexture::compare(const osg::StateAttribute& rhs) const bool GlyphTexture::getSpaceForGlyph(Glyph* glyph, int& posX, int& posY) { int maxAxis = osg::maximum(glyph->s(), glyph->t()); - int margin = _margin + (int)((float)maxAxis * _marginRatio); + int margin_from_ratio = (int)((float)maxAxis * _marginRatio); + int search_distance = glyph->getFontResolution().second/8; + + int margin = _margin + osg::maximum(margin_from_ratio, search_distance); int width = glyph->s()+2*margin; int height = glyph->t()+2*margin; From 0d5a42f635d7e5b433995e9b86e91d87135a7e6e Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Tue, 12 Sep 2017 19:13:01 +0100 Subject: [PATCH 074/327] Added setting of the Text::BackdropImplementation type to USE_SHADERS when setting up shaders --- examples/osgfont/osgfont.cpp | 10 ++++- src/osgText/Text.cpp | 74 ++++++++++++++++++++++++++++++++++-- 2 files changed, 80 insertions(+), 4 deletions(-) diff --git a/examples/osgfont/osgfont.cpp b/examples/osgfont/osgfont.cpp index 2d37f4862..3c3fd6128 100644 --- a/examples/osgfont/osgfont.cpp +++ b/examples/osgfont/osgfont.cpp @@ -147,12 +147,20 @@ struct TextSettings font->setMaxAnisotropy(maxAnisotropy); font->setGlyphInterval(glyphInterval); font->setGyphTextureFeatures(glyphTextureFeatures); - text.setFont(font.get()); + // text.setFont(font.get()); text.setColor(textColor); text.setBackdropType(backdropType); text.setBackdropOffset(backdropOffset.x(), backdropOffset.y()); text.setBackdropColor(backdropColor); + + if (glyphTextureFeatures==osgText::GlyphTexture::ALL_FEATURES) + { + text.setBackdropImplementation(osgText::Text::USE_SHADERS); + } + + text.setFont(font.get()); + } std::string fontFilename; diff --git a/src/osgText/Text.cpp b/src/osgText/Text.cpp index f4cb94bd7..97e7c2c70 100644 --- a/src/osgText/Text.cpp +++ b/src/osgText/Text.cpp @@ -149,6 +149,8 @@ Text::~Text() { } +#include + osg::StateSet* Text::createStateSet() { Font* activeFont = getActiveFont(); @@ -156,13 +158,79 @@ osg::StateSet* Text::createStateSet() Font::StateSets& statesets = activeFont->getCachedStateSets(); - if (!statesets.empty()) + osg::StateSet::DefineList defineList; + if (_backdropType!=NONE && _backdropImplementation==USE_SHADERS) { - return statesets.front().get(); + std::stringstream ss; + + ss.str(""); + ss << "vec4("<<_backdropColor.r()<<", "<<_backdropColor.g()<<", "<<_backdropColor.b()<<", "<<_backdropColor.a()<<")"; + + defineList["BACKDROP_COLOR"] = osg::StateSet::DefinePair(ss.str(), osg::StateAttribute::ON); + + if (_backdropType==OUTLINE) + { + ss.str(""); + ss <<_backdropHorizontalOffset; + defineList["OUTLINE"] = osg::StateSet::DefinePair(ss.str(), osg::StateAttribute::ON); + } + else + { + osg::Vec2 offset(_backdropHorizontalOffset, _backdropVerticalOffset); + switch(_backdropType) + { + case(DROP_SHADOW_BOTTOM_RIGHT) : offset.set(_backdropHorizontalOffset, -_backdropVerticalOffset); break; + case(DROP_SHADOW_CENTER_RIGHT) : offset.set(_backdropHorizontalOffset, 0.0f); break; + case(DROP_SHADOW_TOP_RIGHT) : offset.set(_backdropHorizontalOffset, _backdropVerticalOffset); break; + case(DROP_SHADOW_BOTTOM_CENTER) : offset.set(0.0f, -_backdropVerticalOffset); break; + case(DROP_SHADOW_TOP_CENTER) : offset.set(0.0f, _backdropVerticalOffset); break; + case(DROP_SHADOW_BOTTOM_LEFT) : offset.set(-_backdropHorizontalOffset, -_backdropVerticalOffset); break; + case(DROP_SHADOW_CENTER_LEFT) : offset.set(-_backdropHorizontalOffset, 0.0f); break; + case(DROP_SHADOW_TOP_LEFT) : offset.set(-_backdropHorizontalOffset, _backdropVerticalOffset); break; + default : break; + } + + ss.str(""); + ss << "vec2("<first<<"] = "<second.first<getDefineList()==defineList) + { + // OSG_NOTICE<<"Text::createStateSet() : Matched DefineList, return StateSet "<get()<get(); + } + else + { + } + } + } + + // OSG_NOTICE<<"Text::createStateSet() : Not Matched DefineList, creating new StateSet"< stateset = new osg::StateSet; + stateset->setDefineList(defineList); + statesets.push_back(stateset.get()); stateset->setRenderingHint(osg::StateSet::TRANSPARENT_BIN); @@ -1281,7 +1349,7 @@ void Text::drawImplementationSinglePass(osg::State& state, const osg::Vec4& colo } else { - OSG_NOTICE<<"Using shaders for backdrop"< Date: Wed, 13 Sep 2017 11:08:51 +0100 Subject: [PATCH 075/327] Added --shadow-* command line variants to provide full control over the position of the text shadow --- examples/osgfont/osgfont.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/examples/osgfont/osgfont.cpp b/examples/osgfont/osgfont.cpp index 3c3fd6128..6ccff4f47 100644 --- a/examples/osgfont/osgfont.cpp +++ b/examples/osgfont/osgfont.cpp @@ -124,6 +124,16 @@ struct TextSettings if (arguments.read("--outline")) backdropType = osgText::Text::OUTLINE; if (arguments.read("--shadow")) backdropType = osgText::Text::DROP_SHADOW_BOTTOM_RIGHT; + if (arguments.read("--shadow-br")) backdropType = osgText::Text::DROP_SHADOW_BOTTOM_RIGHT; + if (arguments.read("--shadow-cr")) backdropType = osgText::Text::DROP_SHADOW_CENTER_RIGHT; + if (arguments.read("--shadow-tr")) backdropType = osgText::Text::DROP_SHADOW_TOP_RIGHT; + if (arguments.read("--shadow-bc")) backdropType = osgText::Text::DROP_SHADOW_BOTTOM_CENTER; + if (arguments.read("--shadow-tc")) backdropType = osgText::Text::DROP_SHADOW_TOP_CENTER; + if (arguments.read("--shadow-bl")) backdropType = osgText::Text::DROP_SHADOW_BOTTOM_LEFT; + if (arguments.read("--shadow-cl")) backdropType = osgText::Text::DROP_SHADOW_CENTER_LEFT; + if (arguments.read("--shadow-tl")) backdropType = osgText::Text::DROP_SHADOW_TOP_LEFT; + + float offset; if (arguments.read("--offset", offset)) backdropOffset.set(offset, offset); From 70b3a3a4421eff88d85def8d16ca10fb71831242 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 13 Sep 2017 11:09:56 +0100 Subject: [PATCH 076/327] Fixed of shadow --- src/osgText/Text.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/osgText/Text.cpp b/src/osgText/Text.cpp index 97e7c2c70..e930386c2 100644 --- a/src/osgText/Text.cpp +++ b/src/osgText/Text.cpp @@ -864,7 +864,7 @@ void Text::computeBackdropPositions() { float horizontal_shift_direction; float vertical_shift_direction; - switch(backdrop_index) + switch(backdrop_index-1) { case DROP_SHADOW_BOTTOM_RIGHT: { From a12a43d3528fcbdac92d0356dfe1629e25f6da25 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Thu, 14 Sep 2017 15:58:38 +0100 Subject: [PATCH 077/327] Impprovide the computation of the Signed Distance Field --- src/osgText/Glyph.cpp | 42 ++++++++++++++++++++++++++++++++++++++++-- src/osgText/Text.cpp | 2 +- 2 files changed, 41 insertions(+), 3 deletions(-) diff --git a/src/osgText/Glyph.cpp b/src/osgText/Glyph.cpp index efdf1cfb0..d418c5829 100644 --- a/src/osgText/Glyph.cpp +++ b/src/osgText/Glyph.cpp @@ -226,6 +226,8 @@ void GlyphTexture::copyGlyphImage(Glyph* glyph) float local_distance = sqrtf(float(radius*radius)+float(span*span)); if (center_value==0) local_distance += (0.5f-local_value_f)*local_multiplier; else local_distance += (local_value_f - 0.5f)*local_multiplier; + + if (local_distancecenter_value) + { + outline -= center_value; + } +#endif *(dest_ptr++) = outline; + outline_distance *= 2.0f; +#if 0 // compute the alpha vlaue of outline two texel thick outline = center_value; if (center_value<255) @@ -342,6 +365,21 @@ void GlyphTexture::copyGlyphImage(Glyph* glyph) else if (min_distancecenter_value) + { + outline -= center_value; + } +#endif *(dest_ptr++) = outline; // original alpha value from glyph image diff --git a/src/osgText/Text.cpp b/src/osgText/Text.cpp index e930386c2..3f102ea86 100644 --- a/src/osgText/Text.cpp +++ b/src/osgText/Text.cpp @@ -684,7 +684,7 @@ void Text::computeGlyphRepresentation() osg::Vec2 maxtc = glyph->getMaxTexCoord(); osg::Vec2 vDiff = maxtc - mintc; - float texelMargin = 4.0f; + float texelMargin = 5.0f; float fHorizTCMargin = texelMargin / glyph->getTexture()->getTextureWidth(); float fVertTCMargin = texelMargin / glyph->getTexture()->getTextureHeight(); From 5ade85217259877d5723c1dd1d3ecc0e8c3c49d3 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Fri, 15 Sep 2017 15:14:19 +0100 Subject: [PATCH 078/327] Added constant sizeing vs changing label size relatve to font resolution, controlled by --constant-size and --scale-size command line options. --- examples/osgfont/osgfont.cpp | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/examples/osgfont/osgfont.cpp b/examples/osgfont/osgfont.cpp index 6ccff4f47..7340a4251 100644 --- a/examples/osgfont/osgfont.cpp +++ b/examples/osgfont/osgfont.cpp @@ -75,7 +75,8 @@ struct TextSettings textColor(1.0f, 1.0f, 1.0f, 1.0f), backdropType(osgText::Text::NONE), backdropOffset(0.04f, 0.04f), - backdropColor(0.0f, 0.0f, 0.0f, 1.0f) + backdropColor(0.0f, 0.0f, 0.0f, 1.0f), + scaleFontSizeToFontResolution(false) { } @@ -142,6 +143,9 @@ struct TextSettings if (arguments.read("--bd-color", backdropColor.r(), backdropColor.g(), backdropColor.b(), backdropColor.a())) {} if (arguments.read("--bg-color", backgroundColor.r(), backgroundColor.g(), backgroundColor.b(), backgroundColor.a())) {} + if (arguments.read("--constant-size")) scaleFontSizeToFontResolution = false; + if (arguments.read("--scale-size")) scaleFontSizeToFontResolution = true; + } void setText(osgText::Text& text) @@ -188,6 +192,7 @@ struct TextSettings osg::Vec4 backdropColor; osg::Vec4 backgroundColor; Sizes sizes; + bool scaleFontSizeToFontResolution; }; osgText::Text* createLabel(const std::string& l, TextSettings& settings, unsigned int size) @@ -198,7 +203,13 @@ osgText::Text* createLabel(const std::string& l, TextSettings& settings, unsigne settings.setText(*label); - label->setCharacterSize(size); + + if (settings.scaleFontSizeToFontResolution) + { + label->setCharacterSize(size); + } + + label->setFontResolution(size, size); label->setPosition(pos); label->setAlignment(osgText::Text::LEFT_BOTTOM); @@ -210,7 +221,7 @@ osgText::Text* createLabel(const std::string& l, TextSettings& settings, unsigne // textInfo(label); - pos.y() += size + 10.0f; + pos.y() += label->getCharacterHeight()*2.0; return label; } From cc7cf54353d9393d86a92c7ecece0235133d3cfa Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Mon, 18 Sep 2017 18:09:15 +0100 Subject: [PATCH 079/327] Added support for subsititing $VAR_NAME entries in shaders to enable writing shaders that work across GLSL versions. --- include/osg/DisplaySettings | 15 ++++- include/osg/State | 5 +- src/osg/DisplaySettings.cpp | 110 ++++++++++++++++++++++++++++++------ src/osg/Shader.cpp | 2 +- src/osg/State.cpp | 68 +++++++++++++++++++++- 5 files changed, 179 insertions(+), 21 deletions(-) diff --git a/include/osg/DisplaySettings b/include/osg/DisplaySettings index 6821d14e9..393aa7415 100644 --- a/include/osg/DisplaySettings +++ b/include/osg/DisplaySettings @@ -20,6 +20,7 @@ #include #include +#include namespace osg { @@ -319,7 +320,9 @@ class OSG_EXPORT DisplaySettings : public osg::Referenced SHADER_GLES3 }; - void setShaderHint(ShaderHint hint) { _shaderHint = hint; } + /** set the ShaderHint to tells shader generating cdoes version to create. + * By default also OSG_GLSL_VERSION and OSG_PRECISION_FLOAT values that can get use directly in shaders using $OSG_GLSL_VERSION and $OSG_PRECISION_FLOAT respectively.*/ + void setShaderHint(ShaderHint hint, bool setShaderValues=true); ShaderHint getShaderHint() const { return _shaderHint; } @@ -358,6 +361,11 @@ class OSG_EXPORT DisplaySettings : public osg::Referenced /** helper function for computing the right eye view matrix.*/ virtual osg::Matrixd computeRightEyeViewImplementation(const osg::Matrixd& view, double eyeSeperationScale=1.0) const; + + void setValue(const std::string& name, const std::string& value); + + bool getValue(const std::string& name, std::string& value, bool use_getenv_fallback=true) const; + protected: virtual ~DisplaySettings(); @@ -422,6 +430,11 @@ class OSG_EXPORT DisplaySettings : public osg::Referenced OSXMenubarBehavior _OSXMenubarBehavior; + typedef std::map ValueMap; + + mutable OpenThreads::Mutex _valueMapMutex; + mutable ValueMap _valueMap; + }; } diff --git a/include/osg/State b/include/osg/State index ee5415660..97b6fec2a 100644 --- a/include/osg/State +++ b/include/osg/State @@ -823,9 +823,12 @@ class OSG_EXPORT State : public Referenced * during rendering. */ inline void setDisplaySettings(DisplaySettings* vs) { _displaySettings = vs; } - /** Get the DisplaySettings */ + /** Get the const DisplaySettings */ inline const DisplaySettings* getDisplaySettings() const { return _displaySettings.get(); } + /** Get the const DisplaySettings that is current active DisplaySettings to be used by osg::State, - if DisplaySettings is not directly assigned then fallback to DisplaySettings::instance(). */ + inline const DisplaySettings* getActiveDisplaySettings() const { return _displaySettings.valid() ? _displaySettings.get() : osg::DisplaySettings::instance().get(); } + /** Set flag for early termination of the draw traversal.*/ diff --git a/src/osg/DisplaySettings.cpp b/src/osg/DisplaySettings.cpp index 1df3e7e89..a07d7e58b 100644 --- a/src/osg/DisplaySettings.cpp +++ b/src/osg/DisplaySettings.cpp @@ -118,7 +118,8 @@ void DisplaySettings::setDisplaySettings(const DisplaySettings& vs) _swapMethod = vs._swapMethod; _vertexBufferHint = vs._vertexBufferHint; - _shaderHint = vs._shaderHint; + + setShaderHint(_shaderHint); _keystoneHint = vs._keystoneHint; _keystoneFileNames = vs._keystoneFileNames; @@ -250,23 +251,17 @@ void DisplaySettings::setDefaults() // _vertexBufferHint = VERTEX_ARRAY_OBJECT; #if defined(OSG_GLES3_AVAILABLE) - _shaderHint = SHADER_GLES3; - OSG_INFO<<"DisplaySettings::SHADER_GLES3"< lock(_valueMapMutex); + + _valueMap[name] = value; +} + +bool DisplaySettings::getValue(const std::string& name, std::string& value, bool use_getenv_fallback) const +{ + OpenThreads::ScopedLock lock(_valueMapMutex); + + ValueMap::iterator itr = _valueMap.find(name); + if (itr!=_valueMap.end()) + { + value = itr->second; + OSG_NOTICE<<"DisplaySettings::getValue("<getShaderSource(); - if (_shader->getType()==osg::Shader::VERTEX && (state.getUseVertexAttributeAliasing() || state.getUseModelViewAndProjectionUniforms())) + // if (_shader->getType()==osg::Shader::VERTEX && (state.getUseVertexAttributeAliasing() || state.getUseModelViewAndProjectionUniforms())) { state.convertVertexShaderSourceToOsgBuiltIns(source); } diff --git a/src/osg/State.cpp b/src/osg/State.cpp index c652d4cc6..e684c6ae7 100644 --- a/src/osg/State.cpp +++ b/src/osg/State.cpp @@ -1216,6 +1216,68 @@ namespace State_Utils source.insert(declPos, qualifier + declarationPrefix + newStr + std::string(";\n")); } } + + void replaceVar(const osg::State& state, std::string& str, std::string::size_type start_pos, std::string::size_type num_chars) + { + std::string var_str(str.substr(start_pos+1, num_chars-1)); + std::string value; + OSG_NOTICE<<" Need to replace : ["< Date: Tue, 19 Sep 2017 16:35:28 +0100 Subject: [PATCH 080/327] Added osgText/shaders to support greyscale and Signed Distance Field based text --- src/osg/State.cpp | 2 +- src/osgText/Text.cpp | 128 +++++------------- src/osgText/shaders/text_greyscale_frag.cpp | 33 +++++ src/osgText/shaders/text_sdf_frag.cpp | 136 ++++++++++++++++++++ src/osgText/shaders/text_vert.cpp | 13 ++ 5 files changed, 214 insertions(+), 98 deletions(-) create mode 100644 src/osgText/shaders/text_greyscale_frag.cpp create mode 100644 src/osgText/shaders/text_sdf_frag.cpp create mode 100644 src/osgText/shaders/text_vert.cpp diff --git a/src/osg/State.cpp b/src/osg/State.cpp index e684c6ae7..ffe6bc351 100644 --- a/src/osg/State.cpp +++ b/src/osg/State.cpp @@ -1345,7 +1345,7 @@ bool State::convertVertexShaderSourceToOsgBuiltIns(std::string& source) const } } - OSG_NOTICE<<"-------- Converted source "<=0.0) color = vertexColor * vec4(1.0, 1.0, 1.0, texture(glyphTexture, texCoord)." GLYPH_CMP ");\n" - " else color = vertexColor;\n" - "}\n" -}; - -static const char* gl2_TextVertexShader = { - "// gl2_TextVertexShader\n" - "#ifdef GL_ES\n" - " precision highp float;\n" - "#endif\n" - "varying vec2 texCoord;\n" - "varying vec4 vertexColor;\n" - "void main(void)\n" - "{\n" - " gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;\n" - " texCoord = gl_MultiTexCoord0.xy;\n" - " vertexColor = gl_Color; \n" - "}\n" -}; - -static const char* gl2_TextFragmentShader = { - "// gl2_TextFragmentShader\n" - "#ifdef GL_ES\n" - " precision highp float;\n" - "#endif\n" - "uniform sampler2D glyphTexture;\n" - "varying vec2 texCoord;\n" - "varying vec4 vertexColor;\n" - "void main(void)\n" - "{\n" - " if (texCoord.x>=0.0) gl_FragColor = vertexColor * vec4(1.0, 1.0, 1.0, texture2D(glyphTexture, texCoord).a);\n" - " else gl_FragColor = vertexColor;\n" - "}\n" -}; - - - - Text::Text(): _enableDepthWrites(true), _backdropType(NONE), @@ -237,35 +159,47 @@ osg::StateSet* Text::createStateSet() stateset->setMode(GL_LIGHTING, osg::StateAttribute::OFF); stateset->setMode(GL_BLEND, osg::StateAttribute::ON); -#if defined(OSG_GL_FIXED_FUNCTION_AVAILABLE) - OSG_INFO<<"Font::Font() Fixed function pipeline"<getGlyphTextureFeatures()="<getGlyphTextureFeatures()<setTextureMode(0, GL_TEXTURE_2D, osg::StateAttribute::ON); -#endif + #if defined(OSG_GL_FIXED_FUNCTION_AVAILABLE) osg::DisplaySettings::ShaderHint shaderHint = osg::DisplaySettings::instance()->getShaderHint(); - if (shaderHint==osg::DisplaySettings::SHADER_GL3 || shaderHint==osg::DisplaySettings::SHADER_GLES3) + if (activeFont->getGlyphTextureFeatures()==GlyphTexture::GREYSCALE && shaderHint==osg::DisplaySettings::SHADER_NONE) { - OSG_INFO<<"Font::Font() Setting up GL3 compatible shaders"< program = new osg::Program; - program->addShader(new osg::Shader(osg::Shader::VERTEX, gl3_TextVertexShader)); - program->addShader(new osg::Shader(osg::Shader::FRAGMENT, gl3_TextFragmentShader)); - stateset->setAttributeAndModes(program.get()); - stateset->addUniform(new osg::Uniform("glyphTexture", 0)); + OSG_INFO<<"Font::Font() Fixed function pipeline"<setTextureMode(0, GL_TEXTURE_2D, osg::StateAttribute::ON); + return stateset.release(); } - else if (shaderHint==osg::DisplaySettings::SHADER_GL2 || shaderHint==osg::DisplaySettings::SHADER_GLES2) + #endif + + // set up the StateSet to use shaders + stateset->addUniform(new osg::Uniform("glyphTexture", 0)); + + osg::ref_ptr program = new osg::Program; + stateset->setAttributeAndModes(program.get()); + { - OSG_INFO<<"Font::Font() Setting up GL2 compatible shaders"< program = new osg::Program; - program->addShader(new osg::Shader(osg::Shader::VERTEX, gl2_TextVertexShader)); - program->addShader(new osg::Shader(osg::Shader::FRAGMENT, gl2_TextFragmentShader)); - stateset->setAttributeAndModes(program.get()); - stateset->addUniform(new osg::Uniform("glyphTexture", 0)); + #include "shaders/text_vert.cpp" + program->addShader(osgDB::readRefShaderFileWithFallback(osg::Shader::VERTEX, "shaders/text.vert", text_vert)); + } + if (activeFont->getGlyphTextureFeatures()==GlyphTexture::GREYSCALE) + { + OSG_NOTICE<<"Using shaders/text_greyscale.frag"<addShader(osgDB::readRefShaderFileWithFallback(osg::Shader::VERTEX, "shaders/text_greyscale.frag", text_greyscale_frag)); + } + else + { + OSG_NOTICE<<"Using shaders/text_sdf.frag"<addShader(osgDB::readRefShaderFileWithFallback(osg::Shader::VERTEX, "shaders/text_sdf.frag", text_sdf_frag)); } return stateset.release(); diff --git a/src/osgText/shaders/text_greyscale_frag.cpp b/src/osgText/shaders/text_greyscale_frag.cpp new file mode 100644 index 000000000..51738a2cf --- /dev/null +++ b/src/osgText/shaders/text_greyscale_frag.cpp @@ -0,0 +1,33 @@ +char text_greyscale_frag[] = "$OSG_GLSL_VERSION\n" + "$OSG_GLSL_PRECISION_FLOAT\n" + "\n" + "#pragma import_defines( BACKDROP_COLOR, OUTLINE, ALPHA )\n" + "\n" + "#if __VERSION__>=130\n" + " #define TEXTURE texture\n" + " out vec4 osg_FragColor;\n" + "#else\n" + " #define TEXTURE texture2D\n" + " #define osg_FragColor gl_FragColor\n" + "#endif\n" + "\n" + "uniform sampler2D glyphTexture;\n" + "\n" + "$OSG_VARYING_IN vec2 texCoord;\n" + "$OSG_VARYING_IN vec4 vertexColor;\n" + "\n" + "#if !defined(GL_ES) && __VERSION__>=130\n" + " #define ALPHA r\n" + "#else\n" + " #define ALPHA a\n" + "#endif\n" + "\n" + "void main(void)\n" + "{\n" + " float alpha = TEXTURE(glyphTexture, texCoord).ALPHA;\n" + "\n" + " if (alpha==0.0) discard;\n" + "\n" + " osg_FragColor = vec4(vertexColor.rgb, alpha);\n" + "}\n" + "\n"; diff --git a/src/osgText/shaders/text_sdf_frag.cpp b/src/osgText/shaders/text_sdf_frag.cpp new file mode 100644 index 000000000..379bcba46 --- /dev/null +++ b/src/osgText/shaders/text_sdf_frag.cpp @@ -0,0 +1,136 @@ +char text_sdf_frag[] = "$OSG_GLSL_VERSION\n" + "$OSG_GLSL_PRECISION_FLOAT\n" + "\n" + "#pragma import_defines( BACKDROP_COLOR, OUTLINE )\n" + "\n" + "#if __VERSION__>=400\n" + " #define osg_TextureQueryLOD textureQueryLod\n" + " #define USE_SIGNED_DISTNACE_FIELD\n" + "#else\n" + " #extension GL_ARB_texture_query_lod : enable\n" + " #ifdef GL_ARB_texture_query_lod\n" + " #define osg_TextureQueryLOD textureQueryLOD\n" + " #define USE_SIGNED_DISTNACE_FIELD\n" + " #endif\n" + "#endif\n" + "\n" + "#undef USE_SIGNED_DISTNACE_FIELD\n" + "\n" + "#if __VERSION__>=130\n" + " #define TEXTURE texture\n" + " out vec4 osg_FragColor;\n" + "#else\n" + " #define TEXTURE texture2D\n" + " #define osg_FragColor gl_FragColor\n" + "#endif\n" + "\n" + "uniform sampler2D glyphTexture;\n" + "\n" + "$OSG_VARYING_IN vec2 texCoord;\n" + "$OSG_VARYING_IN vec4 vertexColor;\n" + "\n" + "vec4 textureColor()\n" + "{\n" + " #ifdef OUTLINE\n" + " // glyph.rgba = (signed_distance, thin_outline, thick_outline, glyph_alpha)\n" + " vec4 glyph = TEXTURE(glyphTexture, texCoord);\n" + "\n" + " #if 0\n" + " float blend_ratio = OUTLINE*17.0;\n" + "\n" + " float outline_alpha = 0.0;\n" + " if (blend_ratio>2.0) outline_alpha = glyph.b;\n" + " else if (blend_ratio>1.0) outline_alpha = mix(glyph.g, glyph.b, blend_ratio-1.0);\n" + " else outline_alpha = glyph.g*blend_ratio;\n" + " #else\n" + " float outline_alpha = glyph.g;\n" + " //float outline_alpha = glyph.b;\n" + " #endif\n" + "\n" + " float alpha = glyph.a+outline_alpha;\n" + " if (alpha>1.0) alpha = 1.0;\n" + "\n" + " return vec4( vertexColor.rgb*glyph.a + BACKDROP_COLOR.rgb*outline_alpha, alpha);\n" + "\n" + " #else\n" + " float alpha = TEXTURE(glyphTexture, texCoord).a;\n" + " if (alpha==0.0) vec4(0.0, 0.0, 0.0, 0.0);\n" + " return vec4(vertexColor.rgb, alpha);\n" + " #endif\n" + "}\n" + "\n" + "#ifdef USE_SIGNED_DISTNACE_FIELD\n" + "vec4 distanceFieldColor()\n" + "{\n" + " float center_alpha = TEXTURE(glyphTexture, texCoord).r;\n" + "\n" + " float blend_width = 0.2;\n" + " float distance_scale = 5.0;\n" + " float edge_distance = (center_alpha-0.5)*distance_scale;\n" + "\n" + " #ifdef OUTLINE\n" + " float outline_width = OUTLINE*17.0;//0.5;\n" + " if (edge_distance>blend_width*0.5)\n" + " {\n" + " return vertexColor;\n" + " }\n" + " else if (edge_distance>-blend_width*0.5)\n" + " {\n" + " return mix(vertexColor, BACKDROP_COLOR, (blend_width*0.5-edge_distance)/(blend_width));\n" + " }\n" + " else if (edge_distance>(blend_width-outline_width))\n" + " {\n" + " return BACKDROP_COLOR;\n" + " }\n" + " else if (edge_distance>-outline_width)\n" + " {\n" + " return vec4(BACKDROP_COLOR.rgb, (outline_width+edge_distance)/blend_width);\n" + " }\n" + " else\n" + " {\n" + " return vec4(0.0, 0.0, 0.0, 0.0);\n" + " }\n" + " #else\n" + " if (edge_distance>0.0)\n" + " {\n" + " return vertexColor;\n" + " }\n" + " else if (edge_distance>-blend_width)\n" + " {\n" + " return vec4(vertexColor.rgb, 1.0+edge_distance/blend_width);\n" + " }\n" + " else\n" + " {\n" + " return vec4(0.0, 0.0, 0.0, 0.0);\n" + " }\n" + " #endif\n" + "}\n" + "#endif\n" + "\n" + "\n" + "void main(void)\n" + "{\n" + "\n" + "#ifdef USE_SIGNED_DISTNACE_FIELD\n" + "\n" + " float mml = osg_TextureQueryLOD(glyphTexture, texCoord).x;\n" + "\n" + " float near_transition = 0.0;\n" + " float far_transition = 1.0;\n" + "\n" + " vec4 color;\n" + " if (mmlfar_transition) color = textureColor();\n" + " else color = mix(distanceFieldColor(), textureColor(), (mml-near_transition)/(far_transition-near_transition));\n" + "\n" + "#else\n" + "\n" + " vec4 color = textureColor();\n" + "\n" + "#endif\n" + "\n" + " if (color.a==0.0) discard;\n" + "\n" + " osg_FragColor = color;\n" + "}\n" + "\n"; diff --git a/src/osgText/shaders/text_vert.cpp b/src/osgText/shaders/text_vert.cpp new file mode 100644 index 000000000..72506284f --- /dev/null +++ b/src/osgText/shaders/text_vert.cpp @@ -0,0 +1,13 @@ +char text_vert[] = "$OSG_GLSL_VERSION\n" + "$OSG_PRECISION_FLOAT\n" + "\n" + "$OSG_VARYING_OUT vec2 texCoord;\n" + "$OSG_VARYING_OUT vec4 vertexColor;\n" + "\n" + "void main(void)\n" + "{\n" + " gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;\n" + " texCoord = gl_MultiTexCoord0.xy;\n" + " vertexColor = gl_Color;\n" + "}\n" + "\n"; From 370ca2b8a3dd0b6ab8df913b9f9e5cb8144ef6ad Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Tue, 19 Sep 2017 17:01:58 +0100 Subject: [PATCH 081/327] Fixed X11 GLES2 build --- include/osgViewer/api/X11/GraphicsWindowX11 | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/include/osgViewer/api/X11/GraphicsWindowX11 b/include/osgViewer/api/X11/GraphicsWindowX11 index 1efb990fe..fe40d7f8c 100644 --- a/include/osgViewer/api/X11/GraphicsWindowX11 +++ b/include/osgViewer/api/X11/GraphicsWindowX11 @@ -37,10 +37,11 @@ class OSGVIEWER_EXPORT GraphicsWindowX11 : public osgViewer::GraphicsWindow, pub _parent(0), _window(0), _visualInfo(0), - _fbConfig(0), #ifdef OSG_USE_EGL _eglDisplay(0), _eglSurface(0), + #else + _fbConfig(0), #endif _currentCursor(0), _initialized(false), @@ -177,11 +178,12 @@ class OSGVIEWER_EXPORT GraphicsWindowX11 : public osgViewer::GraphicsWindow, pub Window _parent; Window _window; XVisualInfo* _visualInfo; - GLXFBConfig _fbConfig; #ifdef OSG_USE_EGL EGLDisplay _eglDisplay; EGLSurface _eglSurface; + #else + GLXFBConfig _fbConfig; #endif Cursor _currentCursor; From fafa468fea781fb890e9a1369e98cfaba12ee7b1 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Tue, 19 Sep 2017 17:07:59 +0100 Subject: [PATCH 082/327] Fixed OSG_PRECISION_FLOAT usage --- src/osgText/shaders/text_greyscale_frag.cpp | 2 +- src/osgText/shaders/text_sdf_frag.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/osgText/shaders/text_greyscale_frag.cpp b/src/osgText/shaders/text_greyscale_frag.cpp index 51738a2cf..cc1625bf7 100644 --- a/src/osgText/shaders/text_greyscale_frag.cpp +++ b/src/osgText/shaders/text_greyscale_frag.cpp @@ -1,5 +1,5 @@ char text_greyscale_frag[] = "$OSG_GLSL_VERSION\n" - "$OSG_GLSL_PRECISION_FLOAT\n" + "$OSG_PRECISION_FLOAT\n" "\n" "#pragma import_defines( BACKDROP_COLOR, OUTLINE, ALPHA )\n" "\n" diff --git a/src/osgText/shaders/text_sdf_frag.cpp b/src/osgText/shaders/text_sdf_frag.cpp index 379bcba46..d04362a0f 100644 --- a/src/osgText/shaders/text_sdf_frag.cpp +++ b/src/osgText/shaders/text_sdf_frag.cpp @@ -1,5 +1,5 @@ char text_sdf_frag[] = "$OSG_GLSL_VERSION\n" - "$OSG_GLSL_PRECISION_FLOAT\n" + "$OSG_PRECISION_FLOAT\n" "\n" "#pragma import_defines( BACKDROP_COLOR, OUTLINE )\n" "\n" @@ -14,7 +14,7 @@ char text_sdf_frag[] = "$OSG_GLSL_VERSION\n" " #endif\n" "#endif\n" "\n" - "#undef USE_SIGNED_DISTNACE_FIELD\n" + "//#undef USE_SIGNED_DISTNACE_FIELD\n" "\n" "#if __VERSION__>=130\n" " #define TEXTURE texture\n" From 420094174e591dcb105b91dc944ea3edbefe0771 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 20 Sep 2017 11:01:04 +0100 Subject: [PATCH 083/327] Added commented out debug output to make it easier to test in future --- src/osg/Shader.cpp | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/osg/Shader.cpp b/src/osg/Shader.cpp index 167d016b1..1b11789fc 100644 --- a/src/osg/Shader.cpp +++ b/src/osg/Shader.cpp @@ -633,7 +633,7 @@ void Shader::PerContextShader::compileShader(osg::State& state) GLint compiled = GL_FALSE; - // OSG_NOTICE<<"Compiling PerContextShader "<(versionLine.c_str()); sourceText[1] = reinterpret_cast(_defineStr.c_str()); sourceText[2] = reinterpret_cast(source.c_str()); _extensions->glShaderSource( _glShaderHandle, 3, sourceText, NULL ); + + + // OSG_NOTICE<<" Version Line : ["<(_defineStr.c_str()); sourceText[1] = reinterpret_cast(source.c_str()); _extensions->glShaderSource( _glShaderHandle, 2, sourceText, NULL ); + + // OSG_NOTICE<<" DefineStr : ["<glCompileShader( _glShaderHandle ); From b0829cc3521cc85f49d3d3bc0ce9316e44025989 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 20 Sep 2017 11:02:06 +0100 Subject: [PATCH 084/327] Updated text_sdf.frag shader to handle GLES2+ versions --- src/osgText/shaders/text_sdf_frag.cpp | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/src/osgText/shaders/text_sdf_frag.cpp b/src/osgText/shaders/text_sdf_frag.cpp index d04362a0f..38f508f09 100644 --- a/src/osgText/shaders/text_sdf_frag.cpp +++ b/src/osgText/shaders/text_sdf_frag.cpp @@ -1,19 +1,23 @@ char text_sdf_frag[] = "$OSG_GLSL_VERSION\n" - "$OSG_PRECISION_FLOAT\n" "\n" "#pragma import_defines( BACKDROP_COLOR, OUTLINE )\n" "\n" - "#if __VERSION__>=400\n" - " #define osg_TextureQueryLOD textureQueryLod\n" - " #define USE_SIGNED_DISTNACE_FIELD\n" - "#else\n" - " #extension GL_ARB_texture_query_lod : enable\n" - " #ifdef GL_ARB_texture_query_lod\n" - " #define osg_TextureQueryLOD textureQueryLOD\n" + "#if !defined(GL_ES)\n" + " #if __VERSION__>=400\n" + " #define osg_TextureQueryLOD textureQueryLod\n" " #define USE_SIGNED_DISTNACE_FIELD\n" + " #else\n" + " #extension GL_ARB_texture_query_lod : enable\n" + " #ifdef GL_ARB_texture_query_lod\n" + " #define osg_TextureQueryLOD textureQueryLOD\n" + " #define USE_SIGNED_DISTNACE_FIELD\n" + " #endif\n" " #endif\n" "#endif\n" "\n" + "\n" + "$OSG_PRECISION_FLOAT\n" + "\n" "//#undef USE_SIGNED_DISTNACE_FIELD\n" "\n" "#if __VERSION__>=130\n" @@ -35,7 +39,7 @@ char text_sdf_frag[] = "$OSG_GLSL_VERSION\n" " // glyph.rgba = (signed_distance, thin_outline, thick_outline, glyph_alpha)\n" " vec4 glyph = TEXTURE(glyphTexture, texCoord);\n" "\n" - " #if 0\n" + " #if 1\n" " float blend_ratio = OUTLINE*17.0;\n" "\n" " float outline_alpha = 0.0;\n" From e8eb1ee0c7e27b5961986bff1a655427a4a8fc53 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 20 Sep 2017 14:29:05 +0100 Subject: [PATCH 085/327] Added Text::assignStateSet() and usage to make sure the correct StateSet is setup for each combination of backdrop settings --- include/osgText/Text | 2 ++ src/osgText/Text.cpp | 17 +++++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/include/osgText/Text b/include/osgText/Text index fc6fbfc0f..0d991a805 100644 --- a/include/osgText/Text +++ b/include/osgText/Text @@ -278,6 +278,8 @@ protected: virtual osg::StateSet* createStateSet(); + void assignStateSet(); + Font* getActiveFont(); const Font* getActiveFont() const; diff --git a/src/osgText/Text.cpp b/src/osgText/Text.cpp index 25585d0d6..665147bd7 100644 --- a/src/osgText/Text.cpp +++ b/src/osgText/Text.cpp @@ -205,6 +205,11 @@ osg::StateSet* Text::createStateSet() return stateset.release(); } +void Text::assignStateSet() +{ + setStateSet(createStateSet()); +} + Font* Text::getActiveFont() { return _font.valid() ? _font.get() : Font::getDefaultFont().get(); @@ -1454,6 +1459,9 @@ void Text::setBackdropType(BackdropType type) if (_backdropType==type) return; _backdropType = type; + + assignStateSet(); + computeGlyphRepresentation(); } @@ -1462,6 +1470,9 @@ void Text::setBackdropImplementation(BackdropImplementation implementation) if (_backdropImplementation==implementation) return; _backdropImplementation = implementation; + + assignStateSet(); + computeGlyphRepresentation(); } @@ -1470,6 +1481,9 @@ void Text::setBackdropOffset(float offset) { _backdropHorizontalOffset = offset; _backdropVerticalOffset = offset; + + assignStateSet(); + computeGlyphRepresentation(); } @@ -1477,6 +1491,9 @@ void Text::setBackdropOffset(float horizontal, float vertical) { _backdropHorizontalOffset = horizontal; _backdropVerticalOffset = vertical; + + assignStateSet(); + computeGlyphRepresentation(); } From fb0a995d7b7f8c2e9cb756ceec484470f1ceab9b Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 20 Sep 2017 14:30:23 +0100 Subject: [PATCH 086/327] cleaned up exmple --- examples/osgfont/osgfont.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/examples/osgfont/osgfont.cpp b/examples/osgfont/osgfont.cpp index 7340a4251..460b6280d 100644 --- a/examples/osgfont/osgfont.cpp +++ b/examples/osgfont/osgfont.cpp @@ -161,7 +161,6 @@ struct TextSettings font->setMaxAnisotropy(maxAnisotropy); font->setGlyphInterval(glyphInterval); font->setGyphTextureFeatures(glyphTextureFeatures); - // text.setFont(font.get()); text.setColor(textColor); text.setBackdropType(backdropType); From 78811462f1c8651dbcf465379fd80323d0b6aa18 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 20 Sep 2017 15:51:03 +0100 Subject: [PATCH 087/327] Added support for only enabling SignedDistanceField shader path when font resolution is greater than 16. --- include/osgText/Text | 2 -- src/osgText/Text.cpp | 17 +++++++++++----- src/osgText/TextBase.cpp | 3 +++ src/osgText/shaders/text_sdf_frag.cpp | 29 +++++++++++++++------------ 4 files changed, 31 insertions(+), 20 deletions(-) diff --git a/include/osgText/Text b/include/osgText/Text index 0d991a805..fc6fbfc0f 100644 --- a/include/osgText/Text +++ b/include/osgText/Text @@ -278,8 +278,6 @@ protected: virtual osg::StateSet* createStateSet(); - void assignStateSet(); - Font* getActiveFont(); const Font* getActiveFont() const; diff --git a/src/osgText/Text.cpp b/src/osgText/Text.cpp index 665147bd7..efb9312a5 100644 --- a/src/osgText/Text.cpp +++ b/src/osgText/Text.cpp @@ -117,6 +117,18 @@ osg::StateSet* Text::createStateSet() defineList["SHADOW"] = osg::StateSet::DefinePair(ss.str(), osg::StateAttribute::ON); } + + if (_fontSize.second>16) + { + OSG_NOTICE<<"Requesting SDF support _fontSize.second="<<_fontSize.second<=400\n" - " #define osg_TextureQueryLOD textureQueryLod\n" - " #define USE_SIGNED_DISTNACE_FIELD\n" - " #else\n" - " #extension GL_ARB_texture_query_lod : enable\n" - " #ifdef GL_ARB_texture_query_lod\n" - " #define osg_TextureQueryLOD textureQueryLOD\n" - " #define USE_SIGNED_DISTNACE_FIELD\n" + "#ifdef SIGNED_DISTNACE_FIELD\n" + "\n" + " #if !defined(GL_ES)\n" + " #if __VERSION__>=400\n" + " #define osg_TextureQueryLOD textureQueryLod\n" + " #define SIGNED_DISTNACE_FIELD_SUPPORTED\n" + " #else\n" + " #extension GL_ARB_texture_query_lod : enable\n" + " #ifdef GL_ARB_texture_query_lod\n" + " #define osg_TextureQueryLOD textureQueryLOD\n" + " #define USE_SIGNED_DISTNACE_FIELD_SUPPORTED\n" + " #endif\n" " #endif\n" " #endif\n" - "#endif\n" "\n" + "#endif\n" "\n" "$OSG_PRECISION_FLOAT\n" "\n" @@ -63,7 +66,7 @@ char text_sdf_frag[] = "$OSG_GLSL_VERSION\n" " #endif\n" "}\n" "\n" - "#ifdef USE_SIGNED_DISTNACE_FIELD\n" + "#ifdef USE_SIGNED_DISTNACE_FIELD_SUPPORTED\n" "vec4 distanceFieldColor()\n" "{\n" " float center_alpha = TEXTURE(glyphTexture, texCoord).r;\n" @@ -115,7 +118,7 @@ char text_sdf_frag[] = "$OSG_GLSL_VERSION\n" "void main(void)\n" "{\n" "\n" - "#ifdef USE_SIGNED_DISTNACE_FIELD\n" + "#ifdef USE_SIGNED_DISTNACE_FIELD_SUPPORTED\n" "\n" " float mml = osg_TextureQueryLOD(glyphTexture, texCoord).x;\n" "\n" From e565a5e1c310b344e1b2c3b3797b5c33b95b5f7e Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 20 Sep 2017 16:51:30 +0100 Subject: [PATCH 088/327] Removed no longer used code paths --- src/osgText/Glyph.cpp | 24 ++---------------------- 1 file changed, 2 insertions(+), 22 deletions(-) diff --git a/src/osgText/Glyph.cpp b/src/osgText/Glyph.cpp index d418c5829..58f25aca4 100644 --- a/src/osgText/Glyph.cpp +++ b/src/osgText/Glyph.cpp @@ -327,16 +327,6 @@ void GlyphTexture::copyGlyphImage(Glyph* glyph) float outline_distance = max_distance/3.0f; -#if 0 - // compute the alpha value of outline, one texel thick - unsigned char outline = center_value; - if (center_value<255) - { - if (min_distance Date: Thu, 21 Sep 2017 14:32:17 +0100 Subject: [PATCH 089/327] Umproved SDF computation. --- src/osgText/Glyph.cpp | 121 ++++++++++++++++++++++++++++-------------- 1 file changed, 80 insertions(+), 41 deletions(-) diff --git a/src/osgText/Glyph.cpp b/src/osgText/Glyph.cpp index 58f25aca4..4b0658a36 100644 --- a/src/osgText/Glyph.cpp +++ b/src/osgText/Glyph.cpp @@ -175,6 +175,11 @@ void GlyphTexture::copyGlyphImage(Glyph* glyph) if ((upper+glyph->getTexturePositionY())>=dest_rows) upper = dest_rows-glyph->getTexturePositionY()-1; + bool use_SDF_for_Outline = true; + + float outer_outline_distance = float(search_distance); + float inner_outline_distance = float(outer_outline_distance)/2.0f; + for(int dr=lower; dr<=upper; ++dr) { for(int dc=left; dc<=right; ++dc) @@ -184,11 +189,17 @@ void GlyphTexture::copyGlyphImage(Glyph* glyph) unsigned char center_value = 0; if (dr>=0 && dr=0 && dc0 && center_value<255) { + inner_max_value = 255; + outer_max_value = 255; + if (center_value_f>=0.5f) { min_distance = center_value_f-0.5f; @@ -204,7 +215,7 @@ void GlyphTexture::copyGlyphImage(Glyph* glyph) { for(int radius=1; radiusinner_max_value && local_distance<=inner_outline_distance) inner_max_value = local_value; + if (local_value>outer_max_value && local_distance<=outer_outline_distance) outer_max_value = local_value; } } { // top + int dx = span; + int dy = radius; + + int c = dc+dx; + int r = dr+dy; + + unsigned char local_value = 0; + if (r>=0 && r=0 && cabs(dy)) ? D/float(abs(dx)) : D/float(abs(dy)); + + float local_distance = sqrtf(float(radius*radius)+float(span*span)); + if (center_value==0) local_distance += (0.5f-local_value_f)*local_multiplier; + else local_distance += (local_value_f - 0.5f)*local_multiplier; + + if (local_distanceinner_max_value && local_distance<=inner_outline_distance) inner_max_value = local_value; + if (local_value>outer_max_value && local_distance<=outer_outline_distance) outer_max_value = local_value; + } + } + + { + // right int dx = radius; int dy = span; @@ -249,42 +291,21 @@ void GlyphTexture::copyGlyphImage(Glyph* glyph) float local_multiplier = (abs(dx)>abs(dy)) ? D/float(abs(dx)) : D/float(abs(dy)); float local_distance = sqrtf(float(radius*radius)+float(span*span)); + if (center_value==0) local_distance += (0.5f-local_value_f)*local_multiplier; else local_distance += (local_value_f - 0.5f)*local_multiplier; if (local_distance=0 && r=0 && cabs(dy)) ? D/float(abs(dx)) : D/float(abs(dy)); - - float local_distance = sqrtf(float(radius*radius)+float(span*span)); - if (center_value==0) local_distance += (0.5f-local_value_f)*local_multiplier; - else local_distance += (local_value_f - 0.5f)*local_multiplier; - - if (local_distanceinner_max_value && local_distance<=inner_outline_distance) inner_max_value = local_value; + if (local_value>outer_max_value && local_distance<=outer_outline_distance) outer_max_value = local_value; } } { // bottom - int dx = -radius; - int dy = -span; + int dx = span; + int dy = -radius; int c = dc+dx; int r = dr+dy; @@ -303,6 +324,9 @@ void GlyphTexture::copyGlyphImage(Glyph* glyph) else local_distance += (local_value_f - 0.5f)*local_multiplier; if (local_distanceinner_max_value && local_distance<=inner_outline_distance) inner_max_value = local_value; + if (local_value>outer_max_value && local_distance<=outer_outline_distance) outer_max_value = local_value; } } } @@ -329,16 +353,24 @@ void GlyphTexture::copyGlyphImage(Glyph* glyph) // compute the alpha value of outline, one texel thick unsigned char outline = 0; - if (center_value<255) + + if (use_SDF_for_Outline) { - float inner_outline = outline_distance-1.0f; - if (min_distancecenter_value) + { + outline -= center_value; + } } - if (outline>center_value) + else { - outline -= center_value; + outline = inner_max_value-center_value; } *(dest_ptr++) = outline; @@ -348,16 +380,23 @@ void GlyphTexture::copyGlyphImage(Glyph* glyph) // compute the alpha value of outline, one texel thick outline = 0; - if (center_value<255) + if (use_SDF_for_Outline) { - float inner_outline = outline_distance-1.0f; - if (min_distancecenter_value) + { + outline -= center_value; + } } - if (outline>center_value) + else { - outline -= center_value; + outline = outer_max_value-center_value; } *(dest_ptr++) = outline; From 957a7d4e9251962c0532881f770a8981b3bed71f Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Thu, 21 Sep 2017 14:35:31 +0100 Subject: [PATCH 090/327] Moved enabling/disabling of SDF so it's done regardless of whether a backdrop is used. --- src/osgText/Text.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/osgText/Text.cpp b/src/osgText/Text.cpp index efb9312a5..c00cbb2eb 100644 --- a/src/osgText/Text.cpp +++ b/src/osgText/Text.cpp @@ -118,17 +118,17 @@ osg::StateSet* Text::createStateSet() defineList["SHADOW"] = osg::StateSet::DefinePair(ss.str(), osg::StateAttribute::ON); } - if (_fontSize.second>16) - { - OSG_NOTICE<<"Requesting SDF support _fontSize.second="<<_fontSize.second<getAuthenticationDetails(hostname.substr(0, pos)); + } + } + // configure authentication if required. + if (details != NULL) + { + OSG_NOTICE << "Passing in password = " << details->password << std::endl; - const osgDB::AuthenticationDetails* details = authenticationMap ? - authenticationMap->getAuthenticationDetails(hostname) : - 0; - - // configure authentication if required. - if (details) - { - OSG_NOTICE<<"Passing in password = "<password<_username = details->username; - image->_password = details->password; + image->_username = details->username; + image->_password = details->password; + } } - if (options && !options->getOptionString().empty()) { image->_optionString = options->getOptionString(); From a1f519cbecbd23a5e173be65c2568112678f1b50 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Thu, 21 Sep 2017 15:41:21 +0100 Subject: [PATCH 092/327] Removed debug info --- examples/osglogo/osglogo.cpp | 46 +++++++++++++++++------------------- include/osgText/TextBase | 3 +++ src/osg/DisplaySettings.cpp | 4 ++-- src/osg/State.cpp | 10 -------- src/osgText/Text.cpp | 2 +- 5 files changed, 28 insertions(+), 37 deletions(-) diff --git a/examples/osglogo/osglogo.cpp b/examples/osglogo/osglogo.cpp index 18699462d..67d1eff5d 100644 --- a/examples/osglogo/osglogo.cpp +++ b/examples/osglogo/osglogo.cpp @@ -41,6 +41,9 @@ #include + +static bool s_useSDF = false; + class MyBillboardTransform : public osg::PositionAttitudeTransform { public: @@ -147,6 +150,13 @@ osg:: Node* createTextBelow(const osg::BoundingBox& bb, const std::string& label text->setFont(font); text->setFontResolution(64,64); + + if (s_useSDF) + { + text->getFont()->setGyphTextureFeatures(osgText::GlyphTexture::ALL_FEATURES); + text->setBackdropImplementation(osgText::Text::USE_SHADERS); + } + text->setAlignment(osgText::Text::CENTER_CENTER); text->setAxisAlignment(osgText::Text::XZ_PLANE); text->setPosition(bb.center()-osg::Vec3(0.0f,0.0f,(bb.zMax()-bb.zMin()))); @@ -174,48 +184,36 @@ osg:: Node* createTextLeft(const osg::BoundingBox& bb, const std::string& label, text->setFont(font); text->setFontResolution(110,120); + if (s_useSDF) + { + text->getFont()->setGyphTextureFeatures(osgText::GlyphTexture::ALL_FEATURES); + text->setBackdropImplementation(osgText::Text::USE_SHADERS); + } + text->setAlignment(osgText::Text::RIGHT_CENTER); text->setAxisAlignment(osgText::Text::XZ_PLANE); text->setCharacterSize((bb.zMax()-bb.zMin())*1.0f); + text->setPosition(bb.center()-osg::Vec3((bb.xMax()-bb.xMin()),-(bb.yMax()-bb.yMin())*0.5f,(bb.zMax()-bb.zMin())*0.1f)); //text->setColor(osg::Vec4(0.37f,0.48f,0.67f,1.0f)); // Neil's original OSG colour text->setColor(osg::Vec4(0.20f,0.45f,0.60f,1.0f)); // OGL logo colour + text->setText(label); -#if 1 text->setBackdropType(osgText::Text::OUTLINE); -// text->setBackdropType(osgText::Text::DROP_SHADOW_BOTTOM_RIGHT); - - text->setBackdropImplementation(osgText::Text::POLYGON_OFFSET); -// text->setBackdropImplementation(osgText::Text::NO_DEPTH_BUFFER); -// text->setBackdropImplementation(osgText::Text::DEPTH_RANGE); -// text->setBackdropImplementation(osgText::Text::STENCIL_BUFFER); - - text->setBackdropOffset(0.05f); + text->setBackdropOffset(0.03f); text->setBackdropColor(osg::Vec4(0.0f, 0.0f, 0.5f, 1.0f)); -#endif - -#if 1 text->setColorGradientMode(osgText::Text::OVERALL); osg::Vec4 lightblue(0.30f,0.6f,0.90f,1.0f); osg::Vec4 blue(0.10f,0.30f,0.40f,1.0f); text->setColorGradientCorners(lightblue, blue, blue, lightblue); -#else - text->setColorGradientMode(osgText::Text::OVERALL); - osg::Vec4 light = osg::Vec4(0.0f, 1.0f, 1.0f, 1.0f); - osg::Vec4 dark = osg::Vec4(0.0f, 0.0f, 0.5f, 1.0f); - text->setColorGradientCorners(light, dark, dark, light); -// text->setColorGradientCorners(dark, light, light, dark); -#endif geode->addDrawable( text ); if (!subscript.empty()) { - //osgText::Text* subscript = new osgText::Text(new osgText::TextureFont(font,45)); - osgText::Text* subscriptText = new osgText::Text; subscriptText->setFont(font); subscriptText->setText(subscript); @@ -353,9 +351,6 @@ osg:: Node* createBoxNo5No2(const osg::BoundingBox& bb,float chordRatio) osg:: Node* createBackdrop(const osg::Vec3& corner,const osg::Vec3& top,const osg::Vec3& right) { - - - osg::Geometry* geom = new osg::Geometry; osg::Vec3 normal = (corner-top)^(right-corner); @@ -475,6 +470,9 @@ int main( int argc, char **argv ) return 1; } + + while(arguments.read("--sdf")) { s_useSDF = true; } + std::string label = "OpenSceneGraph"; std::string subscript = ""; diff --git a/include/osgText/TextBase b/include/osgText/TextBase index dceac86b7..d75e41ff2 100644 --- a/include/osgText/TextBase +++ b/include/osgText/TextBase @@ -53,6 +53,9 @@ public: virtual void setFont(const std::string& fontfile); /** Get the font. Return 0 if default is being used.*/ + Font* getFont() { return _font.get(); } + + /** Get the const font. Return 0 if default is being used.*/ const Font* getFont() const { return _font.get(); } diff --git a/src/osg/DisplaySettings.cpp b/src/osg/DisplaySettings.cpp index a07d7e58b..8346d11ed 100644 --- a/src/osg/DisplaySettings.cpp +++ b/src/osg/DisplaySettings.cpp @@ -1155,7 +1155,7 @@ bool DisplaySettings::getValue(const std::string& name, std::string& value, bool if (itr!=_valueMap.end()) { value = itr->second; - OSG_NOTICE<<"DisplaySettings::getValue("< Date: Thu, 21 Sep 2017 15:52:07 +0100 Subject: [PATCH 093/327] Added support for toggling on use of the new SignedDistanceFunction function now built into osgText, just use --sdf to enable. --- examples/osglogo/osglogo.cpp | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/examples/osglogo/osglogo.cpp b/examples/osglogo/osglogo.cpp index 67d1eff5d..db0a4bff0 100644 --- a/examples/osglogo/osglogo.cpp +++ b/examples/osglogo/osglogo.cpp @@ -184,11 +184,6 @@ osg:: Node* createTextLeft(const osg::BoundingBox& bb, const std::string& label, text->setFont(font); text->setFontResolution(110,120); - if (s_useSDF) - { - text->getFont()->setGyphTextureFeatures(osgText::GlyphTexture::ALL_FEATURES); - text->setBackdropImplementation(osgText::Text::USE_SHADERS); - } text->setAlignment(osgText::Text::RIGHT_CENTER); text->setAxisAlignment(osgText::Text::XZ_PLANE); @@ -198,17 +193,23 @@ osg:: Node* createTextLeft(const osg::BoundingBox& bb, const std::string& label, //text->setColor(osg::Vec4(0.37f,0.48f,0.67f,1.0f)); // Neil's original OSG colour text->setColor(osg::Vec4(0.20f,0.45f,0.60f,1.0f)); // OGL logo colour - text->setText(label); - text->setBackdropType(osgText::Text::OUTLINE); text->setBackdropOffset(0.03f); text->setBackdropColor(osg::Vec4(0.0f, 0.0f, 0.5f, 1.0f)); + if (s_useSDF) + { + text->getFont()->setGyphTextureFeatures(osgText::GlyphTexture::ALL_FEATURES); + text->setBackdropImplementation(osgText::Text::USE_SHADERS); + } + text->setColorGradientMode(osgText::Text::OVERALL); osg::Vec4 lightblue(0.30f,0.6f,0.90f,1.0f); osg::Vec4 blue(0.10f,0.30f,0.40f,1.0f); text->setColorGradientCorners(lightblue, blue, blue, lightblue); + text->setText(label); + geode->addDrawable( text ); From 4b6722ab44bd87db9a75aa7169b89d016df50701 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Thu, 21 Sep 2017 16:01:27 +0100 Subject: [PATCH 094/327] Added assignStateSet() to Text::setBackgroundColor() --- examples/osglogo/osglogo.cpp | 12 +++++++++--- src/osgText/Text.cpp | 2 ++ 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/examples/osglogo/osglogo.cpp b/examples/osglogo/osglogo.cpp index db0a4bff0..61526fb06 100644 --- a/examples/osglogo/osglogo.cpp +++ b/examples/osglogo/osglogo.cpp @@ -193,9 +193,7 @@ osg:: Node* createTextLeft(const osg::BoundingBox& bb, const std::string& label, //text->setColor(osg::Vec4(0.37f,0.48f,0.67f,1.0f)); // Neil's original OSG colour text->setColor(osg::Vec4(0.20f,0.45f,0.60f,1.0f)); // OGL logo colour - text->setBackdropType(osgText::Text::OUTLINE); - text->setBackdropOffset(0.03f); - text->setBackdropColor(osg::Vec4(0.0f, 0.0f, 0.5f, 1.0f)); + OSG_NOTICE<setBackdropImplementation(osgText::Text::USE_SHADERS); } + OSG_NOTICE<setBackdropType(osgText::Text::OUTLINE); + text->setBackdropOffset(0.03f); + text->setBackdropColor(osg::Vec4(0.0f, 0.0f, 0.5f, 1.0f)); + + OSG_NOTICE<setColorGradientMode(osgText::Text::OVERALL); osg::Vec4 lightblue(0.30f,0.6f,0.90f,1.0f); osg::Vec4 blue(0.10f,0.30f,0.40f,1.0f); diff --git a/src/osgText/Text.cpp b/src/osgText/Text.cpp index 227976e28..d67f2dbf1 100644 --- a/src/osgText/Text.cpp +++ b/src/osgText/Text.cpp @@ -1507,6 +1507,8 @@ void Text::setBackdropOffset(float horizontal, float vertical) void Text::setBackdropColor(const osg::Vec4& color) { _backdropColor = color; + + assignStateSet(); } void Text::setColorGradientMode(ColorGradientMode mode) From b6bb0caf8df5684e3bfc6819adae6b013edf3db5 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Thu, 21 Sep 2017 16:04:10 +0100 Subject: [PATCH 095/327] Removed debug output --- examples/osglogo/osglogo.cpp | 19 ++++++------------- src/osgText/Text.cpp | 2 +- 2 files changed, 7 insertions(+), 14 deletions(-) diff --git a/examples/osglogo/osglogo.cpp b/examples/osglogo/osglogo.cpp index 61526fb06..9d02e6141 100644 --- a/examples/osglogo/osglogo.cpp +++ b/examples/osglogo/osglogo.cpp @@ -185,30 +185,23 @@ osg:: Node* createTextLeft(const osg::BoundingBox& bb, const std::string& label, text->setFont(font); text->setFontResolution(110,120); - text->setAlignment(osgText::Text::RIGHT_CENTER); - text->setAxisAlignment(osgText::Text::XZ_PLANE); - text->setCharacterSize((bb.zMax()-bb.zMin())*1.0f); - - text->setPosition(bb.center()-osg::Vec3((bb.xMax()-bb.xMin()),-(bb.yMax()-bb.yMin())*0.5f,(bb.zMax()-bb.zMin())*0.1f)); - //text->setColor(osg::Vec4(0.37f,0.48f,0.67f,1.0f)); // Neil's original OSG colour - text->setColor(osg::Vec4(0.20f,0.45f,0.60f,1.0f)); // OGL logo colour - - OSG_NOTICE<getFont()->setGyphTextureFeatures(osgText::GlyphTexture::ALL_FEATURES); text->setBackdropImplementation(osgText::Text::USE_SHADERS); } - OSG_NOTICE<setAlignment(osgText::Text::RIGHT_CENTER); + text->setAxisAlignment(osgText::Text::XZ_PLANE); + text->setCharacterSize((bb.zMax()-bb.zMin())*1.0f); + + text->setPosition(bb.center()-osg::Vec3((bb.xMax()-bb.xMin()),-(bb.yMax()-bb.yMin())*0.5f,(bb.zMax()-bb.zMin())*0.1f)); + text->setColor(osg::Vec4(0.20f,0.45f,0.60f,1.0f)); // OGL logo colour text->setBackdropType(osgText::Text::OUTLINE); text->setBackdropOffset(0.03f); text->setBackdropColor(osg::Vec4(0.0f, 0.0f, 0.5f, 1.0f)); - OSG_NOTICE<setColorGradientMode(osgText::Text::OVERALL); osg::Vec4 lightblue(0.30f,0.6f,0.90f,1.0f); osg::Vec4 blue(0.10f,0.30f,0.40f,1.0f); diff --git a/src/osgText/Text.cpp b/src/osgText/Text.cpp index d67f2dbf1..fea327527 100644 --- a/src/osgText/Text.cpp +++ b/src/osgText/Text.cpp @@ -131,7 +131,7 @@ osg::StateSet* Text::createStateSet() OSG_NOTICE<<"Disabling SDF support _fontSize.second="<<_fontSize.second< Date: Fri, 22 Sep 2017 08:39:38 +0200 Subject: [PATCH 096/327] addShader fix --- src/osgText/Text.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/osgText/Text.cpp b/src/osgText/Text.cpp index fea327527..7b1afe6dc 100644 --- a/src/osgText/Text.cpp +++ b/src/osgText/Text.cpp @@ -204,14 +204,14 @@ osg::StateSet* Text::createStateSet() OSG_NOTICE<<"Using shaders/text_greyscale.frag"<addShader(osgDB::readRefShaderFileWithFallback(osg::Shader::VERTEX, "shaders/text_greyscale.frag", text_greyscale_frag)); + program->addShader(osgDB::readRefShaderFileWithFallback(osg::Shader::FRAGMENT, "shaders/text_greyscale.frag", text_greyscale_frag)); } else { OSG_NOTICE<<"Using shaders/text_sdf.frag"<addShader(osgDB::readRefShaderFileWithFallback(osg::Shader::VERTEX, "shaders/text_sdf.frag", text_sdf_frag)); + program->addShader(osgDB::readRefShaderFileWithFallback(osg::Shader::FRAGMENT, "shaders/text_sdf.frag", text_sdf_frag)); } return stateset.release(); From cf2b5d030c43dc90d0c8b96916d5c2d05deb873b Mon Sep 17 00:00:00 2001 From: "konstantin.matveyev" Date: Sun, 17 Sep 2017 18:48:32 +0300 Subject: [PATCH 097/327] tellg call removed from StreamOperator's checkStream function, because reading of files (readNodeFile etc.) with tellg on 'every iter' is approximately 100 times slower on Emscripten platform --- src/osgDB/StreamOperator.cpp | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/osgDB/StreamOperator.cpp b/src/osgDB/StreamOperator.cpp index a1ee9a749..d46eef4e9 100644 --- a/src/osgDB/StreamOperator.cpp +++ b/src/osgDB/StreamOperator.cpp @@ -16,21 +16,14 @@ using namespace osgDB; -static long long prev_tellg = 0; - void InputIterator::checkStream() const { if (_in->rdstate()&_in->failbit) { OSG_NOTICE<<"InputIterator::checkStream() : _in->rdstate() "<<_in->rdstate()<<", "<<_in->failbit<tellg() = "<<_in->tellg()< Date: Fri, 22 Sep 2017 11:38:43 +0300 Subject: [PATCH 098/327] LineSegmentIntersector fixed: intersection ratio remaped to the range of LineSegment => correct order in multiset of intersections --- src/osgUtil/LineSegmentIntersector.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/osgUtil/LineSegmentIntersector.cpp b/src/osgUtil/LineSegmentIntersector.cpp index 5a6b69afe..08faade5e 100644 --- a/src/osgUtil/LineSegmentIntersector.cpp +++ b/src/osgUtil/LineSegmentIntersector.cpp @@ -299,13 +299,17 @@ struct IntersectFunctor return; } - Vec3 in = v0*r0 + v1*r1 + v2*r2; + // Remap ratio into the range of LineSegment + const osg::Vec3d& lsStart = _settings->_lineSegIntersector->getStart(); + const osg::Vec3d& lsEnd = _settings->_lineSegIntersector->getEnd(); + double remap_ratio = ((_start - lsStart).length() + r*_length)/(lsEnd - lsStart).length(); + + Vec3 in = lsStart*(1.0 - remap_ratio) + lsEnd*remap_ratio; // == v0*r0 + v1*r1 + v2*r2; Vec3 normal = E1^E2; normal.normalize(); - LineSegmentIntersector::Intersection hit; - hit.ratio = r; + hit.ratio = remap_ratio; hit.matrix = _settings->_iv->getModelMatrix(); hit.nodePath = _settings->_iv->getNodePath(); hit.drawable = _settings->_drawable; From 708ae1c076f7552a531350980644a290458a7ed1 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Fri, 22 Sep 2017 12:22:58 +0100 Subject: [PATCH 099/327] Fixed rendering old sytel outline --- src/osgText/Text.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/osgText/Text.cpp b/src/osgText/Text.cpp index 7b1afe6dc..b83557955 100644 --- a/src/osgText/Text.cpp +++ b/src/osgText/Text.cpp @@ -1275,7 +1275,7 @@ void Text::drawImplementationSinglePass(osg::State& state, const osg::Vec4& colo if(_backdropType == OUTLINE) { backdrop_index = 1; - max_backdrop_index = 8; + max_backdrop_index = backdrop_index+8; } else { From 6d4128324bff4dd2ba74952aec975a5506a38df0 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Tue, 26 Sep 2017 10:42:47 +0100 Subject: [PATCH 100/327] Improvements to SDF and outline generation --- src/osgText/Glyph.cpp | 39 ++++++++++++++++++++++----------------- src/osgText/Text.cpp | 11 ++++++----- 2 files changed, 28 insertions(+), 22 deletions(-) diff --git a/src/osgText/Glyph.cpp b/src/osgText/Glyph.cpp index 4b0658a36..e9236e41e 100644 --- a/src/osgText/Glyph.cpp +++ b/src/osgText/Glyph.cpp @@ -164,7 +164,8 @@ void GlyphTexture::copyGlyphImage(Glyph* glyph) int upper = glyph->t()+search_distance; float multiplier = 1.0/255.0f; - float max_distance = sqrtf(float(search_distance*search_distance)*2.0f); + + float max_distance = glyph->getFontResolution().first/4; int num_channels = TEXTURE_IMAGE_NUM_CHANNELS; @@ -177,8 +178,12 @@ void GlyphTexture::copyGlyphImage(Glyph* glyph) bool use_SDF_for_Outline = true; - float outer_outline_distance = float(search_distance); - float inner_outline_distance = float(outer_outline_distance)/2.0f; + float outer_outline_distance = float(glyph->getFontResolution().first)*0.14f; + float inner_outline_distance = outer_outline_distance*0.5f; + + unsigned char full_on = 255; + unsigned char mid_point = full_on/2; + float mid_point_f = float(mid_point)*multiplier; for(int dr=lower; dr<=upper; ++dr) { @@ -195,19 +200,19 @@ void GlyphTexture::copyGlyphImage(Glyph* glyph) float center_value_f = center_value*multiplier; float min_distance = FLT_MAX; - if (center_value>0 && center_value<255) + if (center_value>0 && center_value=0.5f) + if (center_value_f>=mid_point_f) { - min_distance = center_value_f-0.5f; + min_distance = center_value_f-mid_point_f; value = 128+(min_distance/max_distance)*127; } else { - min_distance = 0.5f-center_value_f; + min_distance = mid_point_f-center_value_f; value = 127-(min_distance/max_distance)*127; } } @@ -235,8 +240,8 @@ void GlyphTexture::copyGlyphImage(Glyph* glyph) float local_multiplier = (abs(dx)>abs(dy)) ? D/float(abs(dx)) : D/float(abs(dy)); float local_distance = sqrtf(float(radius*radius)+float(span*span)); - if (center_value==0) local_distance += (0.5f-local_value_f)*local_multiplier; - else local_distance += (local_value_f - 0.5f)*local_multiplier; + if (center_value==0) local_distance += (mid_point_f-local_value_f)*local_multiplier; + else local_distance += (local_value_f - mid_point_f)*local_multiplier; if (local_distanceabs(dy)) ? D/float(abs(dx)) : D/float(abs(dy)); float local_distance = sqrtf(float(radius*radius)+float(span*span)); - if (center_value==0) local_distance += (0.5f-local_value_f)*local_multiplier; - else local_distance += (local_value_f - 0.5f)*local_multiplier; + if (center_value==0) local_distance += (mid_point_f-local_value_f)*local_multiplier; + else local_distance += (local_value_f - mid_point_f)*local_multiplier; if (local_distanceabs(dy)) ? D/float(abs(dx)) : D/float(abs(dy)); float local_distance = sqrtf(float(radius*radius)+float(span*span)); - if (center_value==0) local_distance += (0.5f-local_value_f)*local_multiplier; - else local_distance += (local_value_f - 0.5f)*local_multiplier; + if (center_value==0) local_distance += (mid_point_f-local_value_f)*local_multiplier; + else local_distance += (local_value_f - mid_point_f)*local_multiplier; if (local_distance8) + if (_fontSize.second>16/* && _backdropImplementation==USE_SHADERS*/) { OSG_NOTICE<<"Requesting SDF support _fontSize.second="<<_fontSize.second<getDefineList()==defineList) { - // OSG_NOTICE<<"Text::createStateSet() : Matched DefineList, return StateSet "<get()<get()<get(); } else @@ -159,7 +160,7 @@ osg::StateSet* Text::createStateSet() } } - // OSG_NOTICE<<"Text::createStateSet() : Not Matched DefineList, creating new StateSet"< stateset = new osg::StateSet; @@ -463,6 +464,8 @@ void Text::computeGlyphRepresentation() float hr = _characterHeight; float wr = hr/getCharacterAspectRatio(); + float texelMargin = 5.0f; + for(String::iterator itr=_text.begin(); itr!=_text.end(); ) @@ -630,8 +633,6 @@ void Text::computeGlyphRepresentation() osg::Vec2 maxtc = glyph->getMaxTexCoord(); osg::Vec2 vDiff = maxtc - mintc; - float texelMargin = 5.0f; - float fHorizTCMargin = texelMargin / glyph->getTexture()->getTextureWidth(); float fVertTCMargin = texelMargin / glyph->getTexture()->getTextureHeight(); float fHorizQuadMargin = vDiff.x() == 0.0f ? 0.0f : width * fHorizTCMargin / vDiff.x(); From 845e1d446381fa3f4b34347f1f5403933a478419 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Tue, 26 Sep 2017 10:44:14 +0100 Subject: [PATCH 101/327] Updated shaders using latest OpenSceneGraph-Data/shader versions --- src/osgText/shaders/text_greyscale_frag.cpp | 10 ++++++---- src/osgText/shaders/text_sdf_frag.cpp | 21 ++++++++++----------- 2 files changed, 16 insertions(+), 15 deletions(-) diff --git a/src/osgText/shaders/text_greyscale_frag.cpp b/src/osgText/shaders/text_greyscale_frag.cpp index cc1625bf7..6d561fbce 100644 --- a/src/osgText/shaders/text_greyscale_frag.cpp +++ b/src/osgText/shaders/text_greyscale_frag.cpp @@ -16,10 +16,12 @@ char text_greyscale_frag[] = "$OSG_GLSL_VERSION\n" "$OSG_VARYING_IN vec2 texCoord;\n" "$OSG_VARYING_IN vec4 vertexColor;\n" "\n" - "#if !defined(GL_ES) && __VERSION__>=130\n" - " #define ALPHA r\n" - "#else\n" - " #define ALPHA a\n" + "#ifndef ALPHA\n" + " #if !defined(GL_ES) && __VERSION__>=130\n" + " #define ALPHA r\n" + " #else\n" + " #define ALPHA a\n" + " #endif\n" "#endif\n" "\n" "void main(void)\n" diff --git a/src/osgText/shaders/text_sdf_frag.cpp b/src/osgText/shaders/text_sdf_frag.cpp index 0db10880d..c357073e0 100644 --- a/src/osgText/shaders/text_sdf_frag.cpp +++ b/src/osgText/shaders/text_sdf_frag.cpp @@ -12,7 +12,7 @@ char text_sdf_frag[] = "$OSG_GLSL_VERSION\n" " #extension GL_ARB_texture_query_lod : enable\n" " #ifdef GL_ARB_texture_query_lod\n" " #define osg_TextureQueryLOD textureQueryLOD\n" - " #define USE_SIGNED_DISTNACE_FIELD_SUPPORTED\n" + " #define SIGNED_DISTNACE_FIELD_SUPPORTED\n" " #endif\n" " #endif\n" " #endif\n" @@ -42,16 +42,15 @@ char text_sdf_frag[] = "$OSG_GLSL_VERSION\n" " // glyph.rgba = (signed_distance, thin_outline, thick_outline, glyph_alpha)\n" " vec4 glyph = TEXTURE(glyphTexture, texCoord);\n" "\n" - " #if 1\n" - " float blend_ratio = OUTLINE*17.0;\n" + " #ifdef SIGNED_DISTNACE_FIELD_SUPPORTED\n" + " float blend_ratio = OUTLINE*20.0; // assume inner boundary starts at OUTLINE==0.05\n" "\n" " float outline_alpha = 0.0;\n" " if (blend_ratio>2.0) outline_alpha = glyph.b;\n" " else if (blend_ratio>1.0) outline_alpha = mix(glyph.g, glyph.b, blend_ratio-1.0);\n" " else outline_alpha = glyph.g*blend_ratio;\n" " #else\n" - " float outline_alpha = glyph.g;\n" - " //float outline_alpha = glyph.b;\n" + " float outline_alpha = (OUTLINE<=0.075) ? glyph.g : glyph.b;\n" " #endif\n" "\n" " float alpha = glyph.a+outline_alpha;\n" @@ -66,17 +65,17 @@ char text_sdf_frag[] = "$OSG_GLSL_VERSION\n" " #endif\n" "}\n" "\n" - "#ifdef USE_SIGNED_DISTNACE_FIELD_SUPPORTED\n" + "#ifdef SIGNED_DISTNACE_FIELD_SUPPORTED\n" "vec4 distanceFieldColor()\n" "{\n" " float center_alpha = TEXTURE(glyphTexture, texCoord).r;\n" "\n" - " float blend_width = 0.2;\n" - " float distance_scale = 5.0;\n" + " float blend_width = 0.005;\n" + " float distance_scale = 0.25;\n" " float edge_distance = (center_alpha-0.5)*distance_scale;\n" "\n" " #ifdef OUTLINE\n" - " float outline_width = OUTLINE*17.0;//0.5;\n" + " float outline_width = OUTLINE*0.5;;\n" " if (edge_distance>blend_width*0.5)\n" " {\n" " return vertexColor;\n" @@ -118,12 +117,12 @@ char text_sdf_frag[] = "$OSG_GLSL_VERSION\n" "void main(void)\n" "{\n" "\n" - "#ifdef USE_SIGNED_DISTNACE_FIELD_SUPPORTED\n" + "#ifdef SIGNED_DISTNACE_FIELD_SUPPORTED\n" "\n" " float mml = osg_TextureQueryLOD(glyphTexture, texCoord).x;\n" "\n" " float near_transition = 0.0;\n" - " float far_transition = 1.0;\n" + " float far_transition = near_transition+1.0;\n" "\n" " vec4 color;\n" " if (mml Date: Tue, 26 Sep 2017 10:57:09 +0100 Subject: [PATCH 102/327] Updated wiht OpenSceneGraph-Data/shader version that introduced use of textureLOD to reduce aliasing artifacts with SDF --- src/osgText/shaders/text_sdf_frag.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/osgText/shaders/text_sdf_frag.cpp b/src/osgText/shaders/text_sdf_frag.cpp index c357073e0..9f32c1e9a 100644 --- a/src/osgText/shaders/text_sdf_frag.cpp +++ b/src/osgText/shaders/text_sdf_frag.cpp @@ -25,9 +25,11 @@ char text_sdf_frag[] = "$OSG_GLSL_VERSION\n" "\n" "#if __VERSION__>=130\n" " #define TEXTURE texture\n" + " #define TEXTURELOD textureLod\n" " out vec4 osg_FragColor;\n" "#else\n" " #define TEXTURE texture2D\n" + " #define TEXTURELOD texture2DLod\n" " #define osg_FragColor gl_FragColor\n" "#endif\n" "\n" @@ -68,7 +70,7 @@ char text_sdf_frag[] = "$OSG_GLSL_VERSION\n" "#ifdef SIGNED_DISTNACE_FIELD_SUPPORTED\n" "vec4 distanceFieldColor()\n" "{\n" - " float center_alpha = TEXTURE(glyphTexture, texCoord).r;\n" + " float center_alpha = TEXTURELOD(glyphTexture, texCoord, 0.0).r;\n" "\n" " float blend_width = 0.005;\n" " float distance_scale = 0.25;\n" From 6ec9f0a3d35d979322c43c307a7e6c1dea83258d Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Tue, 26 Sep 2017 12:51:03 +0100 Subject: [PATCH 103/327] Updated shader from OpenSceneGraph-Data/shaders to add fade out for SDF and non SDF pathways --- src/osgText/shaders/text_sdf_frag.cpp | 50 ++++++++++++--------------- 1 file changed, 23 insertions(+), 27 deletions(-) diff --git a/src/osgText/shaders/text_sdf_frag.cpp b/src/osgText/shaders/text_sdf_frag.cpp index 9f32c1e9a..ea4b675ae 100644 --- a/src/osgText/shaders/text_sdf_frag.cpp +++ b/src/osgText/shaders/text_sdf_frag.cpp @@ -2,21 +2,15 @@ char text_sdf_frag[] = "$OSG_GLSL_VERSION\n" "\n" "#pragma import_defines( BACKDROP_COLOR, OUTLINE, SIGNED_DISTNACE_FIELD )\n" "\n" - "#ifdef SIGNED_DISTNACE_FIELD\n" - "\n" - " #if !defined(GL_ES)\n" - " #if __VERSION__>=400\n" - " #define osg_TextureQueryLOD textureQueryLod\n" - " #define SIGNED_DISTNACE_FIELD_SUPPORTED\n" - " #else\n" - " #extension GL_ARB_texture_query_lod : enable\n" - " #ifdef GL_ARB_texture_query_lod\n" - " #define osg_TextureQueryLOD textureQueryLOD\n" - " #define SIGNED_DISTNACE_FIELD_SUPPORTED\n" - " #endif\n" + "#if !defined(GL_ES)\n" + " #if __VERSION__>=400\n" + " #define osg_TextureQueryLOD textureQueryLod\n" + " #else\n" + " #extension GL_ARB_texture_query_lod : enable\n" + " #ifdef GL_ARB_texture_query_lod\n" + " #define osg_TextureQueryLOD textureQueryLOD\n" " #endif\n" " #endif\n" - "\n" "#endif\n" "\n" "$OSG_PRECISION_FLOAT\n" @@ -44,16 +38,7 @@ char text_sdf_frag[] = "$OSG_GLSL_VERSION\n" " // glyph.rgba = (signed_distance, thin_outline, thick_outline, glyph_alpha)\n" " vec4 glyph = TEXTURE(glyphTexture, texCoord);\n" "\n" - " #ifdef SIGNED_DISTNACE_FIELD_SUPPORTED\n" - " float blend_ratio = OUTLINE*20.0; // assume inner boundary starts at OUTLINE==0.05\n" - "\n" - " float outline_alpha = 0.0;\n" - " if (blend_ratio>2.0) outline_alpha = glyph.b;\n" - " else if (blend_ratio>1.0) outline_alpha = mix(glyph.g, glyph.b, blend_ratio-1.0);\n" - " else outline_alpha = glyph.g*blend_ratio;\n" - " #else\n" - " float outline_alpha = (OUTLINE<=0.075) ? glyph.g : glyph.b;\n" - " #endif\n" + " float outline_alpha = (OUTLINE<=0.1) ? glyph.g : glyph.b;\n" "\n" " float alpha = glyph.a+outline_alpha;\n" " if (alpha>1.0) alpha = 1.0;\n" @@ -67,17 +52,18 @@ char text_sdf_frag[] = "$OSG_GLSL_VERSION\n" " #endif\n" "}\n" "\n" - "#ifdef SIGNED_DISTNACE_FIELD_SUPPORTED\n" + "#ifdef SIGNED_DISTNACE_FIELD\n" "vec4 distanceFieldColor()\n" "{\n" " float center_alpha = TEXTURELOD(glyphTexture, texCoord, 0.0).r;\n" + " //float center_alpha = TEXTURE(glyphTexture, texCoord).r;\n" "\n" " float blend_width = 0.005;\n" " float distance_scale = 0.25;\n" " float edge_distance = (center_alpha-0.5)*distance_scale;\n" "\n" " #ifdef OUTLINE\n" - " float outline_width = OUTLINE*0.5;;\n" + " float outline_width = OUTLINE*0.5;\n" " if (edge_distance>blend_width*0.5)\n" " {\n" " return vertexColor;\n" @@ -118,10 +104,18 @@ char text_sdf_frag[] = "$OSG_GLSL_VERSION\n" "\n" "void main(void)\n" "{\n" + " float near_fade_away = 2.0;\n" + " float far_fade_away = near_fade_away+5.0;\n" "\n" - "#ifdef SIGNED_DISTNACE_FIELD_SUPPORTED\n" - "\n" + "#ifdef osg_TextureQueryLOD\n" " float mml = osg_TextureQueryLOD(glyphTexture, texCoord).x;\n" + " if (mml>far_fade_away) discard;\n" + "#else\n" + " float mml = 0.0;\n" + "#endif\n" + "\n" + "\n" + "#ifdef SIGNED_DISTNACE_FIELD\n" "\n" " float near_transition = 0.0;\n" " float far_transition = near_transition+1.0;\n" @@ -137,6 +131,8 @@ char text_sdf_frag[] = "$OSG_GLSL_VERSION\n" "\n" "#endif\n" "\n" + " if (mml>near_fade_away) color.a *= (far_fade_away-mml)/(far_fade_away-near_fade_away);\n" + "\n" " if (color.a==0.0) discard;\n" "\n" " osg_FragColor = color;\n" From 8c575c0cea62bb0ab813acffad5bf330a93550d3 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Tue, 26 Sep 2017 15:32:41 +0100 Subject: [PATCH 104/327] UPdated from OpenSceneGraph-Data with handling of non textured text decoration --- examples/osgfont/osgfont.cpp | 93 +++++++++++++++++++++------ src/osgText/Font.cpp | 10 ++- src/osgText/shaders/text_sdf_frag.cpp | 7 ++ 3 files changed, 90 insertions(+), 20 deletions(-) diff --git a/examples/osgfont/osgfont.cpp b/examples/osgfont/osgfont.cpp index 460b6280d..b063325cf 100644 --- a/examples/osgfont/osgfont.cpp +++ b/examples/osgfont/osgfont.cpp @@ -74,7 +74,7 @@ struct TextSettings glyphTextureFeatures(osgText::GlyphTexture::GREYSCALE), textColor(1.0f, 1.0f, 1.0f, 1.0f), backdropType(osgText::Text::NONE), - backdropOffset(0.04f, 0.04f), + backdropOffset(0.07f, 0.07f), backdropColor(0.0f, 0.0f, 0.0f, 1.0f), scaleFontSizeToFontResolution(false) { @@ -194,10 +194,8 @@ struct TextSettings bool scaleFontSizeToFontResolution; }; -osgText::Text* createLabel(const std::string& l, TextSettings& settings, unsigned int size) +osgText::Text* createLabel(const std::string& l, TextSettings& settings, unsigned int size, osg::Vec3& pos) { - static osg::Vec3 pos(10.0f, 10.0f, 0.0f); - osgText::Text* label = new osgText::Text(); settings.setText(*label); @@ -302,21 +300,52 @@ int main(int argc, char** argv) osg::ref_ptr root = new osg::Group; - bool ortho = args.read("--ortho"); - if (ortho) + bool split_screen = args.read("--split"); + + if (split_screen) { - osg::ref_ptr camera = createOrthoCamera(1280.0f, 1024.0f); - root->addChild(camera.get()); - root = camera; - } - else - { - osg::ref_ptr transform = new osg::MatrixTransform; - transform->setMatrix(osg::Matrixd::rotate(osg::DegreesToRadians(90.0), 1.0, 0.0, 0.0)); - root->addChild(transform.get()); - root = transform; + viewer.realize(); + + // quite an dirty divusion of the master Camera's window if one is assigned. + if (viewer.getCamera()->getGraphicsContext()) + { + viewer.stopThreading(); + + osg::ref_ptr gc = viewer.getCamera()->getGraphicsContext(); + osg::ref_ptr traits = gc->getTraits(); + + // left half + { + osg::ref_ptr camera = new osg::Camera; + camera->setCullMask(0x1); + camera->setGraphicsContext(gc.get()); + camera->setViewport(new osg::Viewport(0,0, traits->width/2, traits->height)); + viewer.addSlave(camera.get(), osg::Matrixd::translate(1.0,0.0,0.0), osg::Matrixd::scale(2.0, 1.0, 1.0)); + } + + { + osg::ref_ptr camera = new osg::Camera; + camera->setCullMask(0x2); + camera->setGraphicsContext(gc.get()); + camera->setViewport(new osg::Viewport(traits->width/2+2,0, traits->width/2, traits->height)); + viewer.addSlave(camera.get(), osg::Matrixd::translate(-1.0,0.0,0.0), osg::Matrixd::scale(2.0, 1.0, 1.0)); + } + + viewer.getCamera()->setGraphicsContext(0); + + viewer.startThreading(); + } + else + { + split_screen = false; + } } + osg::ref_ptr transform = new osg::MatrixTransform; + transform->setMatrix(osg::Matrixd::rotate(osg::DegreesToRadians(90.0), 1.0, 0.0, 0.0)); + root->addChild(transform.get()); + root = transform; + osg::ref_ptr program = new osg::Program; std::string shaderFilename; while(args.read("--shader", shaderFilename)) @@ -363,7 +392,9 @@ int main(int argc, char** argv) settings.sizes.push_back(64); } - osg::Geode* geode = new osg::Geode(); + osg::ref_ptr geode = new osg::Geode(); + + osg::Vec3 pos(0.0f, 0.0f, 0.0f); // Add all of our osgText drawables. for(Sizes::const_iterator i = settings.sizes.begin(); i != settings.sizes.end(); i++) @@ -372,10 +403,34 @@ int main(int argc, char** argv) ss << *i << " 1234567890 abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ"; - geode->addDrawable(createLabel(ss.str(), settings, *i)); + geode->addDrawable(createLabel(ss.str(), settings, *i, pos)); + } + + root->addChild(geode.get()); + + if (split_screen) + { + geode->setNodeMask(0x1); + + osg::ref_ptr right_geode = new osg::Geode; + right_geode->setNodeMask(0x2); + + settings.glyphTextureFeatures = osgText::GlyphTexture::GREYSCALE; + + pos.set(0.0f, 0.0f, 0.0f); + + for(Sizes::const_iterator i = settings.sizes.begin(); i != settings.sizes.end(); i++) + { + std::stringstream ss; + + ss << *i << " 1234567890 abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + + right_geode->addDrawable(createLabel(ss.str(), settings, *i, pos)); + } + + root->addChild(right_geode); } - root->addChild(geode); if (!outputFilename.empty()) { diff --git a/src/osgText/Font.cpp b/src/osgText/Font.cpp index c1aa0e077..b8ae6ef1d 100644 --- a/src/osgText/Font.cpp +++ b/src/osgText/Font.cpp @@ -243,7 +243,7 @@ Font::Font(FontImplementation* implementation): setImplementation(implementation); char *ptr; - if( (ptr = getenv("OSG_MAX_TEXTURE_SIZE")) != 0) + if ((ptr = getenv("OSG_MAX_TEXTURE_SIZE")) != 0) { unsigned int osg_max_size = atoi(ptr); @@ -251,6 +251,14 @@ Font::Font(FontImplementation* implementation): if (osg_max_size<_textureHeightHint) _textureHeightHint = osg_max_size; } + if ((ptr = getenv("OSG_SDF_TEXT")) != 0) + { + _glyphTextureFeatures = GlyphTexture::ALL_FEATURES; + } + else if ((ptr = getenv("OSG_GREYSCALE_TEXT")) != 0) + { + _glyphTextureFeatures = GlyphTexture::GREYSCALE; + } } Font::~Font() diff --git a/src/osgText/shaders/text_sdf_frag.cpp b/src/osgText/shaders/text_sdf_frag.cpp index ea4b675ae..fde9f406d 100644 --- a/src/osgText/shaders/text_sdf_frag.cpp +++ b/src/osgText/shaders/text_sdf_frag.cpp @@ -104,6 +104,13 @@ char text_sdf_frag[] = "$OSG_GLSL_VERSION\n" "\n" "void main(void)\n" "{\n" + " if (texCoord.x<0.0 && texCoord.y<0.0)\n" + " {\n" + " osg_FragColor = vertexColor;\n" + " return;\n" + " }\n" + "\n" + "\n" " float near_fade_away = 2.0;\n" " float far_fade_away = near_fade_away+5.0;\n" "\n" From 75d23b2c10936e20e2f4b9234db0b329e4b4e22e Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 27 Sep 2017 11:09:22 +0100 Subject: [PATCH 105/327] Fixed update of GlyphTexture Image when copying new Glyph image's to it. --- src/osgText/Glyph.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/osgText/Glyph.cpp b/src/osgText/Glyph.cpp index e9236e41e..25d9764cd 100644 --- a/src/osgText/Glyph.cpp +++ b/src/osgText/Glyph.cpp @@ -137,16 +137,16 @@ void GlyphTexture::addGlyph(Glyph* glyph, int posX, int posY) void GlyphTexture::copyGlyphImage(Glyph* glyph) { + _image->dirty(); if (_glyphTextureFeatures==GREYSCALE) { - // OSG_NOTICE<<"GlyphTexture::copyGlyphImage() greyscale copy"<setText(str.str()); @@ -670,7 +670,7 @@ int main(int argc, char** argv) text->setUpdateCallback(new TextCounterCallback()); text->setFont("fonts/times.ttf"); text->setAxisAlignment(osgText::Text::XZ_PLANE); - text->setText("This is a counter test"); + text->setText("Text Counter :"); viewer.setSceneData(text.get()); } From 468d6d8eeaff2959421ec93403af202f0a13aa93 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Fri, 29 Sep 2017 10:20:59 +0100 Subject: [PATCH 108/327] Added command line support for specifying "default" for osgText::DefaultFont --- examples/osgfont/osgfont.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/examples/osgfont/osgfont.cpp b/examples/osgfont/osgfont.cpp index b063325cf..f17a0ed9a 100644 --- a/examples/osgfont/osgfont.cpp +++ b/examples/osgfont/osgfont.cpp @@ -152,7 +152,11 @@ struct TextSettings { OSG_NOTICE<<"Settings::setText()"< font = osgText::readRefFontFile(fontFilename); + osg::ref_ptr font; + + if (fontFilename!="default") font = osgText::readRefFontFile(fontFilename); + + if (!font) font = osgText::Font::getDefaultFont(); font->setGlyphImageMargin(glyphImageMargin); font->setGlyphImageMarginRatio(glyphImageMarginRatio); From 1f36f5bd8d032dc0dd423a5ec404ec1951777e3c Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Fri, 29 Sep 2017 10:25:04 +0100 Subject: [PATCH 109/327] Added setting of the FontResolution of the DefaultFont --- src/osgText/DefaultFont.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/osgText/DefaultFont.cpp b/src/osgText/DefaultFont.cpp index cf0b55cc4..1dc251f68 100644 --- a/src/osgText/DefaultFont.cpp +++ b/src/osgText/DefaultFont.cpp @@ -24,8 +24,15 @@ using namespace osgText; DefaultFont::DefaultFont() { + _fontSize = FontResolution(8,12); + _minFilterHint = osg::Texture::LINEAR_MIPMAP_LINEAR; _magFilterHint = osg::Texture::NEAREST; + + _margin = 8; + _marginRatio = 0.0; + _glyphInterval = 16; + constructGlyphs(); } @@ -233,6 +240,8 @@ void DefaultFont::constructGlyphs() glyph->setVerticalBearing(osg::Vec2(0.5f,1.0f)); // top middle. glyph->setVerticalAdvance(sourceHeight*coord_scale); + glyph->setFontResolution(fontRes); + addGlyph(fontRes,i,glyph.get()); } } From beb5801eeeb902038351a1ce6ff58a7cba928e06 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Fri, 29 Sep 2017 10:39:02 +0100 Subject: [PATCH 110/327] Improved SDF generation --- src/osgText/Glyph.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/osgText/Glyph.cpp b/src/osgText/Glyph.cpp index 25d9764cd..b0eac3ec8 100644 --- a/src/osgText/Glyph.cpp +++ b/src/osgText/Glyph.cpp @@ -156,7 +156,7 @@ void GlyphTexture::copyGlyphImage(Glyph* glyph) int dest_rows = _image->t(); unsigned char* dest_data = _image->data(glyph->getTexturePositionX(),glyph->getTexturePositionY()); - int search_distance = glyph->getFontResolution().second/8; + int search_distance = glyph->getFontResolution().second/4; int left = -search_distance; int right = glyph->s()+search_distance; @@ -165,7 +165,7 @@ void GlyphTexture::copyGlyphImage(Glyph* glyph) float multiplier = 1.0/255.0f; - float max_distance = glyph->getFontResolution().first/4; + float max_distance = sqrtf(float(search_distance)*float(search_distance)*2.0); int num_channels = TEXTURE_IMAGE_NUM_CHANNELS; @@ -175,10 +175,9 @@ void GlyphTexture::copyGlyphImage(Glyph* glyph) if ((lower+glyph->getTexturePositionY())<0) lower = -glyph->getTexturePositionY(); if ((upper+glyph->getTexturePositionY())>=dest_rows) upper = dest_rows-glyph->getTexturePositionY()-1; - bool use_SDF_for_Outline = true; - float outer_outline_distance = float(glyph->getFontResolution().first)*0.14f; + float outer_outline_distance = float(glyph->getFontResolution().first)*0.1f; float inner_outline_distance = outer_outline_distance*0.5f; unsigned char full_on = 255; @@ -198,7 +197,7 @@ void GlyphTexture::copyGlyphImage(Glyph* glyph) unsigned char outer_max_value = center_value; float center_value_f = center_value*multiplier; - float min_distance = FLT_MAX; + float min_distance = max_distance; if (center_value>0 && center_value Date: Fri, 29 Sep 2017 20:21:13 +0100 Subject: [PATCH 111/327] Simplified and improved the glyph margin computation and usage --- examples/osgfont/osgfont.cpp | 17 --------- include/osgText/Font | 21 +---------- include/osgText/Glyph | 24 +++++-------- src/osgPlugins/freetype/FreeTypeFont.cpp | 13 ------- src/osgText/DefaultFont.cpp | 3 -- src/osgText/Font.cpp | 32 ----------------- src/osgText/Glyph.cpp | 44 +++++++++++++++++------- src/osgText/Text.cpp | 3 +- 8 files changed, 41 insertions(+), 116 deletions(-) diff --git a/examples/osgfont/osgfont.cpp b/examples/osgfont/osgfont.cpp index f17a0ed9a..b39b19b59 100644 --- a/examples/osgfont/osgfont.cpp +++ b/examples/osgfont/osgfont.cpp @@ -68,9 +68,6 @@ struct TextSettings minFilter(osg::Texture::LINEAR_MIPMAP_LINEAR), magFilter(osg::Texture::LINEAR), maxAnisotropy(16.0f), - glyphImageMargin(1), - glyphImageMarginRatio(0.02), - glyphInterval(1), glyphTextureFeatures(osgText::GlyphTexture::GREYSCALE), textColor(1.0f, 1.0f, 1.0f, 1.0f), backdropType(osgText::Text::NONE), @@ -118,10 +115,6 @@ struct TextSettings if (arguments.read("--anisotropy",maxAnisotropy)) {} - if (arguments.read("--margin", glyphImageMargin)) {} - if (arguments.read("--margin-ratio", glyphImageMarginRatio)) {} - if (arguments.read("--interval", glyphInterval)) {} - if (arguments.read("--outline")) backdropType = osgText::Text::OUTLINE; if (arguments.read("--shadow")) backdropType = osgText::Text::DROP_SHADOW_BOTTOM_RIGHT; @@ -158,12 +151,9 @@ struct TextSettings if (!font) font = osgText::Font::getDefaultFont(); - font->setGlyphImageMargin(glyphImageMargin); - font->setGlyphImageMarginRatio(glyphImageMarginRatio); font->setMinFilterHint(minFilter); font->setMagFilterHint(magFilter); font->setMaxAnisotropy(maxAnisotropy); - font->setGlyphInterval(glyphInterval); font->setGyphTextureFeatures(glyphTextureFeatures); text.setColor(textColor); @@ -184,9 +174,6 @@ struct TextSettings osg::Texture::FilterMode minFilter; osg::Texture::FilterMode magFilter; float maxAnisotropy; - unsigned int glyphImageMargin; - float glyphImageMarginRatio; - int glyphInterval; osgText::GlyphTexture::Features glyphTextureFeatures; osg::Vec4 textColor; @@ -204,22 +191,18 @@ osgText::Text* createLabel(const std::string& l, TextSettings& settings, unsigne settings.setText(*label); - if (settings.scaleFontSizeToFontResolution) { label->setCharacterSize(size); } - label->setFontResolution(size, size); label->setPosition(pos); label->setAlignment(osgText::Text::LEFT_BOTTOM); - // It seems to be important we do this last to get best results? label->setText(l); - // textInfo(label); pos.y() += label->getCharacterHeight()*2.0; diff --git a/include/osgText/Font b/include/osgText/Font index 7b7fd0186..0af593b91 100644 --- a/include/osgText/Font +++ b/include/osgText/Font @@ -107,23 +107,6 @@ public: * return true on success, return false when not supported.*/ virtual bool getVerticalSize(float& ascender, float& descender) const { return _implementation ? _implementation->getVerticalSize(ascender, descender) : false; } - /** Set the margin around each glyph, - * to ensure that texture filtering doesn't bleed adjacent glyph's into each other. - * Default margin is 1 texels.*/ - void setGlyphImageMargin(unsigned int margin); - unsigned int getGlyphImageMargin() const; - - /** Set the margin ratio around each glyph, relative to the glyph's size. - * to ensure that texture filtering doesn't bleed adjacent glyph's into each other. - * Default margin is 0.05.*/ - void setGlyphImageMarginRatio(float margin); - float getGlyphImageMarginRatio() const; - - /** Set the interval that glyph positions are clamped to. - * Default interval is 1 texels.*/ - void setGlyphInterval(int interval); - int getGlyphInterval() const; - void setGyphTextureFeatures(GlyphTexture::Features features) { _glyphTextureFeatures = features; } GlyphTexture::Features getGlyphTextureFeatures() const { return _glyphTextureFeatures; } @@ -202,9 +185,7 @@ protected: // current active size of font FontResolution _fontSize; - unsigned int _margin; - float _marginRatio; - int _glyphInterval; + GlyphTexture::Features _glyphTextureFeatures; unsigned int _textureWidthHint; diff --git a/include/osgText/Glyph b/include/osgText/Glyph index 8dac38051..fb842eb8b 100644 --- a/include/osgText/Glyph +++ b/include/osgText/Glyph @@ -93,6 +93,9 @@ public: void setMaxTexCoord(const osg::Vec2& coord); const osg::Vec2& getMaxTexCoord() const; + void setTexelMargin(float margin) { _texelMargin = margin; } + float getTexelMargin() const { return _texelMargin; } + protected: virtual ~Glyph(); @@ -116,6 +119,7 @@ protected: int _texturePosY; osg::Vec2 _minTexCoord; osg::Vec2 _maxTexCoord; + float _texelMargin; typedef osg::buffered_value GLObjectList; mutable GLObjectList _globjList; @@ -256,16 +260,6 @@ public: /** return -1 if *this < *rhs, 0 if *this==*rhs, 1 if *this>*rhs.*/ virtual int compare(const osg::StateAttribute& rhs) const; - /** Set the margin around each glyph, to ensure that texture filtering doesn't bleed adjacent glyph's into each other.*/ - void setGlyphImageMargin(unsigned int margin) { _margin = margin; } - unsigned int getGlyphImageMargin() const { return _margin; } - - void setGlyphImageMarginRatio(float margin) { _marginRatio = margin; } - float getGlyphImageMarginRatio() const { return _marginRatio; } - - void setGlyphInterval(int interval) { _interval = interval; } - int getGlyphInterval() const { return _interval; } - enum Features { GREYSCALE, @@ -277,6 +271,10 @@ public: void setGlyphTextureFeatures(Features features) { _glyphTextureFeatures = features; } Features getGlyphTextureFeatures() const { return _glyphTextureFeatures; } + + int getEffectMargin(const Glyph* glyph); + int getTexelMargin(const Glyph* glyph); + bool getSpaceForGlyph(Glyph* glyph, int& posX, int& posY); void addGlyph(Glyph* glyph,int posX, int posY); @@ -296,12 +294,6 @@ protected: void copyGlyphImage(Glyph* glyph); - - // parameter used to compute the size and position of empty space - // in the texture which could accommodate new glyphs. - int _margin; - float _marginRatio; - int _interval; Features _glyphTextureFeatures; int _usedY; diff --git a/src/osgPlugins/freetype/FreeTypeFont.cpp b/src/osgPlugins/freetype/FreeTypeFont.cpp index 5d7aee6e9..323a874b6 100644 --- a/src/osgPlugins/freetype/FreeTypeFont.cpp +++ b/src/osgPlugins/freetype/FreeTypeFont.cpp @@ -278,19 +278,6 @@ void FreeTypeFont::setFontResolution(const osgText::FontResolution& fontSize) int width = fontSize.first; int height = fontSize.second; - int maxAxis = std::max(width, height); - int margin = _facade->getGlyphImageMargin() + (int)((float)maxAxis * _facade->getGlyphImageMarginRatio()); - - if ((unsigned int)(width+2*margin) > _facade->getTextureWidthHint() || - (unsigned int)(width+2*margin) > _facade->getTextureHeightHint()) - { - OSG_WARN<<"Warning: FreeTypeFont::setSize("<getTextureWidthHint()-2*margin; - height = _facade->getTextureHeightHint()-2*margin; - - OSG_WARN<<" sizes capped ("< osgText::readRefFontStream(std::istream& stream, const osgDB: Font::Font(FontImplementation* implementation): osg::Object(true), - _margin(1), - _marginRatio(0.02), - _glyphInterval(1), #if 0 _glyphTextureFeatures(GlyphTexture::ALL_FEATURES), #else @@ -289,32 +286,6 @@ std::string Font::getFileName() const return std::string(); } -void Font::setGlyphImageMargin(unsigned int margin) -{ - _margin = margin; -} - -unsigned int Font::getGlyphImageMargin() const -{ - return _margin; -} - -void Font::setGlyphImageMarginRatio(float ratio) -{ - _marginRatio = ratio; -} - -float Font::getGlyphImageMarginRatio() const -{ - return _marginRatio; -} - -void Font::setGlyphInterval(int interval) -{ - _glyphInterval = interval; -} - - void Font::setTextureSizeHint(unsigned int width,unsigned int height) { _textureWidthHint = width; @@ -514,9 +485,6 @@ void Font::addGlyph(const FontResolution& fontRes, unsigned int charcode, Glyph* OSG_INFO<< " Font " << this<< ", numberOfTexturesAllocated "<setGlyphImageMargin(_margin); - glyphTexture->setGlyphImageMarginRatio(_marginRatio); - glyphTexture->setGlyphInterval(_glyphInterval); glyphTexture->setGlyphTextureFeatures(_glyphTextureFeatures); glyphTexture->setTextureSize(_textureWidthHint,_textureHeightHint); glyphTexture->setFilter(osg::Texture::MIN_FILTER,_minFilterHint); diff --git a/src/osgText/Glyph.cpp b/src/osgText/Glyph.cpp index b0eac3ec8..4953c2913 100644 --- a/src/osgText/Glyph.cpp +++ b/src/osgText/Glyph.cpp @@ -37,9 +37,6 @@ using namespace std; #endif GlyphTexture::GlyphTexture(): - _margin(1), - _marginRatio(0.02f), - _interval(1), _usedY(0), _partUsedX(0), _partUsedY(0) @@ -60,21 +57,39 @@ int GlyphTexture::compare(const osg::StateAttribute& rhs) const return 0; } +int GlyphTexture::getEffectMargin(const Glyph* glyph) +{ + if (_glyphTextureFeatures==GREYSCALE) return 0; + else return glyph->getFontResolution().second/4; +} + +int GlyphTexture::getTexelMargin(const Glyph* glyph) +{ + int width = glyph->s(); + int height = glyph->t(); + int effect_margin = getEffectMargin(glyph); + + int max_dimension = std::max(width, height) + 2 * effect_margin; + int margin = osg::maximum(max_dimension/4, 2) + effect_margin; + + return margin; +} bool GlyphTexture::getSpaceForGlyph(Glyph* glyph, int& posX, int& posY) { - int maxAxis = osg::maximum(glyph->s(), glyph->t()); - int margin_from_ratio = (int)((float)maxAxis * _marginRatio); - int search_distance = glyph->getFontResolution().second/8; + int width = glyph->s(); + int height = glyph->t(); - int margin = _margin + osg::maximum(margin_from_ratio, search_distance); + int margin = getTexelMargin(glyph); - int width = glyph->s()+2*margin; - int height = glyph->t()+2*margin; + width += 2*margin; + height += 2*margin; - int partUsedX = ((_partUsedX % _interval) == 0) ? _partUsedX : (((_partUsedX/_interval)+1)*_interval); - int partUsedY = ((_partUsedY % _interval) == 0) ? _partUsedY : (((_partUsedY/_interval)+1)*_interval); - int usedY = ((_usedY % _interval) == 0) ? _usedY : (((_usedY/_interval)+1)*_interval); + int interval = 4; + + int partUsedX = ((_partUsedX % interval) == 0) ? _partUsedX : (((_partUsedX/interval)+1)*interval); + int partUsedY = ((_partUsedY % interval) == 0) ? _partUsedY : (((_partUsedY/interval)+1)*interval); + int usedY = ((_usedY % interval) == 0) ? _usedY : (((_usedY/interval)+1)*interval); // first check box (partUsedX, usedY) to (width,height) if (width <= (getTextureWidth()-partUsedX) && @@ -132,6 +147,9 @@ void GlyphTexture::addGlyph(Glyph* glyph, int posX, int posY) glyph->setMaxTexCoord( osg::Vec2( static_cast(posX+glyph->s())/static_cast(getTextureWidth()), static_cast(posY+glyph->t())/static_cast(getTextureHeight()) ) ); + + glyph->setTexelMargin(float(getTexelMargin(glyph))); + copyGlyphImage(glyph); } @@ -156,7 +174,7 @@ void GlyphTexture::copyGlyphImage(Glyph* glyph) int dest_rows = _image->t(); unsigned char* dest_data = _image->data(glyph->getTexturePositionX(),glyph->getTexturePositionY()); - int search_distance = glyph->getFontResolution().second/4; + int search_distance = getEffectMargin(glyph); int left = -search_distance; int right = glyph->s()+search_distance; diff --git a/src/osgText/Text.cpp b/src/osgText/Text.cpp index c9062386f..3e7e1f49a 100644 --- a/src/osgText/Text.cpp +++ b/src/osgText/Text.cpp @@ -464,8 +464,6 @@ void Text::computeGlyphRepresentation() float hr = _characterHeight; float wr = hr/getCharacterAspectRatio(); - float texelMargin = 5.0f; - for(String::iterator itr=_text.begin(); itr!=_text.end(); ) @@ -632,6 +630,7 @@ void Text::computeGlyphRepresentation() osg::Vec2 mintc = glyph->getMinTexCoord(); osg::Vec2 maxtc = glyph->getMaxTexCoord(); osg::Vec2 vDiff = maxtc - mintc; + float texelMargin = glyph->getTexelMargin(); float fHorizTCMargin = texelMargin / glyph->getTexture()->getTextureWidth(); float fVertTCMargin = texelMargin / glyph->getTexture()->getTextureHeight(); From d2162717b8185620e55d2f0df344a1a3f9d46b5a Mon Sep 17 00:00:00 2001 From: Julien Valentin Date: Wed, 4 Oct 2017 05:42:33 +0200 Subject: [PATCH 112/327] fix normalization bug (happen too early ) minor bug bla --- include/osgAnimation/RigTransformSoftware | 1 + src/osgAnimation/RigTransformSoftware.cpp | 42 +++++++++-------------- 2 files changed, 18 insertions(+), 25 deletions(-) diff --git a/include/osgAnimation/RigTransformSoftware b/include/osgAnimation/RigTransformSoftware index 109bf5b85..243c635d2 100644 --- a/include/osgAnimation/RigTransformSoftware +++ b/include/osgAnimation/RigTransformSoftware @@ -124,6 +124,7 @@ namespace osgAnimation accummulateMatrix(invBindMatrix, matrix, w); } } + void normalize(); inline const osg::Matrix& getMatrix() const { return _result;} protected: BonePtrWeightList _boneweights; diff --git a/src/osgAnimation/RigTransformSoftware.cpp b/src/osgAnimation/RigTransformSoftware.cpp index 955f42424..4be4ca6c5 100644 --- a/src/osgAnimation/RigTransformSoftware.cpp +++ b/src/osgAnimation/RigTransformSoftware.cpp @@ -66,35 +66,13 @@ 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) - { - BonePtrWeightList& bones = *it; - float sum = 0; - for(BonePtrWeightList::iterator bwit = bones.begin(); bwit!=bones.end(); ++bwit) - sum += bwit->getWeight(); - if (sum < 1e-4) - { - OSG_WARN << "VertexInfluenceSet::buildVertex2BoneList warning the vertex " << vertexID << " seems to have 0 weight, skip normalize for this vertex" << std::endl; - } - else - { - float mult = 1.0/sum; - for(BonePtrWeightList::iterator bwit = bones.begin(); bwit != bones.end(); ++bwit) - bwit->setWeight(bwit->getWeight() * mult); - } - } - ///2 Create inverse mapping Vec2Vec from previous built Index2Vec ///in order to minimize weighted matrices computation on update _uniqVertexGroupList.clear(); typedef std::map UnifyBoneGroup; UnifyBoneGroup unifyBuffer; - vertexID = 0; + unsigned int vertexID = 0; for (std::vector::iterator perVertinfit = perVertexInfluences.begin(); perVertinfit!=perVertexInfluences.end(); ++perVertinfit,++vertexID) @@ -188,7 +166,7 @@ bool RigTransformSoftware::init(RigGeometry&rig) BoneMap::const_iterator bmit = boneMap.find(bonename); if (bmit == boneMap.end() ) { - if (_invalidInfluence.find(bonename) != _invalidInfluence.end()) + if (_invalidInfluence.find(bonename) == _invalidInfluence.end()) { _invalidInfluence[bonename] = true; OSG_WARN << "RigTransformSoftware Bone " << bonename << " not found, skip the influence group " << std::endl; @@ -214,11 +192,25 @@ bool RigTransformSoftware::init(RigGeometry&rig) bwit++->setBonePtr(b); } } - + for(VertexGroupList::iterator itvg = _uniqVertexGroupList.begin(); itvg != _uniqVertexGroupList.end(); ++itvg) + itvg->normalize(); _needInit = false; return true; } + +void RigTransformSoftware::VertexGroup::normalize(){ + osg::Matrix::value_type sum=0; + for(BonePtrWeightList::iterator bwit = _boneweights.begin(); bwit != _boneweights.end(); ++bwit ) + sum+=bwit->getWeight(); + if (sum < 1e-4) + { + OSG_WARN << "RigTransformSoftware::VertexGroup: warning try to normalize a zero sum vertexgroup" << std::endl; + }else + for(BonePtrWeightList::iterator bwit = _boneweights.begin(); bwit != _boneweights.end(); ++bwit ) + bwit->setWeight(bwit->getWeight()/sum); +} + void RigTransformSoftware::operator()(RigGeometry& geom) { if (_needInit) From 2f19cd4b87bb202c9aaf277cf3e6868a512ac593 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 4 Oct 2017 18:06:42 +0100 Subject: [PATCH 113/327] Improvements to the Signed Distance Field implementation. --- src/osgText/DefaultFont.cpp | 7 +- src/osgText/Glyph.cpp | 4 +- src/osgText/Text.cpp | 34 ++-- src/osgText/shaders/text_sdf_frag.cpp | 216 ++++++++++++++++---------- 4 files changed, 166 insertions(+), 95 deletions(-) diff --git a/src/osgText/DefaultFont.cpp b/src/osgText/DefaultFont.cpp index ad7036b2b..cf3669cef 100644 --- a/src/osgText/DefaultFont.cpp +++ b/src/osgText/DefaultFont.cpp @@ -27,8 +27,13 @@ DefaultFont::DefaultFont() _fontSize = FontResolution(8,12); _minFilterHint = osg::Texture::LINEAR_MIPMAP_LINEAR; - _magFilterHint = osg::Texture::NEAREST; + _magFilterHint = osg::Texture::LINEAR; + char *ptr; + if ((ptr = getenv("OSG_SDF_TEXT")) != 0) + { + _glyphTextureFeatures = osgText::GlyphTexture::ALL_FEATURES; + } constructGlyphs(); } diff --git a/src/osgText/Glyph.cpp b/src/osgText/Glyph.cpp index 4953c2913..e8a11ea87 100644 --- a/src/osgText/Glyph.cpp +++ b/src/osgText/Glyph.cpp @@ -60,7 +60,9 @@ int GlyphTexture::compare(const osg::StateAttribute& rhs) const int GlyphTexture::getEffectMargin(const Glyph* glyph) { if (_glyphTextureFeatures==GREYSCALE) return 0; - else return glyph->getFontResolution().second/4; +// else return glyph->getFontResolution().second/4; + else return osg::maximum(glyph->getFontResolution().second/6, 2u); +// else return osg::maximum(glyph->getFontResolution().second/8,1u); } int GlyphTexture::getTexelMargin(const Glyph* glyph) diff --git a/src/osgText/Text.cpp b/src/osgText/Text.cpp index 3e7e1f49a..23d146372 100644 --- a/src/osgText/Text.cpp +++ b/src/osgText/Text.cpp @@ -47,6 +47,17 @@ Text::Text(): { _supportsVertexBufferObjects = true; + char *ptr; + if ((ptr = getenv("OSG_SDF_TEXT")) != 0) + { + _backdropImplementation = USE_SHADERS; + } + else if ((ptr = getenv("OSG_GREYSCALE_TEXT")) != 0) + { + _backdropImplementation = DELAYED_DEPTH_WRITES; + } + + assignStateSet(); } @@ -80,11 +91,10 @@ osg::StateSet* Text::createStateSet() Font::StateSets& statesets = activeFont->getCachedStateSets(); + std::stringstream ss; osg::StateSet::DefineList defineList; if (_backdropType!=NONE && _backdropImplementation==USE_SHADERS) { - std::stringstream ss; - ss.str(""); ss << "vec4("<<_backdropColor.r()<<", "<<_backdropColor.g()<<", "<<_backdropColor.b()<<", "<<_backdropColor.a()<<")"; @@ -122,15 +132,19 @@ osg::StateSet* Text::createStateSet() } - if (_fontSize.second>16/* && _backdropImplementation==USE_SHADERS*/) + if (activeFont->getGlyphTextureFeatures()!=GlyphTexture::GREYSCALE) { - OSG_NOTICE<<"Requesting SDF support _fontSize.second="<<_fontSize.second<getTextureWidthHint(); + defineList["TEXTURE_DIMENSION"] = osg::StateSet::DefinePair(ss.str(), osg::StateAttribute::ON); + defineList["SIGNED_DISTNACE_FIELD"] = osg::StateSet::DefinePair("1", osg::StateAttribute::ON); } - else - { - OSG_NOTICE<<"Disabling SDF support _fontSize.second="<<_fontSize.second<get()<get()<get(); } else @@ -180,7 +194,7 @@ osg::StateSet* Text::createStateSet() osg::DisplaySettings::ShaderHint shaderHint = osg::DisplaySettings::instance()->getShaderHint(); if (activeFont->getGlyphTextureFeatures()==GlyphTexture::GREYSCALE && shaderHint==osg::DisplaySettings::SHADER_NONE) { - OSG_INFO<<"Font::Font() Fixed function pipeline"<setTextureMode(0, GL_TEXTURE_2D, osg::StateAttribute::ON); return stateset.release(); diff --git a/src/osgText/shaders/text_sdf_frag.cpp b/src/osgText/shaders/text_sdf_frag.cpp index fde9f406d..fa2ed3c10 100644 --- a/src/osgText/shaders/text_sdf_frag.cpp +++ b/src/osgText/shaders/text_sdf_frag.cpp @@ -1,21 +1,17 @@ char text_sdf_frag[] = "$OSG_GLSL_VERSION\n" "\n" - "#pragma import_defines( BACKDROP_COLOR, OUTLINE, SIGNED_DISTNACE_FIELD )\n" + "#pragma import_defines( BACKDROP_COLOR, OUTLINE, SIGNED_DISTNACE_FIELD, TEXTURE_DIMENSION, GLYPH_DIMENSION)\n" "\n" - "#if !defined(GL_ES)\n" - " #if __VERSION__>=400\n" - " #define osg_TextureQueryLOD textureQueryLod\n" - " #else\n" - " #extension GL_ARB_texture_query_lod : enable\n" - " #ifdef GL_ARB_texture_query_lod\n" - " #define osg_TextureQueryLOD textureQueryLOD\n" - " #endif\n" + "#ifdef GL_ES\n" + " #extension GL_OES_standard_derivatives : enable\n" + " #ifndef GL_OES_standard_derivatives\n" + " #undef SIGNED_DISTNACE_FIELD\n" " #endif\n" "#endif\n" "\n" "$OSG_PRECISION_FLOAT\n" "\n" - "//#undef USE_SIGNED_DISTNACE_FIELD\n" + "#undef SIGNED_DISTNACE_FIELD\n" "\n" "#if __VERSION__>=130\n" " #define TEXTURE texture\n" @@ -32,13 +28,138 @@ char text_sdf_frag[] = "$OSG_GLSL_VERSION\n" "$OSG_VARYING_IN vec2 texCoord;\n" "$OSG_VARYING_IN vec4 vertexColor;\n" "\n" + "#ifdef SIGNED_DISTNACE_FIELD\n" + "\n" + "float distanceFromEdge(vec2 tc)\n" + "{\n" + " float center_alpha = TEXTURELOD(glyphTexture, tc, 0.0).r;\n" + " if (center_alpha==0.0) return -1.0;\n" + "\n" + " //float distance_scale = (1.0/4.0)*1.41;\n" + " float distance_scale = (1.0/6.0)*1.41;\n" + " //float distance_scale = (1.0/8.0)*1.41;\n" + "\n" + " return (center_alpha-0.5)*distance_scale;\n" + "}\n" + "\n" + "vec4 distanceFieldColorSample(float edge_distance, float blend_width, float blend_half_width)\n" + "{\n" + "#ifdef OUTLINE\n" + " float outline_width = OUTLINE*0.5;\n" + " if (edge_distance>blend_half_width)\n" + " {\n" + " return vertexColor;\n" + " }\n" + " else if (edge_distance>-blend_half_width)\n" + " {\n" + " return mix(vertexColor, BACKDROP_COLOR, smoothstep(0.0, 1.0, (blend_half_width-edge_distance)/(blend_width)));\n" + " }\n" + " else if (edge_distance>(blend_half_width-outline_width))\n" + " {\n" + " return BACKDROP_COLOR;\n" + " }\n" + " else if (edge_distance>-(outline_width+blend_half_width))\n" + " {\n" + " return vec4(BACKDROP_COLOR.rgb, ((blend_half_width+outline_width+edge_distance)/blend_width));\n" + " }\n" + " else\n" + " {\n" + " return vec4(0.0, 0.0, 0.0, 0.0);\n" + " }\n" + "#else\n" + " if (edge_distance>blend_half_width)\n" + " {\n" + " return vertexColor;\n" + " }\n" + " else if (edge_distance>-blend_half_width)\n" + " {\n" + " return vec4(vertexColor.rgb, smoothstep(1.0, 0.0, (blend_half_width-edge_distance)/(blend_width)));\n" + " }\n" + " else\n" + " {\n" + " return vec4(0.0, 0.0, 0.0, 0.0);\n" + " }\n" + "#endif\n" + "}\n" + "\n" + "vec4 distanceFieldColor()\n" + "{\n" + " float sample_distance_scale = 0.75;\n" + " vec2 dx = dFdx(texCoord)*sample_distance_scale;\n" + " vec2 dy = dFdy(texCoord)*sample_distance_scale;\n" + "\n" + " #ifndef TEXTURE_DIMENSION\n" + " float TEXTURE_DIMENSION = 1024.0;\n" + " #endif\n" + "\n" + " #ifndef GLYPH_DIMENSION\n" + " float GLYPH_DIMENSION = 32.0;\n" + " #endif\n" + "\n" + " float distance_across_pixel = length(dx+dy)*(TEXTURE_DIMENSION/GLYPH_DIMENSION);\n" + "\n" + " // compute the appropriate number of samples required to avoid aliasing.\n" + " int maxNumSamplesAcrossSide = 4;\n" + "\n" + " int numSamplesX = int(TEXTURE_DIMENSION * length(dx));\n" + " int numSamplesY = int(TEXTURE_DIMENSION * length(dy));\n" + " if (numSamplesX<2) numSamplesX = 2;\n" + " if (numSamplesY<2) numSamplesY = 2;\n" + " if (numSamplesX>maxNumSamplesAcrossSide) numSamplesX = maxNumSamplesAcrossSide;\n" + " if (numSamplesY>maxNumSamplesAcrossSide) numSamplesY = maxNumSamplesAcrossSide;\n" + "\n" + "\n" + " vec2 delta_tx = dx/float(numSamplesX-1);\n" + " vec2 delta_ty = dy/float(numSamplesY-1);\n" + "\n" + " float numSamples = float(numSamplesX)*float(numSamplesY);\n" + " float scale = 1.0/numSamples;\n" + " vec4 total_color = vec4(0.0,0.0,0.0,0.0);\n" + "\n" + " float blend_width = 1.5*distance_across_pixel/numSamples;\n" + " float blend_half_width = blend_width*0.5;\n" + "\n" + " // check whether fragment is wholly within or outwith glyph body+outline\n" + " float cd = distanceFromEdge(texCoord); // central distance (distance from center to edge)\n" + " if (cd-blend_half_width>distance_across_pixel) return vertexColor; // pixel fully within glyph body\n" + "\n" + " #ifdef OUTLINE\n" + " float outline_width = OUTLINE*0.5;\n" + " if ((-cd-outline_width-blend_half_width)>distance_across_pixel) return vec4(0.0, 0.0, 0.0, 0.0); // pixel fully outside outline+glyph body\n" + " #else\n" + " if (-cd-blend_half_width>distance_across_pixel) return vec4(0.0, 0.0, 0.0, 0.0); // pixel fully outside glyph body\n" + " #endif\n" + "\n" + "\n" + " // use multi-sampling to provide high quality antialised fragments\n" + " vec2 origin = texCoord - dx*0.5 - dy*0.5;\n" + " for(;numSamplesY>0; --numSamplesY)\n" + " {\n" + " vec2 pos = origin;\n" + " int numX = numSamplesX;\n" + " for(;numX>0; --numX)\n" + " {\n" + " vec4 c = distanceFieldColorSample(distanceFromEdge(pos), blend_width, blend_half_width);\n" + " total_color = total_color + c * c.a;\n" + " pos += delta_tx;\n" + " }\n" + " origin += delta_ty;\n" + " }\n" + "\n" + " total_color.rgb /= total_color.a;\n" + " total_color.a *= scale;\n" + "\n" + " return total_color;\n" + "}\n" + "#else\n" + "\n" "vec4 textureColor()\n" "{\n" " #ifdef OUTLINE\n" " // glyph.rgba = (signed_distance, thin_outline, thick_outline, glyph_alpha)\n" " vec4 glyph = TEXTURE(glyphTexture, texCoord);\n" "\n" - " float outline_alpha = (OUTLINE<=0.1) ? glyph.g : glyph.b;\n" + " float outline_alpha = (OUTLINE<=0.05) ? glyph.g : glyph.b;\n" "\n" " float alpha = glyph.a+outline_alpha;\n" " if (alpha>1.0) alpha = 1.0;\n" @@ -52,53 +173,6 @@ char text_sdf_frag[] = "$OSG_GLSL_VERSION\n" " #endif\n" "}\n" "\n" - "#ifdef SIGNED_DISTNACE_FIELD\n" - "vec4 distanceFieldColor()\n" - "{\n" - " float center_alpha = TEXTURELOD(glyphTexture, texCoord, 0.0).r;\n" - " //float center_alpha = TEXTURE(glyphTexture, texCoord).r;\n" - "\n" - " float blend_width = 0.005;\n" - " float distance_scale = 0.25;\n" - " float edge_distance = (center_alpha-0.5)*distance_scale;\n" - "\n" - " #ifdef OUTLINE\n" - " float outline_width = OUTLINE*0.5;\n" - " if (edge_distance>blend_width*0.5)\n" - " {\n" - " return vertexColor;\n" - " }\n" - " else if (edge_distance>-blend_width*0.5)\n" - " {\n" - " return mix(vertexColor, BACKDROP_COLOR, (blend_width*0.5-edge_distance)/(blend_width));\n" - " }\n" - " else if (edge_distance>(blend_width-outline_width))\n" - " {\n" - " return BACKDROP_COLOR;\n" - " }\n" - " else if (edge_distance>-outline_width)\n" - " {\n" - " return vec4(BACKDROP_COLOR.rgb, (outline_width+edge_distance)/blend_width);\n" - " }\n" - " else\n" - " {\n" - " return vec4(0.0, 0.0, 0.0, 0.0);\n" - " }\n" - " #else\n" - " if (edge_distance>0.0)\n" - " {\n" - " return vertexColor;\n" - " }\n" - " else if (edge_distance>-blend_width)\n" - " {\n" - " return vec4(vertexColor.rgb, 1.0+edge_distance/blend_width);\n" - " }\n" - " else\n" - " {\n" - " return vec4(0.0, 0.0, 0.0, 0.0);\n" - " }\n" - " #endif\n" - "}\n" "#endif\n" "\n" "\n" @@ -110,36 +184,12 @@ char text_sdf_frag[] = "$OSG_GLSL_VERSION\n" " return;\n" " }\n" "\n" - "\n" - " float near_fade_away = 2.0;\n" - " float far_fade_away = near_fade_away+5.0;\n" - "\n" - "#ifdef osg_TextureQueryLOD\n" - " float mml = osg_TextureQueryLOD(glyphTexture, texCoord).x;\n" - " if (mml>far_fade_away) discard;\n" - "#else\n" - " float mml = 0.0;\n" - "#endif\n" - "\n" - "\n" "#ifdef SIGNED_DISTNACE_FIELD\n" - "\n" - " float near_transition = 0.0;\n" - " float far_transition = near_transition+1.0;\n" - "\n" - " vec4 color;\n" - " if (mmlfar_transition) color = textureColor();\n" - " else color = mix(distanceFieldColor(), textureColor(), (mml-near_transition)/(far_transition-near_transition));\n" - "\n" + " vec4 color = distanceFieldColor();\n" "#else\n" - "\n" " vec4 color = textureColor();\n" - "\n" "#endif\n" "\n" - " if (mml>near_fade_away) color.a *= (far_fade_away-mml)/(far_fade_away-near_fade_away);\n" - "\n" " if (color.a==0.0) discard;\n" "\n" " osg_FragColor = color;\n" From c918916bcb78419bdde2b67a730b51a8074e1445 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Thu, 5 Oct 2017 12:45:47 +0100 Subject: [PATCH 114/327] Steamlined the handling of osg::Geometry --- src/osgPlugins/obj/OBJWriterNodeVisitor.cpp | 24 ++++++++++----------- src/osgPlugins/obj/OBJWriterNodeVisitor.h | 13 +++-------- 2 files changed, 15 insertions(+), 22 deletions(-) diff --git a/src/osgPlugins/obj/OBJWriterNodeVisitor.cpp b/src/osgPlugins/obj/OBJWriterNodeVisitor.cpp index 74dda31ea..3437a60b9 100644 --- a/src/osgPlugins/obj/OBJWriterNodeVisitor.cpp +++ b/src/osgPlugins/obj/OBJWriterNodeVisitor.cpp @@ -546,27 +546,27 @@ void OBJWriterNodeVisitor::processGeometry(osg::Geometry* geo, osg::Matrix& m) { } +void OBJWriterNodeVisitor::apply(osg::Geometry& geometry) +{ + osg::Matrix m = osg::computeLocalToWorld(getNodePath()); + + pushStateSet(geometry.getStateSet()); + + processGeometry(&geometry,m); + + popStateSet(geometry.getStateSet()); +} + void OBJWriterNodeVisitor::apply( osg::Geode &node ) { - pushStateSet(node.getStateSet()); _nameStack.push_back(node.getName()); - osg::Matrix m = osg::computeLocalToWorld(getNodePath()); unsigned int count = node.getNumDrawables(); for ( unsigned int i = 0; i < count; i++ ) { - osg::Geometry *g = node.getDrawable( i )->asGeometry(); - if ( g != NULL ) - { - pushStateSet(g->getStateSet()); - - processGeometry(g,m); - - popStateSet(g->getStateSet()); - } + node.getDrawable( i )->accept(*this); } - popStateSet(node.getStateSet()); _nameStack.pop_back(); } diff --git a/src/osgPlugins/obj/OBJWriterNodeVisitor.h b/src/osgPlugins/obj/OBJWriterNodeVisitor.h index be4c8cabd..8dc16a0d5 100644 --- a/src/osgPlugins/obj/OBJWriterNodeVisitor.h +++ b/src/osgPlugins/obj/OBJWriterNodeVisitor.h @@ -65,9 +65,10 @@ class OBJWriterNodeVisitor: public osg::NodeVisitor { } } - virtual void apply(osg::Geode &node); + virtual void apply(osg::Geometry & geometry); + virtual void apply(osg::Geode & node); - virtual void apply(osg::Group &node) + virtual void apply(osg::Group & node) { pushStateSet(node.getStateSet()); _nameStack.push_back( node.getName().empty() ? node.className() : node.getName() ); @@ -78,14 +79,6 @@ class OBJWriterNodeVisitor: public osg::NodeVisitor { traverse( node ); _nameStack.pop_back(); - popStateSet(node.getStateSet()); - } - - void traverse (osg::Node &node) - { - pushStateSet(node.getStateSet()); - - osg::NodeVisitor::traverse( node ); popStateSet(node.getStateSet()); } From ddf8c68d267669290a8dc08a7f7d2ea2f1ece1b4 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Thu, 5 Oct 2017 15:37:03 +0100 Subject: [PATCH 115/327] Added support for multiple --login url username password entries to osgviewer --- applications/osgviewer/osgviewer.cpp | 12 ++++-------- include/osgDB/Registry | 7 +++++++ 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/applications/osgviewer/osgviewer.cpp b/applications/osgviewer/osgviewer.cpp index d790d3873..0d7919687 100644 --- a/applications/osgviewer/osgviewer.cpp +++ b/applications/osgviewer/osgviewer.cpp @@ -74,14 +74,10 @@ int main(int argc, char** argv) std::string url, username, password; while(arguments.read("--login",url, username, password)) { - if (!osgDB::Registry::instance()->getAuthenticationMap()) - { - osgDB::Registry::instance()->setAuthenticationMap(new osgDB::AuthenticationMap); - osgDB::Registry::instance()->getAuthenticationMap()->addAuthenticationDetails( - url, - new osgDB::AuthenticationDetails(username, password) - ); - } + osgDB::Registry::instance()->getOrCreateAuthenticationMap()->addAuthenticationDetails( + url, + new osgDB::AuthenticationDetails(username, password) + ); } std::string device; diff --git a/include/osgDB/Registry b/include/osgDB/Registry index 62d4ac884..87076dc81 100644 --- a/include/osgDB/Registry +++ b/include/osgDB/Registry @@ -366,6 +366,13 @@ class OSGDB_EXPORT Registry : public osg::Referenced /** Set the password map to be used by plugins when access files from secure locations.*/ void setAuthenticationMap(AuthenticationMap* authenticationMap) { _authenticationMap = authenticationMap; } + /** Get the password map to be used by plugins when access files from secure locations. Create a AuthenticationMap if one isn't already assigned.*/ + AuthenticationMap* getOrCreateAuthenticationMap() + { + if (!_authenticationMap) _authenticationMap = new AuthenticationMap; + return _authenticationMap.get(); + } + /** Get the password map to be used by plugins when access files from secure locations.*/ AuthenticationMap* getAuthenticationMap() { return _authenticationMap.get(); } From 042a357278411b7c5c2ee91fd0f3089080499d3d Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Thu, 5 Oct 2017 15:59:26 +0100 Subject: [PATCH 116/327] Fixed spacing to make it consistent with the rest of the OSG and make it easier to read. --- src/osgPlugins/vnc/ReaderWriterVNC.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/osgPlugins/vnc/ReaderWriterVNC.cpp b/src/osgPlugins/vnc/ReaderWriterVNC.cpp index 926ab930e..ce68fd688 100644 --- a/src/osgPlugins/vnc/ReaderWriterVNC.cpp +++ b/src/osgPlugins/vnc/ReaderWriterVNC.cpp @@ -397,14 +397,19 @@ class ReaderWriterVNC : public osgDB::ReaderWriter const osgDB::AuthenticationMap* authenticationMap = (options && options->getAuthenticationMap()) ? options->getAuthenticationMap() : osgDB::Registry::instance()->getAuthenticationMap(); - if (authenticationMap != NULL) { + + if (authenticationMap != NULL) + { const osgDB::AuthenticationDetails* details = authenticationMap->getAuthenticationDetails(hostname); - if (details == NULL) { + if (details == NULL) + { size_t pos = hostname.find(":"); - if (pos != std::string::npos) { + if (pos != std::string::npos) + { details = authenticationMap->getAuthenticationDetails(hostname.substr(0, pos)); } } + // configure authentication if required. if (details != NULL) { @@ -414,6 +419,7 @@ class ReaderWriterVNC : public osgDB::ReaderWriter image->_password = details->password; } } + if (options && !options->getOptionString().empty()) { image->_optionString = options->getOptionString(); From 7868b42ef2a1d19f943096253fa1e25b5b499a67 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Thu, 5 Oct 2017 16:56:30 +0100 Subject: [PATCH 117/327] Improved the readability of recent changes by adding spaces, {} and moving { onto separate lines to keep things consistent with the rest of the OSG. --- src/osgAnimation/RigTransformSoftware.cpp | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/src/osgAnimation/RigTransformSoftware.cpp b/src/osgAnimation/RigTransformSoftware.cpp index 4be4ca6c5..35993817a 100644 --- a/src/osgAnimation/RigTransformSoftware.cpp +++ b/src/osgAnimation/RigTransformSoftware.cpp @@ -183,7 +183,7 @@ bool RigTransformSoftware::init(RigGeometry&rig) 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()]; if(!b) @@ -192,23 +192,36 @@ bool RigTransformSoftware::init(RigGeometry&rig) bwit++->setBonePtr(b); } } + for(VertexGroupList::iterator itvg = _uniqVertexGroupList.begin(); itvg != _uniqVertexGroupList.end(); ++itvg) + { itvg->normalize(); + } + _needInit = false; return true; } -void RigTransformSoftware::VertexGroup::normalize(){ +void RigTransformSoftware::VertexGroup::normalize() +{ osg::Matrix::value_type sum=0; for(BonePtrWeightList::iterator bwit = _boneweights.begin(); bwit != _boneweights.end(); ++bwit ) - sum+=bwit->getWeight(); + { + sum += bwit->getWeight(); + } + if (sum < 1e-4) { OSG_WARN << "RigTransformSoftware::VertexGroup: warning try to normalize a zero sum vertexgroup" << std::endl; - }else + } + else + { for(BonePtrWeightList::iterator bwit = _boneweights.begin(); bwit != _boneweights.end(); ++bwit ) + { bwit->setWeight(bwit->getWeight()/sum); + } + } } void RigTransformSoftware::operator()(RigGeometry& geom) From a87e57e9469ad58dce3830700f5e0d07aa9a61a0 Mon Sep 17 00:00:00 2001 From: "Konstantin S. Matveyev" Date: Fri, 6 Oct 2017 14:33:07 +0300 Subject: [PATCH 118/327] VertexAttribDivisor compare function fix: index must be compared --- include/osg/VertexAttribDivisor | 1 + 1 file changed, 1 insertion(+) diff --git a/include/osg/VertexAttribDivisor b/include/osg/VertexAttribDivisor index 7b222cd38..a38b31da5 100644 --- a/include/osg/VertexAttribDivisor +++ b/include/osg/VertexAttribDivisor @@ -50,6 +50,7 @@ class OSG_EXPORT VertexAttribDivisor : public StateAttribute COMPARE_StateAttribute_Types(VertexAttribDivisor,sa) // compare each parameter in turn against the rhs. + COMPARE_StateAttribute_Parameter(_index) COMPARE_StateAttribute_Parameter(_divisor) return 0; // passed all the above comparison macros, must be equal. From 1e1f69febcb14fe7e7ebdcda8501f20168b21237 Mon Sep 17 00:00:00 2001 From: "Konstantin S. Matveyev" Date: Fri, 6 Oct 2017 17:37:50 +0300 Subject: [PATCH 119/327] Added defines: GL_ALPHA4/8/12/16 in osg/Image, this will fix compilation error while building for GLES2 --- include/osg/Image | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/include/osg/Image b/include/osg/Image index 3a90175ea..663761c80 100644 --- a/include/osg/Image +++ b/include/osg/Image @@ -68,6 +68,10 @@ #endif #if defined(OSG_GLES1_AVAILABLE) || defined(OSG_GLES2_AVAILABLE) || defined(OSG_GLES3_AVAILABLE) || defined(OSG_GL3_AVAILABLE) + #define GL_ALPHA4 0x803B + #define GL_ALPHA8 0x803C + #define GL_ALPHA12 0x803D + #define GL_ALPHA16 0x803E #define GL_BITMAP 0x1A00 #define GL_COLOR_INDEX 0x1900 #define GL_INTENSITY12 0x804C From 9ac2b2eb7b56fe88d5731847f0defbf708068f4c Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Fri, 6 Oct 2017 17:47:19 +0100 Subject: [PATCH 120/327] Added VertexArrayState::ArrayDispatch::className() method and implementation for each ArrayDispatch subclass to help with debugging --- include/osg/VertexArrayState | 2 ++ src/osg/VertexArrayState.cpp | 14 ++++++++++++++ 2 files changed, 16 insertions(+) diff --git a/include/osg/VertexArrayState b/include/osg/VertexArrayState index cfd8dae86..ce5956315 100644 --- a/include/osg/VertexArrayState +++ b/include/osg/VertexArrayState @@ -34,6 +34,8 @@ public: modifiedCount(0xffffffff), active(false) {} + virtual const char* className() const = 0; // { return "ArrayDispatch"; } + virtual void enable_and_dispatch(osg::State& /*state*/, const osg::Array* /*new_array*/) {} // = 0; virtual void enable_and_dispatch(osg::State& /*state*/, const osg::Array* /*new_array*/, const osg::GLBufferObject* /*vbo*/) {} // = 0; diff --git a/src/osg/VertexArrayState.cpp b/src/osg/VertexArrayState.cpp index 9f474fc0f..1095e11f4 100644 --- a/src/osg/VertexArrayState.cpp +++ b/src/osg/VertexArrayState.cpp @@ -118,6 +118,8 @@ struct VertexArrayDispatch : public VertexArrayState::ArrayDispatch { VertexArrayDispatch() {} + virtual const char* className() const { return "VertexArrayDispatch"; } + virtual void enable_and_dispatch(osg::State&, const osg::Array* new_array) { VAS_NOTICE<<" VertexArrayDispatch::enable_and_dispatch("<getNumElements()<<")"<getNumElements()<<")"<getNumElements()<<")"<getNumElements()<<") unit="<getPreserveDataType()) From 4906844ea76054a83ad96afb8439dd521db456ff Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Fri, 6 Oct 2017 18:03:36 +0100 Subject: [PATCH 121/327] Added explictly unbinding of VBO for setInterleavedArrays(). --- src/osg/VertexArrayState.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/osg/VertexArrayState.cpp b/src/osg/VertexArrayState.cpp index 1095e11f4..a0d082d43 100644 --- a/src/osg/VertexArrayState.cpp +++ b/src/osg/VertexArrayState.cpp @@ -745,8 +745,10 @@ void VertexArrayState::setArray(ArrayDispatch* vad, osg::State& state, GLint siz void VertexArrayState::setInterleavedArrays( osg::State& state, GLenum format, GLsizei stride, const GLvoid* pointer) { #if defined(OSG_GL_VERTEX_ARRAY_FUNCS_AVAILABLE) && !defined(OSG_GLES1_AVAILABLE) - lazyDisablingOfVertexAttributes(); - applyDisablingOfVertexAttributes(state); + unbindVertexBufferObject(); + + //lazyDisablingOfVertexAttributes(); + //applyDisablingOfVertexAttributes(state); glInterleavedArrays( format, stride, pointer); #else From d64933466233a3fd6ccc60ccb66b0b6cef3726e6 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Mon, 9 Oct 2017 12:23:45 +0100 Subject: [PATCH 122/327] Updated AUTHORS --- AUTHORS.txt | 6 ++++-- applications/osgversion/Contributors.cpp | 4 +++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/AUTHORS.txt b/AUTHORS.txt index 720da1a06..58628fdd5 100644 --- a/AUTHORS.txt +++ b/AUTHORS.txt @@ -1,6 +1,6 @@ OpenSceneGraph Library 3.5.7 -566 Contributors: +568 Contributors: Firstname Surname ----------------- @@ -175,6 +175,7 @@ John Ivar Gustav Haapalahti Erik den Dekker Emmanuel Roche +Don Burns Domenico Mangieri Daniel Larimer Colin Dunlop @@ -226,7 +227,6 @@ Fabio Mierlo Doug McCorkle Donald Cipperly Don Leich -Don Burns Dietmar Funck Colin Cochran Christian Ruzicka @@ -362,6 +362,7 @@ Shuxing Xiao Shane Arnott Sergey Kurdakov Sebastien Kuntz +Sandro Mani Ruth Lang Ruben The Ruben Smelik @@ -538,6 +539,7 @@ Christian Noon Christian Kaser Christian Ehrlicher Chris McGlone +Chris Djali Carlos Garcea Bryce Eldridge Bruno Herbelin diff --git a/applications/osgversion/Contributors.cpp b/applications/osgversion/Contributors.cpp index 86a585b87..a5a495536 100644 --- a/applications/osgversion/Contributors.cpp +++ b/applications/osgversion/Contributors.cpp @@ -699,7 +699,9 @@ NameCorrection nameCorrections[] = {"WeSee", "", "Alois", "Wismer"}, {"We", "See", - "Alois", "Wismer"} + "Alois", "Wismer"}, + {"AnyOldName3", "", + "Chris", "Djali"} }; From b2603d6c935797b517245e6b498184d5e01c4881 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Mon, 9 Oct 2017 12:25:40 +0100 Subject: [PATCH 123/327] Updated version number --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8f9645210..6625f0f86 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -115,7 +115,7 @@ PROJECT(OpenSceneGraph) SET(OPENSCENEGRAPH_MAJOR_VERSION 3) SET(OPENSCENEGRAPH_MINOR_VERSION 5) -SET(OPENSCENEGRAPH_PATCH_VERSION 7) +SET(OPENSCENEGRAPH_PATCH_VERSION 8) SET(OPENSCENEGRAPH_SOVERSION 150) # set to 0 when not a release candidate, non zero means that any generated From adb6ae849d3f4cff5d0abcac5adf57847e05824c Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Mon, 9 Oct 2017 12:33:06 +0100 Subject: [PATCH 124/327] Updated ChangeLog --- ChangeLog | 375 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 375 insertions(+) diff --git a/ChangeLog b/ChangeLog index 277fa4301..01ff512e2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,274 @@ +Mon, 9 Oct 2017 12:25:40 +0100 +Author : Robert Osfield +Updated version number + +Mon, 9 Oct 2017 12:23:45 +0100 +Author : Robert Osfield +Updated AUTHORS + +Mon, 9 Oct 2017 10:03:21 +0100 +Author : OpenSceneGraph git repository +Merge pull request #359 from eligovision/OpenSceneGraph_glesAdded defines: GL_ALPHA4/8/12/16 in osg/Image, this will fix compilat… + +Mon, 9 Oct 2017 10:02:51 +0100 +Author : OpenSceneGraph git repository +Merge pull request #358 from eligovision/OpenSceneGraph_optimizerVertexAttribDivisor compare function fix: index must be compared + +Fri, 6 Oct 2017 18:03:36 +0100 +Author : Robert Osfield +Added explictly unbinding of VBO for setInterleavedArrays(). + +Fri, 6 Oct 2017 17:47:19 +0100 +Author : Robert Osfield +Added VertexArrayState::ArrayDispatch::className() method and implementation for each ArrayDispatch subclass to help with debugging + +Fri, 6 Oct 2017 17:37:50 +0300 +Author : Konstantin S. Matveyev +Added defines: GL_ALPHA4/8/12/16 in osg/Image, this will fix compilation error while building for GLES2 + +Fri, 6 Oct 2017 14:33:07 +0300 +Author : Konstantin S. Matveyev +VertexAttribDivisor compare function fix: index must be compared + +Thu, 5 Oct 2017 16:31:45 +0100 +Author : OpenSceneGraph git repository +Merge pull request #354 from eligovision/OpenSceneGraph_intersectionLineSegmentIntersector fixed: intersection ratio remaped to the range… + +Thu, 5 Oct 2017 16:30:21 +0100 +Author : OpenSceneGraph git repository +Merge pull request #353 from eligovision/OpenSceneGraph_iotellg call removed from StreamOperator's checkStream function, becaus… + +Thu, 5 Oct 2017 16:29:37 +0100 +Author : OpenSceneGraph git repository +Merge pull request #355 from denyskoch/patch-1Fix loading of 16bit PNG images + +Thu, 5 Oct 2017 15:59:26 +0100 +Author : Robert Osfield +Fixed spacing to make it consistent with the rest of the OSG and make it easier to read. + +Thu, 5 Oct 2017 15:57:02 +0100 +Author : OpenSceneGraph git repository +Merge pull request #351 from LaurensVoerman/vncHostPwVNC: try to find password for host if no password for host:port is found + +Thu, 5 Oct 2017 15:37:03 +0100 +Author : Robert Osfield +Added support for multiple --login url username password entries to osgviewer + +Thu, 5 Oct 2017 15:02:17 +0100 +Author : OpenSceneGraph git repository +Merge pull request #348 from eligovision/OpenSceneGraph_serializersosg serializers fixed for static build, ShaderAttribute wrapper added + +Thu, 5 Oct 2017 12:45:47 +0100 +Author : Robert Osfield +Steamlined the handling of osg::Geometry + +Thu, 5 Oct 2017 12:15:23 +0100 +Author : OpenSceneGraph git repository +Merge pull request #346 from LaurensVoerman/FindLIBLASremoved las_c library from FindLIBLAS.cmake, it's not used by the osgplugin. + +Thu, 28 Sep 2017 11:09:18 +0200 +Author : Denys Koch +Fix loading of 16bit PNG imagesWhen a 16bit PNG image is loaded, the internalTextureFormat is set to unsized (i.e pixelFormat) constant. This results in 8 Bit Texture2D + +Fri, 22 Sep 2017 11:38:43 +0300 +Author : Konstantin S. Matveyev +LineSegmentIntersector fixed: intersection ratio remaped to the range of LineSegment => correct order in multiset of intersections + +Sun, 17 Sep 2017 18:48:32 +0300 +Author : konstantin.matveyev +tellg call removed from StreamOperator's checkStream function, because reading of files (readNodeFile etc.) with tellg on 'every iter' is approximately 100 times slower on Emscripten platform + +Thu, 21 Sep 2017 16:33:14 +0200 +Author : Laurens Voerman +VNC: try to find password for host if no password for host:port is found + +Fri, 15 Sep 2017 12:14:37 +0300 +Author : Konstantin S. Matveyev +osg serializers fixed for static build, ShaderAttribute wrapper added + +Tue, 12 Sep 2017 09:19:33 +0200 +Author : Laurens Voerman +removed las_c library from FindLIBLAS.cmake, it's not used by the osg plugin. + +Mon, 4 Sep 2017 15:21:26 +0100 +Author : OpenSceneGraph git repository +Merge pull request #344 from eligovision/OpenSceneGraph_text3dText3D dynamic changing fix + +Mon, 4 Sep 2017 15:20:54 +0100 +Author : OpenSceneGraph git repository +Merge pull request #345 from eligovision/OpenSceneGraph_example_text3dexample_osgtext3d: more options for testing + +Mon, 4 Sep 2017 11:44:30 +0300 +Author : Konstantin S. Matveyev +example_osgtext3d: more options for testing + +Mon, 4 Sep 2017 11:29:50 +0300 +Author : Konstantin S. Matveyev +Text3D dynamic changing fix + +Mon, 4 Sep 2017 08:36:49 +0100 +Author : OpenSceneGraph git repository +Merge pull request #341 from scrawl/cullingactive_fixLineSegmentIntersector: respect the 'cullingActive' flag for bounding box check + +Sun, 3 Sep 2017 14:15:36 +0000 +Author : scrawl +LineSegmentIntersector: respect the 'cullingActive' flag when testing drawable bounding box + +Fri, 1 Sep 2017 15:50:47 +0100 +Author : OpenSceneGraph git repository +Merge pull request #337 from mp3butcher/osganimbugfixfix a bug in how vertexattributes are filled + +Wed, 30 Aug 2017 23:15:01 +0200 +Author : Julien Valentin +fix a bug in how vertexattributes are filled + +Tue, 29 Aug 2017 10:51:06 +0100 +Author : OpenSceneGraph git repository +Merge pull request #334 from mathieu/ValidateProgramTooEarlyUnder macOS the glValidateProgram reports too many errors + +Tue, 29 Aug 2017 11:34:27 +0200 +Author : Mathieu MARACHE +Under macOS the glValidateProgram reports too many false negatives (errors) about missing buffers, etc..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. » + +Mon, 28 Aug 2017 16:28:30 +0100 +Author : OpenSceneGraph git repository +Merge pull request #332 from denyskoch/fix-boundingsphere-inequality-operatorFix flawed BoundingSphere inequality operator + +Mon, 28 Aug 2017 14:34:39 +0200 +Author : Denys Koch +Fix flawed BoundingSphere inequality operator + +Mon, 28 Aug 2017 10:02:27 +0100 +Author : OpenSceneGraph git repository +Merge pull request #330 from mathieu/ProgramFixFunctionAvailableCoreProfileosg::Program::isFixedFunction() should'nt return true if fixed function unavailable + +Mon, 28 Aug 2017 09:44:10 +0200 +Author : Mathieu MARACHE +osg::Program::isFixedFunction() should'nt return true fixed function is unavailable, even if _shaderList.empty() is true + +Sun, 27 Aug 2017 18:08:09 +0100 +Author : OpenSceneGraph git repository +Merge pull request #327 from kornerr/masterFix Emscripten build errors + +Sun, 27 Aug 2017 18:07:21 +0100 +Author : OpenSceneGraph git repository +Merge pull request #328 from scrawl/group-docsFix docs for Group::addChild to match implementation + +Sat, 26 Aug 2017 19:25:00 +0300 +Author : Michael Kapelko +Fix Emscripten build errors + +Sat, 26 Aug 2017 11:30:55 +0000 +Author : scrawl +Fix docs for Group::addChild to match implementationChecking for duplicates is only done if ENSURE_CHILD_IS_UNIQUE is defined, but this is never defined anywhere. + +Fri, 25 Aug 2017 14:49:38 +0100 +Author : OpenSceneGraph git repository +Merge pull request #326 from emminizer/glcore3_cmakefixSETUP_EXE in CMake now uses same define for including the GLCORE head… + +Fri, 25 Aug 2017 14:48:42 +0100 +Author : OpenSceneGraph git repository +Merge pull request #325 from emminizer/msvc2015_exportfixRemoved inappropriate use of OSG_EXPORT on DefaultIndirectCommandDrawArrays and De… + +Fri, 25 Aug 2017 09:04:05 -0400 +Author : Daniel Emminizer +SETUP_EXE in CMake now uses same define for including the GLCORE headers as SETUP_LIBRARY and SETUP_PLUGIN. Fixes Windows build errors for applications. + +Fri, 25 Aug 2017 08:55:25 -0400 +Author : Daniel Emminizer +No longer using OSG_EXPORT on DefaultIndirectCommandDrawArrays and DefaultIndirectCommandDrawElements, fixing compile errors in MSVC 2015. + +Fri, 25 Aug 2017 10:04:40 +0100 +Author : OpenSceneGraph git repository +Merge pull request #324 from mp3butcher/osganimationAdd extensions + +Fri, 25 Aug 2017 00:19:22 +0200 +Author : Julien Valentin +Add extensions + +Thu, 24 Aug 2017 15:13:14 +0100 +Author : Robert Osfield +Cleaned up warnings and removed assorts. + +Thu, 24 Aug 2017 13:55:56 +0100 +Author : OpenSceneGraph git repository +Merge pull request #322 from mp3butcher/MDI7fix osggpucull to fit both new BIB and MDI + +Thu, 24 Aug 2017 14:15:09 +0200 +Author : Julien Valentin +fix osggpucull to fit both new BIB and MDI + +Thu, 24 Aug 2017 11:17:43 +0100 +Author : Robert Osfield +Bumped SO version to reflect changes in ABI + +Thu, 24 Aug 2017 11:08:38 +0100 +Author : OpenSceneGraph git repository +Merge pull request #321 from LaurensVoerman/tgaMissingColormapfix gcc/VC compile warnings, reject color mapped tga files with missing colormap. + +Thu, 24 Aug 2017 11:33:23 +0200 +Author : Laurens Voerman +fix gcc/VC compile warnings, reject color mapped tga files with missing colormap. + +Thu, 24 Aug 2017 10:33:44 +0100 +Author : OpenSceneGraph git repository +Merge pull request #320 from mp3butcher/MDI7MultiDrawIndirect + +Thu, 24 Aug 2017 11:26:23 +0200 +Author : Julien Valentin +Merge remote-tracking branch 'upstream/master' into MDI7 + +Thu, 24 Aug 2017 09:53:32 +0100 +Author : OpenSceneGraph git repository +Merge pull request #318 from mp3butcher/osganimationchange the design of BufferIndexBinding to work with BufferData instead of BufferObject +matrix transpose + +Thu, 24 Aug 2017 10:29:19 +0200 +Author : Julien Valentin +comply with osg::BufferIndexBinding new design (a miss) + +Wed, 23 Aug 2017 23:42:12 +0200 +Author : Julien Valentin +change the design of BufferIndexBinding to work with BufferData instead of BufferObject allow convenient BufferData abstraction + serialization of BufferIndexBinding + +Wed, 23 Aug 2017 19:06:25 +0200 +Author : Julien Valentin +add a transpose method for 4x4 and a transpose3x3 to transpose only orthogonal part of a mat4x4 + +Wed, 23 Aug 2017 15:26:07 +0100 +Author : Robert Osfield +Fixed underflow issue + +Wed, 23 Aug 2017 14:51:18 +0100 +Author : Robert Osfield +Fixed comparison to properly handle texture coordinates being assigned + +Wed, 23 Aug 2017 14:48:04 +0100 +Author : OpenSceneGraph git repository +Merge pull request #314 from LaurensVoerman/notify2reduce the need to reallocate the std::ostream buffer behind osg::Notify + +Wed, 23 Aug 2017 14:39:35 +0100 +Author : Robert Osfield +Warning fixes + +Tue, 22 Aug 2017 15:23:47 +0200 +Author : Laurens Voerman +reduce the need to reallocate the std::ostream buffer behind osg::Notify (causing multitreading issues) by pre-allocating 4095 bytes. + +Wed, 23 Aug 2017 08:54:10 +0100 +Author : OpenSceneGraph git repository +Merge pull request #315 from kornerr/masterFix stat64 build issue with NDK 15 by definining it as stat for Android + +Tue, 22 Aug 2017 22:49:56 +0300 +Author : Michael Kapelko +Fix stat64 build issue with NDK 15 by definining at stat for Android + +Tue, 22 Aug 2017 12:04:18 +0100 +Author : Robert Osfield +Updated ChangeLog + Tue, 22 Aug 2017 09:04:49 +0100 Author : Robert Osfield Added catch for controbutors list @@ -165,18 +436,122 @@ Mon, 7 Aug 2017 16:32:44 +0100 Author : Robert Osfield Added link to ABI tracker +Sun, 6 Aug 2017 15:30:27 +0100 +Author : OpenSceneGraph git repository +Merge pull request #294 from mp3butcher/MDI6add resize methods method in IndirectCommandArrays ..etc.. + +Sat, 5 Aug 2017 18:03:27 +0200 +Author : Julien Valentin +update IndirectCommandArrays interfaces and default impl to use DrawElements like semantic + +Wed, 2 Aug 2017 22:10:02 +0200 +Author : Julien Valentin +add MDI support + +Wed, 2 Aug 2017 21:50:25 +0200 +Author : Julien Valentin +add resize methods method in CommandArrays (it allows user to work without casting to the concrete class result of MDI.getCommandArray()) move getTotalDataSize in CommandArrays interfaces comply with other DrawElementsXXX removing parameters in mdi constructors and add several method ( allow use of osgUtil::DrawElementTypeSimplifer on these) + +Tue, 1 Aug 2017 07:54:37 +0100 +Author : OpenSceneGraph git repository +Merge pull request #293 from mp3butcher/MDI6fix a bug in MDI serializer + +Tue, 1 Aug 2017 02:18:15 +0200 +Author : Julien Valentin +fix a bug in MDI serializer + Mon, 31 Jul 2017 13:38:18 +0100 Author : Robert Osfield Merged #pragmatic shader fix from OpenSceneGraph-3.4 branch. +Mon, 31 Jul 2017 08:09:16 +0100 +Author : OpenSceneGraph git repository +Merge pull request #287 from mp3butcher/MDI6correct a bug and make MDI example more conservative + +Mon, 31 Jul 2017 03:15:03 +0200 +Author : Julien Valentin +fix a bug : indices pre incremented should be post + +Mon, 31 Jul 2017 03:08:52 +0200 +Author : Julien Valentin +Add arguments, command line usage and use DrawElementsUInt for classic case + +Mon, 31 Jul 2017 02:43:50 +0200 +Author : Julien Valentin +correct a bug and make it more conservative + +Sun, 30 Jul 2017 15:40:17 +0100 +Author : OpenSceneGraph git repository +Merge pull request #285 from mp3butcher/MDI6add a very simple example for mdi with basevertex + +Sun, 30 Jul 2017 10:15:32 +0200 +Author : Julien Valentin +add a very simple example for mdi with basevertex + Fri, 28 Jul 2017 17:17:25 +0100 Author : Robert Osfield Updated version number, ChangeLog and AUTHORS file for 3.5.7 developer release +Fri, 28 Jul 2017 14:34:59 +0100 +Author : Robert Osfield +Added missing break statements + +Fri, 28 Jul 2017 14:32:56 +0100 +Author : Robert Osfield +Improved readability and consistency with the rest OSG by adding/removing spaces and brackets where appropriate. + +Fri, 28 Jul 2017 13:30:36 +0100 +Author : Robert Osfield +Improved the readability and consistency with the rest of the OSG by inserting/removing spaces and line spacing. + Fri, 28 Jul 2017 10:27:47 +0100 Author : OpenSceneGraph git repository Merge pull request #267 from kornerr/masterAdd osgemscripten example +Fri, 28 Jul 2017 08:46:30 +0100 +Author : OpenSceneGraph git repository +Merge pull request #278 from mp3butcher/MDI2Mdi + +Thu, 27 Jul 2017 12:27:55 +0200 +Author : mp3butcher +set DIBO of the drawcommandarray directly in their interface constructor it makes osggpu use case lighter + drawcommandarray can't exist without a BO + +Thu, 27 Jul 2017 12:00:41 +0200 +Author : mp3butcher +Promote PrimitiveSetIndirect's VBO to a target explicited DIBO (in order to benefit from BOSet queue management) + +Thu, 27 Jul 2017 10:26:43 +0100 +Author : OpenSceneGraph git repository +Merge pull request #277 from mp3butcher/MDI2PrimitiveSetIndirect cleanup + serializers + +Thu, 27 Jul 2017 01:54:25 +0200 +Author : mp3butcher +add DrawIndirectBufferObject as State variable in order to minimize call to glBindBuffer(GL_DRAW_INDIRECT_BUFFER,X) TODO: Promote PrimitiveSetIndirect's VBO to target explicited DIBO (in order to benefit from BOSet queue management) + +Thu, 27 Jul 2017 01:40:04 +0200 +Author : mp3butcher +remove deprecated DrawIndirectBufferBinding + +Thu, 27 Jul 2017 01:08:37 +0200 +Author : mp3butcher +fix some errors during renaming and cleanup code + +Wed, 26 Jul 2017 23:38:20 +0200 +Author : mp3butcher +add untested serializers for PrimitiveSetIndirect + +Wed, 26 Jul 2017 23:36:55 +0200 +Author : mp3butcher +some renaming and harmonisations with osg metamodel convention + +Wed, 26 Jul 2017 20:46:09 +0100 +Author : Robert Osfield +Merge branch 'MDI2' of https://github.com/mp3butcher/OpenSceneGraph into MultiDrawIndirect + +Wed, 26 Jul 2017 20:25:41 +0200 +Author : mp3butcher +first commit for Indirect Draw integration in osg users will have to implement interfaces for their custom drawcommandarrays add a lot of new primitive set + few defines integration is made in osggpucull + Wed, 26 Jul 2017 12:54:37 +0100 Author : Robert Osfield Replaced FindOurDCMTK.cmake usage with FindDCMTK.cmake From eebb679754796742f2330520bf2f98e5f3623e1a Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Thu, 12 Oct 2017 11:12:47 +0100 Subject: [PATCH 125/327] Updated text_sdf_frag.cpp from OpenSceneGraph-Data changes that add outline generation for non SIGNED_DISTANCE_FIELD text. --- src/osgText/shaders/text_sdf_frag.cpp | 81 ++++++++++++++++++++------- 1 file changed, 61 insertions(+), 20 deletions(-) diff --git a/src/osgText/shaders/text_sdf_frag.cpp b/src/osgText/shaders/text_sdf_frag.cpp index fa2ed3c10..90bd739ab 100644 --- a/src/osgText/shaders/text_sdf_frag.cpp +++ b/src/osgText/shaders/text_sdf_frag.cpp @@ -9,9 +9,18 @@ char text_sdf_frag[] = "$OSG_GLSL_VERSION\n" " #endif\n" "#endif\n" "\n" - "$OSG_PRECISION_FLOAT\n" + "#if !defined(GL_ES)\n" + " #if __VERSION__>=400\n" + " #define osg_TextureQueryLOD textureQueryLod\n" + " #else\n" + " #extension GL_ARB_texture_query_lod : enable\n" + " #ifdef GL_ARB_texture_query_lod\n" + " #define osg_TextureQueryLOD textureQueryLOD\n" + " #endif\n" + " #endif\n" + "#endif\n" "\n" - "#undef SIGNED_DISTNACE_FIELD\n" + "$OSG_PRECISION_FLOAT\n" "\n" "#if __VERSION__>=130\n" " #define TEXTURE texture\n" @@ -28,6 +37,14 @@ char text_sdf_frag[] = "$OSG_GLSL_VERSION\n" "$OSG_VARYING_IN vec2 texCoord;\n" "$OSG_VARYING_IN vec4 vertexColor;\n" "\n" + "#ifndef TEXTURE_DIMENSION\n" + "const float TEXTURE_DIMENSION = 1024.0;\n" + "#endif\n" + "\n" + "#ifndef GLYPH_DIMENSION\n" + "const float GLYPH_DIMENSION = 32.0;\n" + "#endif\n" + "\n" "#ifdef SIGNED_DISTNACE_FIELD\n" "\n" "float distanceFromEdge(vec2 tc)\n" @@ -88,13 +105,6 @@ char text_sdf_frag[] = "$OSG_GLSL_VERSION\n" " vec2 dx = dFdx(texCoord)*sample_distance_scale;\n" " vec2 dy = dFdy(texCoord)*sample_distance_scale;\n" "\n" - " #ifndef TEXTURE_DIMENSION\n" - " float TEXTURE_DIMENSION = 1024.0;\n" - " #endif\n" - "\n" - " #ifndef GLYPH_DIMENSION\n" - " float GLYPH_DIMENSION = 32.0;\n" - " #endif\n" "\n" " float distance_across_pixel = length(dx+dy)*(TEXTURE_DIMENSION/GLYPH_DIMENSION);\n" "\n" @@ -151,26 +161,57 @@ char text_sdf_frag[] = "$OSG_GLSL_VERSION\n" "\n" " return total_color;\n" "}\n" + "\n" "#else\n" "\n" "vec4 textureColor()\n" "{\n" - " #ifdef OUTLINE\n" - " // glyph.rgba = (signed_distance, thin_outline, thick_outline, glyph_alpha)\n" - " vec4 glyph = TEXTURE(glyphTexture, texCoord);\n" + " float alpha = TEXTURE(glyphTexture, texCoord).a;\n" "\n" - " float outline_alpha = (OUTLINE<=0.05) ? glyph.g : glyph.b;\n" + "#ifdef OUTLINE\n" "\n" - " float alpha = glyph.a+outline_alpha;\n" - " if (alpha>1.0) alpha = 1.0;\n" + " float delta_tc = 1.6*OUTLINE*GLYPH_DIMENSION/TEXTURE_DIMENSION;\n" "\n" - " return vec4( vertexColor.rgb*glyph.a + BACKDROP_COLOR.rgb*outline_alpha, alpha);\n" + " float outline_alpha = alpha;\n" + " vec2 origin = texCoord-vec2(delta_tc*0.5, delta_tc*0.5);\n" "\n" - " #else\n" - " float alpha = TEXTURE(glyphTexture, texCoord).a;\n" - " if (alpha==0.0) vec4(0.0, 0.0, 0.0, 0.0);\n" - " return vec4(vertexColor.rgb, alpha);\n" + " float numSamples = 3.0;\n" + " delta_tc = delta_tc/(numSamples-1);\n" + "\n" + " float background_alpha = 1.0;\n" + "\n" + " for(float i=0.0; i1.0) outline_alpha = 1.0;\n" + "\n" + " if (outline_alpha==0.0) return vec4(0.0, 0.0, 0.0, 0.0); // outside glyph and outline\n" + "\n" + " vec4 color = mix(BACKDROP_COLOR, vertexColor, smoothstep(0.0, 1.0, alpha));\n" + " color.a = smoothstep(0.0, 1.0, outline_alpha);\n" + "\n" + " return color;\n" + "\n" + "#else\n" + " if (alpha==0.0) vec4(0.0, 0.0, 0.0, 0.0);\n" + " return vec4(vertexColor.rgb, vertexColor.a * alpha);\n" + "#endif\n" "}\n" "\n" "#endif\n" From 63f12986b476562a06fa675732b2b015c01dd0a0 Mon Sep 17 00:00:00 2001 From: Laurens Voerman Date: Thu, 12 Oct 2017 13:49:57 +0200 Subject: [PATCH 126/327] added dxtc support in Image::getColor, enhanced Image::isImageTranslucent to test opacity of dxt3 and dxt5 images --- src/osg/Image.cpp | 8 +- src/osg/dxtctool.cpp | 449 ++++++++++++++++++++++++++++++++++++++++++- src/osg/dxtctool.h | 24 ++- 3 files changed, 463 insertions(+), 18 deletions(-) diff --git a/src/osg/Image.cpp b/src/osg/Image.cpp index 1149acdc4..ed8175e46 100644 --- a/src/osg/Image.cpp +++ b/src/osg/Image.cpp @@ -1719,7 +1719,7 @@ bool Image::isImageTranslucent() const case(GL_COMPRESSED_RGBA_S3TC_DXT1_EXT): case(GL_COMPRESSED_RGBA_S3TC_DXT3_EXT): case(GL_COMPRESSED_RGBA_S3TC_DXT5_EXT): - return dxtc_tool::CompressedImageTranslucent(_s, _t, _pixelFormat, _data); + return dxtc_tool::isCompressedImageTranslucent(_s, _t, _pixelFormat, _data); default: return false; } @@ -1919,6 +1919,12 @@ Vec4 _readColor(GLenum pixelFormat, T* data,float scale) Vec4 Image::getColor(unsigned int s,unsigned t,unsigned r) const { + if (dxtc_tool::isDXTC(_pixelFormat)) { + unsigned char color[4]; + if (dxtc_tool::CompressedImageGetColor(color, s, t, r, _s, _t, _r, _pixelFormat, _data)) { + return Vec4(((float)color[0]) / 255.0f, ((float)color[1]) / 255.0f, ((float)color[2]) / 255.0f, ((float)color[3]) / 255.0f ); + } + } const unsigned char* ptr = data(s,t,r); switch(_dataType) diff --git a/src/osg/dxtctool.cpp b/src/osg/dxtctool.cpp index 7e486972a..b8f9ed2b6 100644 --- a/src/osg/dxtctool.cpp +++ b/src/osg/dxtctool.cpp @@ -166,11 +166,28 @@ struct DXT1TexelsBlock unsigned short color_1; // extreme unsigned int texels4x4; // interpolated colors (2 bits per texel) }; - -bool CompressedImageTranslucent(size_t width, size_t height, GLenum format, void * imageData) +struct DXT3TexelsBlock { - // OSG_NOTICE<<"CompressedImageTranslucent("<> 2) * ((height + 3) >> 2); switch(format) { case(GL_COMPRESSED_RGB_S3TC_DXT1_EXT): @@ -182,9 +199,8 @@ bool CompressedImageTranslucent(size_t width, size_t height, GLenum format, void // Only do the check on the first mipmap level, and stop when we // see the first alpha texel - int i = (width*height)/16; - bool foundAlpha = false; - while ((!foundAlpha) && (i>0)) + int i = blockCount; + while (i>0) { // See if this block might contain transparent texels if (texelsBlock->color_0<=texelsBlock->color_1) @@ -192,7 +208,7 @@ bool CompressedImageTranslucent(size_t width, size_t height, GLenum format, void // Scan the texels block for the '11' bit pattern that // indicates a transparent texel int j = 0; - while ((!foundAlpha) && (j < 32)) + while (j < 32) { // Check for the '11' bit pattern on this texel if ( ((texelsBlock->texels4x4 >> j) & 0x03) == 0x03) @@ -214,11 +230,67 @@ bool CompressedImageTranslucent(size_t width, size_t height, GLenum format, void } case(GL_COMPRESSED_RGBA_S3TC_DXT3_EXT): - return true; - + { + const DXT3TexelsBlock *texelsBlock = reinterpret_cast(imageData); + // Only do the check on the first mipmap level, and stop when we see the first alpha texel + int i = blockCount; + while (i>0) + { + for (int j =0; j < 4; ++j) + if ( texelsBlock->alpha4[j] != 0xFFFF) //4 pixels at once + return true; //not fully opaque + // Next block + --i; + ++texelsBlock; + } + return false; + } case(GL_COMPRESSED_RGBA_S3TC_DXT5_EXT): - return true; + { + const DXT5TexelsBlock *texelsBlock = reinterpret_cast(imageData); + // Only do the check on the first mipmap level, and stop when we see the first alpha texel + int i = blockCount; + unsigned char alphaBlock[8]; + while (i>0) + { + bool eightStep = texelsBlock->alpha_0 > texelsBlock->alpha_1; + alphaBlock[0] = texelsBlock->alpha_0; + alphaBlock[1] = texelsBlock->alpha_1; + if (eightStep) { + if (texelsBlock->alpha_0 < 255) return true; //not fully opaque + alphaBlock[2] = (6 * alphaBlock[0] + 1 * alphaBlock[1] + 3) / 7; // bit code 010 + alphaBlock[3] = (5 * alphaBlock[0] + 2 * alphaBlock[1] + 3) / 7; // bit code 011 + alphaBlock[4] = (4 * alphaBlock[0] + 3 * alphaBlock[1] + 3) / 7; // bit code 100 + alphaBlock[5] = (3 * alphaBlock[0] + 4 * alphaBlock[1] + 3) / 7; // bit code 101 + alphaBlock[6] = (2 * alphaBlock[0] + 5 * alphaBlock[1] + 3) / 7; // bit code 110 + alphaBlock[7] = (1 * alphaBlock[0] + 6 * alphaBlock[1] + 3) / 7; // bit code 111 + } else { + alphaBlock[2] = (4 * alphaBlock[0] + 1 * alphaBlock[1] + 2) / 5; // bit code 010 + alphaBlock[3] = (3 * alphaBlock[0] + 2 * alphaBlock[1] + 2) / 5; // bit code 011 + alphaBlock[4] = (2 * alphaBlock[0] + 3 * alphaBlock[1] + 2) / 5; // bit code 100 + alphaBlock[5] = (1 * alphaBlock[0] + 4 * alphaBlock[1] + 2) / 5; // bit code 101 + alphaBlock[6] = 0; // bit code 110 + alphaBlock[7] = 255; // bit code 111 + } + int last_added_byte = 1; + unsigned short running_a_index = texelsBlock->alpha3[0] + (((unsigned short)texelsBlock->alpha3[last_added_byte]) << 8); + for (int j = 0; j < 16; ++j) { + unsigned char alphaIndex = running_a_index & 0x7; + if (alphaBlock[alphaIndex] < 255) return true; //not fully opaque + running_a_index >>= 3; + if ((3 * j / 8) == last_added_byte) { + ++last_added_byte; + //(&texelsBlock->alpha3[0]) to avoid gcc warning: array subscript is above array bounds [-Warray-bounds] + running_a_index += (((unsigned short)(&(texelsBlock->alpha3[0]))[last_added_byte]) << (8 - (3 * j & 0x7))); + } + } + // Next block + --i; + ++texelsBlock; + } + return false; + } default: break; } @@ -226,4 +298,361 @@ bool CompressedImageTranslucent(size_t width, size_t height, GLenum format, void return false; } +unsigned short interpolateColors21(unsigned short color1, unsigned short color2) { + unsigned short result = (((color1 >> 11) * 2 + (color2 >> 11) + 1) / 3) << 11; + result += (((color1 >> 5 & 0x3F) * 2 + (color2 >> 5 & 0x3F) + 1) / 3) << 5; + result += (((color1 & 0x1F) * 2 + (color2 & 0x1F) + 1) / 3); + return result; +} +unsigned short interpolateColors11(unsigned short color1, unsigned short color2) { + unsigned short result = (((color1 >> 11) + (color2 >> 11) ) / 2) << 11; + result += (((color1 >> 5 & 0x3F) + (color2 >> 5 & 0x3F)) / 2) << 5; + result += (((color1 & 0x1F) + (color2 & 0x1F) ) / 2); + return result; +} + +bool CompressedImageGetColor(unsigned char color[4], unsigned int s, unsigned int t, unsigned int r, int width, int height, int depth, GLenum format, unsigned char *imageData) +{ + unsigned short color16 = 0;//RGB 5:6:5 format + + + unsigned int slab4Count = (depth & ~0x3); //4*floor(d/4) + unsigned int col = (s >> 2);//(floor(x/4) + unsigned int row = (t >> 2);//(floor(y/4) + unsigned int blockWidth = (width + 3) >> 2;//ceil(w/4) + unsigned int blockHeight = (height + 3) >> 2;//ceil(h/4) + int blockNumber = col + blockWidth * row ; // block to jump to + + if (depth > 1) { +// https://www.opengl.org/registry/specs/NV/texture_compression_vtc.txt +// if (z >= 4*floor(d/4)) { +// blockIndex = blocksize * (ceil(w/4) * ceil(h/4) * 4*floor(d/4) + floor(x/4) + ceil(w/4) * (floor(y/4) + ceil(h/4) * (z-4*floor(d/4)) )); +// } else { +// blockIndex = blocksize * 4 * (floor(x/4) + ceil(w/4) * (floor(y/4) + ceil(h/4) * floor(z/4))); +// } +// note floor(a/4) = (a >> 2) +// note 4*floor(a/4) = a & ~0x3 +// note ceil(a/4) = ((a + 3) >> 2) +// +// rewrite: this describes the final blocks as consecutive 4x4x1 blocks - and thats not in the wording of the specs +// if (r >= slab4Count) { +// blockNumber = (blockWidth * blockHeight * slab4Count + col + blockWidth * (row + blockHeight * (r-slab4Count) )); +// } else { +// blockNumber = 4 * (col + blockWidth * (row + blockHeight * (r >> 2)) ); +// } + +// or in the version of the openGL specs: +// if (z >= 4*floor(d/4)) { +// blockIndex = blocksize * (ceil(w/4) * ceil(h/4) * 4*floor(d/4) + (z - 4*floor(d/4)) * ( (floor(x/4) + ceil(w/4) * (floor(y/4) ); +// } else { +// blockIndex = blocksize * 4 * (floor(x/4) + ceil(w/4) * (floor(y/4) + ceil(h/4) * floor(z/4))); +// } + + unsigned int sub_r = r & 0x3;//(r-slab4Count) + if (r >= slab4Count) { //slice number beyond 4x4x4 slabs + unsigned int blockDepth = depth & 0x3;// equals: depth - slab4Count;//depth of this final block: 1/2/3 in case of 4x4x1; 4x4x2 or 4x4x3 bricks + blockNumber = (blockWidth * blockHeight * slab4Count //jump full 4x4x4 slabs + + blockDepth * ( col + blockWidth * row ) + + sub_r); + } else { + blockNumber = 4 * (col + blockWidth * (row + blockHeight * (r >> 2)) ) + sub_r; + } + } + + int sub_s = s & 0x3; + int sub_t = t & 0x3; + switch (format) + { + case(GL_COMPRESSED_RGB_S3TC_DXT1_EXT) : + case(GL_COMPRESSED_RGBA_S3TC_DXT1_EXT) : + { + const DXT1TexelsBlock *texelsBlock = reinterpret_cast(imageData); + texelsBlock += blockNumber; //jump to block + char index = (texelsBlock->texels4x4 >> (2 * sub_s + 8 * sub_t)) & 0x3; //two bit "index value" + color[3] = 255; + switch (index) { + case 0: + color16 = texelsBlock->color_0; + break; + case 1: + color16 = texelsBlock->color_1; + break; + case 2: + if (texelsBlock->color_0 > texelsBlock->color_1) { + color16 = interpolateColors21(texelsBlock->color_0, texelsBlock->color_1); + } + else { + color16 = interpolateColors11(texelsBlock->color_0, texelsBlock->color_1); + } + break; + case 3: + if (texelsBlock->color_0 > texelsBlock->color_1) { + color16 = interpolateColors21(texelsBlock->color_1, texelsBlock->color_0); + } + else { + color16 = 0;//black + if (format == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT) color[3] = 0;//transparent + } + break; + } + break; + } + case(GL_COMPRESSED_RGBA_S3TC_DXT3_EXT) : + { + const DXT3TexelsBlock *texelsBlock = reinterpret_cast(imageData); + texelsBlock += blockNumber; //jump to block + color[3] = 17 * (texelsBlock->alpha4[sub_t] >> 4 * sub_s & 0xF); + char index = (texelsBlock->texels4x4 >> (2 * sub_s + 8 * sub_t)) & 0x3; //two bit "index value" + switch (index) { + case 0: + color16 = texelsBlock->color_0; + break; + case 1: + color16 = texelsBlock->color_1; + break; + case 2: + color16 = interpolateColors21(texelsBlock->color_0, texelsBlock->color_1); + break; + case 3: + color16 = interpolateColors21(texelsBlock->color_1, texelsBlock->color_0); + break; + } + break; + } + case(GL_COMPRESSED_RGBA_S3TC_DXT5_EXT) : + { + const DXT5TexelsBlock *texelsBlock = reinterpret_cast(imageData); + texelsBlock += blockNumber; //jump to block + char index = (texelsBlock->texels4x4 >> (2 * sub_s + 8 * sub_t)) & 0x3; //two bit "index value" + switch (index) { + case 0: + color16 = texelsBlock->color_0; + break; + case 1: + color16 = texelsBlock->color_1; + break; + case 2: + color16 = interpolateColors21(texelsBlock->color_0, texelsBlock->color_1); + break; + case 3: + color16 = interpolateColors21(texelsBlock->color_1, texelsBlock->color_0); + break; + } + char pixel = sub_s + 4 * sub_t;//pixel number in block: 0 - 15 + char firstBit = 3 * pixel;//least significant bit: range 0 - 45 + unsigned char alpha_index; + if ((firstBit & 0x7) < 6) { + alpha_index = texelsBlock->alpha3[firstBit >> 3] >> (firstBit & 0x7) & 0x7;//grab byte containing least significant bit; shift and get 3 bits + } else { + alpha_index = texelsBlock->alpha3[firstBit >> 3] >> (firstBit & 0x7); + alpha_index |= texelsBlock->alpha3[1 + (firstBit >> 3)] << (8 - (firstBit & 0x7)); + alpha_index &= 0x7; + } + if (alpha_index == 0) { + color[3] = texelsBlock->alpha_0; + } else { + if (alpha_index == 1) { + color[3] = texelsBlock->alpha_1; + } else { + if (texelsBlock->alpha_0 > texelsBlock->alpha_1) { + color[3] = ((unsigned short)texelsBlock->alpha_0 * (8 - alpha_index) + (unsigned short)texelsBlock->alpha_1 * (alpha_index - 1) + 3) / 7; + } else { + if (alpha_index < 6) { + color[3] = ((unsigned short)texelsBlock->alpha_0 * (6 - alpha_index) + (unsigned short)texelsBlock->alpha_1 * (alpha_index - 1) + 3) / 5; + } else { + if (alpha_index == 6) { + color[3] = 0; + } else { + color[3] = 255; + } + } + } + } + } + break; + } + default: + return false; + } + unsigned short colorChannel = color16 >> 11;//red - 5 bits + color[0] = colorChannel << 3 | colorChannel >> 2 ; + colorChannel = color16 >> 5 & 0x3F;//green - 6 bits + color[1] = colorChannel << 2 | colorChannel >> 3; + colorChannel = color16 & 0x1F;//blue - 5 bits + color[2] = colorChannel << 3 | colorChannel >> 2; + return true; +} +void compressedBlockOrientationConversion(const GLenum format, const unsigned char *src_block, unsigned char *dst_block, const osg::Vec3i& srcOrigin, const osg::Vec3i& rowDelta, const osg::Vec3i& columnDelta) +{ + unsigned int src_texels4x4; + unsigned int *dst_texels4x4 = NULL; + switch (format) + { + case(GL_COMPRESSED_RGB_S3TC_DXT1_EXT) : + case(GL_COMPRESSED_RGBA_S3TC_DXT1_EXT) : + { + const DXT1TexelsBlock *src_texelsBlock = reinterpret_cast(src_block); + //make a copy as source might be equal to destination + src_texels4x4 = src_texelsBlock->texels4x4; // interpolated colors (2 bits per texel) + DXT1TexelsBlock *dst_texelsBlock = reinterpret_cast(dst_block); + dst_texels4x4 = &dst_texelsBlock->texels4x4; + + break; + } + case(GL_COMPRESSED_RGBA_S3TC_DXT3_EXT) : + { + const DXT3TexelsBlock *src_texelsBlock = reinterpret_cast(src_block); + //make a copy as source might be equal to destination + src_texels4x4 = src_texelsBlock->texels4x4; // interpolated colors (2 bits per texel) + DXT3TexelsBlock *dst_texelsBlock = reinterpret_cast(dst_block); + dst_texels4x4 = &dst_texelsBlock->texels4x4; + unsigned short src_alpha4[4]; // alpha values (4 bits per texel) - 64 bits + + memcpy(src_alpha4, src_texelsBlock->alpha4, 4 * sizeof(unsigned short));//make a copy as source might be equal to destination + + memset(dst_texelsBlock->alpha4, 0, 4 * sizeof(unsigned short)); //clear + osg::Vec3i source_pixel(srcOrigin); + for (int r = 0; r<4; r++)//rows + { + for (int c = 0; c<4; c++)//columns + { + int sub_s = source_pixel.x() & 0x3; + int sub_t = source_pixel.y() & 0x3; + int shiftBits = 4 * sub_s; + unsigned int alpha_value = src_alpha4[sub_t] >> shiftBits & 0xf; //four bit alpha values + + shiftBits = 4 * c;//destination + alpha_value <<= shiftBits; + dst_texelsBlock->alpha4[r] |= alpha_value; + + source_pixel = source_pixel + rowDelta; + } + source_pixel = source_pixel + columnDelta; + } + break; + } + case(GL_COMPRESSED_RGBA_S3TC_DXT5_EXT) : + { + const DXT5TexelsBlock *src_texelsBlock = reinterpret_cast(src_block); + //make a copy as source might be equal to destination + src_texels4x4 = src_texelsBlock->texels4x4; // interpolated colors (2 bits per texel) + DXT5TexelsBlock *dst_texelsBlock = reinterpret_cast(dst_block); + dst_texels4x4 = &dst_texelsBlock->texels4x4; + + unsigned char src_alpha3[6]; // alpha index values (3 bits per texel) + + memcpy(src_alpha3, src_texelsBlock->alpha3, 6 * sizeof(unsigned char));//make a copy as source might be equal to destination + + memset(dst_texelsBlock->alpha3, 0, 6 * sizeof(unsigned char)); //clear + osg::Vec3i source_pixel(srcOrigin); + unsigned int last_added_byte = 1; + unsigned short running_a_index = src_texelsBlock->alpha3[0] + (((unsigned short)src_texelsBlock->alpha3[last_added_byte]) << 8); + unsigned int j = 0; + for (int r = 0; r<4; r++)//rows + { + for (int c = 0; c<4; c++)//columns + { + int sub_s = source_pixel.x() & 0x3; + int sub_t = source_pixel.y() & 0x3; + + unsigned char alphaIndex = running_a_index & 0x7; + //store alphaIndex in output position: + int shiftBits = 3 * sub_s + 12 * sub_t;//LSB + dst_texelsBlock->alpha3[shiftBits >> 3] |= alphaIndex << (shiftBits & 0x7); + if ((shiftBits & 0x7) > 5) { + dst_texelsBlock->alpha3[1 + (shiftBits >> 3)] |= alphaIndex >> (8 - (shiftBits & 0x7)); + } + + running_a_index >>= 3; + if ((3 * ++j / 8) == last_added_byte) { + ++last_added_byte; + //(&texelsBlock->alpha3[0]) to avoid gcc warning: array subscript is above array bounds [-Warray-bounds] + running_a_index += (((unsigned short)(&(src_texelsBlock->alpha3[0]))[last_added_byte]) << (8 - (3 * j & 0x7))); + } + source_pixel = source_pixel + rowDelta; + } + source_pixel = source_pixel + columnDelta; + } + break; + } + default: + return; + }//switch + + //all formats: rearrange the colors + *dst_texels4x4 = 0;//clear + osg::Vec3i source_pixel(srcOrigin); + for (int r = 0; r<4; r++)//rows + { + for (int c = 0; c<4; c++)//columns + { + int sub_s = source_pixel.x() & 0x3; + int sub_t = source_pixel.y() & 0x3; + int shiftBits = 2 * sub_s + 8 * sub_t; + unsigned int index = (src_texels4x4 >> (shiftBits)) & 0x3; //two bit "index value" + + shiftBits = 2 * c + 8 * r;//destination + index <<= shiftBits; + *dst_texels4x4 |= index; + + source_pixel = source_pixel + rowDelta; + } + source_pixel = source_pixel + columnDelta; + } +} + +void compressedBlockStripAlhpa(const GLenum format, const unsigned char *src_block, unsigned char *dst_block) { + unsigned int src_texels4x4; + char reshuffle[4] = { 1, 0, 3, 2 }; + switch (format) + { + default: + case(GL_COMPRESSED_RGB_S3TC_DXT1_EXT) : + case(GL_COMPRESSED_RGBA_S3TC_DXT1_EXT) : + { + const DXT1TexelsBlock *src_texelsBlock = reinterpret_cast(src_block); + //make a copy as source might be equal to destination + src_texels4x4 = src_texelsBlock->texels4x4; // interpolated colors (2 bits per texel) + DXT1TexelsBlock *dst_texelsBlock = reinterpret_cast(dst_block); + if (src_texelsBlock->color_0 > src_texelsBlock->color_1) { + // Four-color block + memcpy(dst_texelsBlock, src_texelsBlock, sizeof(DXT1TexelsBlock)); + } else { + dst_texelsBlock->color_0 = src_texelsBlock->color_1; + dst_texelsBlock->color_1 = src_texelsBlock->color_0; + dst_texelsBlock->texels4x4 = 0; + for (unsigned int shiftBits = 0; shiftBits < 32; shiftBits += 2) { + unsigned char index = src_texels4x4 >> shiftBits & 0x3; //two bit "index value" + dst_texelsBlock->texels4x4 |= reshuffle[index] << shiftBits; + } + + } + break; + } + case(GL_COMPRESSED_RGBA_S3TC_DXT3_EXT) : + case(GL_COMPRESSED_RGBA_S3TC_DXT5_EXT) : + { + const DXT3TexelsBlock *src_texelsBlock = reinterpret_cast(src_block); + //make a copy as source might be equal to destination + src_texels4x4 = src_texelsBlock->texels4x4; // interpolated colors (2 bits per texel) + DXT1TexelsBlock *dst_texelsBlock = reinterpret_cast(dst_block); + if (src_texelsBlock->color_0 > src_texelsBlock->color_1) { + // Four-color block + memcpy(dst_texelsBlock, src_texelsBlock, sizeof(DXT3TexelsBlock)); + } + else { + dst_texelsBlock->color_0 = src_texelsBlock->color_1; + dst_texelsBlock->color_1 = src_texelsBlock->color_0; + dst_texelsBlock->texels4x4 = 0; + for (unsigned int shiftBits = 0; shiftBits < 32; shiftBits += 2) { + unsigned char index = src_texels4x4 >> shiftBits & 0x3; //two bit "index value" + dst_texelsBlock->texels4x4 |= reshuffle[index] << shiftBits; + + } + + } + break; + } + } +} } // namespace dxtc_tool diff --git a/src/osg/dxtctool.h b/src/osg/dxtctool.h index f24cf9c90..304399d99 100644 --- a/src/osg/dxtctool.h +++ b/src/osg/dxtctool.h @@ -31,17 +31,18 @@ // Current version: 1.00 BETA 1 (27/08/2002) // // Comment: Only works with DXTC mode supported by OpenGL. -// (currently: DXT1/DXT3/DXT5) +// (currently: DXT1/DXT3/DXT5) // // History: - // ////////////////////////////////////////////////////////////////////// #ifndef DXTCTOOL_H -#define DXTCTOOL_H +#define DXTCTOOL_H #include #include +#include #if defined(_MSC_VER) @@ -78,10 +79,19 @@ bool isDXTC(GLenum pixelFormat); bool VerticalFlip(size_t Width, size_t Height, GLenum Format, void * pPixels); -bool CompressedImageTranslucent(size_t Width, size_t Height, GLenum Format, void * pPixels); +bool isCompressedImageTranslucent(size_t Width, size_t Height, GLenum Format, void * pPixels); +//interpolate RGB565 colors with 2/3 part color1 and 1/3 part color2 +unsigned short interpolateColors21(unsigned short color1, unsigned short color2); +//interpolate RGB565 colors with equal weights +unsigned short interpolateColors11(unsigned short color1, unsigned short color2); -// Class holding reference to DXTC image pixels +bool CompressedImageGetColor(unsigned char color[4], unsigned int s, unsigned int t, unsigned int r, int width, int height, int depth, GLenum format, unsigned char *imageData); + +void compressedBlockOrientationConversion(const GLenum format, const unsigned char *src_block, unsigned char *dst_block, const osg::Vec3i& srcOrigin, const osg::Vec3i& rowDelta, const osg::Vec3i& columnDelta); + +void compressedBlockStripAlhpa(const GLenum format, const unsigned char *src_block, unsigned char *dst_block); +// Class holding reference to DXTC image pixels class dxtc_pixels { public: @@ -102,7 +112,7 @@ protected: inline bool SupportedFormat() const; // Vertical flipping functions - void VFlip_DXT1() const; + void VFlip_DXT1() const; void VFlip_DXT3() const; void VFlip_DXT5() const; @@ -116,7 +126,7 @@ protected: inline void BVF_Alpha_DXT5_H2(void * const pBlock) const; // V. flip one alpha (DXT5) block with its virtual height == 2 inline void BVF_Alpha_DXT5_H4(void * const pBlock) const; // V. flip one alpha (DXT5) block with its virtual height == 4 inline void BVF_Alpha_DXT5(void * const pBlock1, void * const pBlock2) const; // V. flip and swap two alpha (DXT5) blocks, with their virtual height == 4 - + // Block localization functions inline void * GetBlock(size_t i, size_t j, size_t BlockSize) const; @@ -155,7 +165,7 @@ inline bool isDXTC(GLenum pixelFormat) } inline bool VerticalFlip(size_t Width, size_t Height, GLenum Format, void * pPixels) { - return (dxtc_pixels(Width, Height, Format, pPixels)).VFlip(); + return (dxtc_pixels(Width, Height, Format, pPixels)).VFlip(); } From 99491e46ec818c1cca19ec79a669da958ffcac1d Mon Sep 17 00:00:00 2001 From: Laurens Voerman Date: Thu, 12 Oct 2017 17:21:10 +0200 Subject: [PATCH 127/327] modified present3D to allow multiple --login arguments like osgViewer, added --login option to osgvnc example --- applications/present3D/present3D.cpp | 12 ++++-------- examples/osgvnc/osgvnc.cpp | 21 ++++++++++++++++++--- 2 files changed, 22 insertions(+), 11 deletions(-) diff --git a/applications/present3D/present3D.cpp b/applications/present3D/present3D.cpp index 0e0c6abec..24318d9ec 100644 --- a/applications/present3D/present3D.cpp +++ b/applications/present3D/present3D.cpp @@ -336,14 +336,10 @@ int main( int argc, char **argv ) std::string url, username, password; while(arguments.read("--login",url, username, password)) { - if (!osgDB::Registry::instance()->getAuthenticationMap()) - { - osgDB::Registry::instance()->setAuthenticationMap(new osgDB::AuthenticationMap); - osgDB::Registry::instance()->getAuthenticationMap()->addAuthenticationDetails( - url, - new osgDB::AuthenticationDetails(username, password) - ); - } + osgDB::Registry::instance()->getOrCreateAuthenticationMap()->addAuthenticationDetails( + url, + new osgDB::AuthenticationDetails(username, password) + ); } diff --git a/examples/osgvnc/osgvnc.cpp b/examples/osgvnc/osgvnc.cpp index a286b59b0..68f4f0485 100644 --- a/examples/osgvnc/osgvnc.cpp +++ b/examples/osgvnc/osgvnc.cpp @@ -37,7 +37,9 @@ class EscapeHandler : public osgGA::GUIEventHandler int main(int argc,char** argv) { osg::ArgumentParser arguments(&argc, argv); - osgViewer::Viewer viewer(arguments); + arguments.getApplicationUsage()->addCommandLineOption("--login ", "Provide authentication information for http file access."); + arguments.getApplicationUsage()->addCommandLineOption("--password ", "Provide password for any vnc url on command line not mentioned in --login."); + osgViewer::Viewer viewer(arguments); osgWidget::GeometryHints hints(osg::Vec3(0.0f,0.0f,0.0f), osg::Vec3(1.0f,0.0f,0.0f), @@ -52,6 +54,15 @@ int main(int argc,char** argv) { } + std::string url, username, password; + while (arguments.read("--login", url, username, password)) + { + osgDB::Registry::instance()->getOrCreateAuthenticationMap()->addAuthenticationDetails( + url, + new osgDB::AuthenticationDetails(username, password) + ); + } + for(int i=1; igetAuthenticationMap()) osgDB::Registry::instance()->setAuthenticationMap(new osgDB::AuthenticationMap); - osgDB::Registry::instance()->getAuthenticationMap()->addAuthenticationDetails(hostname, new osgDB::AuthenticationDetails("", password)); + const osgDB::AuthenticationMap* authenticationMap = osgDB::Registry::instance()->getOrCreateAuthenticationMap(); + const osgDB::AuthenticationDetails* details = authenticationMap->getAuthenticationDetails(hostname); + if (details == NULL) + { + authenticationMap->addAuthenticationDetails(hostname, new osgDB::AuthenticationDetails("", password)); + } } osg::ref_ptr vncClient = new osgWidget::VncClient; From 0fedfd2ff97036c488571e4f952c7367145fe5b8 Mon Sep 17 00:00:00 2001 From: Laurens Voerman Date: Thu, 12 Oct 2017 17:38:16 +0200 Subject: [PATCH 128/327] add support for dxt compressed images to createImageWithOrientationConversion --- src/osg/ImageUtils.cpp | 43 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/src/osg/ImageUtils.cpp b/src/osg/ImageUtils.cpp index 6131630f6..74f0ae9f4 100644 --- a/src/osg/ImageUtils.cpp +++ b/src/osg/ImageUtils.cpp @@ -20,6 +20,7 @@ #include #include +#include "dxtctool.h" namespace osg { @@ -716,6 +717,48 @@ OSG_EXPORT osg::Image* createImageWithOrientationConversion(const osg::Image* sr unsigned int pixelSizeInBits = srcImage->getPixelSizeInBits(); unsigned int pixelSizeInBytes = pixelSizeInBits/8; unsigned int pixelSizeRemainder = pixelSizeInBits%8; + if (dxtc_tool::isDXTC(srcImage->getPixelFormat())) { + unsigned int DXTblockSize = 8; + if ((srcImage->getPixelFormat() == GL_COMPRESSED_RGBA_S3TC_DXT3_EXT) || (srcImage->getPixelFormat() == GL_COMPRESSED_RGBA_S3TC_DXT5_EXT)) DXTblockSize = 16; + unsigned int DXTblocksWidht = (srcImage->s() + 3) / 4;//width in 4x4 blocks + unsigned int DXTblocksHeight = (srcImage->t() + 3) / 4;//height in 4x4 blocks + unsigned int dst_DXTblocksWidht = (width + 3) / 4;//width in 4x4 blocks + unsigned int dst_DXTblocksHeight = (height + 3) / 4;//height in 4x4 blocks + + dstImage->allocateImage(width, height, depth, srcImage->getPixelFormat(), srcImage->getDataType()); + // copy across the pixels from the source image to the destination image. + if (depth != 1) + { + OSG_NOTICE << "Warning: createImageWithOrientationConversion(..) cannot handle dxt-compressed images with depth." << std::endl; + return const_cast(srcImage); + } + for (int l = 0; l> 2) + DXTblocksWidht * ((cp.y() >> 2) + (cp.z() >> 2) * DXTblocksHeight); + const unsigned char *src_block = srcImage->data() + src_blockIndex * DXTblockSize; + + unsigned int dst_blockIndex = (c >> 2) + dst_DXTblocksWidht * ((r >> 2) + (l >> 2) * dst_DXTblocksHeight); + unsigned char *dst_block = dstImage->data() + dst_blockIndex * DXTblockSize; + + memcpy((void *)dst_block, (void *)src_block, DXTblockSize); + osg::Vec3i srcSubOrigin(cp.x() & 0x7, cp.y() & 0x7, cp.z() & 0x7); + dxtc_tool::compressedBlockOrientationConversion(srcImage->getPixelFormat(),src_block, dst_block, srcSubOrigin, rowDelta, columnDelta); + + cp.x() += 4 * rowDelta.x(); + cp.y() += 4 * rowDelta.y(); + cp.z() += 4 * rowDelta.z(); + } + } + } + return dstImage.release(); + } if (pixelSizeRemainder!=0) { OSG_NOTICE<<"Warning: createImageWithOrientationConversion(..) cannot handle non byte aligned pixel formats."< Date: Thu, 12 Oct 2017 18:45:38 +0100 Subject: [PATCH 129/327] Updated from OpenSceneGraph-Data/shaders/text_sdf.frag to add support for SHADOW --- src/osgText/shaders/text_sdf_frag.cpp | 35 +++++++++++++++++---------- 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/src/osgText/shaders/text_sdf_frag.cpp b/src/osgText/shaders/text_sdf_frag.cpp index 90bd739ab..567e6a1bc 100644 --- a/src/osgText/shaders/text_sdf_frag.cpp +++ b/src/osgText/shaders/text_sdf_frag.cpp @@ -1,6 +1,6 @@ char text_sdf_frag[] = "$OSG_GLSL_VERSION\n" "\n" - "#pragma import_defines( BACKDROP_COLOR, OUTLINE, SIGNED_DISTNACE_FIELD, TEXTURE_DIMENSION, GLYPH_DIMENSION)\n" + "#pragma import_defines( BACKDROP_COLOR, SHADOW, OUTLINE, SIGNED_DISTNACE_FIELD, TEXTURE_DIMENSION, GLYPH_DIMENSION)\n" "\n" "#ifdef GL_ES\n" " #extension GL_OES_standard_derivatives : enable\n" @@ -99,11 +99,11 @@ char text_sdf_frag[] = "$OSG_GLSL_VERSION\n" "#endif\n" "}\n" "\n" - "vec4 distanceFieldColor()\n" + "vec4 textColor(vec2 src_texCoord)\n" "{\n" " float sample_distance_scale = 0.75;\n" - " vec2 dx = dFdx(texCoord)*sample_distance_scale;\n" - " vec2 dy = dFdy(texCoord)*sample_distance_scale;\n" + " vec2 dx = dFdx(src_texCoord)*sample_distance_scale;\n" + " vec2 dy = dFdy(src_texCoord)*sample_distance_scale;\n" "\n" "\n" " float distance_across_pixel = length(dx+dy)*(TEXTURE_DIMENSION/GLYPH_DIMENSION);\n" @@ -130,7 +130,7 @@ char text_sdf_frag[] = "$OSG_GLSL_VERSION\n" " float blend_half_width = blend_width*0.5;\n" "\n" " // check whether fragment is wholly within or outwith glyph body+outline\n" - " float cd = distanceFromEdge(texCoord); // central distance (distance from center to edge)\n" + " float cd = distanceFromEdge(src_texCoord); // central distance (distance from center to edge)\n" " if (cd-blend_half_width>distance_across_pixel) return vertexColor; // pixel fully within glyph body\n" "\n" " #ifdef OUTLINE\n" @@ -142,7 +142,7 @@ char text_sdf_frag[] = "$OSG_GLSL_VERSION\n" "\n" "\n" " // use multi-sampling to provide high quality antialised fragments\n" - " vec2 origin = texCoord - dx*0.5 - dy*0.5;\n" + " vec2 origin = src_texCoord - dx*0.5 - dy*0.5;\n" " for(;numSamplesY>0; --numSamplesY)\n" " {\n" " vec2 pos = origin;\n" @@ -164,16 +164,16 @@ char text_sdf_frag[] = "$OSG_GLSL_VERSION\n" "\n" "#else\n" "\n" - "vec4 textureColor()\n" + "vec4 textColor(vec2 src_texCoord)\n" "{\n" - " float alpha = TEXTURE(glyphTexture, texCoord).a;\n" "\n" "#ifdef OUTLINE\n" "\n" + " float alpha = TEXTURE(glyphTexture, src_texCoord).a;\n" " float delta_tc = 1.6*OUTLINE*GLYPH_DIMENSION/TEXTURE_DIMENSION;\n" "\n" " float outline_alpha = alpha;\n" - " vec2 origin = texCoord-vec2(delta_tc*0.5, delta_tc*0.5);\n" + " vec2 origin = src_texCoord-vec2(delta_tc*0.5, delta_tc*0.5);\n" "\n" " float numSamples = 3.0;\n" " delta_tc = delta_tc/(numSamples-1);\n" @@ -191,7 +191,7 @@ char text_sdf_frag[] = "$OSG_GLSL_VERSION\n" " }\n" "\n" " #ifdef osg_TextureQueryLOD\n" - " float mipmapLevel = osg_TextureQueryLOD(glyphTexture, texCoord).x;\n" + " float mipmapLevel = osg_TextureQueryLOD(glyphTexture, src_texCoord).x;\n" " if (mipmapLevel<1.0)\n" " {\n" " outline_alpha = mix(1.0-background_alpha, outline_alpha, mipmapLevel/1.0);\n" @@ -209,8 +209,11 @@ char text_sdf_frag[] = "$OSG_GLSL_VERSION\n" " return color;\n" "\n" "#else\n" + "\n" + " float alpha = TEXTURE(glyphTexture, src_texCoord).a;\n" " if (alpha==0.0) vec4(0.0, 0.0, 0.0, 0.0);\n" " return vec4(vertexColor.rgb, vertexColor.a * alpha);\n" + "\n" "#endif\n" "}\n" "\n" @@ -225,10 +228,16 @@ char text_sdf_frag[] = "$OSG_GLSL_VERSION\n" " return;\n" " }\n" "\n" - "#ifdef SIGNED_DISTNACE_FIELD\n" - " vec4 color = distanceFieldColor();\n" + "#ifdef SHADOW\n" + " float scale = -1.0*GLYPH_DIMENSION/TEXTURE_DIMENSION;\n" + " vec2 delta_tc = SHADOW*scale;\n" + " vec4 shadow_color = textColor(texCoord+delta_tc);\n" + " shadow_color.rgb = BACKDROP_COLOR.rgb;\n" + "\n" + " vec4 glyph_color = textColor(texCoord);\n" + " vec4 color = mix(shadow_color, glyph_color, glyph_color.a);\n" "#else\n" - " vec4 color = textureColor();\n" + " vec4 color = textColor(texCoord);\n" "#endif\n" "\n" " if (color.a==0.0) discard;\n" From b540ed70ba7d3ab59d33338851b8774c9f0c9d69 Mon Sep 17 00:00:00 2001 From: Julien Valentin Date: Thu, 12 Oct 2017 17:19:24 +0200 Subject: [PATCH 130/327] add osg::Program::BindUniformBlock serialization --- src/osgWrappers/serializers/osg/Program.cpp | 37 +++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/src/osgWrappers/serializers/osg/Program.cpp b/src/osgWrappers/serializers/osg/Program.cpp index d00096d5c..1513aa484 100644 --- a/src/osgWrappers/serializers/osg/Program.cpp +++ b/src/osgWrappers/serializers/osg/Program.cpp @@ -145,6 +145,39 @@ static bool writeComputeGroups( osgDB::OutputStream& os, const osg::Program& att return true; } +static bool checkBindUniformBlock( const osg::Program& node ) +{ + return true; +} + +static bool readBindUniformBlock( osgDB::InputStream& is, osg::Program& p ) +{ + unsigned int size = 0; is >> size >> is.BEGIN_BRACKET; + std::string name; unsigned int index; + for ( unsigned int i=0; i>name; is >>index; + p.addBindUniformBlock(name, index); + } + is >> is.END_BRACKET; + return true; +} + + +static bool writeBindUniformBlock( osgDB::OutputStream& os, const osg::Program& p ) +{ + unsigned int size = p.getUniformBlockBindingList().size(); + os << size << os.BEGIN_BRACKET << std::endl; + for(osg::Program::UniformBlockBindingList::const_iterator bbit = p.getUniformBlockBindingList().begin(); + bbit != p.getUniformBlockBindingList().end(); ++bbit) + { + os << bbit->first; + os << bbit->second; + } + os << os.END_BRACKET << std::endl; + return true; +} + REGISTER_OBJECT_WRAPPER( Program, new osg::Program, osg::Program, @@ -167,4 +200,8 @@ REGISTER_OBJECT_WRAPPER( Program, ADD_USER_SERIALIZER( FeedBackVaryingsName ); ADD_USER_SERIALIZER( FeedBackMode ); } + { + UPDATE_TO_VERSION_SCOPED( 150 ) + ADD_USER_SERIALIZER( BindUniformBlock ); + } } From 28561b2b7705f751657984a8371790ac8b9fc60f Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Fri, 13 Oct 2017 08:40:58 +0100 Subject: [PATCH 131/327] Removed old multipass implemenmtations of backdrops as effect is now fully implememted in shaders --- include/osgText/Text | 3 +- src/osgText/Text.cpp | 226 +++---------------------------------------- 2 files changed, 13 insertions(+), 216 deletions(-) diff --git a/include/osgText/Text b/include/osgText/Text index fc6fbfc0f..95b8e7d46 100644 --- a/include/osgText/Text +++ b/include/osgText/Text @@ -231,7 +231,7 @@ public: typedef std::vector Glyphs; Glyphs _glyphs; - Primitives _primitives; + osg::ref_ptr _primitives; GlyphQuads(); GlyphQuads(const GlyphQuads& gq); @@ -296,7 +296,6 @@ protected: virtual void computePositionsImplementation(); - void computeBackdropPositions(); void computeBackdropBoundingBox(); void computeBoundingBoxMargin(); diff --git a/src/osgText/Text.cpp b/src/osgText/Text.cpp index 23d146372..7f05d1021 100644 --- a/src/osgText/Text.cpp +++ b/src/osgText/Text.cpp @@ -380,18 +380,14 @@ void Text::addGlyphQuad(Glyph* glyph, const osg::Vec2& minc, const osg::Vec2& ma glyphquad._glyphs.push_back(glyph); - osg::DrawElements* primitives = 0; - if (glyphquad._primitives.empty()) + osg::DrawElements* primitives = glyphquad._primitives.get(); + if (!primitives) { unsigned int maxIndices = _text.size()*4; if (maxIndices>=16384) primitives = new osg::DrawElementsUInt(GL_TRIANGLES); else primitives = new osg::DrawElementsUShort(GL_TRIANGLES); primitives->setBufferObject(_ebo.get()); - glyphquad._primitives.push_back(primitives); - } - else - { - primitives = glyphquad._primitives[0].get(); + glyphquad._primitives = primitives; } @@ -431,25 +427,18 @@ void Text::computeGlyphRepresentation() if (!_texcoords) { _texcoords = new osg::Vec2Array(osg::Array::BIND_PER_VERTEX); _texcoords->setBufferObject(_vbo.get()); } else _texcoords->clear(); -#if 0 - _textureGlyphQuadMap.clear(); -#else for(TextureGlyphQuadMap::iterator itr = _textureGlyphQuadMap.begin(); itr != _textureGlyphQuadMap.end(); ++itr) { GlyphQuads& glyphquads = itr->second; glyphquads._glyphs.clear(); - for(Primitives::iterator pitr = glyphquads._primitives.begin(); - pitr != glyphquads._primitives.end(); - ++pitr) + if (glyphquads._primitives.valid()) { - (*pitr)->resizeElements(0); - (*pitr)->dirty(); + glyphquads._primitives->resizeElements(0); + glyphquads._primitives->dirty(); } } -#endif - _lineCount = 0; @@ -774,153 +763,10 @@ void Text::computePositionsImplementation() { TextBase::computePositionsImplementation(); - computeBackdropPositions(); computeBackdropBoundingBox(); computeBoundingBoxMargin(); } -// Presumes the atc matrix is already up-to-date -void Text::computeBackdropPositions() -{ - if(_backdropType == NONE || _backdropImplementation == USE_SHADERS) - { - return; - } - - float avg_width = 0.0f; - float avg_height = 0.0f; - - // FIXME: OPTIMIZE: This function produces the same value regardless of contextID. - // Since we tend to loop over contextID, we should cache this value some how - // instead of recomputing it each time. - bool is_valid_size = computeAverageGlyphWidthAndHeight(avg_width, avg_height); - if (!is_valid_size) return; - - unsigned int backdrop_index; - unsigned int max_backdrop_index; - if(_backdropType == OUTLINE) - { - // For outline, we want to draw the in every direction - backdrop_index = 1; - max_backdrop_index = backdrop_index+8; - } - else - { - // Yes, this may seem a little strange, - // but since the code is using references, - // I would have to duplicate the following code twice - // for each part of the if/else because I can't - // declare a reference without setting it immediately - // and it wouldn't survive the scope. - // So it happens that the _backdropType value matches - // the index in the array I want to store the coordinates - // in. So I'll just setup the for-loop so it only does - // the one direction I'm interested in. - backdrop_index = _backdropType+1; - max_backdrop_index = backdrop_index+1; - } - - for( ; backdrop_index < max_backdrop_index; backdrop_index++) - { - float horizontal_shift_direction; - float vertical_shift_direction; - switch(backdrop_index-1) - { - case DROP_SHADOW_BOTTOM_RIGHT: - { - horizontal_shift_direction = 1.0f; - vertical_shift_direction = -1.0f; - break; - } - case DROP_SHADOW_CENTER_RIGHT: - { - horizontal_shift_direction = 1.0f; - vertical_shift_direction = 0.0f; - break; - } - case DROP_SHADOW_TOP_RIGHT: - { - horizontal_shift_direction = 1.0f; - vertical_shift_direction = 1.0f; - break; - } - case DROP_SHADOW_BOTTOM_CENTER: - { - horizontal_shift_direction = 0.0f; - vertical_shift_direction = -1.0f; - break; - } - case DROP_SHADOW_TOP_CENTER: - { - horizontal_shift_direction = 0.0f; - vertical_shift_direction = 1.0f; - break; - } - case DROP_SHADOW_BOTTOM_LEFT: - { - horizontal_shift_direction = -1.0f; - vertical_shift_direction = -1.0f; - break; - } - case DROP_SHADOW_CENTER_LEFT: - { - horizontal_shift_direction = -1.0f; - vertical_shift_direction = 0.0f; - break; - } - case DROP_SHADOW_TOP_LEFT: - { - horizontal_shift_direction = -1.0f; - vertical_shift_direction = 1.0f; - break; - } - default: // error - { - horizontal_shift_direction = 1.0f; - vertical_shift_direction = -1.0f; - } - } - - // now apply matrix to the glyphs. - for(TextureGlyphQuadMap::iterator titr=_textureGlyphQuadMap.begin(); - titr!=_textureGlyphQuadMap.end(); - ++titr) - { - GlyphQuads& glyphquad = titr->second; - - osg::DrawElements* src_primitives = glyphquad._primitives[0].get(); - - for(unsigned int i=glyphquad._primitives.size(); i<=backdrop_index; ++i) - { - osg::DrawElementsUShort* dst_primitives = new osg::DrawElementsUShort(GL_TRIANGLES); - dst_primitives->setBufferObject(src_primitives->getBufferObject()); - glyphquad._primitives.push_back(dst_primitives); - } - - osg::DrawElements* dst_primitives = glyphquad._primitives[backdrop_index].get(); - dst_primitives->resizeElements(0); - - unsigned int numCoords = src_primitives->getNumIndices(); - - Coords& src_coords = _coords; - TexCoords& src_texcoords = _texcoords; - - Coords& dst_coords = _coords; - TexCoords& dst_texcoords = _texcoords; - - for(unsigned int i=0;isize(); - (*dst_primitives).addElement(di); - (*dst_coords).push_back(v); - (*dst_texcoords).push_back((*src_texcoords)[si]); - } - } - } -} - // This method adjusts the bounding box to account for the expanded area caused by the backdrop. // This assumes that the bounding box has already been computed for the text without the backdrop. void Text::computeBackdropBoundingBox() @@ -1269,7 +1115,6 @@ void Text::drawImplementationSinglePass(osg::State& state, const osg::Vec4& colo } if (_drawMode & TEXT) -// if (false) { for(TextureGlyphQuadMap::const_iterator titr=_textureGlyphQuadMap.begin(); titr!=_textureGlyphQuadMap.end(); @@ -1280,39 +1125,6 @@ void Text::drawImplementationSinglePass(osg::State& state, const osg::Vec4& colo const GlyphQuads& glyphquad = titr->second; - if(_backdropType != NONE) - { - if (_backdropImplementation != USE_SHADERS) - { - unsigned int backdrop_index; - unsigned int max_backdrop_index; - if(_backdropType == OUTLINE) - { - backdrop_index = 1; - max_backdrop_index = backdrop_index+8; - } - else - { - backdrop_index = _backdropType+1; - max_backdrop_index = backdrop_index+1; - } - - if (max_backdrop_index>glyphquad._primitives.size()) max_backdrop_index=glyphquad._primitives.size(); - - state.disableColorPointer(); - state.Color(_backdropColor.r(),_backdropColor.g(),_backdropColor.b(),_backdropColor.a()); - - for( ; backdrop_index < max_backdrop_index; backdrop_index++) - { - glyphquad._primitives[backdrop_index]->draw(state, usingVertexBufferObjects); - } - } - else - { - // OSG_NOTICE<<"Using shaders for backdrop"<disableColorArray(state); @@ -1326,7 +1138,7 @@ void Text::drawImplementationSinglePass(osg::State& state, const osg::Vec4& colo } } - glyphquad._primitives[0]->draw(state, usingVertexBufferObjects); + glyphquad._primitives->draw(state, usingVertexBufferObjects); } } } @@ -1374,9 +1186,6 @@ void Text::drawImplementation(osg::State& state, const osg::Vec4& colorMultiplie vas->applyDisablingOfVertexAttributes(state); } -#if 0 - drawImplementationSinglePass(state, colorMultiplier); -#else glDepthMask(GL_FALSE); drawImplementationSinglePass(state, colorMultiplier); @@ -1393,7 +1202,6 @@ void Text::drawImplementation(osg::State& state, const osg::Vec4& colorMultiplie } state.haveAppliedAttribute(osg::StateAttribute::DEPTH); -#endif if (usingVertexBufferObjects && !usingVertexArrayObjects) { @@ -1431,16 +1239,16 @@ void Text::accept(osg::PrimitiveFunctor& pf) const ++titr) { const GlyphQuads& glyphquad = titr->second; - if (!glyphquad._primitives.empty()) + if (glyphquad._primitives.valid()) { - const osg::DrawElementsUShort* drawElementsUShort = dynamic_cast(glyphquad._primitives[0].get()); + const osg::DrawElementsUShort* drawElementsUShort = dynamic_cast(glyphquad._primitives.get()); if (drawElementsUShort) { pf.drawElements(GL_TRIANGLES, drawElementsUShort->size(), &(drawElementsUShort->front())); } else { - const osg::DrawElementsUInt* drawElementsUInt = dynamic_cast(glyphquad._primitives[0].get()); + const osg::DrawElementsUInt* drawElementsUInt = dynamic_cast(glyphquad._primitives.get()); if (drawElementsUInt) { pf.drawElements(GL_TRIANGLES, drawElementsUInt->size(), &(drawElementsUInt->front())); @@ -1563,20 +1371,10 @@ Text::GlyphQuads::GlyphQuads(const GlyphQuads&) void Text::GlyphQuads::resizeGLObjectBuffers(unsigned int maxSize) { - for(Primitives::iterator itr = _primitives.begin(); - itr != _primitives.end(); - ++itr) - { - (*itr)->resizeGLObjectBuffers(maxSize); - } + if (_primitives.valid()) _primitives->resizeGLObjectBuffers(maxSize); } void Text::GlyphQuads::releaseGLObjects(osg::State* state) const { - for(Primitives::const_iterator itr = _primitives.begin(); - itr != _primitives.end(); - ++itr) - { - (*itr)->releaseGLObjects(state); - } + if (_primitives.valid()) _primitives->releaseGLObjects(state); } From 8b12d2d71a1cfd680d3ed9c27c56b744c178070f Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Fri, 13 Oct 2017 11:42:25 +0100 Subject: [PATCH 132/327] Deprecated Text:BackdropImplementation, removing the backend as it no longer required when using shaders for backdrop effects --- examples/osgSSBO/osgSSBO.cpp | 1 - examples/osgfont/osgfont.cpp | 5 -- examples/osglogo/osglogo.cpp | 2 - examples/osgviewerCocoa/ViewerCocoa.mm | 1 - examples/osgwidgetlabel/osgwidgetlabel.cpp | 6 --- include/osgText/Text | 54 +++++-------------- src/osgPlugins/ive/Text.cpp | 4 +- src/osgText/Text.cpp | 34 +----------- src/osgWidget/Label.cpp | 1 - .../deprecated-dotosg/osgText/IO_Text.cpp | 30 ----------- 10 files changed, 17 insertions(+), 121 deletions(-) diff --git a/examples/osgSSBO/osgSSBO.cpp b/examples/osgSSBO/osgSSBO.cpp index 9db8161dc..2fa6c21d0 100644 --- a/examples/osgSSBO/osgSSBO.cpp +++ b/examples/osgSSBO/osgSSBO.cpp @@ -473,7 +473,6 @@ void ComputeNode::addDataMonitor(osg::Vec3 placement, osg::Vec3 relativePlacemen pat->setName(labelCaption); text->setText(pat->getName()); text->setBackdropType(osgText::Text::OUTLINE); - text->setBackdropImplementation(osgText::Text::POLYGON_OFFSET); text->setBackdropOffset(0.05f); text->setBackdropColor(osg::Vec4(0.0f, 0.0f, 0.0f, 1.0f)); diff --git a/examples/osgfont/osgfont.cpp b/examples/osgfont/osgfont.cpp index b39b19b59..b20ad43e1 100644 --- a/examples/osgfont/osgfont.cpp +++ b/examples/osgfont/osgfont.cpp @@ -161,11 +161,6 @@ struct TextSettings text.setBackdropOffset(backdropOffset.x(), backdropOffset.y()); text.setBackdropColor(backdropColor); - if (glyphTextureFeatures==osgText::GlyphTexture::ALL_FEATURES) - { - text.setBackdropImplementation(osgText::Text::USE_SHADERS); - } - text.setFont(font.get()); } diff --git a/examples/osglogo/osglogo.cpp b/examples/osglogo/osglogo.cpp index 9d02e6141..fe8a12475 100644 --- a/examples/osglogo/osglogo.cpp +++ b/examples/osglogo/osglogo.cpp @@ -154,7 +154,6 @@ osg:: Node* createTextBelow(const osg::BoundingBox& bb, const std::string& label if (s_useSDF) { text->getFont()->setGyphTextureFeatures(osgText::GlyphTexture::ALL_FEATURES); - text->setBackdropImplementation(osgText::Text::USE_SHADERS); } text->setAlignment(osgText::Text::CENTER_CENTER); @@ -188,7 +187,6 @@ osg:: Node* createTextLeft(const osg::BoundingBox& bb, const std::string& label, if (s_useSDF) { text->getFont()->setGyphTextureFeatures(osgText::GlyphTexture::ALL_FEATURES); - text->setBackdropImplementation(osgText::Text::USE_SHADERS); } text->setAlignment(osgText::Text::RIGHT_CENTER); diff --git a/examples/osgviewerCocoa/ViewerCocoa.mm b/examples/osgviewerCocoa/ViewerCocoa.mm index aded53820..84333c449 100644 --- a/examples/osgviewerCocoa/ViewerCocoa.mm +++ b/examples/osgviewerCocoa/ViewerCocoa.mm @@ -432,7 +432,6 @@ static void Internal_SetAlpha(NSBitmapImageRep *imageRep, unsigned char alpha_va default_text->setAlignment(osgText::Text::CENTER_CENTER); default_text->setBackdropType(osgText::Text::OUTLINE); -// default_text->setBackdropImplementation(osgText::Text::POLYGON_OFFSET); default_text->setColor(osg::Vec4(1.0, 1.0, 0.0, 1.0)); default_text->setBackdropColor(osg::Vec4(0.0, 0.0, 0.0, 1.0)); default_text->setAxisAlignment(osgText::Text::XZ_PLANE); diff --git a/examples/osgwidgetlabel/osgwidgetlabel.cpp b/examples/osgwidgetlabel/osgwidgetlabel.cpp index 39d86fefe..a29320cdf 100644 --- a/examples/osgwidgetlabel/osgwidgetlabel.cpp +++ b/examples/osgwidgetlabel/osgwidgetlabel.cpp @@ -30,12 +30,6 @@ osgWidget::Label* createLabel(const std::string& l, unsigned int size=13) { label->setFontColor(1.0f, 1.0f, 1.0f, 1.0f); label->setLabel(l); - /* - text->setBackdropType(osgText::Text::DROP_SHADOW_BOTTOM_RIGHT); - text->setBackdropImplementation(osgText::Text::NO_DEPTH_BUFFER); - text->setBackdropOffset(0.2f); - */ - return label; } diff --git a/include/osgText/Text b/include/osgText/Text index 95b8e7d46..acb8323f9 100644 --- a/include/osgText/Text +++ b/include/osgText/Text @@ -60,33 +60,6 @@ public: NONE }; - enum BackdropImplementation - { - /* No longer supported, naps to DELAYED_DEPTH_WRITES.*/ - POLYGON_OFFSET = 0, - - /* No longer supported, naps to DELAYED_DEPTH_WRITES.*/ - NO_DEPTH_BUFFER, - - /* No longer supported, naps to DELAYED_DEPTH_WRITES.*/ - DEPTH_RANGE, - - /* No longer supported, naps to DELAYED_DEPTH_WRITES.*/ - STENCIL_BUFFER, - - /* DELAYED_DEPTH_WRITES - * This mode renders all text with depth writes turned off, then - * again with depth writes on, but with the color buffer disabled. - * This should render text accurately for all graphics cards. The - * only downside is the additional pass to render to the depth - * buffer. But if you don't need the depth buffer updated for - * your, this extra pass can be disabled by calling - * enableDepthWrites(false).*/ - DELAYED_DEPTH_WRITES, - - USE_SHADERS - }; - /** * BackdropType gives you a background shadow text behind your regular * text. This helps give text extra contrast which can be useful when @@ -141,18 +114,6 @@ public: const osg::Vec4& getBackdropColor() const { return _backdropColor; } - /** - * This specifies the underlying backdrop rendering implementation. - * Unfortunately, at this time, there is no "perfect" rendering solution - * so this function is provided to let you 'pick your poison'. Each - * implementation has trade-offs. See BackdropImplementation enum - * docs for details.*/ - void setBackdropImplementation(BackdropImplementation implementation); - - BackdropImplementation getBackdropImplementation() const { return _backdropImplementation; } - - - enum ColorGradientMode { SOLID = 0, // a.k.a. ColorGradients off @@ -224,6 +185,20 @@ public: public: + /** deprecated, value ignored.*/ + enum BackdropImplementation + { + POLYGON_OFFSET = 0, + NO_DEPTH_BUFFER, + DEPTH_RANGE, + STENCIL_BUFFER, + DELAYED_DEPTH_WRITES + }; + + /** deprecated, value ignored.*/ + void setBackdropImplementation(BackdropImplementation) {} + /** deprecated, value should be ignored.*/ + BackdropImplementation getBackdropImplementation() const { return DELAYED_DEPTH_WRITES; } // internal structures, variable and methods used for rendering of characters. struct OSGTEXT_EXPORT GlyphQuads @@ -310,7 +285,6 @@ protected: bool _enableDepthWrites; BackdropType _backdropType; - BackdropImplementation _backdropImplementation; float _backdropHorizontalOffset; float _backdropVerticalOffset; diff --git a/src/osgPlugins/ive/Text.cpp b/src/osgPlugins/ive/Text.cpp index ae9da298f..0139695c5 100644 --- a/src/osgPlugins/ive/Text.cpp +++ b/src/osgPlugins/ive/Text.cpp @@ -90,7 +90,7 @@ void Text::write(DataOutputStream* out){ out->writeFloat(getBackdropVerticalOffset()); out->writeVec4(getBackdropColor()); - out->writeUInt(getBackdropImplementation()); + out->writeUInt(4); // old DELAYED_DEPTH_WRITES out->writeUInt(getColorGradientMode()); out->writeVec4(getColorGradientTopLeft()); @@ -213,7 +213,7 @@ void Text::read(DataInputStream* in){ setBackdropOffset(horizontalOffset,verticalOffset); setBackdropColor(in->readVec4()); - setBackdropImplementation((osgText::Text::BackdropImplementation) in->readUInt()); + in->readUInt(); // read old BackdropImplementation value, no longer used setColorGradientMode((osgText::Text::ColorGradientMode) in->readUInt()); osg::Vec4 colorGradientTopLeft,colorGradientBottomLeft,colorGradientBottomRight,colorGradientTopRight; diff --git a/src/osgText/Text.cpp b/src/osgText/Text.cpp index 7f05d1021..54cd841c1 100644 --- a/src/osgText/Text.cpp +++ b/src/osgText/Text.cpp @@ -31,11 +31,6 @@ using namespace osgText; Text::Text(): _enableDepthWrites(true), _backdropType(NONE), -#if 1 - _backdropImplementation(DELAYED_DEPTH_WRITES), -#else - _backdropImplementation(USE_SHADERS), -#endif _backdropHorizontalOffset(0.07f), _backdropVerticalOffset(0.07f), _backdropColor(0.0f, 0.0f, 0.0f, 1.0f), @@ -47,17 +42,6 @@ Text::Text(): { _supportsVertexBufferObjects = true; - char *ptr; - if ((ptr = getenv("OSG_SDF_TEXT")) != 0) - { - _backdropImplementation = USE_SHADERS; - } - else if ((ptr = getenv("OSG_GREYSCALE_TEXT")) != 0) - { - _backdropImplementation = DELAYED_DEPTH_WRITES; - } - - assignStateSet(); } @@ -65,7 +49,6 @@ Text::Text(const Text& text,const osg::CopyOp& copyop): osgText::TextBase(text,copyop), _enableDepthWrites(text._enableDepthWrites), _backdropType(text._backdropType), - _backdropImplementation(text._backdropImplementation), _backdropHorizontalOffset(text._backdropHorizontalOffset), _backdropVerticalOffset(text._backdropVerticalOffset), _backdropColor(text._backdropColor), @@ -93,7 +76,7 @@ osg::StateSet* Text::createStateSet() std::stringstream ss; osg::StateSet::DefineList defineList; - if (_backdropType!=NONE && _backdropImplementation==USE_SHADERS) + if (_backdropType!=NONE) { ss.str(""); ss << "vec4("<<_backdropColor.r()<<", "<<_backdropColor.g()<<", "<<_backdropColor.b()<<", "<<_backdropColor.a()<<")"; @@ -128,8 +111,6 @@ osg::StateSet* Text::createStateSet() defineList["SHADOW"] = osg::StateSet::DefinePair(ss.str(), osg::StateAttribute::ON); } - - } if (activeFont->getGlyphTextureFeatures()!=GlyphTexture::GREYSCALE) @@ -147,7 +128,6 @@ osg::StateSet* Text::createStateSet() } #if 0 - OSG_NOTICE<<"Text::createStateSet() _backdropType="<<_backdropType<<", _backdropImplementation="<<_backdropImplementation<setBackdropType(osgText::Text::DROP_SHADOW_BOTTOM_RIGHT); - _text->setBackdropImplementation(osgText::Text::NO_DEPTH_BUFFER); _text->setBackdropOffset(offset); _calculateSize(getTextSize()); diff --git a/src/osgWrappers/deprecated-dotosg/osgText/IO_Text.cpp b/src/osgWrappers/deprecated-dotosg/osgText/IO_Text.cpp index e34c1d46e..c2bb99e6a 100644 --- a/src/osgWrappers/deprecated-dotosg/osgText/IO_Text.cpp +++ b/src/osgWrappers/deprecated-dotosg/osgText/IO_Text.cpp @@ -57,27 +57,6 @@ std::string convertBackdropTypeEnumToString(osgText::Text::BackdropType backdrop } } - -osgText::Text::BackdropImplementation convertBackdropImplementationStringToEnum(std::string & str) -{ - if (str=="POLYGON_OFFSET") return osgText::Text::POLYGON_OFFSET; - else if (str=="NO_DEPTH_BUFFER") return osgText::Text::NO_DEPTH_BUFFER; - else if (str=="DEPTH_RANGE") return osgText::Text::DEPTH_RANGE; - else if (str=="STENCIL_BUFFER") return osgText::Text::STENCIL_BUFFER; - else return static_cast(-1); -} -std::string convertBackdropImplementationEnumToString(osgText::Text::BackdropImplementation backdropImplementation) -{ - switch (backdropImplementation) - { - case osgText::Text::POLYGON_OFFSET: return "POLYGON_OFFSET"; - case osgText::Text::NO_DEPTH_BUFFER: return "NO_DEPTH_BUFFER"; - case osgText::Text::DEPTH_RANGE: return "DEPTH_RANGE"; - case osgText::Text::STENCIL_BUFFER: return "STENCIL_BUFFER"; - default : return ""; - } -} - osgText::Text::ColorGradientMode convertColorGradientModeStringToEnum(std::string & str) { if (str=="SOLID") return osgText::Text::SOLID; @@ -155,12 +134,6 @@ bool Text_readLocalData(osg::Object &obj, osgDB::Input &fr) // backdropImplementation if (fr[0].matchWord("backdropImplementation")) { - std::string str = fr[1].getStr(); - osgText::Text::BackdropImplementation backdropImplementation = convertBackdropImplementationStringToEnum(str); - - if (backdropImplementation != static_cast(-1)) - text.setBackdropImplementation(backdropImplementation); - fr += 2; itAdvanced = true; } @@ -254,9 +227,6 @@ bool Text_writeLocalData(const osg::Object &obj, osgDB::Output &fw) osg::Vec4 c = text.getBackdropColor(); fw.indent() << "backdropColor " << c.x() << " " << c.y() << " " << c.z() << " " << c.w() << std::endl; - // backdropImplementation - fw.indent() << "backdropImplementation " << convertBackdropImplementationEnumToString(text.getBackdropImplementation()) << std::endl; - // colorGradientMode fw.indent() << "colorGradientMode " << convertColorGradientModeEnumToString(text.getColorGradientMode()) << std::endl; From 24bec09b9e56fe87044ffae1f0203e988110e8a2 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Fri, 13 Oct 2017 13:01:57 +0100 Subject: [PATCH 133/327] Removed the glyph image outline support as it's no longer required. --- examples/osgfont/osgfont.cpp | 1 - include/osgText/Glyph | 1 - src/osgText/Glyph.cpp | 84 ++---------------------------------- 3 files changed, 4 insertions(+), 82 deletions(-) diff --git a/examples/osgfont/osgfont.cpp b/examples/osgfont/osgfont.cpp index b20ad43e1..f65e607fc 100644 --- a/examples/osgfont/osgfont.cpp +++ b/examples/osgfont/osgfont.cpp @@ -103,7 +103,6 @@ struct TextSettings } if (arguments.read("--GREYSCALE")) { glyphTextureFeatures = osgText::GlyphTexture::GREYSCALE; } - if (arguments.read("--OUTLINE_GREYSCALE")) { glyphTextureFeatures = osgText::GlyphTexture::OUTLINE_GREYSCALE; } if (arguments.read("--SIGNED_DISTANCE_FIELD")) { glyphTextureFeatures = osgText::GlyphTexture::SIGNED_DISTANCE_FIELD; } if (arguments.read("--ALL_FEATURES")) { glyphTextureFeatures = osgText::GlyphTexture::ALL_FEATURES; } diff --git a/include/osgText/Glyph b/include/osgText/Glyph index fb842eb8b..5dcfd12b3 100644 --- a/include/osgText/Glyph +++ b/include/osgText/Glyph @@ -263,7 +263,6 @@ public: enum Features { GREYSCALE, - OUTLINE_GREYSCALE, SIGNED_DISTANCE_FIELD, ALL_FEATURES }; diff --git a/src/osgText/Glyph.cpp b/src/osgText/Glyph.cpp index e8a11ea87..8ca21f5bc 100644 --- a/src/osgText/Glyph.cpp +++ b/src/osgText/Glyph.cpp @@ -32,7 +32,7 @@ using namespace std; #define TEXTURE_IMAGE_NUM_CHANNELS 1 #define TEXTURE_IMAGE_FORMAT OSGTEXT_GLYPH_FORMAT #else - #define TEXTURE_IMAGE_NUM_CHANNELS 4 + #define TEXTURE_IMAGE_NUM_CHANNELS 2 #define TEXTURE_IMAGE_FORMAT GL_RGBA #endif @@ -60,9 +60,7 @@ int GlyphTexture::compare(const osg::StateAttribute& rhs) const int GlyphTexture::getEffectMargin(const Glyph* glyph) { if (_glyphTextureFeatures==GREYSCALE) return 0; -// else return glyph->getFontResolution().second/4; else return osg::maximum(glyph->getFontResolution().second/6, 2u); -// else return osg::maximum(glyph->getFontResolution().second/8,1u); } int GlyphTexture::getTexelMargin(const Glyph* glyph) @@ -195,10 +193,6 @@ void GlyphTexture::copyGlyphImage(Glyph* glyph) if ((lower+glyph->getTexturePositionY())<0) lower = -glyph->getTexturePositionY(); if ((upper+glyph->getTexturePositionY())>=dest_rows) upper = dest_rows-glyph->getTexturePositionY()-1; - bool use_SDF_for_Outline = true; - - float outer_outline_distance = float(glyph->getFontResolution().first)*0.1f; - float inner_outline_distance = outer_outline_distance*0.5f; unsigned char full_on = 255; unsigned char mid_point = full_on/2; @@ -213,17 +207,11 @@ void GlyphTexture::copyGlyphImage(Glyph* glyph) unsigned char center_value = 0; if (dr>=0 && dr=0 && dc0 && center_value=mid_point_f) { min_distance = center_value_f-mid_point_f; @@ -263,9 +251,6 @@ void GlyphTexture::copyGlyphImage(Glyph* glyph) else local_distance += (local_value_f - mid_point_f)*local_multiplier; if (local_distanceinner_max_value && local_distance<=inner_outline_distance) inner_max_value = local_value; - if (local_value>outer_max_value && local_distance<=outer_outline_distance) outer_max_value = local_value; } } @@ -291,9 +276,6 @@ void GlyphTexture::copyGlyphImage(Glyph* glyph) else local_distance += (local_value_f - mid_point_f)*local_multiplier; if (local_distanceinner_max_value && local_distance<=inner_outline_distance) inner_max_value = local_value; - if (local_value>outer_max_value && local_distance<=outer_outline_distance) outer_max_value = local_value; } } @@ -320,9 +302,6 @@ void GlyphTexture::copyGlyphImage(Glyph* glyph) else local_distance += (local_value_f - mid_point_f)*local_multiplier; if (local_distanceinner_max_value && local_distance<=inner_outline_distance) inner_max_value = local_value; - if (local_value>outer_max_value && local_distance<=outer_outline_distance) outer_max_value = local_value; } } @@ -348,9 +327,6 @@ void GlyphTexture::copyGlyphImage(Glyph* glyph) else local_distance += (local_value_f - mid_point_f)*local_multiplier; if (local_distanceinner_max_value && local_distance<=inner_outline_distance) inner_max_value = local_value; - if (local_value>outer_max_value && local_distance<=outer_outline_distance) outer_max_value = local_value; } } } @@ -368,63 +344,11 @@ void GlyphTexture::copyGlyphImage(Glyph* glyph) unsigned char* dest_ptr = dest_data + (dr*dest_columns + dc)*num_channels; - if (num_channels==4) + if (num_channels==2) { // signed distance field value *(dest_ptr++) = value; - float outline_distance = inner_outline_distance; - - // compute the alpha value of outline, one texel thick - unsigned char outline = 0; - - if (use_SDF_for_Outline) - { - if (center_value<255) - { - float inner_outline = outline_distance-1.0f; - if (min_distancecenter_value) - { - outline -= center_value; - } - } - else - { - outline = inner_max_value-center_value; - } - - *(dest_ptr++) = outline; - - - outline_distance = outer_outline_distance; - - // compute the alpha value of outline, one texel thick - outline = 0; - if (use_SDF_for_Outline) - { - if (center_value<255) - { - float inner_outline = outline_distance-1.0f; - if (min_distancecenter_value) - { - outline -= center_value; - } - } - else - { - outline = outer_max_value-center_value; - } - - *(dest_ptr++) = outline; - // original alpha value from glyph image *(dest_ptr) = center_value; } @@ -468,9 +392,9 @@ osg::Image* GlyphTexture::createImage() _image = new osg::Image; #if defined(OSG_GL3_AVAILABLE) && !defined(OSG_GL2_AVAILABLE) && !defined(OSG_GL1_AVAILABLE) - GLenum imageFormat = (_glyphTextureFeatures==GREYSCALE) ? GL_RED : GL_RGBA; + GLenum imageFormat = (_glyphTextureFeatures==GREYSCALE) ? GL_RED : GL_RG; #else - GLenum imageFormat = (_glyphTextureFeatures==GREYSCALE) ? GL_ALPHA : GL_RGBA; + GLenum imageFormat = (_glyphTextureFeatures==GREYSCALE) ? GL_ALPHA : GL_LUMINANCE_ALPHA; #endif _image->allocateImage(getTextureWidth(), getTextureHeight(), 1, imageFormat, GL_UNSIGNED_BYTE); From 274cea19bf9ae0e8e598dde3686c2671b50e1623 Mon Sep 17 00:00:00 2001 From: Laurens Voerman Date: Fri, 13 Oct 2017 16:54:04 +0200 Subject: [PATCH 134/327] copySubImage support for block compressed images, added support for astc compressed type. --- include/osg/Image | 39 ++++++ src/osg/Image.cpp | 327 +++++++++++++++++++++++++++++++++++++++------- 2 files changed, 319 insertions(+), 47 deletions(-) diff --git a/include/osg/Image b/include/osg/Image index 663761c80..4bf7df74b 100644 --- a/include/osg/Image +++ b/include/osg/Image @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -118,6 +119,38 @@ #define GL_COMPRESSED_SIGNED_RG11_EAC 0x9273 #endif +#ifndef GL_KHR_texture_compression_astc_hdr +#define GL_KHR_texture_compression_astc_hdr 1 +#define GL_COMPRESSED_RGBA_ASTC_4x4_KHR 0x93B0 +#define GL_COMPRESSED_RGBA_ASTC_5x4_KHR 0x93B1 +#define GL_COMPRESSED_RGBA_ASTC_5x5_KHR 0x93B2 +#define GL_COMPRESSED_RGBA_ASTC_6x5_KHR 0x93B3 +#define GL_COMPRESSED_RGBA_ASTC_6x6_KHR 0x93B4 +#define GL_COMPRESSED_RGBA_ASTC_8x5_KHR 0x93B5 +#define GL_COMPRESSED_RGBA_ASTC_8x6_KHR 0x93B6 +#define GL_COMPRESSED_RGBA_ASTC_8x8_KHR 0x93B7 +#define GL_COMPRESSED_RGBA_ASTC_10x5_KHR 0x93B8 +#define GL_COMPRESSED_RGBA_ASTC_10x6_KHR 0x93B9 +#define GL_COMPRESSED_RGBA_ASTC_10x8_KHR 0x93BA +#define GL_COMPRESSED_RGBA_ASTC_10x10_KHR 0x93BB +#define GL_COMPRESSED_RGBA_ASTC_12x10_KHR 0x93BC +#define GL_COMPRESSED_RGBA_ASTC_12x12_KHR 0x93BD +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR 0x93D0 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR 0x93D1 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR 0x93D2 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR 0x93D3 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR 0x93D4 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR 0x93D5 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR 0x93D6 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR 0x93D7 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR 0x93D8 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR 0x93D9 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR 0x93DA +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR 0x93DB +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR 0x93DC +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR 0x93DD +#endif /* GL_KHR_texture_compression_astc_hdr */ + #ifndef GL_DEPTH_COMPONENT #define GL_DEPTH_COMPONENT 0x1902 #endif @@ -408,11 +441,17 @@ class OSG_EXPORT Image : public BufferData static bool isPackedType(GLenum type); static GLenum computePixelFormat(GLenum pixelFormat); static GLenum computeFormatDataType(GLenum pixelFormat); + + /** return the dimensions of a block of compressed pixels */ + static osg::Vec3i computeBlockFootprint(GLenum pixelFormat); + + /** return the size in bytes of a block of compressed pixels */ static unsigned int computeBlockSize(GLenum pixelFormat, GLenum packing); static unsigned int computeNumComponents(GLenum pixelFormat); static unsigned int computePixelSizeInBits(GLenum pixelFormat,GLenum type); static unsigned int computeRowWidthInBytes(int width,GLenum pixelFormat,GLenum type,int packing); static unsigned int computeImageSizeInBytes(int width,int height, int depth, GLenum pixelFormat, GLenum type, int packing = 1, int slice_packing = 1, int image_packing = 1); + static int roudUpToMultiple(int s, int pack); static int computeNearestPowerOfTwo(int s,float bias=0.5f); static int computeNumberOfMipmapLevels(int s,int t = 1, int r = 1); diff --git a/src/osg/Image.cpp b/src/osg/Image.cpp index ed8175e46..e755cc65a 100644 --- a/src/osg/Image.cpp +++ b/src/osg/Image.cpp @@ -241,11 +241,17 @@ Image::Image(const Image& image,const CopyOp& copyop): { unsigned int size = image.getTotalSizeInBytesIncludingMipmaps(); setData(new unsigned char [size],USE_NEW_DELETE); - unsigned char* dest_ptr = _data; - for(DataIterator itr(&image); itr.valid(); ++itr) + if (unsigned char* dest_ptr = _data) { - memcpy(dest_ptr, itr.data(), itr.size()); - dest_ptr += itr.size(); + for(DataIterator itr(&image); itr.valid(); ++itr) + { + memcpy(dest_ptr, itr.data(), itr.size()); + dest_ptr += itr.size(); + } + } + else + { + OSG_WARN<<"Warning: Image::Image(const Image&, const CopyOp&) out of memory, no image copy made."<= GL_COMPRESSED_RGB_S3TC_DXT1_EXT && - pixelFormat <= GL_COMPRESSED_RGBA_S3TC_DXT5_EXT ) - { - width = (width + 3) & ~3; - height = (height + 3) & ~3; - } - - // 3dc ATI formats - // GL_COMPRESSED_RED_RGTC1_EXT 0x8DBB - // GL_COMPRESSED_SIGNED_RED_RGTC1_EXT 0x8DBC - // GL_COMPRESSED_RED_GREEN_RGTC2_EXT 0x8DBD - // GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT 0x8DBE - if( pixelFormat >= GL_COMPRESSED_RED_RGTC1_EXT && - pixelFormat <= GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT ) - { - width = (width + 3) & ~3; - height = (height + 3) & ~3; + int blockSize = computeBlockSize(pixelFormat, 0); + if (blockSize > 0) { + osg::Vec3i footprint = computeBlockFootprint(pixelFormat); + width = (width + footprint.x() - 1) / footprint.x(); + height = (height + footprint.y() - 1) / footprint.y(); + unsigned int size = blockSize * width; + size = roudUpToMultiple(size, packing); + size *= height; + size = roudUpToMultiple(size, slice_packing); + size *= depth; + size = roudUpToMultiple(size, image_packing); + return size; } // compute size of one row @@ -821,6 +984,13 @@ unsigned int Image::computeImageSizeInBytes(int width,int height, int depth, GLe return osg::maximum( size, computeBlockSize(pixelFormat, packing) ); } +int Image::roudUpToMultiple(int s, int pack) { + if (pack < 2) return s; + s += pack - 1; + s -= s % pack; + return s; +} + int Image::computeNearestPowerOfTwo(int s,float bias) { if ((s & (s-1))!=0) @@ -880,6 +1050,34 @@ bool Image::isCompressed() const case(GL_COMPRESSED_SIGNED_R11_EAC): case(GL_COMPRESSED_RG11_EAC): case(GL_COMPRESSED_SIGNED_RG11_EAC): + case (GL_COMPRESSED_RGBA_ASTC_4x4_KHR) : + case (GL_COMPRESSED_RGBA_ASTC_5x4_KHR) : + case (GL_COMPRESSED_RGBA_ASTC_5x5_KHR) : + case (GL_COMPRESSED_RGBA_ASTC_6x5_KHR) : + case (GL_COMPRESSED_RGBA_ASTC_6x6_KHR) : + case (GL_COMPRESSED_RGBA_ASTC_8x5_KHR) : + case (GL_COMPRESSED_RGBA_ASTC_8x6_KHR) : + case (GL_COMPRESSED_RGBA_ASTC_8x8_KHR) : + case (GL_COMPRESSED_RGBA_ASTC_10x5_KHR) : + case (GL_COMPRESSED_RGBA_ASTC_10x6_KHR) : + case (GL_COMPRESSED_RGBA_ASTC_10x8_KHR) : + case (GL_COMPRESSED_RGBA_ASTC_10x10_KHR) : + case (GL_COMPRESSED_RGBA_ASTC_12x10_KHR) : + case (GL_COMPRESSED_RGBA_ASTC_12x12_KHR) : + case (GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR) : + case (GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR) : + case (GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR) : + case (GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR) : + case (GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR) : + case (GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR) : + case (GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR) : + case (GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR) : + case (GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR) : + case (GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR) : + case (GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR) : + case (GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR) : + case (GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR) : + case (GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR) : return true; default: return false; @@ -1189,7 +1387,7 @@ void Image::readImageFromCurrentTexture(unsigned int contextID, bool copyMipMaps unsigned char* data = new unsigned char[total_size]; if (!data) { - OSG_WARN<<"Warning: Image::readImageFromCurrentTexture(..) out of memory, now image read."<s() & 0x3) || (source->t() & 0x3) || (s_offset & 0x3) || (t_offset & 0x3)) + { + OSG_WARN << "Error Image::copySubImage() did not succeed : size " << source->s() << "x" << source->t() << " or offset " << s_offset<< "," << t_offset << " not multiple of 4." << std::endl; + return; + } + } else { + if ((source->s() % footprint.x()) || (source->t() % footprint.y()) || (s_offset % footprint.x()) || (t_offset% footprint.y())) + { + OSG_WARN << "Error Image::copySubImage() did not succeed : size " << source->s() << "x" << source->t() << " or offset " << s_offset << "," << t_offset << " not multiple of footprint " << footprint.x() << "x" << footprint.y() << std::endl; + return; + } + } + unsigned int rowWidthInBlocks = (_s + footprint.x() - 1) / footprint.x(); + unsigned int blockSize = computeBlockSize(_pixelFormat, 0); + data_destination = _data + blockSize * (rowWidthInBlocks * t_offset + (s_offset / footprint.x())); + unsigned int copy_width = (osg::minimum(source->s(), _s - s_offset) + footprint.x() - 1) / footprint.x(); + unsigned int copy_height = (osg::minimum(source->t(), _t - t_offset) + footprint.y() - 1) / footprint.y(); + unsigned int dstRowStep = blockSize * rowWidthInBlocks; + unsigned int srcRowStep = blockSize * (source->_s + footprint.x() - 1) / footprint.x(); + const unsigned char* data_source = source->data(0, 0, 0); + for (unsigned int row = 0; row < copy_height; row += 1) { //copy blocks in a row, footprint.y() rows at a time + memcpy(data_destination, data_source, copy_width * blockSize); + data_source += srcRowStep; + data_destination += dstRowStep; + } + return; + } PixelStorageModes psm; psm.pack_alignment = _packing; psm.pack_row_length = _rowLength!=0 ? _rowLength : _s; @@ -1919,24 +2147,29 @@ Vec4 _readColor(GLenum pixelFormat, T* data,float scale) Vec4 Image::getColor(unsigned int s,unsigned t,unsigned r) const { - if (dxtc_tool::isDXTC(_pixelFormat)) { - unsigned char color[4]; - if (dxtc_tool::CompressedImageGetColor(color, s, t, r, _s, _t, _r, _pixelFormat, _data)) { - return Vec4(((float)color[0]) / 255.0f, ((float)color[1]) / 255.0f, ((float)color[2]) / 255.0f, ((float)color[3]) / 255.0f ); + if (isCompressed(_pixelFormat)) + { + if (dxtc_tool::isDXTC(_pixelFormat)) { + unsigned char color[4]; + if (dxtc_tool::CompressedImageGetColor(color, s, t, r, _s, _t, _r, _pixelFormat, _data)) { + return Vec4(((float)color[0]) / 255.0f, ((float)color[1]) / 255.0f, ((float)color[2]) / 255.0f, ((float)color[3]) / 255.0f ); + } } } - const unsigned char* ptr = data(s,t,r); - - switch(_dataType) + else { - case(GL_BYTE): return _readColor(_pixelFormat, (char*)ptr, 1.0f/128.0f); - case(GL_UNSIGNED_BYTE): return _readColor(_pixelFormat, (unsigned char*)ptr, 1.0f/255.0f); - case(GL_SHORT): return _readColor(_pixelFormat, (short*)ptr, 1.0f/32768.0f); - case(GL_UNSIGNED_SHORT): return _readColor(_pixelFormat, (unsigned short*)ptr, 1.0f/65535.0f); - case(GL_INT): return _readColor(_pixelFormat, (int*)ptr, 1.0f/2147483648.0f); - case(GL_UNSIGNED_INT): return _readColor(_pixelFormat, (unsigned int*)ptr, 1.0f/4294967295.0f); - case(GL_FLOAT): return _readColor(_pixelFormat, (float*)ptr, 1.0f); - case(GL_DOUBLE): return _readColor(_pixelFormat, (double*)ptr, 1.0f); + const unsigned char* ptr = data(s,t,r); + switch(_dataType) + { + case(GL_BYTE): return _readColor(_pixelFormat, (char*)ptr, 1.0f/128.0f); + case(GL_UNSIGNED_BYTE): return _readColor(_pixelFormat, (unsigned char*)ptr, 1.0f/255.0f); + case(GL_SHORT): return _readColor(_pixelFormat, (short*)ptr, 1.0f/32768.0f); + case(GL_UNSIGNED_SHORT): return _readColor(_pixelFormat, (unsigned short*)ptr, 1.0f/65535.0f); + case(GL_INT): return _readColor(_pixelFormat, (int*)ptr, 1.0f/2147483648.0f); + case(GL_UNSIGNED_INT): return _readColor(_pixelFormat, (unsigned int*)ptr, 1.0f/4294967295.0f); + case(GL_FLOAT): return _readColor(_pixelFormat, (float*)ptr, 1.0f); + case(GL_DOUBLE): return _readColor(_pixelFormat, (double*)ptr, 1.0f); + } } return Vec4(1.0f,1.0f,1.0f,1.0f); } From 2303d6afc4a48adf3b7b8a309249b1f834808d42 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Fri, 13 Oct 2017 17:03:31 +0100 Subject: [PATCH 135/327] Cleaned up support for GL3 build --- include/osgText/Glyph | 9 ----- src/osgPlugins/freetype/FreeTypeFont.cpp | 6 ++-- src/osgText/DefaultFont.cpp | 6 ++-- src/osgText/Glyph.cpp | 44 ++++++++++++++++++------ src/osgText/shaders/text_sdf_frag.cpp | 18 +++++++--- 5 files changed, 51 insertions(+), 32 deletions(-) diff --git a/include/osgText/Glyph b/include/osgText/Glyph index 5dcfd12b3..adba880bc 100644 --- a/include/osgText/Glyph +++ b/include/osgText/Glyph @@ -30,15 +30,6 @@ #include -// GL_ALPHA is deprecated in GL3/GL4 core profile, use GL_RED and a shader in this case. See osgText example. -#if defined(OSG_GL3_AVAILABLE) && !defined(OSG_GL2_AVAILABLE) && !defined(OSG_GL1_AVAILABLE) -#define OSGTEXT_GLYPH_FORMAT GL_RED -#define OSGTEXT_GLYPH_INTERNALFORMAT GL_R8 -#else -#define OSGTEXT_GLYPH_FORMAT GL_ALPHA -#define OSGTEXT_GLYPH_INTERNALFORMAT GL_ALPHA -#endif - namespace osgText { class Font; diff --git a/src/osgPlugins/freetype/FreeTypeFont.cpp b/src/osgPlugins/freetype/FreeTypeFont.cpp index 323a874b6..d39f984c2 100644 --- a/src/osgPlugins/freetype/FreeTypeFont.cpp +++ b/src/osgPlugins/freetype/FreeTypeFont.cpp @@ -348,14 +348,12 @@ osgText::Glyph* FreeTypeFont::getGlyph(const osgText::FontResolution& fontRes, u for(unsigned char* p=data;psetImage(width,height,1, - OSGTEXT_GLYPH_INTERNALFORMAT, - OSGTEXT_GLYPH_FORMAT, GL_UNSIGNED_BYTE, + GL_ALPHA, + GL_ALPHA, GL_UNSIGNED_BYTE, data, osg::Image::USE_NEW_DELETE, 1); - glyph->setInternalTextureFormat(OSGTEXT_GLYPH_INTERNALFORMAT); - // copy image across to osgText::Glyph image. switch(glyphslot->bitmap.pixel_mode) { diff --git a/src/osgText/DefaultFont.cpp b/src/osgText/DefaultFont.cpp index cf3669cef..94aac9be3 100644 --- a/src/osgText/DefaultFont.cpp +++ b/src/osgText/DefaultFont.cpp @@ -207,14 +207,12 @@ void DefaultFont::constructGlyphs() for(unsigned char* p=data;psetImage(sourceWidth,sourceHeight,1, - OSGTEXT_GLYPH_INTERNALFORMAT, - OSGTEXT_GLYPH_FORMAT, GL_UNSIGNED_BYTE, + GL_ALPHA, + GL_ALPHA, GL_UNSIGNED_BYTE, data, osg::Image::USE_NEW_DELETE, 1); - glyph->setInternalTextureFormat(OSGTEXT_GLYPH_INTERNALFORMAT); - // now populate data array by converting bitmap into a luminance_alpha map. unsigned char* ptr = rasters[i-32]; unsigned char value_on = 255; diff --git a/src/osgText/Glyph.cpp b/src/osgText/Glyph.cpp index 8ca21f5bc..114f6649a 100644 --- a/src/osgText/Glyph.cpp +++ b/src/osgText/Glyph.cpp @@ -28,6 +28,22 @@ using namespace osgText; using namespace std; +// GL_ALPHA and GL_LUMINANCE_ALPHA are deprecated in GL3/GL4 core profile, use GL_RED & GL_RB in this case. +#if defined(OSG_GL3_AVAILABLE) && !defined(OSG_GL2_AVAILABLE) && !defined(OSG_GL1_AVAILABLE) +#define OSGTEXT_GLYPH_ALPHA_FORMAT GL_RED +#define OSGTEXT_GLYPH_ALPHA_INTERNALFORMAT GL_R8 +#define OSGTEXT_GLYPH_SDF_FORMAT GL_RG +#define OSGTEXT_GLYPH_SDF_INTERNALFORMAT GL_RG8 +#else +#define OSGTEXT_GLYPH_ALPHA_FORMAT GL_ALPHA +#define OSGTEXT_GLYPH_ALPHA_INTERNALFORMAT GL_ALPHA +#define OSGTEXT_GLYPH_SDF_FORMAT GL_LUMINANCE_ALPHA +#define OSGTEXT_GLYPH_SDF_INTERNALFORMAT GL_LUMINANCE_ALPHA +#endif + + + + #if 0 #define TEXTURE_IMAGE_NUM_CHANNELS 1 #define TEXTURE_IMAGE_FORMAT OSGTEXT_GLYPH_FORMAT @@ -160,6 +176,9 @@ void GlyphTexture::copyGlyphImage(Glyph* glyph) if (_glyphTextureFeatures==GREYSCALE) { // OSG_NOTICE<<"GlyphTexture::copyGlyphImage() greyscale copying. glyphTexture="<=130\n" + " #define ALPHA r\n" + " #define SDF g\n" + "#else\n" + " #define ALPHA a\n" + " #define SDF r\n" + "#endif\n" + "\n" + "\n" "uniform sampler2D glyphTexture;\n" "\n" "$OSG_VARYING_IN vec2 texCoord;\n" @@ -49,7 +59,7 @@ char text_sdf_frag[] = "$OSG_GLSL_VERSION\n" "\n" "float distanceFromEdge(vec2 tc)\n" "{\n" - " float center_alpha = TEXTURELOD(glyphTexture, tc, 0.0).r;\n" + " float center_alpha = TEXTURELOD(glyphTexture, tc, 0.0).SDF;\n" " if (center_alpha==0.0) return -1.0;\n" "\n" " //float distance_scale = (1.0/4.0)*1.41;\n" @@ -169,7 +179,7 @@ char text_sdf_frag[] = "$OSG_GLSL_VERSION\n" "\n" "#ifdef OUTLINE\n" "\n" - " float alpha = TEXTURE(glyphTexture, src_texCoord).a;\n" + " float alpha = TEXTURE(glyphTexture, src_texCoord).ALPHA;\n" " float delta_tc = 1.6*OUTLINE*GLYPH_DIMENSION/TEXTURE_DIMENSION;\n" "\n" " float outline_alpha = alpha;\n" @@ -184,7 +194,7 @@ char text_sdf_frag[] = "$OSG_GLSL_VERSION\n" " {\n" " for(float j=0.0; j Date: Sat, 14 Oct 2017 09:03:08 +0100 Subject: [PATCH 136/327] Improved the formating of GLSL source that is passed to OpenGL to make debugging shaders easier. --- src/osg/Shader.cpp | 28 +++++++++++++++++++++------- src/osg/State.cpp | 6 +++--- 2 files changed, 24 insertions(+), 10 deletions(-) diff --git a/src/osg/Shader.cpp b/src/osg/Shader.cpp index 1b11789fc..349c55edf 100644 --- a/src/osg/Shader.cpp +++ b/src/osg/Shader.cpp @@ -624,13 +624,6 @@ void Shader::PerContextShader::compileShader(osg::State& state) } - if (osg::getNotifyLevel()>=osg::INFO) - { - std::string sourceWithLineNumbers = insertLineNumbers(source); - OSG_INFO << "\nCompiling " << _shader->getTypename() - << " source:\n" << sourceWithLineNumbers << std::endl; - } - GLint compiled = GL_FALSE; // OSG_NOTICE<<"Compiling PerContextShader "<getTypename() + << " source:\n" << sourceWithLineNumbers << std::endl; + } } else { @@ -681,6 +681,12 @@ void Shader::PerContextShader::compileShader(osg::State& state) sourceText[2] = reinterpret_cast(source.c_str()); _extensions->glShaderSource( _glShaderHandle, 3, sourceText, NULL ); + if (osg::getNotifyLevel()>=osg::INFO) + { + std::string sourceWithLineNumbers = insertLineNumbers(versionLine+_defineStr+source); + OSG_INFO << "\nCompiling B: " << _shader->getTypename() + << " source:\n" << sourceWithLineNumbers << std::endl; + } // OSG_NOTICE<<" Version Line : ["<(source.c_str()); _extensions->glShaderSource( _glShaderHandle, 2, sourceText, NULL ); + + if (osg::getNotifyLevel()>=osg::INFO) + { + std::string sourceWithLineNumbers = insertLineNumbers(_defineStr+source); + OSG_INFO << "\nCompiling C: " << _shader->getTypename() + << " source:\n" << sourceWithLineNumbers << std::endl; + } + // OSG_NOTICE<<" DefineStr : ["< Date: Sat, 14 Oct 2017 09:06:37 +0100 Subject: [PATCH 137/327] Changed the precision setting of #pargma(tic) shader composition define setup to address GLES compatibility issues --- src/osgText/Text.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/osgText/Text.cpp b/src/osgText/Text.cpp index 54cd841c1..8e213d15c 100644 --- a/src/osgText/Text.cpp +++ b/src/osgText/Text.cpp @@ -66,6 +66,7 @@ Text::~Text() } #include +#include osg::StateSet* Text::createStateSet() { @@ -75,6 +76,8 @@ osg::StateSet* Text::createStateSet() Font::StateSets& statesets = activeFont->getCachedStateSets(); std::stringstream ss; + ss<getGlyphTextureFeatures()!=GlyphTexture::GREYSCALE) { + ss<getTextureWidthHint(); + ss << float(activeFont->getTextureWidthHint()); defineList["TEXTURE_DIMENSION"] = osg::StateSet::DefinePair(ss.str(), osg::StateAttribute::ON); defineList["SIGNED_DISTNACE_FIELD"] = osg::StateSet::DefinePair("1", osg::StateAttribute::ON); From a9ef5a90eb856f80100c13838ebc0dbac38cbf99 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Mon, 16 Oct 2017 09:49:47 +0100 Subject: [PATCH 138/327] Fixed indentation --- examples/osgvnc/osgvnc.cpp | 42 +++++++++++++++++++------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/examples/osgvnc/osgvnc.cpp b/examples/osgvnc/osgvnc.cpp index 68f4f0485..35089afb9 100644 --- a/examples/osgvnc/osgvnc.cpp +++ b/examples/osgvnc/osgvnc.cpp @@ -7,7 +7,7 @@ class EscapeHandler : public osgGA::GUIEventHandler { public: - + EscapeHandler() {} bool handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter& aa) @@ -22,7 +22,7 @@ class EscapeHandler : public osgGA::GUIEventHandler { osgViewer::View* view = dynamic_cast(&aa); if (view) view->getViewerBase()->setDone(true); - + return true; } } @@ -37,9 +37,9 @@ class EscapeHandler : public osgGA::GUIEventHandler int main(int argc,char** argv) { osg::ArgumentParser arguments(&argc, argv); - arguments.getApplicationUsage()->addCommandLineOption("--login ", "Provide authentication information for http file access."); - arguments.getApplicationUsage()->addCommandLineOption("--password ", "Provide password for any vnc url on command line not mentioned in --login."); - osgViewer::Viewer viewer(arguments); + arguments.getApplicationUsage()->addCommandLineOption("--login ", "Provide authentication information for http file access."); + arguments.getApplicationUsage()->addCommandLineOption("--password ", "Provide password for any vnc url on command line not mentioned in --login."); + osgViewer::Viewer viewer(arguments); osgWidget::GeometryHints hints(osg::Vec3(0.0f,0.0f,0.0f), osg::Vec3(1.0f,0.0f,0.0f), @@ -54,14 +54,14 @@ int main(int argc,char** argv) { } - std::string url, username, password; - while (arguments.read("--login", url, username, password)) - { - osgDB::Registry::instance()->getOrCreateAuthenticationMap()->addAuthenticationDetails( - url, - new osgDB::AuthenticationDetails(username, password) - ); - } + std::string url, username, password; + while (arguments.read("--login", url, username, password)) + { + osgDB::Registry::instance()->getOrCreateAuthenticationMap()->addAuthenticationDetails( + url, + new osgDB::AuthenticationDetails(username, password) + ); + } for(int i=1; igetOrCreateAuthenticationMap(); - const osgDB::AuthenticationDetails* details = authenticationMap->getAuthenticationDetails(hostname); - if (details == NULL) - { - authenticationMap->addAuthenticationDetails(hostname, new osgDB::AuthenticationDetails("", password)); - } + const osgDB::AuthenticationMap* authenticationMap = osgDB::Registry::instance()->getOrCreateAuthenticationMap(); + const osgDB::AuthenticationDetails* details = authenticationMap->getAuthenticationDetails(hostname); + if (details == NULL) + { + authenticationMap->addAuthenticationDetails(hostname, new osgDB::AuthenticationDetails("", password)); + } } osg::ref_ptr vncClient = new osgWidget::VncClient; if (vncClient->connect(arguments[i], hints)) - { + { group->addChild(vncClient.get()); - + hints.position.x() += 1.1f; } } From 5067db39f8435b24cebc645ae73364e3d0b32733 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Mon, 16 Oct 2017 10:08:18 +0100 Subject: [PATCH 139/327] Moved bracket to be consistent with the rest of the OSG --- src/osg/ImageUtils.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/osg/ImageUtils.cpp b/src/osg/ImageUtils.cpp index 74f0ae9f4..de965b230 100644 --- a/src/osg/ImageUtils.cpp +++ b/src/osg/ImageUtils.cpp @@ -717,7 +717,8 @@ OSG_EXPORT osg::Image* createImageWithOrientationConversion(const osg::Image* sr unsigned int pixelSizeInBits = srcImage->getPixelSizeInBits(); unsigned int pixelSizeInBytes = pixelSizeInBits/8; unsigned int pixelSizeRemainder = pixelSizeInBits%8; - if (dxtc_tool::isDXTC(srcImage->getPixelFormat())) { + if (dxtc_tool::isDXTC(srcImage->getPixelFormat())) + { unsigned int DXTblockSize = 8; if ((srcImage->getPixelFormat() == GL_COMPRESSED_RGBA_S3TC_DXT3_EXT) || (srcImage->getPixelFormat() == GL_COMPRESSED_RGBA_S3TC_DXT5_EXT)) DXTblockSize = 16; unsigned int DXTblocksWidht = (srcImage->s() + 3) / 4;//width in 4x4 blocks From ea379e64e76a7f078f61ae810bd968f28b7b291b Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Mon, 16 Oct 2017 10:12:19 +0100 Subject: [PATCH 140/327] Fixed build error --- src/osg/Image.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/osg/Image.cpp b/src/osg/Image.cpp index e755cc65a..2c36d5af8 100644 --- a/src/osg/Image.cpp +++ b/src/osg/Image.cpp @@ -2147,7 +2147,7 @@ Vec4 _readColor(GLenum pixelFormat, T* data,float scale) Vec4 Image::getColor(unsigned int s,unsigned t,unsigned r) const { - if (isCompressed(_pixelFormat)) + if (isCompressed()) { if (dxtc_tool::isDXTC(_pixelFormat)) { unsigned char color[4]; From 639ced08fce0c1b901d36c95f1d9c6bff4ef8cf4 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Mon, 16 Oct 2017 10:38:33 +0100 Subject: [PATCH 141/327] Removed inappropriate tabs&spaces --- include/osgViewer/api/X11/GraphicsWindowX11 | 22 ++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/include/osgViewer/api/X11/GraphicsWindowX11 b/include/osgViewer/api/X11/GraphicsWindowX11 index 1efb990fe..f837c81ea 100644 --- a/include/osgViewer/api/X11/GraphicsWindowX11 +++ b/include/osgViewer/api/X11/GraphicsWindowX11 @@ -54,7 +54,7 @@ class OSGVIEWER_EXPORT GraphicsWindowX11 : public osgViewer::GraphicsWindow, pub memset(_keyMap, 0, 32); init(); - + if (valid()) { setState( new osg::State ); @@ -72,7 +72,7 @@ class OSGVIEWER_EXPORT GraphicsWindowX11 : public osgViewer::GraphicsWindow, pub } } - + virtual bool isSameKindAs(const Object* object) const { return dynamic_cast(object)!=0; } virtual const char* libraryName() const { return "osgViewer"; } virtual const char* className() const { return "GraphicsWindowX11"; } @@ -129,35 +129,35 @@ class OSGVIEWER_EXPORT GraphicsWindowX11 : public osgViewer::GraphicsWindow, pub { WindowData(Window window): _window(window) {} - + Window _window; }; public: - + // X11 specific access functions Display* getEventDisplay() const { return _eventDisplay; } Display* getDisplayToUse() const ; - + Window& getParent() { return _parent; } Window& getWindow() { return _window; } Cursor getCurrentCursor() { return _currentCursor; } protected: - + ~GraphicsWindowX11(); - + Cursor getOrCreateCursor(MouseCursor mouseShape); - + bool createVisualInfo(); bool createWindow(); bool setWindow(Window window); - + void init(); bool checkAndSendEventFullScreenIfNeeded(Display* display, int x, int y, int width, int height, bool windowDecoration); @@ -171,7 +171,7 @@ class OSGVIEWER_EXPORT GraphicsWindowX11 : public osgViewer::GraphicsWindow, pub int getModifierMask() const; void syncLocks(); void flushKeyEvents(); - + bool _valid; Display* _eventDisplay; Window _parent; @@ -187,7 +187,7 @@ class OSGVIEWER_EXPORT GraphicsWindowX11 : public osgViewer::GraphicsWindow, pub Cursor _currentCursor; Atom _deleteWindow; - + bool _initialized; bool _realized; bool _ownsWindow; From 879b54f6e9b3ad76e10bf1c8be91b324be738fd1 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Mon, 16 Oct 2017 10:47:47 +0100 Subject: [PATCH 142/327] Fixed GLX EGL build --- include/osgViewer/api/X11/GraphicsWindowX11 | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/include/osgViewer/api/X11/GraphicsWindowX11 b/include/osgViewer/api/X11/GraphicsWindowX11 index f837c81ea..0af24fdb1 100644 --- a/include/osgViewer/api/X11/GraphicsWindowX11 +++ b/include/osgViewer/api/X11/GraphicsWindowX11 @@ -37,10 +37,11 @@ class OSGVIEWER_EXPORT GraphicsWindowX11 : public osgViewer::GraphicsWindow, pub _parent(0), _window(0), _visualInfo(0), - _fbConfig(0), #ifdef OSG_USE_EGL _eglDisplay(0), _eglSurface(0), + #else + _fbConfig(0), #endif _currentCursor(0), _initialized(false), @@ -177,11 +178,12 @@ class OSGVIEWER_EXPORT GraphicsWindowX11 : public osgViewer::GraphicsWindow, pub Window _parent; Window _window; XVisualInfo* _visualInfo; - GLXFBConfig _fbConfig; #ifdef OSG_USE_EGL EGLDisplay _eglDisplay; EGLSurface _eglSurface; + #else + GLXFBConfig _fbConfig; #endif Cursor _currentCursor; From ad45bf1d616816413f490c3eb116928a56db36ba Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Mon, 16 Oct 2017 11:52:54 +0100 Subject: [PATCH 143/327] Fixed warning --- src/osg/VertexArrayState.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/osg/VertexArrayState.cpp b/src/osg/VertexArrayState.cpp index a0d082d43..7af9bec4a 100644 --- a/src/osg/VertexArrayState.cpp +++ b/src/osg/VertexArrayState.cpp @@ -742,7 +742,7 @@ void VertexArrayState::setArray(ArrayDispatch* vad, osg::State& state, GLint siz } } -void VertexArrayState::setInterleavedArrays( osg::State& state, GLenum format, GLsizei stride, const GLvoid* pointer) +void VertexArrayState::setInterleavedArrays(osg::State& /*state*/, GLenum format, GLsizei stride, const GLvoid* pointer) { #if defined(OSG_GL_VERTEX_ARRAY_FUNCS_AVAILABLE) && !defined(OSG_GLES1_AVAILABLE) unbindVertexBufferObject(); From cc8a34cd14886ec02a50eef7660b6c85bc398311 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Si=C3=B1uela=20Pastor?= Date: Tue, 17 Oct 2017 17:11:12 +0200 Subject: [PATCH 144/327] Do not break systems with cr as line endings --- src/osg/Shader.cpp | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/osg/Shader.cpp b/src/osg/Shader.cpp index f255a2ddb..9815021e2 100644 --- a/src/osg/Shader.cpp +++ b/src/osg/Shader.cpp @@ -89,6 +89,20 @@ struct NoneOf const char* _str; }; +// Replaces all occurrences of "from" with the contents of "to" +// It does only one pass, i.e. new matches created in a position before the current match are not replaced +std::string replaceAll(const std::string& str, const std::string& from, const std::string& to) +{ + std::string result = str; + std::string::size_type pos = 0; + while ((pos = result.find(from, pos)) != std::string::npos) + { + result.replace(pos, from.length(), to); + pos += to.length(); + } + return result; +} + } using namespace osg; @@ -642,6 +656,8 @@ void Shader::PerContextShader::compileShader(osg::State& state) } else { + // Convert all windows line endings to \n + source = replaceAll(source, "\r\n", "\n"); std::string versionLine; unsigned int lineNum = 0; From 6496c304f99e162d4f45ddc886b96f82eb7d30b2 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 18 Oct 2017 10:11:43 +0100 Subject: [PATCH 145/327] Implemented inplace replacement --- src/osg/Shader.cpp | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/osg/Shader.cpp b/src/osg/Shader.cpp index 9815021e2..47d6ec5bc 100644 --- a/src/osg/Shader.cpp +++ b/src/osg/Shader.cpp @@ -91,16 +91,15 @@ struct NoneOf // Replaces all occurrences of "from" with the contents of "to" // It does only one pass, i.e. new matches created in a position before the current match are not replaced -std::string replaceAll(const std::string& str, const std::string& from, const std::string& to) +void replaceAll(std::string& str, const std::string& from, const std::string& to) { - std::string result = str; std::string::size_type pos = 0; - while ((pos = result.find(from, pos)) != std::string::npos) + while ((pos = str.find(from, pos)) != std::string::npos) { - result.replace(pos, from.length(), to); + str.replace(pos, from.length(), to); + pos += to.length(); } - return result; } } @@ -657,7 +656,7 @@ void Shader::PerContextShader::compileShader(osg::State& state) else { // Convert all windows line endings to \n - source = replaceAll(source, "\r\n", "\n"); + replaceAll(source, "\r\n", " \n"); std::string versionLine; unsigned int lineNum = 0; From 3c6f56936074fe5a43ea86f4715b1e6eef372db9 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Thu, 19 Oct 2017 11:06:23 +0100 Subject: [PATCH 146/327] Fixed placement of { and spacing to make the code more readable and consistent with the rest of the OSG --- examples/osgsimpleMDI/osgsimpleMDI.cpp | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/examples/osgsimpleMDI/osgsimpleMDI.cpp b/examples/osgsimpleMDI/osgsimpleMDI.cpp index be7bd2c31..bd94c4785 100644 --- a/examples/osgsimpleMDI/osgsimpleMDI.cpp +++ b/examples/osgsimpleMDI/osgsimpleMDI.cpp @@ -86,6 +86,7 @@ int main( int argc, char**argv ) osg::ref_ptr geom=new osg::Geometry(); geom->setUseVertexBufferObjects(true); + osg::BoundingBox bb; bb.set(0,0,0,MAXX,0,MAXY); //set bounds by hand cause of the lack of support of basevertex in PrimitiveFunctors @@ -104,10 +105,10 @@ int main( int argc, char**argv ) osg::Vec3Array * verts=new osg::Vec3Array(); - - for(int j =0 ; jsize(); mdicommands->push_back(cmd); - for(int z=0; z<4; z++) { + for(int z=0; z<4; z++) + { verts->push_back(osg::Vec3(i,0,j)+myCoords[z]); mdi->addElement(myIndices[z]); } } } + geom->setVertexArray(verts); - if(MDIenable) { + + if(MDIenable) + { geom->addPrimitiveSet(mdi); } else - for(int i=0; isetElementBufferObject(ebo); geom->addPrimitiveSet(dre); for(int z=0; z<4; z++)myIndicesUI[z]+=4; } + } + root->addChild(geom); + osgViewer::Viewer viewer; viewer.addEventHandler(new osgViewer::StatsHandler); viewer.setSceneData( root ); From 068f47d91fa59d0638ac26238b21c36eeb2284a3 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Thu, 19 Oct 2017 11:57:53 +0100 Subject: [PATCH 147/327] Build fixes with ref_ptr<> autoconversion disabled --- examples/osgSSBO/osgSSBO.cpp | 2 +- examples/osggpucull/osggpucull.cpp | 6 +++--- examples/osgsimpleMDI/osgsimpleMDI.cpp | 2 +- include/osg/PrimitiveSetIndirect | 8 ++++---- src/osgPlugins/ply/vertexData.cpp | 2 +- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/examples/osgSSBO/osgSSBO.cpp b/examples/osgSSBO/osgSSBO.cpp index 9db8161dc..c058664be 100644 --- a/examples/osgSSBO/osgSSBO.cpp +++ b/examples/osgSSBO/osgSSBO.cpp @@ -773,7 +773,7 @@ void ComputeNode::initComputingSetup() _dataArray->setBufferObject(_ssbo.get()); - _ssbb = new osg::ShaderStorageBufferBinding(0, _dataArray, 0, blockSize); + _ssbb = new osg::ShaderStorageBufferBinding(0, _dataArray.get(), 0, blockSize); statesetComputation->setAttributeAndModes(_ssbb.get(), osg::StateAttribute::ON); diff --git a/examples/osggpucull/osggpucull.cpp b/examples/osggpucull/osggpucull.cpp index 78650cc16..da9ab5c8f 100644 --- a/examples/osggpucull/osggpucull.cpp +++ b/examples/osggpucull/osggpucull.cpp @@ -188,7 +188,7 @@ struct IndirectTarget } void endRegister(unsigned int index, unsigned int rowsPerInstance, GLenum pixelFormat, GLenum type, GLint internalFormat, bool useMultiDrawArraysIndirect ) { - indirectCommandTextureBuffer = new osg::TextureBuffer(indirectCommands); + indirectCommandTextureBuffer = new osg::TextureBuffer(indirectCommands.get()); indirectCommandTextureBuffer->setInternalFormat( GL_R32I ); indirectCommandTextureBuffer->bindToImageUnit(index, osg::Texture::READ_WRITE); indirectCommandTextureBuffer->setUnRefImageDataAfterApply(false); @@ -201,7 +201,7 @@ struct IndirectTarget for(unsigned int j=0;jsize(); ++j){ osg::DrawArraysIndirect *ipr=new osg::DrawArraysIndirect( GL_TRIANGLES, j ); - ipr->setIndirectCommandArray( indirectCommands); + ipr->setIndirectCommandArray( indirectCommands.get()); newPrimitiveSets.push_back(ipr); } @@ -215,7 +215,7 @@ struct IndirectTarget else // use glMultiDrawArraysIndirect() { osg::MultiDrawArraysIndirect *ipr=new osg::MultiDrawArraysIndirect( GL_TRIANGLES ); - ipr->setIndirectCommandArray( indirectCommands ); + ipr->setIndirectCommandArray( indirectCommands.get() ); geometryAggregator->getAggregatedGeometry()->removePrimitiveSet(0,geometryAggregator->getAggregatedGeometry()->getNumPrimitiveSets() ); geometryAggregator->getAggregatedGeometry()->addPrimitiveSet( ipr ); } diff --git a/examples/osgsimpleMDI/osgsimpleMDI.cpp b/examples/osgsimpleMDI/osgsimpleMDI.cpp index bd94c4785..48b56074c 100644 --- a/examples/osgsimpleMDI/osgsimpleMDI.cpp +++ b/examples/osgsimpleMDI/osgsimpleMDI.cpp @@ -136,7 +136,7 @@ int main( int argc, char**argv ) for(int i=0; isetElementBufferObject(ebo); + dre->setElementBufferObject(ebo.get()); geom->addPrimitiveSet(dre); for(int z=0; z<4; z++)myIndicesUI[z]+=4; } diff --git a/include/osg/PrimitiveSetIndirect b/include/osg/PrimitiveSetIndirect index bf7b1a5ce..8ede4471c 100644 --- a/include/osg/PrimitiveSetIndirect +++ b/include/osg/PrimitiveSetIndirect @@ -168,8 +168,8 @@ public: } /// get command array of this indirect primitive set - inline IndirectCommandDrawElements* getIndirectCommandArray() { return _indirectCommandArray; } - inline const IndirectCommandDrawElements* getIndirectCommandArray() const { return _indirectCommandArray; } + inline IndirectCommandDrawElements* getIndirectCommandArray() { return _indirectCommandArray.get(); } + inline const IndirectCommandDrawElements* getIndirectCommandArray() const { return _indirectCommandArray.get(); } ///Further methods are for advanced DI when you plan to use your own IndirectCommandElement (stride) ///or if you want to draw a particular command index of the IndirectCommandElement(FirstCommandToDraw) @@ -616,8 +616,8 @@ public: if(!dynamic_cast(_indirectCommandArray->getBufferObject())) _indirectCommandArray->setBufferObject(new DrawIndirectBufferObject()); } - inline const IndirectCommandDrawArrays* getIndirectCommandArray() const { return _indirectCommandArray; } - inline IndirectCommandDrawArrays* getIndirectCommandArray() { return _indirectCommandArray; } + inline const IndirectCommandDrawArrays* getIndirectCommandArray() const { return _indirectCommandArray.get(); } + inline IndirectCommandDrawArrays* getIndirectCommandArray() { return _indirectCommandArray.get(); } protected: diff --git a/src/osgPlugins/ply/vertexData.cpp b/src/osgPlugins/ply/vertexData.cpp index 00ce08758..faeca766b 100644 --- a/src/osgPlugins/ply/vertexData.cpp +++ b/src/osgPlugins/ply/vertexData.cpp @@ -546,7 +546,7 @@ osg::Node* VertexData::readPlyFile( const char* filename, const bool ignoreColor } else if (_texcoord.valid()) { - geom->setTexCoordArray(0, _texcoord); + geom->setTexCoordArray(0, _texcoord.get()); } // If the model has normals, add them to the geometry From 4791e5f6b520965b50943ea73d6ec4d77164385e Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Thu, 19 Oct 2017 12:06:59 +0100 Subject: [PATCH 148/327] Improved spacing to make code more readable --- examples/osggpucull/osggpucull.cpp | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/examples/osggpucull/osggpucull.cpp b/examples/osggpucull/osggpucull.cpp index da9ab5c8f..4b87433b6 100644 --- a/examples/osggpucull/osggpucull.cpp +++ b/examples/osggpucull/osggpucull.cpp @@ -199,11 +199,12 @@ struct IndirectTarget { std::vector newPrimitiveSets; - for(unsigned int j=0;jsize(); ++j){ + for(unsigned int j=0;jsize(); ++j) + { osg::DrawArraysIndirect *ipr=new osg::DrawArraysIndirect( GL_TRIANGLES, j ); ipr->setIndirectCommandArray( indirectCommands.get()); newPrimitiveSets.push_back(ipr); - } + } geometryAggregator->getAggregatedGeometry()->removePrimitiveSet(0,geometryAggregator->getAggregatedGeometry()->getNumPrimitiveSets() ); @@ -236,6 +237,7 @@ struct IndirectTarget instanceTarget->bindToImageUnit(OSGGPUCULL_MAXIMUM_INDIRECT_TARGET_NUMBER+index, osg::Texture::READ_WRITE); } + void addIndirectCommandData( const std::string& uniformNamePrefix, int index, osg::StateSet* stateset ) { std::string uniformName = uniformNamePrefix + char( '0' + index ); @@ -245,6 +247,7 @@ struct IndirectTarget } + void addIndirectTargetData( bool cullPhase, const std::string& uniformNamePrefix, int index, osg::StateSet* stateset ) { std::string uniformName; @@ -257,6 +260,7 @@ struct IndirectTarget stateset->addUniform( uniform ); stateset->setTextureAttribute( OSGGPUCULL_MAXIMUM_INDIRECT_TARGET_NUMBER+index, instanceTarget.get() ); } + void addDrawProgram( const std::string& uniformBlockName, osg::StateSet* stateset ) { drawProgram->addBindUniformBlock(uniformBlockName, 1); @@ -286,6 +290,7 @@ struct GPUCullData instanceTypesUBB = new osg::UniformBufferBinding(1, instanceTypes.get(), 0, 0); } + void setUseMultiDrawArraysIndirect( bool value ) { useMultiDrawArraysIndirect = value; @@ -297,6 +302,7 @@ struct GPUCullData return; targets[index] = IndirectTarget( agv, targetDrawProgram ); } + bool registerType(unsigned int typeID, unsigned int targetID, osg::Node* node, const osg::Vec4& lodDistances, float maxDensityPerSquareKilometer ) { if( typeID >= instanceTypes->getData().size() ) @@ -328,6 +334,7 @@ struct GPUCullData target->second.maxTargetQuantity += maxQuantity; return true; } + // endRegister() method is called after all indirect targets and instance types are registered. // It creates indirect targets with pixel format and data type provided by user ( indirect targets may hold // different information about single instance depending on user's needs ( in our example : static rendering @@ -388,10 +395,12 @@ struct StaticInstance : position(m), extraParams(params), idParams(typeID,id,0,0) { } + osg::Vec3d getPosition() const { return position.getTrans(); } + osg::Matrixf position; osg::Vec4f extraParams; osg::Vec4i idParams; @@ -705,10 +714,12 @@ struct ResetTexturesCallback : public osg::StateSet::Callback ResetTexturesCallback() { } + void addTextureDirty( unsigned int texUnit ) { texUnitsDirty.push_back(texUnit); } + void addTextureDirtyParams( unsigned int texUnit ) { texUnitsDirtyParams.push_back(texUnit); @@ -748,6 +759,7 @@ struct InvokeMemoryBarrier : public osg::Drawable::DrawCallback : _barriers(barriers) { } + virtual void drawImplementation(osg::RenderInfo& renderInfo,const osg::Drawable* drawable) const { //DrawIndirectGLExtensions *ext = DrawIndirectGLExtensions::getExtensions( renderInfo.getContextID(), true ); @@ -836,11 +848,13 @@ osg::Group* createSimpleHouse( float detailRatio, const osg::Vec4& buildingColor osg::ref_ptr chimneyGeode = convertShapeToGeode( *chimney.get(), tessHints.get(), chimneyColor ); root->addChild( chimneyGeode.get() ); } + { osg::ref_ptr chimney = new osg::Cylinder( osg::Vec3( -5.5, 3.0, 16.5 ), 0.1, 1.0 ); osg::ref_ptr chimneyGeode = convertShapeToGeode( *chimney.get(), tessHints.get(), chimneyColor ); root->addChild( chimneyGeode.get() ); } + { osg::ref_ptr chimney = new osg::Cylinder( osg::Vec3( -5.0, 3.0, 16.25 ), 0.1, 0.5 ); osg::ref_ptr chimneyGeode = convertShapeToGeode( *chimney.get(), tessHints.get(), chimneyColor ); @@ -1183,6 +1197,7 @@ struct AnimateObjectsCallback : public osg::DrawableUpdateCallback for(; i<3*_quantityPerType; ++i) // speed of airplanes _speed.push_back( random( 10.0, 16.0 ) ); } + virtual void update(osg::NodeVisitor* nv, osg::Drawable* drawable) { if( nv->getVisitorType() != osg::NodeVisitor::UPDATE_VISITOR ) @@ -1213,6 +1228,7 @@ struct AnimateObjectsCallback : public osg::DrawableUpdateCallback setRotationUsingRotSpeed( i, 5, osg::Matrix::rotate( osg::DegreesToRadians(90.0), osg::Vec3(0.0,1.0,0.0)) * osg::Matrix::translate(0.0,2.0,-6.0), currentTime, 0.5 ); setRotationUsingRotSpeed( i, 6, osg::Matrix::rotate( osg::DegreesToRadians(90.0), osg::Vec3(0.0,1.0,0.0)) * osg::Matrix::translate(0.0,-2.0,-6.0), currentTime, -0.5 ); } + for(;i<2*_quantityPerType;++i) //update cars { nbbox.expandBy( updateObjectPosition( vertexArray, i, deltaTime ) ); @@ -1223,6 +1239,7 @@ struct AnimateObjectsCallback : public osg::DrawableUpdateCallback setRotationUsingRotSpeed( i, 3, osg::Matrix::rotate( osg::DegreesToRadians(90.0), osg::Vec3(1.0,0.0,0.0)) * osg::Matrix::translate(2.0,-1.8,1.0), currentTime, wheelRotSpeed ); setRotationUsingRotSpeed( i, 4, osg::Matrix::rotate( osg::DegreesToRadians(90.0), osg::Vec3(1.0,0.0,0.0)) * osg::Matrix::translate(-2.0,-1.8,1.0), currentTime, wheelRotSpeed ); } + for(;i<3*_quantityPerType;++i) // update airplanes { nbbox.expandBy( updateObjectPosition( vertexArray, i, deltaTime ) ); @@ -1251,6 +1268,7 @@ struct AnimateObjectsCallback : public osg::DrawableUpdateCallback (*vertexArray)[index] = newPosition; return newPosition; } + void setRotationUsingRotSpeed( unsigned int index, unsigned int boneIndex, const osg::Matrix& zeroMatrix, double currentTime, double rotSpeed ) { // setRotationUsingRotSpeed() is a very unoptimally written ( because it uses osg::Matrix::inverse() ), @@ -1473,12 +1491,16 @@ int main( int argc, char **argv ) if ( arguments.read("--skip-static") ) showStaticRendering = false; + if ( arguments.read("--skip-dynamic") ) showDynamicRendering = false; + if ( arguments.read("--export-objects") ) exportInstanceObjects = true; + if ( arguments.read("--use-multi-draw") ) useMultiDrawArraysIndirect = true; + arguments.read("--instances-per-cell",instancesPerCell); arguments.read("--static-area-size",staticAreaSize); arguments.read("--dynamic-area-size",dynamicAreaSize); From 8965c9369e86291a13ab6d7538935d2d677a9f11 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Thu, 19 Oct 2017 12:39:22 +0100 Subject: [PATCH 149/327] Implemented --single command line option that creates a single osg::DrawElementsUInt primitive set instead of using MultiDrawIndirect. --- examples/osgsimpleMDI/osgsimpleMDI.cpp | 65 ++++++++++++++++++++------ 1 file changed, 52 insertions(+), 13 deletions(-) diff --git a/examples/osgsimpleMDI/osgsimpleMDI.cpp b/examples/osgsimpleMDI/osgsimpleMDI.cpp index 48b56074c..94309b56b 100644 --- a/examples/osgsimpleMDI/osgsimpleMDI.cpp +++ b/examples/osgsimpleMDI/osgsimpleMDI.cpp @@ -69,10 +69,24 @@ int main( int argc, char**argv ) arguments.read("--numX",MAXX); arguments.read("--numY",MAXY); - bool MDIenable=true; + enum PrimtiveSetUsage + { + MultiDraw, + MultiplePrimitiveSets, + SinglePrimitiveSet + }; + + PrimtiveSetUsage usage = MultiDraw; if(arguments.read("--classic")) - { MDIenable=false; - OSG_WARN<<"disabling MDI"<setVertexArray(verts); - if(MDIenable) + switch(usage) { - geom->addPrimitiveSet(mdi); - - } else - { - for(int i=0; isetElementBufferObject(ebo.get()); - geom->addPrimitiveSet(dre); - for(int z=0; z<4; z++)myIndicesUI[z]+=4; + geom->addPrimitiveSet(mdi); + break; + + } + case(MultiplePrimitiveSets): + { + for(int i=0; i dre = new osg::DrawElementsUInt(osg::PrimitiveSet::TRIANGLE_STRIP,4,myIndicesUI); + dre->setElementBufferObject(ebo.get()); + geom->addPrimitiveSet(dre.get()); + for(int z=0; z<4; z++) myIndicesUI[z]+=4; + } + break; + } + case(SinglePrimitiveSet): + { + osg::ref_ptr primitives = new osg::DrawElementsUInt(GL_TRIANGLES); + primitives->setElementBufferObject(ebo.get()); + geom->addPrimitiveSet(primitives.get()); + + unsigned int vi = 0; + for(int i=0; ipush_back(vi); + primitives->push_back(vi+2); + primitives->push_back(vi+1); + primitives->push_back(vi+1); + primitives->push_back(vi+2); + primitives->push_back(vi+3); + vi += 4; + } + break; } } From 24c2a0ca605260778835418e1c19534bec157947 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Thu, 19 Oct 2017 20:57:25 +0100 Subject: [PATCH 150/327] Moved the assignment of the ModifiedCount to before GL texture calls. --- src/osg/Texture1D.cpp | 10 +++++----- src/osg/Texture2D.cpp | 14 +++++++------- src/osg/Texture2DArray.cpp | 4 ++-- src/osg/Texture3D.cpp | 13 ++++++------- src/osg/TextureBuffer.cpp | 6 ++++-- src/osg/TextureCubeMap.cpp | 4 ++-- src/osg/TextureRectangle.cpp | 4 ++-- 7 files changed, 28 insertions(+), 27 deletions(-) diff --git a/src/osg/Texture1D.cpp b/src/osg/Texture1D.cpp index 4fe3fda46..38327b07d 100644 --- a/src/osg/Texture1D.cpp +++ b/src/osg/Texture1D.cpp @@ -168,10 +168,10 @@ void Texture1D::apply(State& state) const } else if (_image.valid() && getModifiedCount(contextID) != _image->getModifiedCount()) { - applyTexImage1D(GL_TEXTURE_1D,_image.get(),state, _textureWidth, _numMipmapLevels); - // update the modified count to show that it is up to date. getModifiedCount(contextID) = _image->getModifiedCount(); + + applyTexImage1D(GL_TEXTURE_1D,_image.get(),state, _textureWidth, _numMipmapLevels); } } @@ -206,13 +206,13 @@ void Texture1D::apply(State& state) const applyTexParameters(GL_TEXTURE_1D,state); + // update the modified count to show that it is upto date. + getModifiedCount(contextID) = _image->getModifiedCount(); + applyTexImage1D(GL_TEXTURE_1D,_image.get(),state, _textureWidth, _numMipmapLevels); textureObject->setAllocated(_numMipmapLevels,_internalFormat,_textureWidth,1,1,0); - // update the modified count to show that it is up to date. - getModifiedCount(contextID) = _image->getModifiedCount(); - _textureObjectBuffer[contextID] = textureObject; // unref image data? diff --git a/src/osg/Texture2D.cpp b/src/osg/Texture2D.cpp index d73cebc37..1090f64e1 100644 --- a/src/osg/Texture2D.cpp +++ b/src/osg/Texture2D.cpp @@ -202,12 +202,11 @@ void Texture2D::apply(State& state) const } else if (_image.valid() && getModifiedCount(contextID) != _image->getModifiedCount()) { - applyTexImage2D_subload(state,GL_TEXTURE_2D,_image.get(), - _textureWidth, _textureHeight, _internalFormat, _numMipmapLevels); - // update the modified tag to show that it is up to date. getModifiedCount(contextID) = _image->getModifiedCount(); + applyTexImage2D_subload(state,GL_TEXTURE_2D,_image.get(), + _textureWidth, _textureHeight, _internalFormat, _numMipmapLevels); } else if (_readPBuffer.valid()) { @@ -224,6 +223,8 @@ void Texture2D::apply(State& state) const applyTexParameters(GL_TEXTURE_2D,state); + if (_image.valid()) getModifiedCount(contextID) = _image->getModifiedCount(); + _subloadCallback->load(*this,state); textureObject->setAllocated(_numMipmapLevels,_internalFormat,_textureWidth,_textureHeight,1,_borderWidth); @@ -235,7 +236,6 @@ void Texture2D::apply(State& state) const //glBindTexture( GL_TEXTURE_2D, handle ); // update the modified tag to show that it is up to date. - if (_image.valid()) getModifiedCount(contextID) = _image->getModifiedCount(); } else if (_image.valid() && _image->data()) { @@ -255,6 +255,9 @@ void Texture2D::apply(State& state) const applyTexParameters(GL_TEXTURE_2D,state); + // update the modified tag to show that it is up to date. + getModifiedCount(contextID) = image->getModifiedCount(); + if (textureObject->isAllocated() && image->supportsTextureSubloading()) { //OSG_NOTICE<<"Reusing texture object"<setAllocated(true); } - // update the modified tag to show that it is up to date. - getModifiedCount(contextID) = image->getModifiedCount(); - // unref image data? if (isSafeToUnrefImageData(state) && image->getDataVariance()==STATIC) { diff --git a/src/osg/Texture2DArray.cpp b/src/osg/Texture2DArray.cpp index 2f55e596c..b37051167 100644 --- a/src/osg/Texture2DArray.cpp +++ b/src/osg/Texture2DArray.cpp @@ -297,8 +297,8 @@ void Texture2DArray::apply(State& state) const { if (getModifiedCount(n,contextID) != image->getModifiedCount()) { - applyTexImage2DArray_subload(state, image, n, _textureWidth, _textureHeight, image->r(), _internalFormat, _numMipmapLevels); getModifiedCount(n,contextID) = image->getModifiedCount(); + applyTexImage2DArray_subload(state, image, n, _textureWidth, _textureHeight, image->r(), _internalFormat, _numMipmapLevels); } n += image->r(); } @@ -380,8 +380,8 @@ void Texture2DArray::apply(State& state) const { if (getModifiedCount(n,contextID) != image->getModifiedCount()) { - applyTexImage2DArray_subload(state, image, n, _textureWidth, _textureHeight, image->r(), _internalFormat, _numMipmapLevels); getModifiedCount(n,contextID) = image->getModifiedCount(); + applyTexImage2DArray_subload(state, image, n, _textureWidth, _textureHeight, image->r(), _internalFormat, _numMipmapLevels); } n += image->r(); } diff --git a/src/osg/Texture3D.cpp b/src/osg/Texture3D.cpp index 68e42fe42..5294b5a38 100644 --- a/src/osg/Texture3D.cpp +++ b/src/osg/Texture3D.cpp @@ -249,12 +249,12 @@ void Texture3D::apply(State& state) const } else if (_image.get() && getModifiedCount(contextID) != _image->getModifiedCount()) { - computeRequiredTextureDimensions(state,*_image,_textureWidth, _textureHeight, _textureDepth,_numMipmapLevels); - - applyTexImage3D(GL_TEXTURE_3D,_image.get(),state, _textureWidth, _textureHeight, _textureDepth,_numMipmapLevels); - // update the modified count to show that it is up to date. getModifiedCount(contextID) = _image->getModifiedCount(); + + computeRequiredTextureDimensions(state,*_image,_textureWidth, _textureHeight, _textureDepth,_numMipmapLevels); + + applyTexImage3D(GL_TEXTURE_3D,_image.get(),state, _textureWidth, _textureHeight, _textureDepth,_numMipmapLevels); } } @@ -291,6 +291,8 @@ void Texture3D::apply(State& state) const textureObject->bind(); + // update the modified count to show that it is up to date. + getModifiedCount(contextID) = _image->getModifiedCount(); applyTexParameters(GL_TEXTURE_3D,state); @@ -298,9 +300,6 @@ void Texture3D::apply(State& state) const textureObject->setAllocated(_numMipmapLevels,_internalFormat,_textureWidth,_textureHeight,_textureDepth,0); - // update the modified count to show that it is up to date. - getModifiedCount(contextID) = _image->getModifiedCount(); - // unref image data? if (isSafeToUnrefImageData(state) && _image->getDataVariance()==STATIC) { diff --git a/src/osg/TextureBuffer.cpp b/src/osg/TextureBuffer.cpp index d88646f3a..349b6e0bf 100644 --- a/src/osg/TextureBuffer.cpp +++ b/src/osg/TextureBuffer.cpp @@ -163,6 +163,8 @@ void TextureBuffer::apply(State& state) const const GLExtensions* extensions = state.get(); if(_bufferData.valid() &&_modifiedCount[contextID]!=_bufferData->getModifiedCount() ) { + _modifiedCount[contextID]=_bufferData->getModifiedCount() ; + GLBufferObject* glBufferObject = _bufferData->getBufferObject()->getOrCreateGLBufferObject(contextID); if (glBufferObject) { @@ -174,7 +176,6 @@ void TextureBuffer::apply(State& state) const } - _modifiedCount[contextID]=_bufferData->getModifiedCount() ; } textureObject->bind(); @@ -198,6 +199,8 @@ void TextureBuffer::apply(State& state) const { const GLExtensions* extensions = state.get(); + _modifiedCount[contextID] = _bufferData->getModifiedCount(); + textureObject = generateAndAssignTextureObject(contextID, GL_TEXTURE_BUFFER); textureObject->_profile._internalFormat=_internalFormat; textureObject->bind(); @@ -221,7 +224,6 @@ void TextureBuffer::apply(State& state) const textureObject->bind(); extensions->glTexBuffer(GL_TEXTURE_BUFFER, _internalFormat, glBufferObject->getGLObjectID()); - _modifiedCount[contextID] = _bufferData->getModifiedCount(); } } diff --git a/src/osg/TextureCubeMap.cpp b/src/osg/TextureCubeMap.cpp index 6e447e2e8..6618958a9 100644 --- a/src/osg/TextureCubeMap.cpp +++ b/src/osg/TextureCubeMap.cpp @@ -246,8 +246,8 @@ void TextureCubeMap::apply(State& state) const const osg::Image* image = _images[n].get(); if (image && getModifiedCount((Face)n,contextID) != image->getModifiedCount()) { - applyTexImage2D_subload( state, faceTarget[n], _images[n].get(), _textureWidth, _textureHeight, _internalFormat, _numMipmapLevels); getModifiedCount((Face)n,contextID) = image->getModifiedCount(); + applyTexImage2D_subload( state, faceTarget[n], _images[n].get(), _textureWidth, _textureHeight, _internalFormat, _numMipmapLevels); } } } @@ -297,6 +297,7 @@ void TextureCubeMap::apply(State& state) const const osg::Image* image = _images[n].get(); if (image) { + getModifiedCount((Face)n,contextID) = image->getModifiedCount(); if (textureObject->isAllocated()) { applyTexImage2D_subload( state, faceTarget[n], image, _textureWidth, _textureHeight, _internalFormat, _numMipmapLevels); @@ -305,7 +306,6 @@ void TextureCubeMap::apply(State& state) const { applyTexImage2D_load( state, faceTarget[n], image, _textureWidth, _textureHeight, _numMipmapLevels); } - getModifiedCount((Face)n,contextID) = image->getModifiedCount(); } diff --git a/src/osg/TextureRectangle.cpp b/src/osg/TextureRectangle.cpp index 87dbf6f9c..4a60e166d 100644 --- a/src/osg/TextureRectangle.cpp +++ b/src/osg/TextureRectangle.cpp @@ -204,10 +204,10 @@ void TextureRectangle::apply(State& state) const } else if (_image.valid() && getModifiedCount(contextID) != _image->getModifiedCount()) { - applyTexImage_subload(GL_TEXTURE_RECTANGLE, _image.get(), state, _textureWidth, _textureHeight, _internalFormat); - // update the modified count to show that it is up to date. getModifiedCount(contextID) = _image->getModifiedCount(); + + applyTexImage_subload(GL_TEXTURE_RECTANGLE, _image.get(), state, _textureWidth, _textureHeight, _internalFormat); } } else if (_subloadCallback.valid()) From 4645cc789e8243e155f622c90b6e171e93b213c2 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Fri, 20 Oct 2017 10:18:21 +0100 Subject: [PATCH 151/327] Updated shaders from OpenSceneGraph-Data/shaders --- src/osgTerrain/shaders/terrain_displacement_mapping_vert.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/osgTerrain/shaders/terrain_displacement_mapping_vert.cpp b/src/osgTerrain/shaders/terrain_displacement_mapping_vert.cpp index b3b0ce5d9..a052d4dc1 100644 --- a/src/osgTerrain/shaders/terrain_displacement_mapping_vert.cpp +++ b/src/osgTerrain/shaders/terrain_displacement_mapping_vert.cpp @@ -125,5 +125,5 @@ char terrain_displacement_mapping_vert[] = "#version 120\n" " vec3 position = gl_Vertex.xyz + gl_Normal.xyz * height_center;\n" " gl_Position = gl_ModelViewProjectionMatrix * vec4(position,1.0);\n" "\n" - "};\n" + "}\n" "\n"; From a2ad1c96066e8d9e21a42f6a56ae1517a788b51c Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Fri, 20 Oct 2017 11:37:41 +0100 Subject: [PATCH 152/327] Added built-in support for lighting.vert --- src/osgTerrain/GeometryPool.cpp | 5 ++++- src/osgTerrain/shaders/lighting_vert.cpp | 25 ++++++++++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) create mode 100644 src/osgTerrain/shaders/lighting_vert.cpp diff --git a/src/osgTerrain/GeometryPool.cpp b/src/osgTerrain/GeometryPool.cpp index c7fb3c5f8..e028aa99d 100644 --- a/src/osgTerrain/GeometryPool.cpp +++ b/src/osgTerrain/GeometryPool.cpp @@ -554,7 +554,10 @@ osg::ref_ptr GeometryPool::getOrCreateProgram(LayerTypes& layerTyp _programMap[layerTypes] = program; // add shader that provides the lighting functions - program->addShader(osgDB::readRefShaderFile("shaders/lighting.vert")); + { + #include "shaders/lighting_vert.cpp" + program->addShader(osgDB::readRefShaderFileWithFallback(osg::Shader::VERTEX, "shaders/lighting.vert", lighting_vert)); + } // OSG_NOTICE<<") creating new Program "< 0.0 )\n" + " color += gl_FrontLightProduct[lightNum].specular * pow( NdotHV, gl_FrontMaterial.shininess );\n" + "#endif\n" + "}\n" + "\n"; From 38e5fdadf022a46584ffbd9ea3f1b843d51ed680 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Fri, 20 Oct 2017 11:52:48 +0100 Subject: [PATCH 153/327] From Ralf Habacker, patch refactoring struct ObjOptionsStruct in obj plugin into a real class, which is a preparation for further obj related patches. --- src/osgPlugins/obj/ReaderWriterOBJ.cpp | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/src/osgPlugins/obj/ReaderWriterOBJ.cpp b/src/osgPlugins/obj/ReaderWriterOBJ.cpp index 5c14abddf..137996ea8 100644 --- a/src/osgPlugins/obj/ReaderWriterOBJ.cpp +++ b/src/osgPlugins/obj/ReaderWriterOBJ.cpp @@ -142,7 +142,8 @@ public: protected: - struct ObjOptionsStruct { + class ObjOptionsStruct { + public: bool rotate; bool noTesselateLargePolygons; bool noTriStripPolygons; @@ -155,6 +156,17 @@ protected: TextureAllocationMap textureUnitAllocation; /// Coordinates precision. int precision; + + ObjOptionsStruct() + { + rotate = true; + noTesselateLargePolygons = false; + noTriStripPolygons = false; + generateFacetNormals = false; + fixBlackMaterials = true; + noReverseFaces = false; + precision = std::numeric_limits::digits10 + 2; + } }; typedef std::map< std::string, osg::ref_ptr > MaterialToStateSetMap; @@ -831,13 +843,6 @@ osg::Node* ReaderWriterOBJ::convertModelToSceneGraph(obj::Model& model, ObjOptio ReaderWriterOBJ::ObjOptionsStruct ReaderWriterOBJ::parseOptions(const osgDB::ReaderWriter::Options* options) const { ObjOptionsStruct localOptions; - localOptions.rotate = true; - localOptions.noTesselateLargePolygons = false; - localOptions.noTriStripPolygons = false; - localOptions.generateFacetNormals = false; - localOptions.fixBlackMaterials = true; - localOptions.noReverseFaces = false; - localOptions.precision = std::numeric_limits::digits10 + 2; if (options!=NULL) { From 97aeb16551659c18f71987de78d5faa72718f474 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Fri, 20 Oct 2017 17:03:25 +0100 Subject: [PATCH 154/327] Moved osgText::GlyphTechnique::Features enum to osgText::ShaderTechinque enum to make it's roll clearer --- examples/osgfont/osgfont.cpp | 16 ++++++++-------- examples/osglogo/osglogo.cpp | 4 ++-- include/osgText/Font | 6 +++--- include/osgText/Glyph | 25 +++++++++++++------------ src/osgText/DefaultFont.cpp | 2 +- src/osgText/Font.cpp | 10 +++++----- src/osgText/Glyph.cpp | 8 ++++---- src/osgText/Text.cpp | 8 ++++---- 8 files changed, 40 insertions(+), 39 deletions(-) diff --git a/examples/osgfont/osgfont.cpp b/examples/osgfont/osgfont.cpp index f65e607fc..e16ab4079 100644 --- a/examples/osgfont/osgfont.cpp +++ b/examples/osgfont/osgfont.cpp @@ -68,7 +68,7 @@ struct TextSettings minFilter(osg::Texture::LINEAR_MIPMAP_LINEAR), magFilter(osg::Texture::LINEAR), maxAnisotropy(16.0f), - glyphTextureFeatures(osgText::GlyphTexture::GREYSCALE), + shaderTechnique(osgText::GREYSCALE), textColor(1.0f, 1.0f, 1.0f, 1.0f), backdropType(osgText::Text::NONE), backdropOffset(0.07f, 0.07f), @@ -102,9 +102,9 @@ struct TextSettings sizes.push_back(128); } - if (arguments.read("--GREYSCALE")) { glyphTextureFeatures = osgText::GlyphTexture::GREYSCALE; } - if (arguments.read("--SIGNED_DISTANCE_FIELD")) { glyphTextureFeatures = osgText::GlyphTexture::SIGNED_DISTANCE_FIELD; } - if (arguments.read("--ALL_FEATURES")) { glyphTextureFeatures = osgText::GlyphTexture::ALL_FEATURES; } + if (arguments.read("--GREYSCALE")) { shaderTechnique = osgText::GREYSCALE; } + if (arguments.read("--SIGNED_DISTANCE_FIELD")) { shaderTechnique = osgText::SIGNED_DISTANCE_FIELD; } + if (arguments.read("--ALL_FEATURES")) { shaderTechnique = osgText::ALL_FEATURES; } if (arguments.read("--font",fontFilename)) {} @@ -153,7 +153,7 @@ struct TextSettings font->setMinFilterHint(minFilter); font->setMagFilterHint(magFilter); font->setMaxAnisotropy(maxAnisotropy); - font->setGyphTextureFeatures(glyphTextureFeatures); + font->setShaderTechnique(shaderTechnique); text.setColor(textColor); text.setBackdropType(backdropType); @@ -168,7 +168,7 @@ struct TextSettings osg::Texture::FilterMode minFilter; osg::Texture::FilterMode magFilter; float maxAnisotropy; - osgText::GlyphTexture::Features glyphTextureFeatures; + osgText::ShaderTechnique shaderTechnique; osg::Vec4 textColor; osgText::Text::BackdropType backdropType; @@ -345,7 +345,7 @@ int main(int argc, char** argv) root->getOrCreateStateSet()->setAttribute(program.get(), osg::StateAttribute::OVERRIDE | osg::StateAttribute::ON); root->getOrCreateStateSet()->addUniform(new osg::Uniform("glyphTexture", 0)); - settings.glyphTextureFeatures = osgText::GlyphTexture::ALL_FEATURES; + settings.shaderTechnique = osgText::ALL_FEATURES; } @@ -396,7 +396,7 @@ int main(int argc, char** argv) osg::ref_ptr right_geode = new osg::Geode; right_geode->setNodeMask(0x2); - settings.glyphTextureFeatures = osgText::GlyphTexture::GREYSCALE; + settings.shaderTechnique = osgText::GREYSCALE; pos.set(0.0f, 0.0f, 0.0f); diff --git a/examples/osglogo/osglogo.cpp b/examples/osglogo/osglogo.cpp index fe8a12475..c419103cb 100644 --- a/examples/osglogo/osglogo.cpp +++ b/examples/osglogo/osglogo.cpp @@ -153,7 +153,7 @@ osg:: Node* createTextBelow(const osg::BoundingBox& bb, const std::string& label if (s_useSDF) { - text->getFont()->setGyphTextureFeatures(osgText::GlyphTexture::ALL_FEATURES); + text->getFont()->setShaderTechnique(osgText::ALL_FEATURES); } text->setAlignment(osgText::Text::CENTER_CENTER); @@ -186,7 +186,7 @@ osg:: Node* createTextLeft(const osg::BoundingBox& bb, const std::string& label, if (s_useSDF) { - text->getFont()->setGyphTextureFeatures(osgText::GlyphTexture::ALL_FEATURES); + text->getFont()->setShaderTechnique(osgText::ALL_FEATURES); } text->setAlignment(osgText::Text::RIGHT_CENTER); diff --git a/include/osgText/Font b/include/osgText/Font index 0af593b91..f8fcc89b0 100644 --- a/include/osgText/Font +++ b/include/osgText/Font @@ -108,8 +108,8 @@ public: virtual bool getVerticalSize(float& ascender, float& descender) const { return _implementation ? _implementation->getVerticalSize(ascender, descender) : false; } - void setGyphTextureFeatures(GlyphTexture::Features features) { _glyphTextureFeatures = features; } - GlyphTexture::Features getGlyphTextureFeatures() const { return _glyphTextureFeatures; } + void setShaderTechnique(ShaderTechnique features) { _shaderTechnique = features; } + ShaderTechnique getShaderTechnique() const { return _shaderTechnique; } /** Set the size of texture to create to store the glyph images when rendering. @@ -186,7 +186,7 @@ protected: // current active size of font FontResolution _fontSize; - GlyphTexture::Features _glyphTextureFeatures; + ShaderTechnique _shaderTechnique; unsigned int _textureWidthHint; unsigned int _textureHeightHint; diff --git a/include/osgText/Glyph b/include/osgText/Glyph index adba880bc..c7d717f25 100644 --- a/include/osgText/Glyph +++ b/include/osgText/Glyph @@ -38,6 +38,13 @@ class Glyph3D; class GlyphGeometry; class GlyphTexture; +enum ShaderTechnique +{ + GREYSCALE = 0x1, + SIGNED_DISTANCE_FIELD = 0x2, + ALL_FEATURES = GREYSCALE | SIGNED_DISTANCE_FIELD +}; + class OSGTEXT_EXPORT Glyph : public osg::Image { public: @@ -251,15 +258,9 @@ public: /** return -1 if *this < *rhs, 0 if *this==*rhs, 1 if *this>*rhs.*/ virtual int compare(const osg::StateAttribute& rhs) const; - enum Features - { - GREYSCALE, - SIGNED_DISTANCE_FIELD, - ALL_FEATURES - }; + void setShaderTechnique(ShaderTechnique technique) { _shaderTechnique = technique; } - void setGlyphTextureFeatures(Features features) { _glyphTextureFeatures = features; } - Features getGlyphTextureFeatures() const { return _glyphTextureFeatures; } + ShaderTechnique getShaderTechnique() const { return _shaderTechnique; } int getEffectMargin(const Glyph* glyph); @@ -284,11 +285,11 @@ protected: void copyGlyphImage(Glyph* glyph); - Features _glyphTextureFeatures; + ShaderTechnique _shaderTechnique; - int _usedY; - int _partUsedX; - int _partUsedY; + int _usedY; + int _partUsedX; + int _partUsedY; typedef std::vector< osg::ref_ptr > GlyphRefList; typedef std::vector< const Glyph* > GlyphPtrList; diff --git a/src/osgText/DefaultFont.cpp b/src/osgText/DefaultFont.cpp index 94aac9be3..ac1a5d8ba 100644 --- a/src/osgText/DefaultFont.cpp +++ b/src/osgText/DefaultFont.cpp @@ -32,7 +32,7 @@ DefaultFont::DefaultFont() char *ptr; if ((ptr = getenv("OSG_SDF_TEXT")) != 0) { - _glyphTextureFeatures = osgText::GlyphTexture::ALL_FEATURES; + _shaderTechnique = osgText::ALL_FEATURES; } constructGlyphs(); diff --git a/src/osgText/Font.cpp b/src/osgText/Font.cpp index 3e3402b53..bfe67cd74 100644 --- a/src/osgText/Font.cpp +++ b/src/osgText/Font.cpp @@ -225,9 +225,9 @@ osg::ref_ptr osgText::readRefFontStream(std::istream& stream, const osgDB: Font::Font(FontImplementation* implementation): osg::Object(true), #if 0 - _glyphTextureFeatures(GlyphTexture::ALL_FEATURES), + _shaderTechnique(ALL_FEATURES), #else - _glyphTextureFeatures(GlyphTexture::GREYSCALE), + _shaderTechnique(GREYSCALE), #endif _textureWidthHint(1024), _textureHeightHint(1024), @@ -250,11 +250,11 @@ Font::Font(FontImplementation* implementation): if ((ptr = getenv("OSG_SDF_TEXT")) != 0) { - _glyphTextureFeatures = GlyphTexture::ALL_FEATURES; + _shaderTechnique = ALL_FEATURES; } else if ((ptr = getenv("OSG_GREYSCALE_TEXT")) != 0) { - _glyphTextureFeatures = GlyphTexture::GREYSCALE; + _shaderTechnique = GREYSCALE; } } @@ -485,7 +485,7 @@ void Font::addGlyph(const FontResolution& fontRes, unsigned int charcode, Glyph* OSG_INFO<< " Font " << this<< ", numberOfTexturesAllocated "<setGlyphTextureFeatures(_glyphTextureFeatures); + glyphTexture->setShaderTechnique(_shaderTechnique); glyphTexture->setTextureSize(_textureWidthHint,_textureHeightHint); glyphTexture->setFilter(osg::Texture::MIN_FILTER,_minFilterHint); glyphTexture->setFilter(osg::Texture::MAG_FILTER,_magFilterHint); diff --git a/src/osgText/Glyph.cpp b/src/osgText/Glyph.cpp index 114f6649a..d7f2395fb 100644 --- a/src/osgText/Glyph.cpp +++ b/src/osgText/Glyph.cpp @@ -75,7 +75,7 @@ int GlyphTexture::compare(const osg::StateAttribute& rhs) const int GlyphTexture::getEffectMargin(const Glyph* glyph) { - if (_glyphTextureFeatures==GREYSCALE) return 0; + if (_shaderTechnique==GREYSCALE) return 0; else return osg::maximum(glyph->getFontResolution().second/6, 2u); } @@ -173,7 +173,7 @@ void GlyphTexture::copyGlyphImage(Glyph* glyph) { _image->dirty(); - if (_glyphTextureFeatures==GREYSCALE) + if (_shaderTechnique==GREYSCALE) { // OSG_NOTICE<<"GlyphTexture::copyGlyphImage() greyscale copying. glyphTexture="<getGlyphTextureFeatures()="<getGlyphTextureFeatures()<getShaderTechnique()="<getShaderTechnique()<getShaderHint(); - if (activeFont->getGlyphTextureFeatures()==GlyphTexture::GREYSCALE && shaderHint==osg::DisplaySettings::SHADER_NONE) + if (activeFont->getShaderTechnique()==GREYSCALE && shaderHint==osg::DisplaySettings::SHADER_NONE) { OSG_NOTICE<<"Font::Font() Fixed function pipeline"<addShader(osgDB::readRefShaderFileWithFallback(osg::Shader::VERTEX, "shaders/text.vert", text_vert)); } - if (activeFont->getGlyphTextureFeatures()==GlyphTexture::GREYSCALE) + if (activeFont->getShaderTechnique()==GREYSCALE) { OSG_NOTICE<<"Using shaders/text_greyscale.frag"< Date: Sat, 21 Oct 2017 10:08:41 +0100 Subject: [PATCH 155/327] Added Text::s/getShaderTechnique() --- include/osgText/Text | 8 ++++++++ src/osgText/Text.cpp | 17 +++++++++++++++-- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/include/osgText/Text b/include/osgText/Text index acb8323f9..ab5e547a0 100644 --- a/include/osgText/Text +++ b/include/osgText/Text @@ -36,6 +36,13 @@ public: virtual const char* className() const { return "Text"; } virtual const char* libraryName() const { return "osgText"; } + /** Set the ShaderTechnique hint to specify what fatures in the text shaders to enable.*/ + void setShaderTechnique(ShaderTechnique technique); + + /** Get the ShaderTechnique hint.*/ + ShaderTechnique getShaderTechnique() { return _shaderTechnique; } + + /** * Turns off writing to the depth buffer when rendering text. This only affects text * with no backdrop or text using the DELAYED_DEPTH_WRITES implementation, since @@ -282,6 +289,7 @@ protected: void drawImplementationSinglePass(osg::State& state, const osg::Vec4& colorMultiplier) const; + ShaderTechnique _shaderTechnique; bool _enableDepthWrites; BackdropType _backdropType; diff --git a/src/osgText/Text.cpp b/src/osgText/Text.cpp index 82c77d548..f2ef6ecbb 100644 --- a/src/osgText/Text.cpp +++ b/src/osgText/Text.cpp @@ -25,10 +25,15 @@ #include +#include +#include + + using namespace osg; using namespace osgText; Text::Text(): + _shaderTechnique(GREYSCALE), _enableDepthWrites(true), _backdropType(NONE), _backdropHorizontalOffset(0.07f), @@ -47,6 +52,7 @@ Text::Text(): Text::Text(const Text& text,const osg::CopyOp& copyop): osgText::TextBase(text,copyop), + _shaderTechnique(text._shaderTechnique), _enableDepthWrites(text._enableDepthWrites), _backdropType(text._backdropType), _backdropHorizontalOffset(text._backdropHorizontalOffset), @@ -65,8 +71,15 @@ Text::~Text() { } -#include -#include + +void Text::setShaderTechnique(ShaderTechnique technique) +{ + if (_shaderTechnique==technique) return; + + _shaderTechnique = technique; + + assignStateSet(); +} osg::StateSet* Text::createStateSet() { From ade97dcd9526eb46b84b1914f827f63294c7b1d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Si=C3=B1uela=20Pastor?= Date: Wed, 18 Oct 2017 12:20:35 +0200 Subject: [PATCH 156/327] Fix ccache configuration in travis Use ccache as explained in https://docs.travis-ci.com/user/caching/#ccache-cache --- .travis.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 687c7c43d..ac38b0ed5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,6 +4,9 @@ env: # via the "travis encrypt" command using the project repo's public key - secure: "0ROQiFbsZo33ce2v5VjBxNljemh/HU70ntSSPygYwaDFymubts/62SixXVkbKNIFdrs3uYD6qeA/eMmpqXxLcs+PXNq5NrH7eSWw9oDIKMhq3NQH/IZLdRfXwihHimZ1qEs/TXyWlT2aC4rpBi1py3cJeTh1aBMlz4V/nm16iRAgc596ThNTuPDHa0F9/gZnwccI/Rr9VpiYn7vEBbuY9lYr43D0G3NuuQyvvlHShroH09fh6KyFOWIY38AQtnuVGNC1fIiAUk7TUqDqSBwhIrUV5saHbP0kca6DP32REkv//h4JwM76UHv+ntVEoK/UiztJHMkrw71gXYTyvIvlDBpT+IDoeIwUW2QFNQ5zJZI7FM8k0+oeK+F7k/mkffDzr1zww/PQoxqFBF0PoxAni/L9qkA4X2o1A6mRDbe9besp2LQG6Vniwj3bHpCId2QiiMrANVg0EAqkcL2mVFEaqZsh90qCkr1UDq4WQoYbXh0Fy3UnQpbuxDvCME8u03lwuv6ds/SBxc5cgKv7oWXgezaDg7/OCR+0lIAGuLqmNRD8Xw7a0WZGmSbYCHIZmeyFja2KuUvMiVCt8+QsyZr3e523DwBwnSj1BIYFRstMaSEJgu9B8rfTRRllOOKJXCQtdFVuGu8VI6PniSAkI6c535yOWzsuS8HwIkN2ll+Wn7E=" +language: cpp +cache: ccache + matrix: fast_finish: true include: @@ -18,8 +21,7 @@ matrix: sudo: false cache: apt: true - directories: - - $HOME/.ccache + ccache: true compiler: #- clang - gcc @@ -43,11 +45,9 @@ matrix: # OSX build - os: osx - language: cpp env: - CMAKECMD_ARGS="-DBUILD_OSG_EXAMPLES=OFF -DBUILD_OSG_PLUGINS_BY_DEFAULT=ON -DBUILD_OSG_APPLICATIONS=ON" - os: osx - language: cpp env: - CMAKECMD_ARGS="-DBUILD_OSG_EXAMPLES=ON -DBUILD_OSG_PLUGINS_BY_DEFAULT=OFF -DBUILD_OSG_APPLICATIONS=OFF" From 727653695d62526a23a52f01646241dbb88b2e23 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Si=C3=B1uela=20Pastor?= Date: Fri, 20 Oct 2017 14:09:11 +0200 Subject: [PATCH 157/327] Install ccache on MacOs Note that brew update must be run before any brew install command or it will fail, see https://github.com/travis-ci/travis-ci/issues/8552. --- .travis.yml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/.travis.yml b/.travis.yml index ac38b0ed5..27f0fc6f0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -45,9 +45,19 @@ matrix: # OSX build - os: osx + before_install: + - brew update + install: + - brew install ccache + - export PATH="/usr/local/opt/ccache/libexec:$PATH" env: - CMAKECMD_ARGS="-DBUILD_OSG_EXAMPLES=OFF -DBUILD_OSG_PLUGINS_BY_DEFAULT=ON -DBUILD_OSG_APPLICATIONS=ON" - os: osx + before_install: + - brew update + install: + - brew install ccache + - export PATH="/usr/local/opt/ccache/libexec:$PATH" env: - CMAKECMD_ARGS="-DBUILD_OSG_EXAMPLES=ON -DBUILD_OSG_PLUGINS_BY_DEFAULT=OFF -DBUILD_OSG_APPLICATIONS=OFF" From abb7f46371eee19b7bc6f5ea804ff559c39311e6 Mon Sep 17 00:00:00 2001 From: Hartwig Date: Sun, 22 Oct 2017 13:47:51 +0200 Subject: [PATCH 158/327] Removal of compiler warning for Cocoa builds --- src/osgViewer/GraphicsWindowCocoa.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/osgViewer/GraphicsWindowCocoa.mm b/src/osgViewer/GraphicsWindowCocoa.mm index bbca00de9..14f6fcb5f 100644 --- a/src/osgViewer/GraphicsWindowCocoa.mm +++ b/src/osgViewer/GraphicsWindowCocoa.mm @@ -199,7 +199,7 @@ static NSRect convertToQuartzCoordinates(const NSRect& rect) // the app-delegate, handling quit-requests // ---------------------------------------------------------------------------------------------------------- -@interface CocoaAppDelegate : NSObject +@interface CocoaAppDelegate : NSObject { } From 41e9cd315762c7317493b841ff063c1706e2bfd4 Mon Sep 17 00:00:00 2001 From: Hartwig Date: Sun, 22 Oct 2017 15:04:33 +0200 Subject: [PATCH 159/327] Replacement of commas with semicolons --- include/osgDB/DataTypes | 2 +- include/osgUtil/RenderLeaf | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/include/osgDB/DataTypes b/include/osgDB/DataTypes index 8d319e806..4b6a8bbca 100644 --- a/include/osgDB/DataTypes +++ b/include/osgDB/DataTypes @@ -134,7 +134,7 @@ public: : _name(copy._name), _indentDelta(copy._indentDelta) {} void set( const char* name, int delta=0 ) - { _name = name, _indentDelta = delta; } + { _name = name; _indentDelta = delta; } std::string _name; int _indentDelta; diff --git a/include/osgUtil/RenderLeaf b/include/osgUtil/RenderLeaf index b1d36fb03..6e699602a 100644 --- a/include/osgUtil/RenderLeaf +++ b/include/osgUtil/RenderLeaf @@ -52,8 +52,8 @@ class OSGUTIL_EXPORT RenderLeaf : public osg::Referenced { _parent = 0; _drawable = drawable; - _projection = projection, - _modelview = modelview, + _projection = projection; + _modelview = modelview; _depth = depth; _dynamic = (drawable->getDataVariance()==osg::Object::DYNAMIC); _traversalNumber = traversalNumber; From 2fc3387429338a0eab4ace4e0dfb927114806f55 Mon Sep 17 00:00:00 2001 From: Hartwig Date: Sun, 22 Oct 2017 22:13:46 +0200 Subject: [PATCH 160/327] BUG FIX - Addition of missing #endif directive --- src/osgViewer/GraphicsWindowCarbon.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/osgViewer/GraphicsWindowCarbon.cpp b/src/osgViewer/GraphicsWindowCarbon.cpp index 0fbb6f21c..18169b3f0 100644 --- a/src/osgViewer/GraphicsWindowCarbon.cpp +++ b/src/osgViewer/GraphicsWindowCarbon.cpp @@ -1100,3 +1100,6 @@ public: REGISTER_WINDOWINGSYSTEMINTERFACE(Carbon, CarbonWindowingSystemInterface) } + +#endif + From 4b295c46d16ef837b8fb8a93417df5bd2ca95596 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Mon, 23 Oct 2017 14:50:35 +0100 Subject: [PATCH 161/327] Restructed the way that GlyphTexture is set up to better support control of osgText::ShaderTechnique from osgText::Text --- examples/osgfont/osgfont.cpp | 2 +- examples/osglogo/osglogo.cpp | 4 +- include/osgText/Font | 9 +-- include/osgText/Glyph | 56 ++++++++++-------- src/osgText/DefaultFont.cpp | 6 -- src/osgText/Font.cpp | 21 ++----- src/osgText/Glyph.cpp | 80 +++++++++++++------------- src/osgText/Text.cpp | 108 +++++++++++++++++++++-------------- 8 files changed, 147 insertions(+), 139 deletions(-) diff --git a/examples/osgfont/osgfont.cpp b/examples/osgfont/osgfont.cpp index e16ab4079..bad750798 100644 --- a/examples/osgfont/osgfont.cpp +++ b/examples/osgfont/osgfont.cpp @@ -153,12 +153,12 @@ struct TextSettings font->setMinFilterHint(minFilter); font->setMagFilterHint(magFilter); font->setMaxAnisotropy(maxAnisotropy); - font->setShaderTechnique(shaderTechnique); text.setColor(textColor); text.setBackdropType(backdropType); text.setBackdropOffset(backdropOffset.x(), backdropOffset.y()); text.setBackdropColor(backdropColor); + text.setShaderTechnique(shaderTechnique); text.setFont(font.get()); diff --git a/examples/osglogo/osglogo.cpp b/examples/osglogo/osglogo.cpp index c419103cb..f5161c041 100644 --- a/examples/osglogo/osglogo.cpp +++ b/examples/osglogo/osglogo.cpp @@ -153,7 +153,7 @@ osg:: Node* createTextBelow(const osg::BoundingBox& bb, const std::string& label if (s_useSDF) { - text->getFont()->setShaderTechnique(osgText::ALL_FEATURES); + text->setShaderTechnique(osgText::ALL_FEATURES); } text->setAlignment(osgText::Text::CENTER_CENTER); @@ -186,7 +186,7 @@ osg:: Node* createTextLeft(const osg::BoundingBox& bb, const std::string& label, if (s_useSDF) { - text->getFont()->setShaderTechnique(osgText::ALL_FEATURES); + text->setShaderTechnique(osgText::ALL_FEATURES); } text->setAlignment(osgText::Text::RIGHT_CENTER); diff --git a/include/osgText/Font b/include/osgText/Font index f8fcc89b0..ab4641c93 100644 --- a/include/osgText/Font +++ b/include/osgText/Font @@ -107,11 +107,6 @@ public: * return true on success, return false when not supported.*/ virtual bool getVerticalSize(float& ascender, float& descender) const { return _implementation ? _implementation->getVerticalSize(ascender, descender) : false; } - - void setShaderTechnique(ShaderTechnique features) { _shaderTechnique = features; } - ShaderTechnique getShaderTechnique() const { return _shaderTechnique; } - - /** Set the size of texture to create to store the glyph images when rendering. * Note, this doesn't affect already created Texture Glhph's.*/ void setTextureSizeHint(unsigned int width,unsigned int height); @@ -162,6 +157,8 @@ public: typedef std::vector< osg::ref_ptr > GlyphTextureList; GlyphTextureList& getGlyphTextureList() { return _glyphTextureList; } + void assignGlyphToGlyphTexture(Glyph* glyph, ShaderTechnique shaderTechnique); + protected: virtual ~Font(); @@ -186,8 +183,6 @@ protected: // current active size of font FontResolution _fontSize; - ShaderTechnique _shaderTechnique; - unsigned int _textureWidthHint; unsigned int _textureHeightHint; osg::Texture::FilterMode _minFilterHint; diff --git a/include/osgText/Glyph b/include/osgText/Glyph index c7d717f25..782b402dd 100644 --- a/include/osgText/Glyph +++ b/include/osgText/Glyph @@ -77,22 +77,40 @@ public: void setVerticalAdvance(float advance); float getVerticalAdvance() const; - void setTexture(GlyphTexture* texture); - GlyphTexture* getTexture(); - const GlyphTexture* getTexture() const; + struct TextureInfo : public osg::Referenced + { + TextureInfo(): + texture(0), + texelMargin(0.0f) {} - void setTexturePosition(int posX,int posY); - int getTexturePositionX() const; - int getTexturePositionY() const; + TextureInfo(GlyphTexture* tex, int x, int y, const osg::Vec2& mintc, const osg::Vec2& maxtc, float margin): + texture(tex), + texturePositionX(x), + texturePositionY(y), + minTexCoord(mintc), + maxTexCoord(maxtc), + texelMargin(margin) {} - void setMinTexCoord(const osg::Vec2& coord); - const osg::Vec2& getMinTexCoord() const; + GlyphTexture* texture; + int texturePositionX; + int texturePositionY; + osg::Vec2 minTexCoord; + osg::Vec2 maxTexCoord; + float texelMargin; + }; - void setMaxTexCoord(const osg::Vec2& coord); - const osg::Vec2& getMaxTexCoord() const; + void setTextureInfo(ShaderTechnique technique, TextureInfo* info) + { + if (technique>=_textureInfoList.size()) _textureInfoList.resize(technique+1); + _textureInfoList[technique] = info; + } - void setTexelMargin(float margin) { _texelMargin = margin; } - float getTexelMargin() const { return _texelMargin; } + const TextureInfo* getTextureInfo(ShaderTechnique technique) const + { + return (technique<_textureInfoList.size()) ? _textureInfoList[technique].get() : 0; + } + + TextureInfo* getOrCreateTextureInfo(ShaderTechnique technique); protected: @@ -112,16 +130,8 @@ protected: osg::Vec2 _verticalBearing; float _verticalAdvance; - GlyphTexture* _texture; - int _texturePosX; - int _texturePosY; - osg::Vec2 _minTexCoord; - osg::Vec2 _maxTexCoord; - float _texelMargin; - - typedef osg::buffered_value GLObjectList; - mutable GLObjectList _globjList; - + typedef std::vector< osg::ref_ptr > TextureInfoList; + TextureInfoList _textureInfoList; }; class OSGTEXT_EXPORT GlyphGeometry : public osg::Referenced @@ -283,7 +293,7 @@ protected: virtual ~GlyphTexture(); - void copyGlyphImage(Glyph* glyph); + void copyGlyphImage(Glyph* glyph, Glyph::TextureInfo* info); ShaderTechnique _shaderTechnique; diff --git a/src/osgText/DefaultFont.cpp b/src/osgText/DefaultFont.cpp index ac1a5d8ba..dfc9b5945 100644 --- a/src/osgText/DefaultFont.cpp +++ b/src/osgText/DefaultFont.cpp @@ -29,12 +29,6 @@ DefaultFont::DefaultFont() _minFilterHint = osg::Texture::LINEAR_MIPMAP_LINEAR; _magFilterHint = osg::Texture::LINEAR; - char *ptr; - if ((ptr = getenv("OSG_SDF_TEXT")) != 0) - { - _shaderTechnique = osgText::ALL_FEATURES; - } - constructGlyphs(); } diff --git a/src/osgText/Font.cpp b/src/osgText/Font.cpp index bfe67cd74..7d6c61c1f 100644 --- a/src/osgText/Font.cpp +++ b/src/osgText/Font.cpp @@ -224,11 +224,6 @@ osg::ref_ptr osgText::readRefFontStream(std::istream& stream, const osgDB: Font::Font(FontImplementation* implementation): osg::Object(true), -#if 0 - _shaderTechnique(ALL_FEATURES), -#else - _shaderTechnique(GREYSCALE), -#endif _textureWidthHint(1024), _textureHeightHint(1024), _minFilterHint(osg::Texture::LINEAR_MIPMAP_LINEAR), @@ -247,15 +242,6 @@ Font::Font(FontImplementation* implementation): if (osg_max_size<_textureWidthHint) _textureWidthHint = osg_max_size; if (osg_max_size<_textureHeightHint) _textureHeightHint = osg_max_size; } - - if ((ptr = getenv("OSG_SDF_TEXT")) != 0) - { - _shaderTechnique = ALL_FEATURES; - } - else if ((ptr = getenv("OSG_GREYSCALE_TEXT")) != 0) - { - _shaderTechnique = GREYSCALE; - } } Font::~Font() @@ -459,6 +445,10 @@ void Font::addGlyph(const FontResolution& fontRes, unsigned int charcode, Glyph* _sizeGlyphMap[fontRes][charcode]=glyph; +} + +void Font::assignGlyphToGlyphTexture(Glyph* glyph, ShaderTechnique shaderTechnique) +{ int posX=0,posY=0; GlyphTexture* glyphTexture = 0; @@ -485,7 +475,7 @@ void Font::addGlyph(const FontResolution& fontRes, unsigned int charcode, Glyph* OSG_INFO<< " Font " << this<< ", numberOfTexturesAllocated "<setShaderTechnique(_shaderTechnique); + glyphTexture->setShaderTechnique(shaderTechnique); glyphTexture->setTextureSize(_textureWidthHint,_textureHeightHint); glyphTexture->setFilter(osg::Texture::MIN_FILTER,_minFilterHint); glyphTexture->setFilter(osg::Texture::MAG_FILTER,_magFilterHint); @@ -503,5 +493,4 @@ void Font::addGlyph(const FontResolution& fontRes, unsigned int charcode, Glyph* // add the glyph into the texture. glyphTexture->addGlyph(glyph,posX,posY); - } diff --git a/src/osgText/Glyph.cpp b/src/osgText/Glyph.cpp index d7f2395fb..fbd793cfa 100644 --- a/src/osgText/Glyph.cpp +++ b/src/osgText/Glyph.cpp @@ -42,8 +42,6 @@ using namespace std; #endif - - #if 0 #define TEXTURE_IMAGE_NUM_CHANNELS 1 #define TEXTURE_IMAGE_FORMAT OSGTEXT_GLYPH_FORMAT @@ -52,6 +50,11 @@ using namespace std; #define TEXTURE_IMAGE_FORMAT GL_RGBA #endif + +////////////////////////////////////////////////////////////////////////////////////////////////////////// +// +// GlyphTexture +// GlyphTexture::GlyphTexture(): _usedY(0), _partUsedX(0), @@ -154,22 +157,19 @@ void GlyphTexture::addGlyph(Glyph* glyph, int posX, int posY) _glyphs.push_back(glyph); - // set up the details of where to place glyph's image in the texture. - glyph->setTexture(this); - glyph->setTexturePosition(posX,posY); + osg::ref_ptr info = new Glyph::TextureInfo( + this, + posX, posY, + osg::Vec2( static_cast(posX)/static_cast(getTextureWidth()), static_cast(posY)/static_cast(getTextureHeight()) ), // minTexCoord + osg::Vec2( static_cast(posX+glyph->s())/static_cast(getTextureWidth()), static_cast(posY+glyph->t())/static_cast(getTextureHeight()) ), // maxTexCoord + float(getTexelMargin(glyph))); // margin - glyph->setMinTexCoord( osg::Vec2( static_cast(posX)/static_cast(getTextureWidth()), - static_cast(posY)/static_cast(getTextureHeight()) ) ); - glyph->setMaxTexCoord( osg::Vec2( static_cast(posX+glyph->s())/static_cast(getTextureWidth()), - static_cast(posY+glyph->t())/static_cast(getTextureHeight()) ) ); + glyph->setTextureInfo(_shaderTechnique, info.get()); - - glyph->setTexelMargin(float(getTexelMargin(glyph))); - - copyGlyphImage(glyph); + copyGlyphImage(glyph, info); } -void GlyphTexture::copyGlyphImage(Glyph* glyph) +void GlyphTexture::copyGlyphImage(Glyph* glyph, Glyph::TextureInfo* info) { _image->dirty(); @@ -179,7 +179,7 @@ void GlyphTexture::copyGlyphImage(Glyph* glyph) // make sure the glyph image settings and the target image are consisent before copying. glyph->setPixelFormat(_image->getPixelFormat()); glyph->setInternalTextureFormat(_image->getPixelFormat()); - _image->copySubImage(glyph->getTexturePositionX(), glyph->getTexturePositionY(), 0, glyph); + _image->copySubImage(info->texturePositionX, info->texturePositionY, 0, glyph); return; } @@ -191,7 +191,7 @@ void GlyphTexture::copyGlyphImage(Glyph* glyph) int dest_columns = _image->s(); int dest_rows = _image->t(); - unsigned char* dest_data = _image->data(glyph->getTexturePositionX(),glyph->getTexturePositionY()); + unsigned char* dest_data = _image->data(info->texturePositionX, info->texturePositionY); int search_distance = getEffectMargin(glyph); @@ -204,11 +204,11 @@ void GlyphTexture::copyGlyphImage(Glyph* glyph) float max_distance = sqrtf(float(search_distance)*float(search_distance)*2.0); - if ((left+glyph->getTexturePositionX())<0) left = -glyph->getTexturePositionX(); - if ((right+glyph->getTexturePositionX())>=dest_columns) right = dest_columns-glyph->getTexturePositionX()-1; + if ((left+info->texturePositionX)<0) left = -info->texturePositionX; + if ((right+info->texturePositionX)>=dest_columns) right = dest_columns-info->texturePositionX-1; - if ((lower+glyph->getTexturePositionY())<0) lower = -glyph->getTexturePositionY(); - if ((upper+glyph->getTexturePositionY())>=dest_rows) upper = dest_rows-glyph->getTexturePositionY()-1; + if ((lower+info->texturePositionY)<0) lower = -info->texturePositionY; + if ((upper+info->texturePositionY)>=dest_rows) upper = dest_rows-info->texturePositionY-1; int num_components = osg::Image::computeNumComponents(_image->getPixelFormat()); @@ -427,13 +427,18 @@ osg::Image* GlyphTexture::createImage() ++itr) { Glyph* glyph = itr->get(); - copyGlyphImage(glyph); + // copyGlyphImage(glyph); // TODO!!!!! + OSG_NOTICE<<"GlyphTexture::createImage() need to implement copy"<=_textureInfoList.size()) _textureInfoList.resize(technique+1); + if (!_textureInfoList[technique]) + { + _font->assignGlyphToGlyphTexture(this, technique); + } + return _textureInfoList[technique].get(); +} +////////////////////////////////////////////////////////////////////////////////////////////////////////// +// +// Glyph3D +// Glyph3D::Glyph3D(Font* font, unsigned int glyphCode): osg::Referenced(true), _font(font), diff --git a/src/osgText/Text.cpp b/src/osgText/Text.cpp index f2ef6ecbb..4651edb5d 100644 --- a/src/osgText/Text.cpp +++ b/src/osgText/Text.cpp @@ -47,6 +47,16 @@ Text::Text(): { _supportsVertexBufferObjects = true; + char* ptr = 0; + if ((ptr = getenv("OSG_SDF_TEXT")) != 0) + { + _shaderTechnique = ALL_FEATURES; + } + else if ((ptr = getenv("OSG_GREYSCALE_TEXT")) != 0) + { + _shaderTechnique = GREYSCALE; + } + assignStateSet(); } @@ -129,7 +139,7 @@ osg::StateSet* Text::createStateSet() } } - if (activeFont->getShaderTechnique()!=GREYSCALE) + if (_shaderTechnique!=GREYSCALE) { ss<setMode(GL_BLEND, osg::StateAttribute::ON); - OSG_NOTICE<<"Text::createStateSet() activeFont->getShaderTechnique()="<getShaderTechnique()<addShader(osgDB::readRefShaderFileWithFallback(osg::Shader::VERTEX, "shaders/text.vert", text_vert)); } - if (activeFont->getShaderTechnique()==GREYSCALE) + if (_shaderTechnique==GREYSCALE) { OSG_NOTICE<<"Using shaders/text_greyscale.frag"<getTexture()]; + const Glyph::TextureInfo* info = glyph->getOrCreateTextureInfo(_shaderTechnique); + GlyphTexture* glyphTexture = info ? info->texture : 0; + GlyphQuads& glyphquad = _textureGlyphQuadMap[glyphTexture]; glyphquad._glyphs.push_back(glyph); @@ -625,46 +637,54 @@ void Text::computeGlyphRepresentation() local.x() += bearing.x() * wr; local.y() += bearing.y() * hr; - - // Adjust coordinates and texture coordinates to avoid - // clipping the edges of antialiased characters. - osg::Vec2 mintc = glyph->getMinTexCoord(); - osg::Vec2 maxtc = glyph->getMaxTexCoord(); - osg::Vec2 vDiff = maxtc - mintc; - float texelMargin = glyph->getTexelMargin(); - - float fHorizTCMargin = texelMargin / glyph->getTexture()->getTextureWidth(); - float fVertTCMargin = texelMargin / glyph->getTexture()->getTextureHeight(); - float fHorizQuadMargin = vDiff.x() == 0.0f ? 0.0f : width * fHorizTCMargin / vDiff.x(); - float fVertQuadMargin = vDiff.y() == 0.0f ? 0.0f : height * fVertTCMargin / vDiff.y(); - - mintc.x() -= fHorizTCMargin; - mintc.y() -= fVertTCMargin; - maxtc.x() += fHorizTCMargin; - maxtc.y() += fVertTCMargin; - osg::Vec2 minc = local+osg::Vec2(0.0f-fHorizQuadMargin,0.0f-fVertQuadMargin); - osg::Vec2 maxc = local+osg::Vec2(width+fHorizQuadMargin,height+fVertQuadMargin); - - addGlyphQuad(glyph, minc, maxc, mintc, maxtc); - - // move the cursor onto the next character. - // also expand bounding box - switch(_layout) + const Glyph::TextureInfo* info = glyph->getOrCreateTextureInfo(_shaderTechnique); + if (info) { - case LEFT_TO_RIGHT: - cursor.x() += glyph->getHorizontalAdvance() * wr; - _textBB.expandBy(osg::Vec3(minc.x(), minc.y(), 0.0f)); //lower left corner - _textBB.expandBy(osg::Vec3(maxc.x(), maxc.y(), 0.0f)); //upper right corner - break; - case VERTICAL: - cursor.y() -= glyph->getVerticalAdvance() * hr; - _textBB.expandBy(osg::Vec3(minc.x(),maxc.y(),0.0f)); //upper left corner - _textBB.expandBy(osg::Vec3(maxc.x(),minc.y(),0.0f)); //lower right corner - break; - case RIGHT_TO_LEFT: - _textBB.expandBy(osg::Vec3(maxc.x(),minc.y(),0.0f)); //lower right corner - _textBB.expandBy(osg::Vec3(minc.x(),maxc.y(),0.0f)); //upper left corner - break; + + // Adjust coordinates and texture coordinates to avoid + // clipping the edges of antialiased characters. + osg::Vec2 mintc = info->minTexCoord; + osg::Vec2 maxtc = info->maxTexCoord; + osg::Vec2 vDiff = maxtc - mintc; + float texelMargin = info->texelMargin; + + float fHorizTCMargin = texelMargin / info->texture->getTextureWidth(); + float fVertTCMargin = texelMargin / info->texture->getTextureHeight(); + float fHorizQuadMargin = vDiff.x() == 0.0f ? 0.0f : width * fHorizTCMargin / vDiff.x(); + float fVertQuadMargin = vDiff.y() == 0.0f ? 0.0f : height * fVertTCMargin / vDiff.y(); + + mintc.x() -= fHorizTCMargin; + mintc.y() -= fVertTCMargin; + maxtc.x() += fHorizTCMargin; + maxtc.y() += fVertTCMargin; + osg::Vec2 minc = local+osg::Vec2(0.0f-fHorizQuadMargin,0.0f-fVertQuadMargin); + osg::Vec2 maxc = local+osg::Vec2(width+fHorizQuadMargin,height+fVertQuadMargin); + + addGlyphQuad(glyph, minc, maxc, mintc, maxtc); + + // move the cursor onto the next character. + // also expand bounding box + switch(_layout) + { + case LEFT_TO_RIGHT: + cursor.x() += glyph->getHorizontalAdvance() * wr; + _textBB.expandBy(osg::Vec3(minc.x(), minc.y(), 0.0f)); //lower left corner + _textBB.expandBy(osg::Vec3(maxc.x(), maxc.y(), 0.0f)); //upper right corner + break; + case VERTICAL: + cursor.y() -= glyph->getVerticalAdvance() * hr; + _textBB.expandBy(osg::Vec3(minc.x(),maxc.y(),0.0f)); //upper left corner + _textBB.expandBy(osg::Vec3(maxc.x(),minc.y(),0.0f)); //lower right corner + break; + case RIGHT_TO_LEFT: + _textBB.expandBy(osg::Vec3(maxc.x(),minc.y(),0.0f)); //lower right corner + _textBB.expandBy(osg::Vec3(minc.x(),maxc.y(),0.0f)); //upper left corner + break; + } + } + else + { + OSG_NOTICE<<"No TextureInfo for "< Date: Mon, 23 Oct 2017 16:07:24 +0100 Subject: [PATCH 162/327] Renamed text_sdf.frag to text.frag and removed text_greyscale_frag. Cleaned up setup of osgText::ShaderTechnique adding a NO_SHADER_TECHNIQUE option. --- include/osgText/Glyph | 1 + src/osgText/Glyph.cpp | 15 +- src/osgText/Text.cpp | 24 +- src/osgText/shaders/text_frag.cpp | 257 ++++++++++++++++++++ src/osgText/shaders/text_greyscale_frag.cpp | 35 --- src/osgText/shaders/text_sdf_frag.cpp | 257 -------------------- 6 files changed, 272 insertions(+), 317 deletions(-) create mode 100644 src/osgText/shaders/text_frag.cpp delete mode 100644 src/osgText/shaders/text_greyscale_frag.cpp delete mode 100644 src/osgText/shaders/text_sdf_frag.cpp diff --git a/include/osgText/Glyph b/include/osgText/Glyph index 782b402dd..125cf7476 100644 --- a/include/osgText/Glyph +++ b/include/osgText/Glyph @@ -40,6 +40,7 @@ class GlyphTexture; enum ShaderTechnique { + NO_TEXT_SHADER = 0x0, GREYSCALE = 0x1, SIGNED_DISTANCE_FIELD = 0x2, ALL_FEATURES = GREYSCALE | SIGNED_DISTANCE_FIELD diff --git a/src/osgText/Glyph.cpp b/src/osgText/Glyph.cpp index fbd793cfa..229efd14c 100644 --- a/src/osgText/Glyph.cpp +++ b/src/osgText/Glyph.cpp @@ -173,7 +173,7 @@ void GlyphTexture::copyGlyphImage(Glyph* glyph, Glyph::TextureInfo* info) { _image->dirty(); - if (_shaderTechnique==GREYSCALE) + if (_shaderTechnique<=GREYSCALE) { // OSG_NOTICE<<"GlyphTexture::copyGlyphImage() greyscale copying. glyphTexture="<getTextureWidthHint()); defineList["TEXTURE_DIMENSION"] = osg::StateSet::DefinePair(ss.str(), osg::StateAttribute::ON); + } + if (_shaderTechnique>GREYSCALE) + { defineList["SIGNED_DISTNACE_FIELD"] = osg::StateSet::DefinePair("1", osg::StateAttribute::ON); } @@ -200,7 +206,7 @@ osg::StateSet* Text::createStateSet() #if defined(OSG_GL_FIXED_FUNCTION_AVAILABLE) osg::DisplaySettings::ShaderHint shaderHint = osg::DisplaySettings::instance()->getShaderHint(); - if (_shaderTechnique==GREYSCALE && shaderHint==osg::DisplaySettings::SHADER_NONE) + if (_shaderTechnique==NO_TEXT_SHADER && shaderHint==osg::DisplaySettings::SHADER_NONE) { OSG_NOTICE<<"Font::Font() Fixed function pipeline"<addShader(osgDB::readRefShaderFileWithFallback(osg::Shader::VERTEX, "shaders/text.vert", text_vert)); } - if (_shaderTechnique==GREYSCALE) { - OSG_NOTICE<<"Using shaders/text_greyscale.frag"<addShader(osgDB::readRefShaderFileWithFallback(osg::Shader::FRAGMENT, "shaders/text_greyscale.frag", text_greyscale_frag)); - } - else - { - OSG_NOTICE<<"Using shaders/text_sdf.frag"<addShader(osgDB::readRefShaderFileWithFallback(osg::Shader::FRAGMENT, "shaders/text_sdf.frag", text_sdf_frag)); + #include "shaders/text_frag.cpp" + program->addShader(osgDB::readRefShaderFileWithFallback(osg::Shader::FRAGMENT, "shaders/text.frag", text_frag)); } return stateset.release(); diff --git a/src/osgText/shaders/text_frag.cpp b/src/osgText/shaders/text_frag.cpp new file mode 100644 index 000000000..09b68444b --- /dev/null +++ b/src/osgText/shaders/text_frag.cpp @@ -0,0 +1,257 @@ +char text_frag[] = "$OSG_GLSL_VERSION\n" + "\n" + "#pragma import_defines( BACKDROP_COLOR, SHADOW, OUTLINE, SIGNED_DISTNACE_FIELD, TEXTURE_DIMENSION, GLYPH_DIMENSION)\n" + "\n" + "#ifdef GL_ES\n" + " #extension GL_OES_standard_derivatives : enable\n" + " #ifndef GL_OES_standard_derivatives\n" + " #undef SIGNED_DISTNACE_FIELD\n" + " #endif\n" + "#endif\n" + "\n" + "#if !defined(GL_ES)\n" + " #if __VERSION__>=400\n" + " #define osg_TextureQueryLOD textureQueryLod\n" + " #else\n" + " #extension GL_ARB_texture_query_lod : enable\n" + " #ifdef GL_ARB_texture_query_lod\n" + " #define osg_TextureQueryLOD textureQueryLOD\n" + " #endif\n" + " #endif\n" + "#endif\n" + "\n" + "$OSG_PRECISION_FLOAT\n" + "\n" + "#if __VERSION__>=130\n" + " #define TEXTURE texture\n" + " #define TEXTURELOD textureLod\n" + " out vec4 osg_FragColor;\n" + "#else\n" + " #define TEXTURE texture2D\n" + " #define TEXTURELOD texture2DLod\n" + " #define osg_FragColor gl_FragColor\n" + "#endif\n" + "\n" + "\n" + "#if !defined(GL_ES) && __VERSION__>=130\n" + " #define ALPHA r\n" + " #define SDF g\n" + "#else\n" + " #define ALPHA a\n" + " #define SDF r\n" + "#endif\n" + "\n" + "\n" + "uniform sampler2D glyphTexture;\n" + "\n" + "$OSG_VARYING_IN vec2 texCoord;\n" + "$OSG_VARYING_IN vec4 vertexColor;\n" + "\n" + "#ifndef TEXTURE_DIMENSION\n" + "const float TEXTURE_DIMENSION = 1024.0;\n" + "#endif\n" + "\n" + "#ifndef GLYPH_DIMENSION\n" + "const float GLYPH_DIMENSION = 32.0;\n" + "#endif\n" + "\n" + "#ifdef SIGNED_DISTNACE_FIELD\n" + "\n" + "float distanceFromEdge(vec2 tc)\n" + "{\n" + " float center_alpha = TEXTURELOD(glyphTexture, tc, 0.0).SDF;\n" + " if (center_alpha==0.0) return -1.0;\n" + "\n" + " //float distance_scale = (1.0/4.0)*1.41;\n" + " float distance_scale = (1.0/6.0)*1.41;\n" + " //float distance_scale = (1.0/8.0)*1.41;\n" + "\n" + " return (center_alpha-0.5)*distance_scale;\n" + "}\n" + "\n" + "vec4 distanceFieldColorSample(float edge_distance, float blend_width, float blend_half_width)\n" + "{\n" + "#ifdef OUTLINE\n" + " float outline_width = OUTLINE*0.5;\n" + " if (edge_distance>blend_half_width)\n" + " {\n" + " return vertexColor;\n" + " }\n" + " else if (edge_distance>-blend_half_width)\n" + " {\n" + " return mix(vertexColor, BACKDROP_COLOR, smoothstep(0.0, 1.0, (blend_half_width-edge_distance)/(blend_width)));\n" + " }\n" + " else if (edge_distance>(blend_half_width-outline_width))\n" + " {\n" + " return BACKDROP_COLOR;\n" + " }\n" + " else if (edge_distance>-(outline_width+blend_half_width))\n" + " {\n" + " return vec4(BACKDROP_COLOR.rgb, ((blend_half_width+outline_width+edge_distance)/blend_width));\n" + " }\n" + " else\n" + " {\n" + " return vec4(0.0, 0.0, 0.0, 0.0);\n" + " }\n" + "#else\n" + " if (edge_distance>blend_half_width)\n" + " {\n" + " return vertexColor;\n" + " }\n" + " else if (edge_distance>-blend_half_width)\n" + " {\n" + " return vec4(vertexColor.rgb, smoothstep(1.0, 0.0, (blend_half_width-edge_distance)/(blend_width)));\n" + " }\n" + " else\n" + " {\n" + " return vec4(0.0, 0.0, 0.0, 0.0);\n" + " }\n" + "#endif\n" + "}\n" + "\n" + "vec4 textColor(vec2 src_texCoord)\n" + "{\n" + " float sample_distance_scale = 0.75;\n" + " vec2 dx = dFdx(src_texCoord)*sample_distance_scale;\n" + " vec2 dy = dFdy(src_texCoord)*sample_distance_scale;\n" + "\n" + "\n" + " float distance_across_pixel = length(dx+dy)*(TEXTURE_DIMENSION/GLYPH_DIMENSION);\n" + "\n" + " // compute the appropriate number of samples required to avoid aliasing.\n" + " int maxNumSamplesAcrossSide = 4;\n" + "\n" + " int numSamplesX = int(TEXTURE_DIMENSION * length(dx));\n" + " int numSamplesY = int(TEXTURE_DIMENSION * length(dy));\n" + " if (numSamplesX<2) numSamplesX = 2;\n" + " if (numSamplesY<2) numSamplesY = 2;\n" + " if (numSamplesX>maxNumSamplesAcrossSide) numSamplesX = maxNumSamplesAcrossSide;\n" + " if (numSamplesY>maxNumSamplesAcrossSide) numSamplesY = maxNumSamplesAcrossSide;\n" + "\n" + "\n" + " vec2 delta_tx = dx/float(numSamplesX-1);\n" + " vec2 delta_ty = dy/float(numSamplesY-1);\n" + "\n" + " float numSamples = float(numSamplesX)*float(numSamplesY);\n" + " float scale = 1.0/numSamples;\n" + " vec4 total_color = vec4(0.0,0.0,0.0,0.0);\n" + "\n" + " float blend_width = 1.5*distance_across_pixel/numSamples;\n" + " float blend_half_width = blend_width*0.5;\n" + "\n" + " // check whether fragment is wholly within or outwith glyph body+outline\n" + " float cd = distanceFromEdge(src_texCoord); // central distance (distance from center to edge)\n" + " if (cd-blend_half_width>distance_across_pixel) return vertexColor; // pixel fully within glyph body\n" + "\n" + " #ifdef OUTLINE\n" + " float outline_width = OUTLINE*0.5;\n" + " if ((-cd-outline_width-blend_half_width)>distance_across_pixel) return vec4(0.0, 0.0, 0.0, 0.0); // pixel fully outside outline+glyph body\n" + " #else\n" + " if (-cd-blend_half_width>distance_across_pixel) return vec4(0.0, 0.0, 0.0, 0.0); // pixel fully outside glyph body\n" + " #endif\n" + "\n" + "\n" + " // use multi-sampling to provide high quality antialised fragments\n" + " vec2 origin = src_texCoord - dx*0.5 - dy*0.5;\n" + " for(;numSamplesY>0; --numSamplesY)\n" + " {\n" + " vec2 pos = origin;\n" + " int numX = numSamplesX;\n" + " for(;numX>0; --numX)\n" + " {\n" + " vec4 c = distanceFieldColorSample(distanceFromEdge(pos), blend_width, blend_half_width);\n" + " total_color = total_color + c * c.a;\n" + " pos += delta_tx;\n" + " }\n" + " origin += delta_ty;\n" + " }\n" + "\n" + " total_color.rgb /= total_color.a;\n" + " total_color.a *= scale;\n" + "\n" + " return total_color;\n" + "}\n" + "\n" + "#else\n" + "\n" + "vec4 textColor(vec2 src_texCoord)\n" + "{\n" + "\n" + "#ifdef OUTLINE\n" + "\n" + " float alpha = TEXTURE(glyphTexture, src_texCoord).ALPHA;\n" + " float delta_tc = 1.6*OUTLINE*GLYPH_DIMENSION/TEXTURE_DIMENSION;\n" + "\n" + " float outline_alpha = alpha;\n" + " vec2 origin = src_texCoord-vec2(delta_tc*0.5, delta_tc*0.5);\n" + "\n" + " float numSamples = 3.0;\n" + " delta_tc = delta_tc/(numSamples-1);\n" + "\n" + " float background_alpha = 1.0;\n" + "\n" + " for(float i=0.0; i1.0) outline_alpha = 1.0;\n" + "\n" + " if (outline_alpha==0.0) return vec4(0.0, 0.0, 0.0, 0.0); // outside glyph and outline\n" + "\n" + " vec4 color = mix(BACKDROP_COLOR, vertexColor, smoothstep(0.0, 1.0, alpha));\n" + " color.a = smoothstep(0.0, 1.0, outline_alpha);\n" + "\n" + " return color;\n" + "\n" + "#else\n" + "\n" + " float alpha = TEXTURE(glyphTexture, src_texCoord).ALPHA;\n" + " if (alpha==0.0) vec4(0.0, 0.0, 0.0, 0.0);\n" + " return vec4(vertexColor.rgb, vertexColor.a * alpha);\n" + "\n" + "#endif\n" + "}\n" + "\n" + "#endif\n" + "\n" + "\n" + "void main(void)\n" + "{\n" + " if (texCoord.x<0.0 && texCoord.y<0.0)\n" + " {\n" + " osg_FragColor = vertexColor;\n" + " return;\n" + " }\n" + "\n" + "#ifdef SHADOW\n" + " float scale = -1.0*GLYPH_DIMENSION/TEXTURE_DIMENSION;\n" + " vec2 delta_tc = SHADOW*scale;\n" + " vec4 shadow_color = textColor(texCoord+delta_tc);\n" + " shadow_color.rgb = BACKDROP_COLOR.rgb;\n" + "\n" + " vec4 glyph_color = textColor(texCoord);\n" + " vec4 color = mix(shadow_color, glyph_color, glyph_color.a);\n" + "#else\n" + " vec4 color = textColor(texCoord);\n" + "#endif\n" + "\n" + " if (color.a==0.0) discard;\n" + "\n" + " osg_FragColor = color;\n" + "}\n" + "\n"; diff --git a/src/osgText/shaders/text_greyscale_frag.cpp b/src/osgText/shaders/text_greyscale_frag.cpp deleted file mode 100644 index 6d561fbce..000000000 --- a/src/osgText/shaders/text_greyscale_frag.cpp +++ /dev/null @@ -1,35 +0,0 @@ -char text_greyscale_frag[] = "$OSG_GLSL_VERSION\n" - "$OSG_PRECISION_FLOAT\n" - "\n" - "#pragma import_defines( BACKDROP_COLOR, OUTLINE, ALPHA )\n" - "\n" - "#if __VERSION__>=130\n" - " #define TEXTURE texture\n" - " out vec4 osg_FragColor;\n" - "#else\n" - " #define TEXTURE texture2D\n" - " #define osg_FragColor gl_FragColor\n" - "#endif\n" - "\n" - "uniform sampler2D glyphTexture;\n" - "\n" - "$OSG_VARYING_IN vec2 texCoord;\n" - "$OSG_VARYING_IN vec4 vertexColor;\n" - "\n" - "#ifndef ALPHA\n" - " #if !defined(GL_ES) && __VERSION__>=130\n" - " #define ALPHA r\n" - " #else\n" - " #define ALPHA a\n" - " #endif\n" - "#endif\n" - "\n" - "void main(void)\n" - "{\n" - " float alpha = TEXTURE(glyphTexture, texCoord).ALPHA;\n" - "\n" - " if (alpha==0.0) discard;\n" - "\n" - " osg_FragColor = vec4(vertexColor.rgb, alpha);\n" - "}\n" - "\n"; diff --git a/src/osgText/shaders/text_sdf_frag.cpp b/src/osgText/shaders/text_sdf_frag.cpp deleted file mode 100644 index 1864fc3c3..000000000 --- a/src/osgText/shaders/text_sdf_frag.cpp +++ /dev/null @@ -1,257 +0,0 @@ -char text_sdf_frag[] = "$OSG_GLSL_VERSION\n" - "\n" - "#pragma import_defines( BACKDROP_COLOR, SHADOW, OUTLINE, SIGNED_DISTNACE_FIELD, TEXTURE_DIMENSION, GLYPH_DIMENSION)\n" - "\n" - "#ifdef GL_ES\n" - " #extension GL_OES_standard_derivatives : enable\n" - " #ifndef GL_OES_standard_derivatives\n" - " #undef SIGNED_DISTNACE_FIELD\n" - " #endif\n" - "#endif\n" - "\n" - "#if !defined(GL_ES)\n" - " #if __VERSION__>=400\n" - " #define osg_TextureQueryLOD textureQueryLod\n" - " #else\n" - " #extension GL_ARB_texture_query_lod : enable\n" - " #ifdef GL_ARB_texture_query_lod\n" - " #define osg_TextureQueryLOD textureQueryLOD\n" - " #endif\n" - " #endif\n" - "#endif\n" - "\n" - "$OSG_PRECISION_FLOAT\n" - "\n" - "#if __VERSION__>=130\n" - " #define TEXTURE texture\n" - " #define TEXTURELOD textureLod\n" - " out vec4 osg_FragColor;\n" - "#else\n" - " #define TEXTURE texture2D\n" - " #define TEXTURELOD texture2DLod\n" - " #define osg_FragColor gl_FragColor\n" - "#endif\n" - "\n" - "\n" - "#if !defined(GL_ES) && __VERSION__>=130\n" - " #define ALPHA r\n" - " #define SDF g\n" - "#else\n" - " #define ALPHA a\n" - " #define SDF r\n" - "#endif\n" - "\n" - "\n" - "uniform sampler2D glyphTexture;\n" - "\n" - "$OSG_VARYING_IN vec2 texCoord;\n" - "$OSG_VARYING_IN vec4 vertexColor;\n" - "\n" - "#ifndef TEXTURE_DIMENSION\n" - "const float TEXTURE_DIMENSION = 1024.0;\n" - "#endif\n" - "\n" - "#ifndef GLYPH_DIMENSION\n" - "const float GLYPH_DIMENSION = 32.0;\n" - "#endif\n" - "\n" - "#ifdef SIGNED_DISTNACE_FIELD\n" - "\n" - "float distanceFromEdge(vec2 tc)\n" - "{\n" - " float center_alpha = TEXTURELOD(glyphTexture, tc, 0.0).SDF;\n" - " if (center_alpha==0.0) return -1.0;\n" - "\n" - " //float distance_scale = (1.0/4.0)*1.41;\n" - " float distance_scale = (1.0/6.0)*1.41;\n" - " //float distance_scale = (1.0/8.0)*1.41;\n" - "\n" - " return (center_alpha-0.5)*distance_scale;\n" - "}\n" - "\n" - "vec4 distanceFieldColorSample(float edge_distance, float blend_width, float blend_half_width)\n" - "{\n" - "#ifdef OUTLINE\n" - " float outline_width = OUTLINE*0.5;\n" - " if (edge_distance>blend_half_width)\n" - " {\n" - " return vertexColor;\n" - " }\n" - " else if (edge_distance>-blend_half_width)\n" - " {\n" - " return mix(vertexColor, BACKDROP_COLOR, smoothstep(0.0, 1.0, (blend_half_width-edge_distance)/(blend_width)));\n" - " }\n" - " else if (edge_distance>(blend_half_width-outline_width))\n" - " {\n" - " return BACKDROP_COLOR;\n" - " }\n" - " else if (edge_distance>-(outline_width+blend_half_width))\n" - " {\n" - " return vec4(BACKDROP_COLOR.rgb, ((blend_half_width+outline_width+edge_distance)/blend_width));\n" - " }\n" - " else\n" - " {\n" - " return vec4(0.0, 0.0, 0.0, 0.0);\n" - " }\n" - "#else\n" - " if (edge_distance>blend_half_width)\n" - " {\n" - " return vertexColor;\n" - " }\n" - " else if (edge_distance>-blend_half_width)\n" - " {\n" - " return vec4(vertexColor.rgb, smoothstep(1.0, 0.0, (blend_half_width-edge_distance)/(blend_width)));\n" - " }\n" - " else\n" - " {\n" - " return vec4(0.0, 0.0, 0.0, 0.0);\n" - " }\n" - "#endif\n" - "}\n" - "\n" - "vec4 textColor(vec2 src_texCoord)\n" - "{\n" - " float sample_distance_scale = 0.75;\n" - " vec2 dx = dFdx(src_texCoord)*sample_distance_scale;\n" - " vec2 dy = dFdy(src_texCoord)*sample_distance_scale;\n" - "\n" - "\n" - " float distance_across_pixel = length(dx+dy)*(TEXTURE_DIMENSION/GLYPH_DIMENSION);\n" - "\n" - " // compute the appropriate number of samples required to avoid aliasing.\n" - " int maxNumSamplesAcrossSide = 4;\n" - "\n" - " int numSamplesX = int(TEXTURE_DIMENSION * length(dx));\n" - " int numSamplesY = int(TEXTURE_DIMENSION * length(dy));\n" - " if (numSamplesX<2) numSamplesX = 2;\n" - " if (numSamplesY<2) numSamplesY = 2;\n" - " if (numSamplesX>maxNumSamplesAcrossSide) numSamplesX = maxNumSamplesAcrossSide;\n" - " if (numSamplesY>maxNumSamplesAcrossSide) numSamplesY = maxNumSamplesAcrossSide;\n" - "\n" - "\n" - " vec2 delta_tx = dx/float(numSamplesX-1);\n" - " vec2 delta_ty = dy/float(numSamplesY-1);\n" - "\n" - " float numSamples = float(numSamplesX)*float(numSamplesY);\n" - " float scale = 1.0/numSamples;\n" - " vec4 total_color = vec4(0.0,0.0,0.0,0.0);\n" - "\n" - " float blend_width = 1.5*distance_across_pixel/numSamples;\n" - " float blend_half_width = blend_width*0.5;\n" - "\n" - " // check whether fragment is wholly within or outwith glyph body+outline\n" - " float cd = distanceFromEdge(src_texCoord); // central distance (distance from center to edge)\n" - " if (cd-blend_half_width>distance_across_pixel) return vertexColor; // pixel fully within glyph body\n" - "\n" - " #ifdef OUTLINE\n" - " float outline_width = OUTLINE*0.5;\n" - " if ((-cd-outline_width-blend_half_width)>distance_across_pixel) return vec4(0.0, 0.0, 0.0, 0.0); // pixel fully outside outline+glyph body\n" - " #else\n" - " if (-cd-blend_half_width>distance_across_pixel) return vec4(0.0, 0.0, 0.0, 0.0); // pixel fully outside glyph body\n" - " #endif\n" - "\n" - "\n" - " // use multi-sampling to provide high quality antialised fragments\n" - " vec2 origin = src_texCoord - dx*0.5 - dy*0.5;\n" - " for(;numSamplesY>0; --numSamplesY)\n" - " {\n" - " vec2 pos = origin;\n" - " int numX = numSamplesX;\n" - " for(;numX>0; --numX)\n" - " {\n" - " vec4 c = distanceFieldColorSample(distanceFromEdge(pos), blend_width, blend_half_width);\n" - " total_color = total_color + c * c.a;\n" - " pos += delta_tx;\n" - " }\n" - " origin += delta_ty;\n" - " }\n" - "\n" - " total_color.rgb /= total_color.a;\n" - " total_color.a *= scale;\n" - "\n" - " return total_color;\n" - "}\n" - "\n" - "#else\n" - "\n" - "vec4 textColor(vec2 src_texCoord)\n" - "{\n" - "\n" - "#ifdef OUTLINE\n" - "\n" - " float alpha = TEXTURE(glyphTexture, src_texCoord).ALPHA;\n" - " float delta_tc = 1.6*OUTLINE*GLYPH_DIMENSION/TEXTURE_DIMENSION;\n" - "\n" - " float outline_alpha = alpha;\n" - " vec2 origin = src_texCoord-vec2(delta_tc*0.5, delta_tc*0.5);\n" - "\n" - " float numSamples = 3.0;\n" - " delta_tc = delta_tc/(numSamples-1);\n" - "\n" - " float background_alpha = 1.0;\n" - "\n" - " for(float i=0.0; i1.0) outline_alpha = 1.0;\n" - "\n" - " if (outline_alpha==0.0) return vec4(0.0, 0.0, 0.0, 0.0); // outside glyph and outline\n" - "\n" - " vec4 color = mix(BACKDROP_COLOR, vertexColor, smoothstep(0.0, 1.0, alpha));\n" - " color.a = smoothstep(0.0, 1.0, outline_alpha);\n" - "\n" - " return color;\n" - "\n" - "#else\n" - "\n" - " float alpha = TEXTURE(glyphTexture, src_texCoord).ALPHA;\n" - " if (alpha==0.0) vec4(0.0, 0.0, 0.0, 0.0);\n" - " return vec4(vertexColor.rgb, vertexColor.a * alpha);\n" - "\n" - "#endif\n" - "}\n" - "\n" - "#endif\n" - "\n" - "\n" - "void main(void)\n" - "{\n" - " if (texCoord.x<0.0 && texCoord.y<0.0)\n" - " {\n" - " osg_FragColor = vertexColor;\n" - " return;\n" - " }\n" - "\n" - "#ifdef SHADOW\n" - " float scale = -1.0*GLYPH_DIMENSION/TEXTURE_DIMENSION;\n" - " vec2 delta_tc = SHADOW*scale;\n" - " vec4 shadow_color = textColor(texCoord+delta_tc);\n" - " shadow_color.rgb = BACKDROP_COLOR.rgb;\n" - "\n" - " vec4 glyph_color = textColor(texCoord);\n" - " vec4 color = mix(shadow_color, glyph_color, glyph_color.a);\n" - "#else\n" - " vec4 color = textColor(texCoord);\n" - "#endif\n" - "\n" - " if (color.a==0.0) discard;\n" - "\n" - " osg_FragColor = color;\n" - "}\n" - "\n"; From 1cd0a5fe03c1cf07a5a5a5a45464ba2c2ebb03cd Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Tue, 24 Oct 2017 11:36:00 +0100 Subject: [PATCH 163/327] Fixed Glyph::TextureInfo assignment bug --- include/osgText/Glyph | 11 ++--------- src/osgText/Font.cpp | 4 ++-- src/osgText/Glyph.cpp | 20 +++++++++++++++++++- src/osgText/Text.cpp | 1 - 4 files changed, 23 insertions(+), 13 deletions(-) diff --git a/include/osgText/Glyph b/include/osgText/Glyph index 125cf7476..2d1eafa05 100644 --- a/include/osgText/Glyph +++ b/include/osgText/Glyph @@ -100,16 +100,9 @@ public: float texelMargin; }; - void setTextureInfo(ShaderTechnique technique, TextureInfo* info) - { - if (technique>=_textureInfoList.size()) _textureInfoList.resize(technique+1); - _textureInfoList[technique] = info; - } + void setTextureInfo(ShaderTechnique technique, TextureInfo* info); - const TextureInfo* getTextureInfo(ShaderTechnique technique) const - { - return (technique<_textureInfoList.size()) ? _textureInfoList[technique].get() : 0; - } + const TextureInfo* getTextureInfo(ShaderTechnique technique) const; TextureInfo* getOrCreateTextureInfo(ShaderTechnique technique); diff --git a/src/osgText/Font.cpp b/src/osgText/Font.cpp index 7d6c61c1f..599dd6f6e 100644 --- a/src/osgText/Font.cpp +++ b/src/osgText/Font.cpp @@ -456,12 +456,12 @@ void Font::assignGlyphToGlyphTexture(Glyph* glyph, ShaderTechnique shaderTechniq itr!=_glyphTextureList.end() && !glyphTexture; ++itr) { - if ((*itr)->getSpaceForGlyph(glyph,posX,posY)) glyphTexture = itr->get(); + if ((*itr)->getShaderTechnique()==shaderTechnique && (*itr)->getSpaceForGlyph(glyph,posX,posY)) glyphTexture = itr->get(); } if (glyphTexture) { - //cout << " found space for texture "< stateset = new osg::StateSet; @@ -201,14 +201,14 @@ osg::StateSet* Text::createStateSet() stateset->setMode(GL_BLEND, osg::StateAttribute::ON); - OSG_NOTICE<<"Text::createStateSet() ShaderTechnique="<<_shaderTechnique<setTextureMode(0, GL_TEXTURE_2D, osg::StateAttribute::ON); return stateset.release(); @@ -222,14 +222,14 @@ osg::StateSet* Text::createStateSet() stateset->setAttributeAndModes(program.get()); { - OSG_NOTICE<<"Using shaders/text.vert"<addShader(osgDB::readRefShaderFileWithFallback(osg::Shader::VERTEX, "shaders/text.vert", text_vert)); } { - OSG_NOTICE<<"Using shaders/text.frag"<addShader(osgDB::readRefShaderFileWithFallback(osg::Shader::FRAGMENT, "shaders/text.frag", text_frag)); From 1ecae6d33ae186d67eaee2cfa74dde9842d38cc1 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Tue, 24 Oct 2017 12:34:48 +0100 Subject: [PATCH 165/327] Improved the Text::_shaderTechnique default setting using OSG_TEXT_SHADER_TECHNIQUE env var, options are ALL_FEATURES, GREYSCALE, SIGNED_DISTANCE_FIELD, SDF, NO_TEXT_SHADER, NONE. --- src/osgText/Text.cpp | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/src/osgText/Text.cpp b/src/osgText/Text.cpp index 12931ffaf..0bd1efade 100644 --- a/src/osgText/Text.cpp +++ b/src/osgText/Text.cpp @@ -48,19 +48,16 @@ Text::Text(): _supportsVertexBufferObjects = true; char* ptr = 0; - if ((ptr = getenv("OSG_SDF_TEXT")) != 0) + if ((ptr = getenv("OSG_TEXT_SHADER_TECHNIQUE")) != 0) { - _shaderTechnique = ALL_FEATURES; - } - else if ((ptr = getenv("OSG_GREYSCALE_TEXT")) != 0) - { - _shaderTechnique = GREYSCALE; - } - else if ((ptr = getenv("OSG_NO_TEXT_SHADER")) != 0) - { - _shaderTechnique = NO_TEXT_SHADER; + if (strcmp(ptr,"ALL_FEATURES")==0) _shaderTechnique = ALL_FEATURES; + else if (strcmp(ptr,"GREYSCALE")==0) _shaderTechnique = GREYSCALE; + else if (strcmp(ptr,"SIGNED_DISTANCE_FIELD")==0 || strcmp(ptr,"SDF")==0) _shaderTechnique = SIGNED_DISTANCE_FIELD; + else if (strcmp(ptr,"NO_TEXT_SHADER")==0 || strcmp(ptr,"NONE")==0) _shaderTechnique = NO_TEXT_SHADER; } + OSG_NOTICE<<"Text::Text() "<<_shaderTechnique< Date: Tue, 24 Oct 2017 14:46:13 +0100 Subject: [PATCH 166/327] Added DisplaySettings:s/getgTextShaderTechnique() and OSG_TEXT_SHADER_TECHNIQUE env var support to DisplaySettings. Added using of DisplaySettings:getgTextShaderTechnique() to Text default constructor. Added better debug output control in Text.cpp --- include/osg/DisplaySettings | 5 +++++ src/osg/DisplaySettings.cpp | 7 +++++++ src/osgText/Text.cpp | 40 +++++++++++++++++++++++-------------- 3 files changed, 37 insertions(+), 15 deletions(-) diff --git a/include/osg/DisplaySettings b/include/osg/DisplaySettings index 393aa7415..0609cf0c6 100644 --- a/include/osg/DisplaySettings +++ b/include/osg/DisplaySettings @@ -325,6 +325,10 @@ class OSG_EXPORT DisplaySettings : public osg::Referenced void setShaderHint(ShaderHint hint, bool setShaderValues=true); ShaderHint getShaderHint() const { return _shaderHint; } + /** Set the TextShaderTechnique that is used in the Text default constructor to choose which osgText::ShaderTechnique to use.*/ + void setTextShaderTechnique(const std::string& str) { _textShaderTechnique = str; } + const std::string& getTextShaderTechnique() const { return _textShaderTechnique; } + void setKeystoneHint(bool enabled) { _keystoneHint = enabled; } bool getKeystoneHint() const { return _keystoneHint; } @@ -423,6 +427,7 @@ class OSG_EXPORT DisplaySettings : public osg::Referenced VertexBufferHint _vertexBufferHint; ShaderHint _shaderHint; + std::string _textShaderTechnique; bool _keystoneHint; FileNames _keystoneFileNames; diff --git a/src/osg/DisplaySettings.cpp b/src/osg/DisplaySettings.cpp index 8346d11ed..5e7259956 100644 --- a/src/osg/DisplaySettings.cpp +++ b/src/osg/DisplaySettings.cpp @@ -385,6 +385,9 @@ static ApplicationUsageProxy DisplaySetting_e31(ApplicationUsage::ENVIRONMENTAL_ static ApplicationUsageProxy DisplaySetting_e32(ApplicationUsage::ENVIRONMENTAL_VARIABLE, "OSG_VERTEX_BUFFER_HINT ", "Set the hint to what backend osg::Geometry implementation to use. NO_PREFERENCE | VERTEX_BUFFER_OBJECT | VERTEX_ARRAY_OBJECT"); +static ApplicationUsageProxy DisplaySetting_e33(ApplicationUsage::ENVIRONMENTAL_VARIABLE, + "OSG_TEXT_SHADER_TECHNIQUE ", + "Set the defafult osgText::ShaderTechnique. ALL_FEATURES | ALL | GREYSCALE | SIGNED_DISTANCE_FIELD | SDF | NO_TEXT_SHADER | NONE"); void DisplaySettings::readEnvironmentalVariables() { @@ -740,6 +743,10 @@ void DisplaySettings::readEnvironmentalVariables() } } + if ((ptr = getenv("OSG_TEXT_SHADER_TECHNIQUE")) != 0) + { + setTextShaderTechnique(ptr); + } if( (ptr = getenv("OSG_KEYSTONE")) != 0) { diff --git a/src/osgText/Text.cpp b/src/osgText/Text.cpp index 0bd1efade..cfc7cf969 100644 --- a/src/osgText/Text.cpp +++ b/src/osgText/Text.cpp @@ -28,6 +28,8 @@ #include #include +#define DEBUG_MESSAGE_LEVEL osg::INFO +#define DEBUG_MESSAGE osg::notify(DEBUG_MESSAGE_LEVEL) using namespace osg; using namespace osgText; @@ -47,17 +49,15 @@ Text::Text(): { _supportsVertexBufferObjects = true; - char* ptr = 0; - if ((ptr = getenv("OSG_TEXT_SHADER_TECHNIQUE")) != 0) + const std::string& str = osg::DisplaySettings::instance()->getTextShaderTechnique(); + if (!str.empty()) { - if (strcmp(ptr,"ALL_FEATURES")==0) _shaderTechnique = ALL_FEATURES; - else if (strcmp(ptr,"GREYSCALE")==0) _shaderTechnique = GREYSCALE; - else if (strcmp(ptr,"SIGNED_DISTANCE_FIELD")==0 || strcmp(ptr,"SDF")==0) _shaderTechnique = SIGNED_DISTANCE_FIELD; - else if (strcmp(ptr,"NO_TEXT_SHADER")==0 || strcmp(ptr,"NONE")==0) _shaderTechnique = NO_TEXT_SHADER; + if (str=="ALL_FEATURES" || str=="ALL") _shaderTechnique = ALL_FEATURES; + else if (str=="GREYSCALE") _shaderTechnique = GREYSCALE; + else if (str=="SIGNED_DISTANCE_FIELD" || str=="SDF") _shaderTechnique = SIGNED_DISTANCE_FIELD; + else if (str=="NO_TEXT_SHADER" || str=="NONE") _shaderTechnique = NO_TEXT_SHADER; } - OSG_NOTICE<<"Text::Text() "<<_shaderTechnique< stateset = new osg::StateSet; @@ -198,14 +211,11 @@ osg::StateSet* Text::createStateSet() stateset->setMode(GL_BLEND, osg::StateAttribute::ON); - OSG_INFO<<"Text::createStateSet() ShaderTechnique="<<_shaderTechnique<getShaderHint(); if (_shaderTechnique==NO_TEXT_SHADER && shaderHint==osg::DisplaySettings::SHADER_NONE) { - OSG_INFO<<"Font::Font() Fixed function pipeline"<setTextureMode(0, GL_TEXTURE_2D, osg::StateAttribute::ON); return stateset.release(); @@ -219,14 +229,14 @@ osg::StateSet* Text::createStateSet() stateset->setAttributeAndModes(program.get()); { - OSG_INFO<<"Using shaders/text.vert"<addShader(osgDB::readRefShaderFileWithFallback(osg::Shader::VERTEX, "shaders/text.vert", text_vert)); } { - OSG_INFO<<"Using shaders/text.frag"<addShader(osgDB::readRefShaderFileWithFallback(osg::Shader::FRAGMENT, "shaders/text.frag", text_frag)); From 8f658fbc3212dd1f03c99e5d92374e2676f6f1f9 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Tue, 24 Oct 2017 15:14:23 +0100 Subject: [PATCH 167/327] Updated from OpenSceneGraph-Data/shaders/text.frag to address GLSL int to float conversion warning --- src/osgText/shaders/text_frag.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/osgText/shaders/text_frag.cpp b/src/osgText/shaders/text_frag.cpp index 09b68444b..03661dd92 100644 --- a/src/osgText/shaders/text_frag.cpp +++ b/src/osgText/shaders/text_frag.cpp @@ -186,7 +186,7 @@ char text_frag[] = "$OSG_GLSL_VERSION\n" " vec2 origin = src_texCoord-vec2(delta_tc*0.5, delta_tc*0.5);\n" "\n" " float numSamples = 3.0;\n" - " delta_tc = delta_tc/(numSamples-1);\n" + " delta_tc = delta_tc/(numSamples-1.0);\n" "\n" " float background_alpha = 1.0;\n" "\n" From c8bd6fd1006b16c4ea64a8d1e3912ac2d01532d7 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Tue, 24 Oct 2017 16:04:14 +0100 Subject: [PATCH 168/327] Added stats handler --- examples/osglauncher/osglauncher.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/examples/osglauncher/osglauncher.cpp b/examples/osglauncher/osglauncher.cpp index 00c98b42c..ce7e4c553 100644 --- a/examples/osglauncher/osglauncher.cpp +++ b/examples/osglauncher/osglauncher.cpp @@ -44,6 +44,7 @@ #include #include +#include #include #include @@ -424,6 +425,9 @@ int main( int argc, char **argv ) // add the handler for doing the picking viewer.addEventHandler(new PickHandler(&viewer,updateText.get())); + // add the stats handler + viewer.addEventHandler(new osgViewer::StatsHandler); + osg::Group* root = new osg::Group(); root->addChild( setupGraph() ); From 248805fedd53dc3ed74e88711f72b8a7b62fc687 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 25 Oct 2017 16:13:26 +0100 Subject: [PATCH 169/327] Fixed pre compilation osg::Program state leaking into the main scene graph rendering --- include/osgUtil/GLObjectsVisitor | 3 +++ src/osgUtil/GLObjectsVisitor.cpp | 17 +++++++++++++++++ src/osgViewer/Renderer.cpp | 3 +-- 3 files changed, 21 insertions(+), 2 deletions(-) diff --git a/include/osgUtil/GLObjectsVisitor b/include/osgUtil/GLObjectsVisitor index b9a130f3e..c52d6cce6 100644 --- a/include/osgUtil/GLObjectsVisitor +++ b/include/osgUtil/GLObjectsVisitor @@ -97,6 +97,9 @@ class OSGUTIL_EXPORT GLObjectsVisitor : public osg::NodeVisitor void apply(osg::Drawable& drawable); void apply(osg::StateSet& stateset); + /** Do a compile traversal and then reset any state,*/ + void compile(osg::Node& node); + protected: typedef std::set DrawableAppliedSet; diff --git a/src/osgUtil/GLObjectsVisitor.cpp b/src/osgUtil/GLObjectsVisitor.cpp index b194b7990..25aa8c896 100644 --- a/src/osgUtil/GLObjectsVisitor.cpp +++ b/src/osgUtil/GLObjectsVisitor.cpp @@ -153,6 +153,23 @@ void GLObjectsVisitor::apply(osg::StateSet& stateset) } } +void GLObjectsVisitor::compile(osg::Node& node) +{ + if (_renderInfo.getState()) + { + node.accept(*this); + + if (_lastCompiledProgram.valid()) + { + osg::State* state = _renderInfo.getState(); + osg::GLExtensions* extensions = state->get(); + extensions->glUseProgram(0); + _renderInfo.getState()->setLastAppliedProgramObject(0); + } + } +} + + ///////////////////////////////////////////////////////////////// // // GLObjectsOperation diff --git a/src/osgViewer/Renderer.cpp b/src/osgViewer/Renderer.cpp index 71f93ccc5..06620af32 100644 --- a/src/osgViewer/Renderer.cpp +++ b/src/osgViewer/Renderer.cpp @@ -571,7 +571,6 @@ void Renderer::compile() { DEBUG_MESSAGE<<"Renderer::compile()"<getState()); - sceneView->getSceneData()->accept(glov); + glov.compile(*(sceneView->getSceneData())); } sceneView->getState()->checkGLErrors("After Renderer::compile"); From fa58d0164463dbec8a4fe69fbaf2c0d95b56a747 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 25 Oct 2017 16:29:25 +0100 Subject: [PATCH 170/327] Added optimization for text where the colour alpha value is 0.0, returning early to aovid any GL calls. --- src/osgText/Text.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/osgText/Text.cpp b/src/osgText/Text.cpp index cfc7cf969..94ac0e923 100644 --- a/src/osgText/Text.cpp +++ b/src/osgText/Text.cpp @@ -1115,6 +1115,8 @@ void Text::drawImplementation(osg::RenderInfo& renderInfo) const void Text::drawImplementationSinglePass(osg::State& state, const osg::Vec4& colorMultiplier) const { + if (colorMultiplier.a()==0.0f || _color.a()==0.0f) return; + osg::VertexArrayState* vas = state.getCurrentVertexArrayState(); bool usingVertexBufferObjects = state.useVertexBufferObject(_supportsVertexBufferObjects && _useVertexBufferObjects); bool usingVertexArrayObjects = usingVertexBufferObjects && state.useVertexArrayObject(_useVertexArrayObject); From 671ea7ae7453262f6e97943dbf504edc80a24df1 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Thu, 26 Oct 2017 12:02:56 +0100 Subject: [PATCH 171/327] Added command line parsing to aid with testing of osgText by allowing osgText::FadeText to be created with various options --- examples/osgfadetext/osgfadetext.cpp | 70 +++++++++++++++++++++++++++- 1 file changed, 68 insertions(+), 2 deletions(-) diff --git a/examples/osgfadetext/osgfadetext.cpp b/examples/osgfadetext/osgfadetext.cpp index 37b0eafe2..308b482b6 100644 --- a/examples/osgfadetext/osgfadetext.cpp +++ b/examples/osgfadetext/osgfadetext.cpp @@ -121,10 +121,70 @@ osg::Node* createFadeText(osg::EllipsoidModel* ellipsoid) } -int main(int, char**) +class TextSettings : public osg::NodeVisitor { +public: + TextSettings(osg::ArgumentParser& arguments): + osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN), + _backdropTypeSet(false), + _backdropType(osgText::Text::NONE), + _shaderTechniqueSet(false), + _shaderTechnique(osgText::GREYSCALE) + { + if (arguments.read("--outline")) + { + _backdropTypeSet = true; + _backdropType = osgText::Text::OUTLINE; + } + if (arguments.read("--sdf")) + { + _shaderTechniqueSet = true; + _shaderTechnique = osgText::SIGNED_DISTANCE_FIELD; + } + if (arguments.read("--all")) + { + _shaderTechniqueSet = true; + _shaderTechnique = osgText::ALL_FEATURES; + } + if (arguments.read("--greyscale")) + { + _shaderTechniqueSet = true; + _shaderTechnique = osgText::GREYSCALE; + } + if (arguments.read("--no-shader")) + { + _shaderTechniqueSet = true; + _shaderTechnique = osgText::NO_TEXT_SHADER; + } + } + + void apply(osg::Drawable& drawable) + { + osgText::Text* text = dynamic_cast(&drawable); + if (text) + { + if (_backdropTypeSet) + { + text->setBackdropType(_backdropType); + text->setBackdropOffset(0.1f); + text->setBackdropColor(osg::Vec4(1.0f, 0.0f, 0.0f, 1.0f)); + } + if (_shaderTechniqueSet) text->setShaderTechnique(_shaderTechnique); + } + } + + bool _backdropTypeSet; + osgText::Text::BackdropType _backdropType; + bool _shaderTechniqueSet; + osgText::ShaderTechnique _shaderTechnique; +}; + +int main(int argc, char** argv) +{ + osg::ArgumentParser arguments(&argc, argv); + // construct the viewer. - osgViewer::Viewer viewer; + osgViewer::Viewer viewer(arguments); viewer.getCamera()->setComputeNearFarMode(osg::CullSettings::COMPUTE_NEAR_FAR_USING_PRIMITIVES); viewer.getCamera()->setNearFarRatio(0.00001f); @@ -144,6 +204,12 @@ int main(int, char**) csn->addChild(createFadeText(csn->getEllipsoidModel())); } + if (arguments.argc()>1) + { + TextSettings textSettings(arguments); + root->accept(textSettings); + } + viewer.setCameraManipulator(new osgGA::TerrainManipulator); return viewer.run(); From 5918735ebca45b71554c7446d31fa08d7b073ff1 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Thu, 26 Oct 2017 12:03:56 +0100 Subject: [PATCH 172/327] Added update of glyph representation to ensure all the glyphs are assigned to the required GlyphTextures --- src/osgText/Text.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/osgText/Text.cpp b/src/osgText/Text.cpp index 94ac0e923..46c857639 100644 --- a/src/osgText/Text.cpp +++ b/src/osgText/Text.cpp @@ -90,6 +90,8 @@ void Text::setShaderTechnique(ShaderTechnique technique) _shaderTechnique = technique; assignStateSet(); + + computeGlyphRepresentation(); } osg::StateSet* Text::createStateSet() From 1e896777d1e52fbaf0e0cb6232c27d849cc63fac Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Thu, 26 Oct 2017 12:08:00 +0100 Subject: [PATCH 173/327] Updated from OpenSceneGraph-Data/shader/text.frag to add fixes to handling of vertexColor's alpha values --- src/osgText/shaders/text_frag.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/osgText/shaders/text_frag.cpp b/src/osgText/shaders/text_frag.cpp index 03661dd92..02c253100 100644 --- a/src/osgText/shaders/text_frag.cpp +++ b/src/osgText/shaders/text_frag.cpp @@ -79,15 +79,15 @@ char text_frag[] = "$OSG_GLSL_VERSION\n" " }\n" " else if (edge_distance>-blend_half_width)\n" " {\n" - " return mix(vertexColor, BACKDROP_COLOR, smoothstep(0.0, 1.0, (blend_half_width-edge_distance)/(blend_width)));\n" + " return mix(vertexColor, vec4(BACKDROP_COLOR.rgb, BACKDROP_COLOR.a*vertexColor.a), smoothstep(0.0, 1.0, (blend_half_width-edge_distance)/(blend_width)));\n" " }\n" " else if (edge_distance>(blend_half_width-outline_width))\n" " {\n" - " return BACKDROP_COLOR;\n" + " return vec4(BACKDROP_COLOR.rgb, BACKDROP_COLOR.a*vertexColor.a);\n" " }\n" " else if (edge_distance>-(outline_width+blend_half_width))\n" " {\n" - " return vec4(BACKDROP_COLOR.rgb, ((blend_half_width+outline_width+edge_distance)/blend_width));\n" + " return vec4(BACKDROP_COLOR.rgb, vertexColor.a * ((blend_half_width+outline_width+edge_distance)/blend_width));\n" " }\n" " else\n" " {\n" @@ -100,7 +100,7 @@ char text_frag[] = "$OSG_GLSL_VERSION\n" " }\n" " else if (edge_distance>-blend_half_width)\n" " {\n" - " return vec4(vertexColor.rgb, smoothstep(1.0, 0.0, (blend_half_width-edge_distance)/(blend_width)));\n" + " return vec4(vertexColor.rgb, vertexColor.a * smoothstep(1.0, 0.0, (blend_half_width-edge_distance)/(blend_width)));\n" " }\n" " else\n" " {\n" @@ -214,7 +214,7 @@ char text_frag[] = "$OSG_GLSL_VERSION\n" " if (outline_alpha==0.0) return vec4(0.0, 0.0, 0.0, 0.0); // outside glyph and outline\n" "\n" " vec4 color = mix(BACKDROP_COLOR, vertexColor, smoothstep(0.0, 1.0, alpha));\n" - " color.a = smoothstep(0.0, 1.0, outline_alpha);\n" + " color.a = vertexColor.a * smoothstep(0.0, 1.0, outline_alpha);\n" "\n" " return color;\n" "\n" From 93ef9d1dc914c005ff979cf95762e8bd899cd471 Mon Sep 17 00:00:00 2001 From: Laurens Voerman Date: Fri, 27 Oct 2017 09:41:28 +0200 Subject: [PATCH 174/327] use osg::maximum, not std::max --- src/osgText/Glyph.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/osgText/Glyph.cpp b/src/osgText/Glyph.cpp index 09c166cf6..17776780c 100644 --- a/src/osgText/Glyph.cpp +++ b/src/osgText/Glyph.cpp @@ -88,7 +88,7 @@ int GlyphTexture::getTexelMargin(const Glyph* glyph) int height = glyph->t(); int effect_margin = getEffectMargin(glyph); - int max_dimension = std::max(width, height) + 2 * effect_margin; + int max_dimension = osg::maximum(width, height) + 2 * effect_margin; int margin = osg::maximum(max_dimension/4, 2) + effect_margin; return margin; From 5d9dcfccbf27bc02976b036b78ad5c6b0afae0f0 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Fri, 27 Oct 2017 13:17:47 +0100 Subject: [PATCH 175/327] From Farshid Lashkari, "fix for the Collada loader to check for some NULL attributes." --- src/osgPlugins/dae/daeRMaterials.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/osgPlugins/dae/daeRMaterials.cpp b/src/osgPlugins/dae/daeRMaterials.cpp index 158ca35ef..2aae4e366 100644 --- a/src/osgPlugins/dae/daeRMaterials.cpp +++ b/src/osgPlugins/dae/daeRMaterials.cpp @@ -1017,6 +1017,11 @@ osg::Texture2D* daeReader::processTexture( domFx_surface_common *surface = NULL; domImage *dImg = NULL; + if(tex->getTexture() == NULL) + { + return NULL; + } + std::string target = std::string("./") + std::string(tex->getTexture()); OSG_INFO<<"processTexture("<getTexcoord(); + if(tex->getTexcoord() != NULL) + { + _texCoordSetMap[TextureToCoordSetMap::key_type(ss, tuu)] = tex->getTexcoord(); + } return t2D; } From 1f913ec13051152981b9fed9f7b2989afdbe654c Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Fri, 27 Oct 2017 13:19:52 +0100 Subject: [PATCH 176/327] Fixed warning --- src/osgAnimation/RigTransformHardware.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/osgAnimation/RigTransformHardware.cpp b/src/osgAnimation/RigTransformHardware.cpp index 651e48cf7..dcd7fe6a3 100644 --- a/src/osgAnimation/RigTransformHardware.cpp +++ b/src/osgAnimation/RigTransformHardware.cpp @@ -178,7 +178,7 @@ RigTransformHardware::BoneWeightAttribList RigTransformHardware::createVertexAtt int boneIndexInVec4 = b*2; (*array)[j][0 + boneIndexInVec4] = 0; (*array)[j][1 + boneIndexInVec4] = 0; - if (boneIndexInList < _vertexIndexMatrixWeightList[j].size()) + if (boneIndexInList < static_cast(_vertexIndexMatrixWeightList[j].size())) { float boneIndex = static_cast(_vertexIndexMatrixWeightList[j][boneIndexInList].getIndex()); float boneWeight = _vertexIndexMatrixWeightList[j][boneIndexInList].getWeight(); From b3515d0e0946605c5a17d4e6de267f3bdf1eaa80 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Fri, 27 Oct 2017 13:48:52 +0100 Subject: [PATCH 177/327] Build fix for when compiling with OSG_USE_REF_PTR_IMPLICIT_OUTPUT_CONVERSION set to OFF --- src/osgText/Glyph.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/osgText/Glyph.cpp b/src/osgText/Glyph.cpp index 17776780c..7c1dba18a 100644 --- a/src/osgText/Glyph.cpp +++ b/src/osgText/Glyph.cpp @@ -167,7 +167,7 @@ void GlyphTexture::addGlyph(Glyph* glyph, int posX, int posY) glyph->setTextureInfo(_shaderTechnique, info.get()); - copyGlyphImage(glyph, info); + copyGlyphImage(glyph, info.get()); } void GlyphTexture::copyGlyphImage(Glyph* glyph, Glyph::TextureInfo* info) From 2b6ffad99a9c487937cd90a5a13dec8d883830c7 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Fri, 27 Oct 2017 13:48:52 +0100 Subject: [PATCH 178/327] Build fix for when compiling with OSG_USE_REF_PTR_IMPLICIT_OUTPUT_CONVERSION set to OFF --- src/osgText/Glyph.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/osgText/Glyph.cpp b/src/osgText/Glyph.cpp index 17776780c..7c1dba18a 100644 --- a/src/osgText/Glyph.cpp +++ b/src/osgText/Glyph.cpp @@ -167,7 +167,7 @@ void GlyphTexture::addGlyph(Glyph* glyph, int posX, int posY) glyph->setTextureInfo(_shaderTechnique, info.get()); - copyGlyphImage(glyph, info); + copyGlyphImage(glyph, info.get()); } void GlyphTexture::copyGlyphImage(Glyph* glyph, Glyph::TextureInfo* info) From c61e4fb15c626f256addeb0ac6bfe92f62952c4d Mon Sep 17 00:00:00 2001 From: Julien Valentin Date: Fri, 27 Oct 2017 14:41:29 +0200 Subject: [PATCH 179/327] fix InfluenceMap "remove useless bones" method --- src/osgAnimation/VertexInfluence.cpp | 93 ++++++++++++++++------------ 1 file changed, 55 insertions(+), 38 deletions(-) diff --git a/src/osgAnimation/VertexInfluence.cpp b/src/osgAnimation/VertexInfluence.cpp index 42ca1f254..46460a8c0 100644 --- a/src/osgAnimation/VertexInfluence.cpp +++ b/src/osgAnimation/VertexInfluence.cpp @@ -210,8 +210,7 @@ void VertexInfluenceMap::computeMinimalVertexGroupList(std::vector& } } - -//Expermental +//Experimental Bone removal stuff typedef std::vector RigList; class CollectRigVisitor : public osg::NodeVisitor { @@ -219,32 +218,33 @@ public: META_NodeVisitor(osgAnimation, CollectRigVisitor) CollectRigVisitor(); - //void apply(osg::Node&); void apply(osg::Geometry& node); - const RigList& getRigList() const; + inline const RigList& getRigList() const{return _map;} 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); + RigGeometry* rig = dynamic_cast(&node); + if ( rig ) + _map.push_back(rig); } -const RigList& CollectRigVisitor::getRigList() const -{ - return _map; +bool recursiveisUsefull( Bone* bone, std::set foundnames) { + for(unsigned int i=0; igetNumChildren(); ++i) { + Bone* child = dynamic_cast< Bone* >(bone->getChild(i)); + if(child){ + if( foundnames.find(child->getName()) != foundnames.end() ) + return true; + if( recursiveisUsefull(child,foundnames) ) + return true; + } + } + return false; } void VertexInfluenceMap::removeUnexpressedBones(Skeleton &skel) const @@ -257,44 +257,61 @@ void VertexInfluenceMap::removeUnexpressedBones(Skeleton &skel) const 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())) + unsigned int removed=0; + Bone* child, *par; + + std::set usebones; + for(RigList::iterator rigit = rigs.begin(); rigit != rigs.end(); ++rigit) { + for(VertexInfluenceMap::iterator mapit = (*rigit)->getInfluenceMap()->begin(); + mapit != (*rigit)->getInfluenceMap()->end(); + ++mapit) { + usebones.insert((*mapit).first); + } + } + + for(BoneMap::iterator bmit = boneMap.begin(); bmit != boneMap.end();) { + if(usebones.find(bmit->second->getName()) == usebones.end()) { + if( !(par = bmit->second->getBoneParent()) ) { ++bmit; continue; } - ///Bone can be removed Bone * bone2rm = bmit->second; + + if( recursiveisUsefull(bone2rm,usebones)) { + ++bmit; + continue; + } + + ///Bone can be removed + ++ removed; + OSG_INFO<<"removing useless bone: "<< bone2rm->getName() <getNumChildren(); numchild++) { if( (child = dynamic_cast(bone2rm->getChild(numchild))) ) { - par->addChild(child); - bone2rm->removeChild(child); + if(par!=child &&child!=bone2rm) { + par->addChild(child); + nodes.push_back(child); + } } } + for(unsigned int i=0; iremoveChild(nodes[i]); par->removeChild(bone2rm); + ///rebuild bonemap after bone removal - skel.accept(mapVisitor); - boneMap = mapVisitor.getBoneMap(); - bmit = boneMap.begin(); + BoneMapVisitor mapVis ; + skel.accept(mapVis); + boneMap = mapVis.getBoneMap(); + bmit = boneMap.begin(); + } else ++bmit; } + OSG_WARN<<"Number of bone removed "< Date: Fri, 27 Oct 2017 14:19:13 +0100 Subject: [PATCH 180/327] Fixed build errors when compiling with OSG_USE_REF_PTR_IMPLICIT_OUTPUT_CONVERSION set to OFF --- include/osgAnimation/MorphGeometry | 4 ++-- include/osgAnimation/MorphTransformHardware | 4 ++-- include/osgAnimation/RigTransformHardware | 6 +++--- src/osgAnimation/MorphGeometry.cpp | 2 +- src/osgAnimation/RigGeometry.cpp | 2 +- src/osgAnimation/VertexInfluence.cpp | 2 +- src/osgWrappers/serializers/osgAnimation/MorphGeometry.cpp | 4 ++-- 7 files changed, 12 insertions(+), 12 deletions(-) diff --git a/include/osgAnimation/MorphGeometry b/include/osgAnimation/MorphGeometry index cf4b06228..f1401b6b1 100644 --- a/include/osgAnimation/MorphGeometry +++ b/include/osgAnimation/MorphGeometry @@ -91,13 +91,13 @@ namespace osgAnimation inline void setVertexSource(osg::Vec3Array *v){ _positionSource=v;} /** Get source of vertices for this morph geometry */ - inline osg::Vec3Array * getVertexSource()const{return _positionSource;} + inline osg::Vec3Array * getVertexSource()const{return _positionSource.get();} /** Set source of normals for this morph geometry */ inline void setNormalSource(osg::Vec3Array *n){ _normalSource=n;} /** Get source of normals for this morph geometry */ - inline osg::Vec3Array * getNormalSource()const{return _normalSource;} + inline osg::Vec3Array * getNormalSource() const {return _normalSource.get();} /** Add a \c MorphTarget to the \c MorphGeometry. * If \c MorphTarget is not \c NULL and is not contained in the \c MorphGeometry diff --git a/include/osgAnimation/MorphTransformHardware b/include/osgAnimation/MorphTransformHardware index 650f62efd..bc0eebe8b 100644 --- a/include/osgAnimation/MorphTransformHardware +++ b/include/osgAnimation/MorphTransformHardware @@ -43,8 +43,8 @@ namespace osgAnimation virtual void operator()(MorphGeometry&); inline void setShader( osg::Shader*s ) { _shader=s; } - inline const osg::Shader * getShader() const{ return _shader; } - inline osg::Shader * getShader() { return _shader; } + inline const osg::Shader * getShader() const{ return _shader.get(); } + inline osg::Shader * getShader() { return _shader.get(); } ///texture unit reserved for morphtarget TBO default is 7 void setReservedTextureUnit(unsigned int t) { _reservedTextureUnit=t; } diff --git a/include/osgAnimation/RigTransformHardware b/include/osgAnimation/RigTransformHardware index cf506580f..c71f2ae16 100644 --- a/include/osgAnimation/RigTransformHardware +++ b/include/osgAnimation/RigTransformHardware @@ -50,8 +50,8 @@ namespace osgAnimation unsigned int getFirstVertexAttributeTarget()const { return _minAttribIndex;} void setShader(osg::Shader* shader) { _shader = shader; } - const osg::Shader* getShader() const { return _shader; } - osg::Shader* getShader() { return _shader; } + const osg::Shader* getShader() const { return _shader.get(); } + osg::Shader* getShader() { return _shader.get(); } osg::Vec4Array* getVertexAttrib(unsigned int index); unsigned int getNumVertexAttrib() const {return _boneWeightAttribArrays.size();} @@ -61,7 +61,7 @@ namespace osgAnimation const BoneNamePaletteIndex& getBoneNameToPalette(){ return _boneNameToPalette; } const BonePalette& getBonePalette() { return _bonePalette; } - osg::Uniform* getMatrixPaletteUniform() { return _uniformMatrixPalette; } + osg::Uniform* getMatrixPaletteUniform() { return _uniformMatrixPalette.get(); } void computeMatrixPaletteUniform(const osg::Matrix& transformFromSkeletonToGeometry, const osg::Matrix& invTransformFromSkeletonToGeometry); diff --git a/src/osgAnimation/MorphGeometry.cpp b/src/osgAnimation/MorphGeometry.cpp index 07a86d1a6..5f499716c 100644 --- a/src/osgAnimation/MorphGeometry.cpp +++ b/src/osgAnimation/MorphGeometry.cpp @@ -47,7 +47,7 @@ MorphGeometry::MorphGeometry(const osg::Geometry& g) : MorphGeometry::MorphGeometry(const MorphGeometry& b, const osg::CopyOp& copyop) : osg::Geometry(b,copyop), - _morphTransformImplementation((MorphTransform*)copyop(b._morphTransformImplementation)), + _morphTransformImplementation(osg::clone(b._morphTransformImplementation.get(), copyop)), _dirty(b._dirty), _method(b._method), _morphTargets(b._morphTargets), diff --git a/src/osgAnimation/RigGeometry.cpp b/src/osgAnimation/RigGeometry.cpp index c176cf9df..6884b6c12 100644 --- a/src/osgAnimation/RigGeometry.cpp +++ b/src/osgAnimation/RigGeometry.cpp @@ -67,7 +67,7 @@ RigGeometry::RigGeometry() RigGeometry::RigGeometry(const RigGeometry& b, const osg::CopyOp& copyop) : osg::Geometry(b,copyop), _geometry(b._geometry), - _rigTransformImplementation((RigTransform*)copyop(b._rigTransformImplementation)), + _rigTransformImplementation(osg::clone(_rigTransformImplementation.get(), copyop)), _vertexInfluenceMap(b._vertexInfluenceMap), _needToComputeMatrix(b._needToComputeMatrix) { diff --git a/src/osgAnimation/VertexInfluence.cpp b/src/osgAnimation/VertexInfluence.cpp index 42ca1f254..444651ce4 100644 --- a/src/osgAnimation/VertexInfluence.cpp +++ b/src/osgAnimation/VertexInfluence.cpp @@ -279,7 +279,7 @@ void VertexInfluenceMap::removeUnexpressedBones(Skeleton &skel) const } ///Bone can be removed - Bone * bone2rm = bmit->second; + Bone * bone2rm = bmit->second.get(); for(unsigned int numchild = 0; numchild < bone2rm->getNumChildren(); numchild++) { if( (child = dynamic_cast(bone2rm->getChild(numchild))) ) diff --git a/src/osgWrappers/serializers/osgAnimation/MorphGeometry.cpp b/src/osgWrappers/serializers/osgAnimation/MorphGeometry.cpp index 5479ebaf5..d2af644a9 100644 --- a/src/osgWrappers/serializers/osgAnimation/MorphGeometry.cpp +++ b/src/osgWrappers/serializers/osgAnimation/MorphGeometry.cpp @@ -41,8 +41,8 @@ static bool writeMorphTargets( osgDB::OutputStream& os, const osgAnimation::Morp { return geom.get##PROP()!=0; } \ static bool read##ORIGINAL_PROP( osgDB::InputStream& is, osgAnimation::MorphGeometry& geom ) { \ is >> is.BEGIN_BRACKET; \ - osg::Array* array =is.readArray(); \ - geom.set##PROP((osg::Vec3Array*)array); \ + osg::ref_ptr array = is.readArray(); \ + geom.set##PROP(dynamic_cast(array.get())); \ is >> is.END_BRACKET; \ return true; \ } \ From 6530b16fc73694a3475f81151e470e288bf0573a Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Fri, 27 Oct 2017 18:14:04 +0100 Subject: [PATCH 181/327] Fixed build error when building wiht OSG_USE_REF_PTR_IMPLICIT_OUTPUT_CONVERSION=OFF --- src/osgAnimation/VertexInfluence.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/osgAnimation/VertexInfluence.cpp b/src/osgAnimation/VertexInfluence.cpp index ad575662c..69941853d 100644 --- a/src/osgAnimation/VertexInfluence.cpp +++ b/src/osgAnimation/VertexInfluence.cpp @@ -278,7 +278,7 @@ void VertexInfluenceMap::removeUnexpressedBones(Skeleton &skel) const continue; } - Bone * bone2rm = bmit->second; + Bone * bone2rm = bmit->second.get(); if( recursiveisUsefull(bone2rm,usebones)) { ++bmit; From 6e79ce348d2d2f5ba87fa32645d1b5842890780d Mon Sep 17 00:00:00 2001 From: Julien Valentin Date: Fri, 27 Oct 2017 21:02:43 +0200 Subject: [PATCH 182/327] reformat with the help of AStyle reformat tool (codeblocks) --- include/osgAnimation/MorphGeometry | 50 ++++++++++++--------- include/osgAnimation/MorphTransformHardware | 11 +++-- include/osgAnimation/MorphTransformSoftware | 4 +- include/osgAnimation/RigGeometry | 26 +++++------ include/osgAnimation/RigTransform | 26 +++++------ include/osgAnimation/RigTransformHardware | 24 +++++----- include/osgAnimation/RigTransformSoftware | 28 ++++++------ include/osgAnimation/VertexInfluence | 16 +++---- 8 files changed, 95 insertions(+), 90 deletions(-) diff --git a/include/osgAnimation/MorphGeometry b/include/osgAnimation/MorphGeometry index f1401b6b1..ab6c1bc8f 100644 --- a/include/osgAnimation/MorphGeometry +++ b/include/osgAnimation/MorphGeometry @@ -29,7 +29,8 @@ namespace osgAnimation public: - enum Method { + enum Method + { NORMALIZED, RELATIVE }; @@ -61,7 +62,7 @@ namespace osgAnimation virtual const char* className() const { return "MorphGeometry"; } // set implementation of rig method - inline void setMorphTransformImplementation(MorphTransform*mt) { _morphTransformImplementation=mt; } + inline void setMorphTransformImplementation(MorphTransform*mt) { _morphTransformImplementation=mt; } inline MorphTransform* getMorphTransformImplementation() { return _morphTransformImplementation.get(); } inline const MorphTransform* getMorphTransformImplementation() const { return _morphTransformImplementation.get(); } @@ -88,16 +89,16 @@ namespace osgAnimation inline MorphTarget& getMorphTarget( unsigned int i ) { return _morphTargets[i]; } /** Set source of vertices for this morph geometry */ - inline void setVertexSource(osg::Vec3Array *v){ _positionSource=v;} + inline void setVertexSource(osg::Vec3Array *v) { _positionSource=v; } /** Get source of vertices for this morph geometry */ - inline osg::Vec3Array * getVertexSource()const{return _positionSource.get();} + inline osg::Vec3Array * getVertexSource() const { return _positionSource.get(); } /** Set source of normals for this morph geometry */ - inline void setNormalSource(osg::Vec3Array *n){ _normalSource=n;} + inline void setNormalSource(osg::Vec3Array *n) { _normalSource=n; } /** Get source of normals for this morph geometry */ - inline osg::Vec3Array * getNormalSource() const {return _normalSource.get();} + inline osg::Vec3Array * getNormalSource() const { return _normalSource.get(); } /** Add a \c MorphTarget to the \c MorphGeometry. * If \c MorphTarget is not \c NULL and is not contained in the \c MorphGeometry @@ -108,20 +109,30 @@ namespace osgAnimation * @param weight The weight to be added to the \c MorphGeometry. * @return \c true for success; \c false otherwise. */ - virtual void addMorphTarget( osg::Geometry *morphTarget, float weight = 1.0 ) { _morphTargets.push_back(MorphTarget(morphTarget, weight)); _dirty = true; } + virtual void addMorphTarget( osg::Geometry *morphTarget, float weight = 1.0 ) + { + _morphTargets.push_back(MorphTarget(morphTarget, weight)); + _dirty = true; + } - virtual void removeMorphTarget( osg::Geometry *morphTarget ) { - for(MorphTargetList::iterator iterator = _morphTargets.begin() ; iterator != _morphTargets.end() ; ++ iterator) { - if(iterator->getGeometry() == morphTarget) { + virtual void removeMorphTarget( osg::Geometry *morphTarget ) + { + for(MorphTargetList::iterator iterator = _morphTargets.begin() ; iterator != _morphTargets.end() ; ++ iterator) + { + if(iterator->getGeometry() == morphTarget) + { _morphTargets.erase(iterator); break; } } } - virtual void removeMorphTarget( const std::string& name ) { - for(MorphTargetList::iterator iterator = _morphTargets.begin() ; iterator != _morphTargets.end() ; ++ iterator) { - if(iterator->getGeometry() && iterator->getGeometry()->getName() == name) { + virtual void removeMorphTarget( const std::string& name ) + { + for(MorphTargetList::iterator iterator = _morphTargets.begin() ; iterator != _morphTargets.end() ; ++ iterator) + { + if(iterator->getGeometry() && iterator->getGeometry()->getName() == name) + { _morphTargets.erase(iterator); break; } @@ -141,10 +152,10 @@ namespace osgAnimation /** Set the MorphGeometry dirty.*/ inline void dirty(bool b=true) { _dirty = b; } - inline bool isDirty()const { return _dirty; } + inline bool isDirty() const { return _dirty; } /** for retrocompatibility */ - void transformSoftwareMethod(){(*_morphTransformImplementation.get())(*this);} + void transformSoftwareMethod() { (*_morphTransformImplementation.get())(*this); } protected: osg::ref_ptr _morphTransformImplementation; @@ -175,7 +186,8 @@ namespace osgAnimation void addTarget(const std::string& name) { _targetNames.push_back(name); } unsigned int getNumTarget() const { return _targetNames.size(); } const std::string& getTargetName(unsigned int index) { return _targetNames[index]; } - void removeTarget(const std::string& name) { + void removeTarget(const std::string& name) + { TargetNames::iterator found = std::find(_targetNames.begin(), _targetNames.end(), name); if(found != _targetNames.end()) _targetNames.erase(found); @@ -185,9 +197,7 @@ namespace osgAnimation const std::vector& getTargetNames() const { return _targetNames; } std::vector& getTargetNames() { return _targetNames; } - void setTargetNames(const TargetNames& targetNames) { - _targetNames.assign(targetNames.begin(), targetNames.end()); - } + void setTargetNames(const TargetNames& targetNames) { _targetNames.assign(targetNames.begin(), targetNames.end()); } /** Callback method called by the NodeVisitor when visiting a node.*/ virtual void operator()(osg::Node* node, osg::NodeVisitor* nv); @@ -226,8 +236,6 @@ namespace osgAnimation (implementation)(*geom); } }; - - } #endif diff --git a/include/osgAnimation/MorphTransformHardware b/include/osgAnimation/MorphTransformHardware index bc0eebe8b..838fc99cf 100644 --- a/include/osgAnimation/MorphTransformHardware +++ b/include/osgAnimation/MorphTransformHardware @@ -42,19 +42,18 @@ namespace osgAnimation virtual void operator()(MorphGeometry&); - inline void setShader( osg::Shader*s ) { _shader=s; } - inline const osg::Shader * getShader() const{ return _shader.get(); } - inline osg::Shader * getShader() { return _shader.get(); } + inline void setShader( osg::Shader*s ) { _shader=s; } + inline const osg::Shader * getShader() const { return _shader.get(); } + inline osg::Shader * getShader() { return _shader.get(); } ///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: bool init(MorphGeometry&); - osg::ref_ptr _uniformTargetsWeight; osg::ref_ptr _shader; diff --git a/include/osgAnimation/MorphTransformSoftware b/include/osgAnimation/MorphTransformSoftware index 1130cdedc..50546501a 100644 --- a/include/osgAnimation/MorphTransformSoftware +++ b/include/osgAnimation/MorphTransformSoftware @@ -29,8 +29,8 @@ namespace osgAnimation class OSGANIMATION_EXPORT MorphTransformSoftware : public MorphTransform { public: - MorphTransformSoftware():_needInit(true){} - MorphTransformSoftware(const MorphTransformSoftware& rts,const osg::CopyOp& copyop): MorphTransform(rts, copyop), _needInit(true){} + MorphTransformSoftware():_needInit(true) {} + MorphTransformSoftware(const MorphTransformSoftware& rts,const osg::CopyOp& copyop): MorphTransform(rts, copyop), _needInit(true) {} META_Object(osgAnimation,MorphTransformSoftware) diff --git a/include/osgAnimation/RigGeometry b/include/osgAnimation/RigGeometry index dc96c98f4..f9a2b1887 100644 --- a/include/osgAnimation/RigGeometry +++ b/include/osgAnimation/RigGeometry @@ -23,7 +23,6 @@ namespace osgAnimation { - // The idea is to compute a bounding box with a factor x of the first step we compute the bounding box class OSGANIMATION_EXPORT RigComputeBoundingBoxCallback : public osg::Drawable::ComputeBoundingBoxCallback { @@ -37,8 +36,8 @@ namespace osgAnimation META_Object(osgAnimation, RigComputeBoundingBoxCallback); - void reset() { _computed = false; } + virtual osg::BoundingBox computeBound(const osg::Drawable& drawable) const; protected: mutable bool _computed; @@ -58,16 +57,16 @@ namespace osgAnimation META_Object(osgAnimation, RigGeometry); inline void setInfluenceMap(VertexInfluenceMap* vertexInfluenceMap) { _vertexInfluenceMap = vertexInfluenceMap; } - inline const VertexInfluenceMap* getInfluenceMap() const { return _vertexInfluenceMap.get();} - inline VertexInfluenceMap* getInfluenceMap() { return _vertexInfluenceMap.get();} + inline const VertexInfluenceMap* getInfluenceMap() const { return _vertexInfluenceMap.get(); } + inline VertexInfluenceMap* getInfluenceMap() { return _vertexInfluenceMap.get(); } inline const Skeleton* getSkeleton() const { return _root.get(); } inline Skeleton* getSkeleton() { return _root.get(); } // will be used by the update callback to init correctly the rig mesh - inline void setSkeleton(Skeleton* root){ _root = root;} + inline void setSkeleton(Skeleton* root) { _root = root; } - void setNeedToComputeMatrix(bool state) { _needToComputeMatrix = state;} - bool getNeedToComputeMatrix() const { return _needToComputeMatrix;} + void setNeedToComputeMatrix(bool state) { _needToComputeMatrix = state; } + bool getNeedToComputeMatrix() const { return _needToComputeMatrix; } void computeMatrixFromRootSkeleton(); @@ -78,9 +77,10 @@ namespace osgAnimation void update(); - void buildVertexInfluenceSet(){_rigTransformImplementation->prepareData(*this);} + void buildVertexInfluenceSet() { _rigTransformImplementation->prepareData(*this); } const osg::Matrix& getMatrixFromSkeletonToGeometry() const; + const osg::Matrix& getInvMatrixFromSkeletonToGeometry() const; inline osg::Geometry* getSourceGeometry() { return _geometry.get(); } @@ -106,7 +106,6 @@ namespace osgAnimation osg::ref_ptr _geometry; osg::ref_ptr _rigTransformImplementation; - osg::ref_ptr _vertexInfluenceMap; osg::Matrix _matrixFromSkeletonToGeometry; @@ -114,8 +113,7 @@ namespace osgAnimation osg::observer_ptr _root; bool _needToComputeMatrix; - - }; + }; struct UpdateRigGeometry : public osg::Drawable::UpdateCallback @@ -129,7 +127,8 @@ namespace osgAnimation META_Object(osgAnimation, UpdateRigGeometry); - virtual void update(osg::NodeVisitor* nv, osg::Drawable* drw) { + virtual void update(osg::NodeVisitor* nv, osg::Drawable* drw) + { RigGeometry* geom = dynamic_cast(drw); if(!geom) return; @@ -155,7 +154,8 @@ namespace osgAnimation if(geom->getNeedToComputeMatrix()) geom->computeMatrixFromRootSkeleton(); - if(geom->getSourceGeometry()) { + if(geom->getSourceGeometry()) + { osg::Drawable::UpdateCallback * up = dynamic_cast(geom->getSourceGeometry()->getUpdateCallback()); if(up) up->update(nv, geom->getSourceGeometry()); diff --git a/include/osgAnimation/RigTransform b/include/osgAnimation/RigTransform index 9a6a0e367..ba41b8db1 100644 --- a/include/osgAnimation/RigTransform +++ b/include/osgAnimation/RigTransform @@ -1,15 +1,15 @@ - /* -*-c++-*- - * Copyright (C) 2009 Cedric Pinson - * - * This library is open source and may be redistributed and/or modified under - * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or - * (at your option) any later version. The full license is in LICENSE file - * included with this distribution, and on the openscenegraph.org website. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * OpenSceneGraph Public License for more details. +/* -*-c++-*- +* Copyright (C) 2009 Cedric Pinson +* +* This library is open source and may be redistributed and/or modified under +* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or +* (at your option) any later version. The full license is in LICENSE file +* included with this distribution, and on the openscenegraph.org website. +* +* This library is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* OpenSceneGraph Public License for more details. */ #ifndef OSGANIMATION_RIGTRANSFORM @@ -35,7 +35,7 @@ namespace osgAnimation /// to call manually when a skeleton is reacheable from the rig /// in order to prepare technic data before rendering - virtual bool prepareData(RigGeometry&){return true;} + virtual bool prepareData(RigGeometry&) { return true; } protected: virtual ~RigTransform() {} diff --git a/include/osgAnimation/RigTransformHardware b/include/osgAnimation/RigTransformHardware index c71f2ae16..5b020f4a4 100644 --- a/include/osgAnimation/RigTransformHardware +++ b/include/osgAnimation/RigTransformHardware @@ -46,22 +46,22 @@ namespace osgAnimation typedef std::vector MatrixPalette; ///set the first Vertex Attribute Array index of the rig generated by this technic (default:11) - void setFirstVertexAttributeTarget(unsigned int i){ _minAttribIndex=i;} - unsigned int getFirstVertexAttributeTarget()const { return _minAttribIndex;} + void setFirstVertexAttributeTarget(unsigned int i) { _minAttribIndex=i; } + unsigned int getFirstVertexAttributeTarget()const { return _minAttribIndex; } - void setShader(osg::Shader* shader) { _shader = shader; } - const osg::Shader* getShader() const { return _shader.get(); } - osg::Shader* getShader() { return _shader.get(); } + void setShader(osg::Shader* shader) { _shader = shader; } + const osg::Shader* getShader() const { return _shader.get(); } + osg::Shader* getShader() { return _shader.get(); } osg::Vec4Array* getVertexAttrib(unsigned int index); - unsigned int getNumVertexAttrib() const {return _boneWeightAttribArrays.size();} + unsigned int getNumVertexAttrib() const { return _boneWeightAttribArrays.size(); } - const unsigned int &getNumBonesPerVertex() const{ return _bonesPerVertex; } - const unsigned int &getNumVertexes() const { return _nbVertices; } + const unsigned int &getNumBonesPerVertex() const { return _bonesPerVertex; } + const unsigned int &getNumVertexes() const { return _nbVertices; } - const BoneNamePaletteIndex& getBoneNameToPalette(){ return _boneNameToPalette; } - const BonePalette& getBonePalette() { return _bonePalette; } - osg::Uniform* getMatrixPaletteUniform() { return _uniformMatrixPalette.get(); } + const BoneNamePaletteIndex& getBoneNameToPalette() { return _boneNameToPalette; } + const BonePalette& getBonePalette() { return _bonePalette; } + osg::Uniform* getMatrixPaletteUniform() { return _uniformMatrixPalette.get(); } void computeMatrixPaletteUniform(const osg::Matrix& transformFromSkeletonToGeometry, const osg::Matrix& invTransformFromSkeletonToGeometry); @@ -84,7 +84,7 @@ namespace osgAnimation bool _needInit; unsigned int _minAttribIndex; - bool buildPalette(const BoneMap& boneMap ,const RigGeometry& rig); + bool buildPalette(const BoneMap& boneMap,const RigGeometry& rig); //on first update virtual bool init(RigGeometry& ); diff --git a/include/osgAnimation/RigTransformSoftware b/include/osgAnimation/RigTransformSoftware index 243c635d2..4424498ba 100644 --- a/include/osgAnimation/RigTransformSoftware +++ b/include/osgAnimation/RigTransformSoftware @@ -44,20 +44,20 @@ namespace osgAnimation class BonePtrWeight: LocalBoneIDWeight { public: - 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 > b1.first); + 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 > b1.first); } ///set Bone pointer - inline const Bone * getBonePtr() const {return _boneptr.get();} - inline void setBonePtr(Bone*b){_boneptr=b;} + inline const Bone * getBonePtr() const { return _boneptr.get(); } + inline void setBonePtr(Bone*b) { _boneptr=b; } protected: osg::observer_ptr< Bone > _boneptr; }; @@ -110,7 +110,7 @@ namespace osgAnimation } resetMatrix(); - for(BonePtrWeightList::iterator bwit=_boneweights.begin();bwit!=_boneweights.end();++bwit ) + for(BonePtrWeightList::iterator bwit=_boneweights.begin(); bwit!=_boneweights.end(); ++bwit ) { const Bone* bone = bwit->getBonePtr(); if (!bone) @@ -125,7 +125,7 @@ namespace osgAnimation } } void normalize(); - inline const osg::Matrix& getMatrix() const { return _result;} + inline const osg::Matrix& getMatrix() const { return _result; } protected: BonePtrWeightList _boneweights; IndexList _vertexes; diff --git a/include/osgAnimation/VertexInfluence b/include/osgAnimation/VertexInfluence index eb2956b72..256d9c198 100644 --- a/include/osgAnimation/VertexInfluence +++ b/include/osgAnimation/VertexInfluence @@ -41,15 +41,14 @@ namespace osgAnimation class OSGANIMATION_EXPORT VertexInfluence : public IndexWeightList { public: - const std::string& getName() const { return _name;} - void setName(const std::string& name) { _name = name;} - + const std::string& getName() const { return _name; } + void setName(const std::string& name) { _name = name; } protected: // the name is the bone to link to std::string _name; }; - class VertexInfluenceMap : public std::map , public osg::Object + class VertexInfluenceMap : public std::map, public osg::Object { public: META_Object(osgAnimation, VertexInfluenceMap); @@ -57,8 +56,8 @@ namespace osgAnimation VertexInfluenceMap() {} VertexInfluenceMap(const osgAnimation::VertexInfluenceMap& org, const osg::CopyOp& copyop): std::map(org), - osg::Object(org, copyop) - {} + osg::Object(org, copyop) {} + ///normalize per vertex weights given numvert of the attached mesh void normalize(unsigned int numvert); @@ -72,8 +71,8 @@ namespace osgAnimation class VertexGroup: public std::pair { public: - inline const BoneWeightList& getBoneWeights()const { return first; } - inline void setBoneWeights( BoneWeightList& o ) { first=o; } + inline const BoneWeightList& getBoneWeights() const { return first; } + inline void setBoneWeights( BoneWeightList& o ) { first=o; } inline IndexList& vertIDs() { return second; } }; @@ -83,7 +82,6 @@ namespace osgAnimation //Experimental removal of unexpressed bone from the skeleton void removeUnexpressedBones(Skeleton &skel) const; }; - } #endif From 053ba83be66c3eb7a565b5d78ac094fa3a4ad125 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Mon, 30 Oct 2017 09:32:04 +0000 Subject: [PATCH 183/327] Merged support for StateSet::DefineList from shader_pipeline branch --- CMakeLists.txt | 2 +- src/osgWrappers/serializers/osg/StateSet.cpp | 49 ++++++++++++++++++++ 2 files changed, 50 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6625f0f86..16c20b47a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -116,7 +116,7 @@ PROJECT(OpenSceneGraph) SET(OPENSCENEGRAPH_MAJOR_VERSION 3) SET(OPENSCENEGRAPH_MINOR_VERSION 5) SET(OPENSCENEGRAPH_PATCH_VERSION 8) -SET(OPENSCENEGRAPH_SOVERSION 150) +SET(OPENSCENEGRAPH_SOVERSION 151) # set to 0 when not a release candidate, non zero means that any generated # git tags will be treated as release candidates of given number diff --git a/src/osgWrappers/serializers/osg/StateSet.cpp b/src/osgWrappers/serializers/osg/StateSet.cpp index 8a94d1875..1112dbd82 100644 --- a/src/osgWrappers/serializers/osg/StateSet.cpp +++ b/src/osgWrappers/serializers/osg/StateSet.cpp @@ -270,6 +270,50 @@ static bool writeUniformList( osgDB::OutputStream& os, const osg::StateSet& ss ) return true; } +// _defineList +static bool checkDefineList( const osg::StateSet& ss ) +{ + return ss.getDefineList().size()>0; +} + +static bool readDefineList( osgDB::InputStream& is, osg::StateSet& ss ) +{ + unsigned int size = is.readSize(); is >> is.BEGIN_BRACKET; + for ( unsigned int i=0; i> is.PROPERTY("Value"); + int overrideValue = readValue( is ); + + ss.setDefine(defineName, defineValue, overrideValue); + + } + is >> is.END_BRACKET; + return true; +} + +static bool writeDefineList( osgDB::OutputStream& os, const osg::StateSet& ss ) +{ + const osg::StateSet::DefineList& df = ss.getDefineList(); + os.writeSize(df.size()); os << os.BEGIN_BRACKET << std::endl; + for ( osg::StateSet::DefineList::const_iterator itr=df.begin(); + itr!=df.end(); ++itr ) + { + os.writeWrappedString(itr->first); + os.writeWrappedString(itr->second.first); + os << os.PROPERTY("Value"); + writeValue(os, itr->second.second); + os << std::endl; + } + os << os.END_BRACKET << std::endl; + return true; +} + REGISTER_OBJECT_WRAPPER( StateSet, new osg::StateSet, osg::StateSet, @@ -295,4 +339,9 @@ REGISTER_OBJECT_WRAPPER( StateSet, ADD_BOOL_SERIALIZER( NestRenderBins, true ); // _nestRenderBins ADD_OBJECT_SERIALIZER( UpdateCallback, osg::StateSet::Callback, NULL ); // _updateCallback ADD_OBJECT_SERIALIZER( EventCallback, osg::StateSet::Callback, NULL ); // _eventCallback + + { + UPDATE_TO_VERSION_SCOPED( 151 ) + ADD_USER_SERIALIZER( DefineList ); // _defineList + } } From 45e520663d146f79857e123206c2e46eb57382c5 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Mon, 30 Oct 2017 13:40:50 +0000 Subject: [PATCH 184/327] Quitened down the DisplaySettings::setShaderHint() output for NONE. --- src/osg/DisplaySettings.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/osg/DisplaySettings.cpp b/src/osg/DisplaySettings.cpp index 5e7259956..9c1f3c75b 100644 --- a/src/osg/DisplaySettings.cpp +++ b/src/osg/DisplaySettings.cpp @@ -1141,7 +1141,7 @@ void DisplaySettings::setShaderHint(ShaderHint hint, bool setShaderValues) setValue("OSG_PRECISION_FLOAT", ""); setValue("OSG_VARYING_IN", "varying"); setValue("OSG_VARYING_OUT", "varying"); - OSG_NOTICE<<"DisplaySettings::NONE"< Date: Mon, 30 Oct 2017 14:05:45 +0000 Subject: [PATCH 185/327] Updated ChangeLog and AUTHORS --- AUTHORS.txt | 44 +-- ChangeLog | 484 +++++++++++++++++++++++ applications/osgversion/Contributors.cpp | 4 +- 3 files changed, 509 insertions(+), 23 deletions(-) diff --git a/AUTHORS.txt b/AUTHORS.txt index 58628fdd5..9f299c9ce 100644 --- a/AUTHORS.txt +++ b/AUTHORS.txt @@ -1,4 +1,4 @@ -OpenSceneGraph Library 3.5.7 +OpenSceneGraph Library 3.5.8 568 Contributors: @@ -8,11 +8,11 @@ Robert Osfield Stephan Huber Paul Martz Farshid Lashkari -Mathias Fröhlich +Mathias Frhlich +Laurens Voerman Marco Jez Wang Rui -Laurens Voerman -Jean-Sébastien Guay +Jean-Sbastien Guay Ulrich Hertlein Mike Weiblen Sukender @@ -65,11 +65,11 @@ Norman Vine Chris Denham Sherman Wilcox Serge Lages -Romano José Magacho da Silva +Romano Jos Magacho da Silva Mourad Boufarguine Alberto Farre Glenn Waldron -André Garneau +Andr Garneau Adrian Egli Sebastian Messerschmidt Randall Hopper @@ -84,7 +84,7 @@ Michael Gronager Martin Naylor Joakim Simonsson David Spilling -Daniel Sjölie +Daniel Sjlie Bryan Thrall Andreas Ekstrand Rafa Gaitan @@ -111,6 +111,7 @@ Sondra Iverson Simon Julier Rune Schmidt Jensen Ravi Mathur +Ralf Habacker Rainer Oder Nico Kruithof Martin Aumueller @@ -121,12 +122,11 @@ Gordon Tomlinson Frederic Marmond Frederic Bouvier Carlo Camporesi -Björn Blissing +Bjrn Blissing Alexander Sinditskiy Vladimir Chebaev Thibault Genessay Sasa Bistrovic -Ralf Habacker Neil Groves Mikhail Izmestev Markus Trenkwalder @@ -141,7 +141,7 @@ Uwe Woessner Tony Horrobin Thom DeCarlo Tatsuhiro Nishioka -Tanguy Fautré +Tanguy Fautr Sean Spicer Ryan Kawicki Richard Schmidt @@ -201,7 +201,7 @@ Phil Atkin Pawel Ksiezopolski Patrick Neary Nathan Monteleone -Miha Rav¨elj +Miha Ravelj Miguel Escriva Mattias Linde Mark Sciabica @@ -233,8 +233,8 @@ Christian Ruzicka Christian Buchner Charles Cole Blake Williams -Björn Hein -Aurélien Chatelain +Bjrn Hein +Aurlien Chatelain Antoine Hue Andrew Bettison Andreas Henne @@ -264,7 +264,7 @@ Paul Obermeier Nguyen Van Truong Nathan Cournia Morten Haukness -Morné Pistorius +Morn Pistorius Michael Mc Donnell Michael Henheffer Michael Guerrero @@ -297,7 +297,7 @@ Guillaume Taze Guillaume Chouvenc Giuseppe Donvito Gill Peacegood -Giampaolo Viganò +Giampaolo Vigan Gerrick Bivins George Tarantilis Ferdi Smit @@ -305,7 +305,7 @@ Eduardo Poyart Edgar Ellis Dmitry Marakasov Dimi Christopoulos -Diane Delallée +Diane Delalle David Longest David Ergo Daniel Trstenjak @@ -337,7 +337,7 @@ Vasily Radostev Valery Bickov Valeriy Dubov Vaclav Bilek -Tyge Løvset +Tyge Lvset Troy Yee Torben Dannahauer Tony Vasile @@ -387,7 +387,7 @@ Piotr Rak Pierre Bourdin Philipp Svehla Philipp Siemoleit -Philipp Mächler +Philipp Mchler Philip Lamb Petr Salinger Peter Bear @@ -412,7 +412,7 @@ Nick Thu Nick Black Mojtaba Fathi Mirko Viviani -Mikkel Gjøl +Mikkel Gjl Mike Krus Mike Garrity Mick Thu @@ -465,7 +465,7 @@ Juan Hernando Josh Portway Jonathan Greig John Tan -John Hedström +John Hedstrm John Grant John Farrier John Donovan @@ -524,11 +524,11 @@ David Jung Danny Valente Daniel Stien Dan Minor -César L. B. Silveira +Csar L. B. Silveira Cyril Brulebois Curtis Rubel Cory Slep -Clément B½sch +Clment Bsch Clay Fowler Claus Steuer Chuck Sembroski diff --git a/ChangeLog b/ChangeLog index 01ff512e2..97e0ca86a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,274 @@ +Mon, 30 Oct 2017 09:32:04 +0000 +Author : Robert Osfield +Merged support for StateSet::DefineList from shader_pipeline branch + +Fri, 27 Oct 2017 13:48:52 +0100 +Author : Robert Osfield +Build fix for when compiling with OSG_USE_REF_PTR_IMPLICIT_OUTPUT_CONVERSION set to OFF + +Fri, 27 Oct 2017 13:19:52 +0100 +Author : Robert Osfield +Fixed warning + +Fri, 27 Oct 2017 13:17:47 +0100 +Author : Robert Osfield +From Farshid Lashkari, "fix for the Collada loader to check for some NULL attributes." + +Fri, 27 Oct 2017 09:33:24 +0100 +Author : OpenSceneGraph git repository +Merge pull request #373 from LaurensVoerman/noStdMaxuse osg::maximum, not std::max + +Fri, 27 Oct 2017 09:41:28 +0200 +Author : Laurens Voerman +use osg::maximum, not std::max + +Thu, 26 Oct 2017 14:26:01 +0100 +Author : OpenSceneGraph git repository +Merge pull request #372 from openscenegraph/text_improvementsText improvements, introducing implementation of Signed Distance Function texture generation and new shaders for outlines and shadows replacing old multi-pass approach + +Thu, 26 Oct 2017 12:08:00 +0100 +Author : Robert Osfield +Updated from OpenSceneGraph-Data/shader/text.frag to add fixes to handling of vertexColor's alpha values + +Thu, 26 Oct 2017 12:03:56 +0100 +Author : Robert Osfield +Added update of glyph representation to ensure all the glyphs are assigned to the required GlyphTextures + +Thu, 26 Oct 2017 12:02:56 +0100 +Author : Robert Osfield +Added command line parsing to aid with testing of osgText by allowing osgText::FadeText to be created with various options + +Wed, 25 Oct 2017 16:29:25 +0100 +Author : Robert Osfield +Added optimization for text where the colour alpha value is 0.0, returning early to aovid any GL calls. + +Wed, 25 Oct 2017 16:13:26 +0100 +Author : Robert Osfield +Fixed pre compilation osg::Program state leaking into the main scene graph rendering + +Tue, 24 Oct 2017 16:04:14 +0100 +Author : Robert Osfield +Added stats handler + +Tue, 24 Oct 2017 15:14:23 +0100 +Author : Robert Osfield +Updated from OpenSceneGraph-Data/shaders/text.frag to address GLSL int to float conversion warning + +Tue, 24 Oct 2017 14:46:13 +0100 +Author : Robert Osfield +Added DisplaySettings:s/getgTextShaderTechnique() and OSG_TEXT_SHADER_TECHNIQUE env var support to DisplaySettings. Added using of DisplaySettings:getgTextShaderTechnique() to Text default constructor. Added better debug output control in Text.cpp + +Tue, 24 Oct 2017 12:34:48 +0100 +Author : Robert Osfield +Improved the Text::_shaderTechnique default setting using OSG_TEXT_SHADER_TECHNIQUE env var, options are ALL_FEATURES, GREYSCALE, SIGNED_DISTANCE_FIELD, SDF, NO_TEXT_SHADER, NONE. + +Tue, 24 Oct 2017 12:07:13 +0100 +Author : Robert Osfield +Quitened down debug info + +Tue, 24 Oct 2017 11:36:00 +0100 +Author : Robert Osfield +Fixed Glyph::TextureInfo assignment bug + +Mon, 23 Oct 2017 16:07:24 +0100 +Author : Robert Osfield +Renamed text_sdf.frag to text.frag and removed text_greyscale_frag. Cleaned up setup of osgText::ShaderTechnique adding a NO_SHADER_TECHNIQUE option. + +Mon, 23 Oct 2017 14:50:35 +0100 +Author : Robert Osfield +Restructed the way that GlyphTexture is set up to better support control of osgText::ShaderTechnique from osgText::Text + +Mon, 23 Oct 2017 09:06:55 +0100 +Author : OpenSceneGraph git repository +Merge pull request #371 from hwiesmann/masterRemoval of compiler warning for Cocoa builds + +Mon, 23 Oct 2017 09:05:34 +0100 +Author : OpenSceneGraph git repository +Merge pull request #370 from siu/master-travisCcacheFix ccache on travis + +Sun, 22 Oct 2017 22:13:46 +0200 +Author : Hartwig +BUG FIX - Addition of missing #endif directive + +Sun, 22 Oct 2017 15:04:33 +0200 +Author : Hartwig +Replacement of commas with semicolons + +Sun, 22 Oct 2017 13:47:51 +0200 +Author : Hartwig +Removal of compiler warning for Cocoa builds + +Fri, 20 Oct 2017 14:09:11 +0200 +Author : David Siñuela Pastor +Install ccache on MacOsNote that brew update must be run before any brew install command or +it will fail, see https://github.com/travis-ci/travis-ci/issues/8552. + + +Wed, 18 Oct 2017 12:20:35 +0200 +Author : David Siñuela Pastor +Fix ccache configuration in travisUse ccache as explained in https://docs.travis-ci.com/user/caching/#ccache-cache + + +Sat, 21 Oct 2017 10:08:41 +0100 +Author : Robert Osfield +Added Text::s/getShaderTechnique() + +Fri, 20 Oct 2017 17:03:25 +0100 +Author : Robert Osfield +Moved osgText::GlyphTechnique::Features enum to osgText::ShaderTechinque enum to make it's roll clearer + +Fri, 20 Oct 2017 14:14:14 +0100 +Author : Robert Osfield +Merge branch 'master' into text_improvements + +Fri, 20 Oct 2017 11:52:48 +0100 +Author : Robert Osfield +From Ralf Habacker, patch refactoring struct ObjOptionsStruct in obj plugin into a real class, which is a preparation for further obj related patches. + +Fri, 20 Oct 2017 11:37:41 +0100 +Author : Robert Osfield +Added built-in support for lighting.vert + +Fri, 20 Oct 2017 10:18:21 +0100 +Author : Robert Osfield +Updated shaders from OpenSceneGraph-Data/shaders + +Thu, 19 Oct 2017 20:57:25 +0100 +Author : Robert Osfield +Moved the assignment of the ModifiedCount to before GL texture calls. + +Thu, 19 Oct 2017 12:39:22 +0100 +Author : Robert Osfield +Implemented --single command line option that creates a single osg::DrawElementsUInt primitive set instead of using MultiDrawIndirect. + +Thu, 19 Oct 2017 12:06:59 +0100 +Author : Robert Osfield +Improved spacing to make code more readable + +Thu, 19 Oct 2017 11:57:53 +0100 +Author : Robert Osfield +Build fixes with ref_ptr<> autoconversion disabled + +Thu, 19 Oct 2017 11:06:23 +0100 +Author : Robert Osfield +Fixed placement of { and spacing to make the code more readable and consistent with the rest of the OSG + +Wed, 18 Oct 2017 10:11:43 +0100 +Author : Robert Osfield +Implemented inplace replacement + +Tue, 17 Oct 2017 17:11:12 +0200 +Author : David Siñuela Pastor +Do not break systems with cr as line endings + +Mon, 16 Oct 2017 11:52:54 +0100 +Author : Robert Osfield +Fixed warning + +Mon, 16 Oct 2017 10:47:47 +0100 +Author : Robert Osfield +Fixed GLX EGL build + +Mon, 16 Oct 2017 10:38:33 +0100 +Author : Robert Osfield +Removed inappropriate tabs&spaces + +Mon, 16 Oct 2017 10:16:49 +0100 +Author : OpenSceneGraph git repository +Merge pull request #364 from mp3butcher/osganimbugfixadd osg::Program::BindUniformBlockList serialization + +Mon, 16 Oct 2017 10:12:19 +0100 +Author : Robert Osfield +Fixed build error + +Mon, 16 Oct 2017 10:08:18 +0100 +Author : Robert Osfield +Moved bracket to be consistent with the rest of the OSG + +Mon, 16 Oct 2017 10:00:49 +0100 +Author : OpenSceneGraph git repository +Merge pull request #366 from LaurensVoerman/rotateDXTadd support for dxt compressed images to createImageWithOrientationConversion + +Mon, 16 Oct 2017 09:58:29 +0100 +Author : OpenSceneGraph git repository +Merge pull request #367 from LaurensVoerman/compression_astccopySubImage support for block compressed images, added support for astc compressed type. + +Mon, 16 Oct 2017 09:49:47 +0100 +Author : Robert Osfield +Fixed indentation + +Mon, 16 Oct 2017 09:45:37 +0100 +Author : OpenSceneGraph git repository +Merge pull request #365 from LaurensVoerman/login2modified present3D and osgvnc to allow multiple --login arguments like osgViewer. + +Sat, 14 Oct 2017 09:06:37 +0100 +Author : Robert Osfield +Changed the precision setting of #pargma(tic) shader composition define setup to address GLES compatibility issues + +Sat, 14 Oct 2017 09:03:08 +0100 +Author : Robert Osfield +Improved the formating of GLSL source that is passed to OpenGL to make debugging shaders easier. + +Fri, 13 Oct 2017 17:03:31 +0100 +Author : Robert Osfield +Cleaned up support for GL3 build + +Fri, 13 Oct 2017 16:54:04 +0200 +Author : Laurens Voerman +copySubImage support for block compressed images, added support for astc compressed type. + +Fri, 13 Oct 2017 13:01:57 +0100 +Author : Robert Osfield +Removed the glyph image outline support as it's no longer required. + +Fri, 13 Oct 2017 11:42:25 +0100 +Author : Robert Osfield +Deprecated Text:BackdropImplementation, removing the backend as it no longer required when using shaders for backdrop effects + +Fri, 13 Oct 2017 08:40:58 +0100 +Author : Robert Osfield +Removed old multipass implemenmtations of backdrops as effect is now fully implememted in shaders + +Thu, 12 Oct 2017 17:19:24 +0200 +Author : Julien Valentin +add osg::Program::BindUniformBlock serialization + +Thu, 12 Oct 2017 18:45:38 +0100 +Author : Robert Osfield +Updated from OpenSceneGraph-Data/shaders/text_sdf.frag to add support for SHADOW + +Thu, 12 Oct 2017 16:44:40 +0100 +Author : Robert Osfield +Merge branch 'master' into text_improvements + +Thu, 12 Oct 2017 17:38:16 +0200 +Author : Laurens Voerman +add support for dxt compressed images to createImageWithOrientationConversion + +Thu, 12 Oct 2017 17:21:10 +0200 +Author : Laurens Voerman +modified present3D to allow multiple --login arguments like osgViewer, added --login option to osgvnc example + +Thu, 12 Oct 2017 15:52:42 +0100 +Author : OpenSceneGraph git repository +Merge pull request #363 from LaurensVoerman/dxtcGetcoloradded dxtc support in Image::getColor, Image::isImageTranscent testdxt3 and dxt5 + +Thu, 12 Oct 2017 13:49:57 +0200 +Author : Laurens Voerman +added dxtc support in Image::getColor, enhanced Image::isImageTranslucent to test opacity of dxt3 and dxt5 images + +Thu, 12 Oct 2017 11:12:47 +0100 +Author : Robert Osfield +Updated text_sdf_frag.cpp from OpenSceneGraph-Data changes that add outline generation for non SIGNED_DISTANCE_FIELD text. + +Tue, 10 Oct 2017 09:21:34 +0100 +Author : Robert Osfield +Merge branch 'master' into text_improvements + +Mon, 9 Oct 2017 12:33:06 +0100 +Author : Robert Osfield +Updated ChangeLog + Mon, 9 Oct 2017 12:25:40 +0100 Author : Robert Osfield Updated version number @@ -66,10 +337,66 @@ Thu, 5 Oct 2017 12:15:23 +0100 Author : OpenSceneGraph git repository Merge pull request #346 from LaurensVoerman/FindLIBLASremoved las_c library from FindLIBLAS.cmake, it's not used by the osgplugin. +Thu, 5 Oct 2017 12:14:03 +0100 +Author : Robert Osfield +Merge branch 'master' into text_improvements + +Wed, 4 Oct 2017 18:06:42 +0100 +Author : Robert Osfield +Improvements to the Signed Distance Field implementation. + +Fri, 29 Sep 2017 20:21:13 +0100 +Author : Robert Osfield +Simplified and improved the glyph margin computation and usage + +Fri, 29 Sep 2017 10:39:02 +0100 +Author : Robert Osfield +Improved SDF generation + +Fri, 29 Sep 2017 10:25:04 +0100 +Author : Robert Osfield +Added setting of the FontResolution of the DefaultFont + +Fri, 29 Sep 2017 10:20:59 +0100 +Author : Robert Osfield +Added command line support for specifying "default" for osgText::DefaultFont + +Fri, 29 Sep 2017 09:54:43 +0100 +Author : Robert Osfield +Improved the setup of the --counter test + Thu, 28 Sep 2017 11:09:18 +0200 Author : Denys Koch Fix loading of 16bit PNG imagesWhen a 16bit PNG image is loaded, the internalTextureFormat is set to unsized (i.e pixelFormat) constant. This results in 8 Bit Texture2D +Wed, 27 Sep 2017 11:09:22 +0100 +Author : Robert Osfield +Fixed update of GlyphTexture Image when copying new Glyph image's to it. + +Tue, 26 Sep 2017 15:32:41 +0100 +Author : Robert Osfield +UPdated from OpenSceneGraph-Data with handling of non textured text decoration + +Tue, 26 Sep 2017 12:51:03 +0100 +Author : Robert Osfield +Updated shader from OpenSceneGraph-Data/shaders to add fade out for SDF and non SDF pathways + +Tue, 26 Sep 2017 10:57:09 +0100 +Author : Robert Osfield +Updated wiht OpenSceneGraph-Data/shader version that introduced use of textureLOD to reduce aliasing artifacts with SDF + +Tue, 26 Sep 2017 10:44:14 +0100 +Author : Robert Osfield +Updated shaders using latest OpenSceneGraph-Data/shader versions + +Tue, 26 Sep 2017 10:42:47 +0100 +Author : Robert Osfield +Improvements to SDF and outline generation + +Fri, 22 Sep 2017 12:22:58 +0100 +Author : Robert Osfield +Fixed rendering old sytel outline + Fri, 22 Sep 2017 11:38:43 +0300 Author : Konstantin S. Matveyev LineSegmentIntersector fixed: intersection ratio remaped to the range of LineSegment => correct order in multiset of intersections @@ -78,18 +405,139 @@ Sun, 17 Sep 2017 18:48:32 +0300 Author : konstantin.matveyev tellg call removed from StreamOperator's checkStream function, because reading of files (readNodeFile etc.) with tellg on 'every iter' is approximately 100 times slower on Emscripten platform +Fri, 22 Sep 2017 07:56:30 +0100 +Author : OpenSceneGraph git repository +Merge pull request #352 from remoe/patch-3addShader fix + +Fri, 22 Sep 2017 08:39:38 +0200 +Author : Remo E +addShader fix + +Thu, 21 Sep 2017 16:04:10 +0100 +Author : Robert Osfield +Removed debug output + +Thu, 21 Sep 2017 16:01:27 +0100 +Author : Robert Osfield +Added assignStateSet() to Text::setBackgroundColor() + +Thu, 21 Sep 2017 15:52:07 +0100 +Author : Robert Osfield +Added support for toggling on use of the new SignedDistanceFunction function now built into osgText, just use --sdf to enable. + +Thu, 21 Sep 2017 15:41:21 +0100 +Author : Robert Osfield +Removed debug info + Thu, 21 Sep 2017 16:33:14 +0200 Author : Laurens Voerman VNC: try to find password for host if no password for host:port is found +Thu, 21 Sep 2017 14:35:31 +0100 +Author : Robert Osfield +Moved enabling/disabling of SDF so it's done regardless of whether a backdrop is used. + +Thu, 21 Sep 2017 14:32:17 +0100 +Author : Robert Osfield +Umproved SDF computation. + +Wed, 20 Sep 2017 16:51:30 +0100 +Author : Robert Osfield +Removed no longer used code paths + +Wed, 20 Sep 2017 15:51:03 +0100 +Author : Robert Osfield +Added support for only enabling SignedDistanceField shader path when font resolution is greater than 16. + +Wed, 20 Sep 2017 14:30:23 +0100 +Author : Robert Osfield +cleaned up exmple + +Wed, 20 Sep 2017 14:29:05 +0100 +Author : Robert Osfield +Added Text::assignStateSet() and usage to make sure the correct StateSet is setup for each combination of backdrop settings + +Wed, 20 Sep 2017 11:02:06 +0100 +Author : Robert Osfield +Updated text_sdf.frag shader to handle GLES2+ versions + +Wed, 20 Sep 2017 11:01:04 +0100 +Author : Robert Osfield +Added commented out debug output to make it easier to test in future + +Tue, 19 Sep 2017 17:07:59 +0100 +Author : Robert Osfield +Fixed OSG_PRECISION_FLOAT usage + +Tue, 19 Sep 2017 17:01:58 +0100 +Author : Robert Osfield +Fixed X11 GLES2 build + +Tue, 19 Sep 2017 16:35:28 +0100 +Author : Robert Osfield +Added osgText/shaders to support greyscale and Signed Distance Field based text + +Mon, 18 Sep 2017 18:09:15 +0100 +Author : Robert Osfield +Added support for subsititing $VAR_NAME entries in shaders to enable writing shaders that work across GLSL versions. + +Fri, 15 Sep 2017 15:14:19 +0100 +Author : Robert Osfield +Added constant sizeing vs changing label size relatve to font resolution, controlled by --constant-size and --scale-size command line options. + Fri, 15 Sep 2017 12:14:37 +0300 Author : Konstantin S. Matveyev osg serializers fixed for static build, ShaderAttribute wrapper added +Thu, 14 Sep 2017 15:58:38 +0100 +Author : Robert Osfield +Impprovide the computation of the Signed Distance Field + +Wed, 13 Sep 2017 11:09:56 +0100 +Author : Robert Osfield +Fixed of shadow + +Wed, 13 Sep 2017 11:08:51 +0100 +Author : Robert Osfield +Added --shadow-* command line variants to provide full control over the position of the text shadow + +Tue, 12 Sep 2017 19:13:01 +0100 +Author : Robert Osfield +Added setting of the Text::BackdropImplementation type to USE_SHADERS when setting up shaders + +Tue, 12 Sep 2017 16:03:35 +0100 +Author : Robert Osfield +Changed the margin computation to properly account of the Signed Distance Function data + +Tue, 12 Sep 2017 11:50:47 +0100 +Author : Robert Osfield +Shifted set up of osgText related StateSet from osgText::Font into into osg::TextBase/Text to enable grater control over state required for specific Text implementations + Tue, 12 Sep 2017 09:19:33 +0200 Author : Laurens Voerman removed las_c library from FindLIBLAS.cmake, it's not used by the osg plugin. +Fri, 8 Sep 2017 17:03:15 +0100 +Author : Robert Osfield +Added extra command line paramter and osgText::Font settings to add better control of osgText::GlyphTexture generation to support signed distance field and outline image data. + +Fri, 8 Sep 2017 17:02:38 +0100 +Author : Robert Osfield +Added setting of the original font reoslution to the created Glyph + +Fri, 8 Sep 2017 16:59:43 +0100 +Author : Robert Osfield +Add support for generating outline and signed distance field channels in a RGBA packed GlyphTexture Image. + +Wed, 6 Sep 2017 16:53:54 +0100 +Author : Robert Osfield +Added KeyHandler for toggling "SIGNED_DISTANCE_FIELD" and "OUTLINE" #pragma(tic) shader defines to control the different shader paths.Keys to press are 'd' for toggle SIGNED_DISTANCE_FIELD and 'o' for OUTLINE. + + +Wed, 6 Sep 2017 10:40:05 +0100 +Author : Robert Osfield +To control the GlyphTexture Min/MagFilter values Added --min and --mag filter with LINEAR, NEAREST and LINEAR_MIPMAP_LINER options for values + Mon, 4 Sep 2017 15:21:26 +0100 Author : OpenSceneGraph git repository Merge pull request #344 from eligovision/OpenSceneGraph_text3dText3D dynamic changing fix @@ -122,6 +570,42 @@ Wed, 30 Aug 2017 23:15:01 +0200 Author : Julien Valentin fix a bug in how vertexattributes are filled +Wed, 30 Aug 2017 17:43:29 +0100 +Author : Robert Osfield +Added --shader filename command line parsing and associated set up of osg::Program to allow shaders to be passed into example to customize rendering + +Wed, 30 Aug 2017 16:22:25 +0100 +Author : Robert Osfield +Added --interval value commnad line option for setting the Font::setGlyphInterval() to experimentation of clamping of glyph images to user specified intervals in the glyph texture + +Wed, 30 Aug 2017 16:21:03 +0100 +Author : Robert Osfield +Added osgText::Font::s/getGlyphInterval(int) and GlyphTexture::s/getGlyphInterval(int) and internal support for clmapping positions of glyph images an defined intervals, defaults to 1. + +Wed, 30 Aug 2017 10:50:26 +0100 +Author : Robert Osfield +Added --margin texel_width and --margin-ration ratio to control the spacing between glyphs in the font. + +Wed, 30 Aug 2017 10:16:18 +0100 +Author : Robert Osfield +Added --test command line option that sets up all the sizes and font settings required for a useufl unit test. + +Tue, 29 Aug 2017 17:32:14 +0100 +Author : Robert Osfield +Removed debug messages + +Tue, 29 Aug 2017 17:19:26 +0100 +Author : Robert Osfield +Added TextSettings struct to manage values used to set up the text. with the addition of following command line parameters: --outline // enable outlne --shadow // enable shadow --offset ratio // set the backdrop offset --text-color r g b a // set the text body color --bd-color r g b a // set the shadow/outline color --bg-color r g b a // window background color -o filename // write create subgraph to disk using specified filename + +Tue, 29 Aug 2017 13:48:06 +0100 +Author : Robert Osfield +Added --ortho command line option to toggle use of orthographic camera or default perspective one + +Tue, 29 Aug 2017 12:21:14 +0100 +Author : Robert Osfield +Added argument parsing to viewer constructor + Tue, 29 Aug 2017 10:51:06 +0100 Author : OpenSceneGraph git repository Merge pull request #334 from mathieu/ValidateProgramTooEarlyUnder macOS the glValidateProgram reports too many errors diff --git a/applications/osgversion/Contributors.cpp b/applications/osgversion/Contributors.cpp index a5a495536..bce3f9f66 100644 --- a/applications/osgversion/Contributors.cpp +++ b/applications/osgversion/Contributors.cpp @@ -275,7 +275,9 @@ const char* invalidNames[] = "I", "TriangleFunctor", "PrimitiveFunctor", - "OpenMW" + "OpenMW", + "StreamOperator", + "FindLIBLAS" }; From bd3262e07f5d836f6b842b831870aa39f5ff636d Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Mon, 30 Oct 2017 14:22:10 +0000 Subject: [PATCH 186/327] From Raymond de Vires, Windows build fix --- src/osgAnimation/VertexInfluence.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/osgAnimation/VertexInfluence.cpp b/src/osgAnimation/VertexInfluence.cpp index 69941853d..1f77be6aa 100644 --- a/src/osgAnimation/VertexInfluence.cpp +++ b/src/osgAnimation/VertexInfluence.cpp @@ -25,7 +25,7 @@ using namespace osgAnimation; struct invweight_ordered { - inline bool operator() (const BoneWeight& bw1, const BoneWeight& bw2) + inline bool operator() (const BoneWeight& bw1, const BoneWeight& bw2) const { if (bw1.second > bw2.second)return true; if (bw1.second < bw2.second)return false; From 4f2328bc099e8d9ad6a1e4e3170b176f2209d29e Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Mon, 30 Oct 2017 14:36:41 +0000 Subject: [PATCH 187/327] From Raymond de Vires, added support for 2018 and 2016 versions of FBX. --- CMakeModules/FindFBX.cmake | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CMakeModules/FindFBX.cmake b/CMakeModules/FindFBX.cmake index ab0a2c2d8..b2f2ac1cb 100644 --- a/CMakeModules/FindFBX.cmake +++ b/CMakeModules/FindFBX.cmake @@ -60,9 +60,13 @@ SET(FBX_LIBNAME_DEBUG ${FBX_LIBNAME}d) SET( FBX_SEARCH_PATHS $ENV{FBX_DIR} + "$ENV{ProgramW6432}/Autodesk/FBX/FBX SDK/2018.1.1" + "$ENV{PROGRAMFILES}/Autodesk/FBX/FBX SDK/2018.1.1" "$ENV{ProgramW6432}/Autodesk/FBX/FBX SDK/2017.1" "$ENV{PROGRAMFILES}/Autodesk/FBX/FBX SDK/2017.1" "/Applications/Autodesk/FBX SDK/2017.1" + "$ENV{ProgramW6432}/Autodesk/FBX/FBX SDK/2016.1.2" + "$ENV{PROGRAMFILES}/Autodesk/FBX/FBX SDK/2016.1.2" "$ENV{ProgramW6432}/Autodesk/FBX/FBX SDK/2016.1.1" "$ENV{PROGRAMFILES}/Autodesk/FBX/FBX SDK/2016.1.1" "$ENV{ProgramW6432}/Autodesk/FBX/FBX SDK/2015.1" From e196b2372362e40f7efde5447a3cc0430599b23e Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Mon, 30 Oct 2017 14:36:41 +0000 Subject: [PATCH 188/327] From Raymond de Vires, added support for 2018 and 2016 versions of FBX. --- CMakeModules/FindFBX.cmake | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CMakeModules/FindFBX.cmake b/CMakeModules/FindFBX.cmake index ab0a2c2d8..b2f2ac1cb 100644 --- a/CMakeModules/FindFBX.cmake +++ b/CMakeModules/FindFBX.cmake @@ -60,9 +60,13 @@ SET(FBX_LIBNAME_DEBUG ${FBX_LIBNAME}d) SET( FBX_SEARCH_PATHS $ENV{FBX_DIR} + "$ENV{ProgramW6432}/Autodesk/FBX/FBX SDK/2018.1.1" + "$ENV{PROGRAMFILES}/Autodesk/FBX/FBX SDK/2018.1.1" "$ENV{ProgramW6432}/Autodesk/FBX/FBX SDK/2017.1" "$ENV{PROGRAMFILES}/Autodesk/FBX/FBX SDK/2017.1" "/Applications/Autodesk/FBX SDK/2017.1" + "$ENV{ProgramW6432}/Autodesk/FBX/FBX SDK/2016.1.2" + "$ENV{PROGRAMFILES}/Autodesk/FBX/FBX SDK/2016.1.2" "$ENV{ProgramW6432}/Autodesk/FBX/FBX SDK/2016.1.1" "$ENV{PROGRAMFILES}/Autodesk/FBX/FBX SDK/2016.1.1" "$ENV{ProgramW6432}/Autodesk/FBX/FBX SDK/2015.1" From 17380a719132de50a08f0bb8ed1adfcb9df18e1b Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Tue, 31 Oct 2017 10:01:52 +0000 Subject: [PATCH 189/327] Simplified build for OSX now that trais builds are running faster. --- .travis.yml | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/.travis.yml b/.travis.yml index 27f0fc6f0..cd75a2587 100644 --- a/.travis.yml +++ b/.travis.yml @@ -15,8 +15,8 @@ matrix: dist: trusty language: cpp env: - # - CMAKECMD_ARGS="-DBUILD_OSG_EXAMPLES=ON -DBUILD_OSG_PLUGINS_BY_DEFAULT=ON -DBUILD_OSG_APPLICATIONS=ON" - - CMAKECMD_ARGS="-DBUILD_OSG_EXAMPLES=OFF -DBUILD_OSG_PLUGINS_BY_DEFAULT=ON -DBUILD_OSG_APPLICATIONS=ON" + - CMAKECMD_ARGS="-DBUILD_OSG_EXAMPLES=ON -DBUILD_OSG_PLUGINS_BY_DEFAULT=ON -DBUILD_OSG_APPLICATIONS=ON" + # - CMAKECMD_ARGS="-DBUILD_OSG_EXAMPLES=OFF -DBUILD_OSG_PLUGINS_BY_DEFAULT=ON -DBUILD_OSG_APPLICATIONS=ON" #- LLVM_VERSION=3.8 sudo: false cache: @@ -51,15 +51,16 @@ matrix: - brew install ccache - export PATH="/usr/local/opt/ccache/libexec:$PATH" env: - - CMAKECMD_ARGS="-DBUILD_OSG_EXAMPLES=OFF -DBUILD_OSG_PLUGINS_BY_DEFAULT=ON -DBUILD_OSG_APPLICATIONS=ON" - - os: osx - before_install: - - brew update - install: - - brew install ccache - - export PATH="/usr/local/opt/ccache/libexec:$PATH" - env: - - CMAKECMD_ARGS="-DBUILD_OSG_EXAMPLES=ON -DBUILD_OSG_PLUGINS_BY_DEFAULT=OFF -DBUILD_OSG_APPLICATIONS=OFF" +# - CMAKECMD_ARGS="-DBUILD_OSG_EXAMPLES=OFF -DBUILD_OSG_PLUGINS_BY_DEFAULT=ON -DBUILD_OSG_APPLICATIONS=ON" + - CMAKECMD_ARGS="-DBUILD_OSG_EXAMPLES=ON -DBUILD_OSG_PLUGINS_BY_DEFAULT=ON -DBUILD_OSG_APPLICATIONS=ON" +# - os: osx +# before_install: +# - brew update +# install: +# - brew install ccache +# - export PATH="/usr/local/opt/ccache/libexec:$PATH" +# env: +# - CMAKECMD_ARGS="-DBUILD_OSG_EXAMPLES=ON -DBUILD_OSG_PLUGINS_BY_DEFAULT=OFF -DBUILD_OSG_APPLICATIONS=OFF" # script: # - mkdir build From 89708ae2770a8dbde9627bc59e6e9e883e7f7bb4 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Tue, 31 Oct 2017 12:32:45 +0000 Subject: [PATCH 190/327] Upped the number of threads used in build to try and improve build speed --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index cd75a2587..aeb202144 100644 --- a/.travis.yml +++ b/.travis.yml @@ -32,7 +32,7 @@ matrix: description: "OpenSceneGraph build" notification_email: robert@openscenegraph.com build_command_prepend: "cmake -DCMAKE_BUILD_TYPE=Release -DBUILD_OSG_DEPRECATED_SERIALIZERS=OFF ." - build_command: "make -j 3" + build_command: "make -j 4" branch_pattern: coverity_scan apt: sources: @@ -70,4 +70,4 @@ matrix: script: - if [ "${COVERITY_SCAN_BRANCH}" != 1 ]; then mkdir build && cd build && travis_wait 60 cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=../product $CMAKECMD_ARGS ../ ; fi - - if [ -f CMakeCache.txt ]; then make -j3 ; fi + - if [ -f CMakeCache.txt ]; then make -j4 ; fi From 6a8fe4554317f8773765b595874f2f861f9e3b42 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Tue, 31 Oct 2017 14:55:41 +0000 Subject: [PATCH 191/327] Reinstated two stage OSX build, and disabled part of the coverity_scan build to attempt to get it running without timeout. --- .travis.yml | 26 ++++++++++---------------- 1 file changed, 10 insertions(+), 16 deletions(-) diff --git a/.travis.yml b/.travis.yml index aeb202144..db9085fe4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -31,7 +31,7 @@ matrix: name: "openscenegraph/OpenSceneGraph" description: "OpenSceneGraph build" notification_email: robert@openscenegraph.com - build_command_prepend: "cmake -DCMAKE_BUILD_TYPE=Release -DBUILD_OSG_DEPRECATED_SERIALIZERS=OFF ." + build_command_prepend: "cmake -DCMAKE_BUILD_TYPE=Release -DBUILD_OSG_DEPRECATED_SERIALIZERS=OFF -DBUILD_OSG_EXAMPLES=OFF ." build_command: "make -j 4" branch_pattern: coverity_scan apt: @@ -51,22 +51,16 @@ matrix: - brew install ccache - export PATH="/usr/local/opt/ccache/libexec:$PATH" env: -# - CMAKECMD_ARGS="-DBUILD_OSG_EXAMPLES=OFF -DBUILD_OSG_PLUGINS_BY_DEFAULT=ON -DBUILD_OSG_APPLICATIONS=ON" - - CMAKECMD_ARGS="-DBUILD_OSG_EXAMPLES=ON -DBUILD_OSG_PLUGINS_BY_DEFAULT=ON -DBUILD_OSG_APPLICATIONS=ON" -# - os: osx -# before_install: -# - brew update -# install: -# - brew install ccache -# - export PATH="/usr/local/opt/ccache/libexec:$PATH" -# env: -# - CMAKECMD_ARGS="-DBUILD_OSG_EXAMPLES=ON -DBUILD_OSG_PLUGINS_BY_DEFAULT=OFF -DBUILD_OSG_APPLICATIONS=OFF" + - CMAKECMD_ARGS="-DBUILD_OSG_EXAMPLES=OFF -DBUILD_OSG_PLUGINS_BY_DEFAULT=ON -DBUILD_OSG_APPLICATIONS=ON" -# script: -# - mkdir build -# - cd build -# - travis_wait 60 cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=../product -DBUILD_OSG_EXAMPLES=ON .. -# - make install -j 3 + - os: osx + before_install: + - brew update + install: + - brew install ccache + - export PATH="/usr/local/opt/ccache/libexec:$PATH" + env: + - CMAKECMD_ARGS="-DBUILD_OSG_EXAMPLES=ON -DBUILD_OSG_PLUGINS_BY_DEFAULT=OFF -DBUILD_OSG_APPLICATIONS=OFF -DBUILD_OSG_DEPRECATED_SERIALIZERS=OFF" script: - if [ "${COVERITY_SCAN_BRANCH}" != 1 ]; then mkdir build && cd build && travis_wait 60 cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=../product $CMAKECMD_ARGS ../ ; fi From 42c7d7ece1f8c076378d45260a0a137bdfa5ffdd Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Tue, 31 Oct 2017 15:47:49 +0000 Subject: [PATCH 192/327] Fixed Coverity reported memory leak --- src/osgPlugins/ply/vertexData.cpp | 42 ++++++------------------------- 1 file changed, 8 insertions(+), 34 deletions(-) diff --git a/src/osgPlugins/ply/vertexData.cpp b/src/osgPlugins/ply/vertexData.cpp index faeca766b..d3f396025 100644 --- a/src/osgPlugins/ply/vertexData.cpp +++ b/src/osgPlugins/ply/vertexData.cpp @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -311,7 +312,8 @@ osg::Node* VertexData::readPlyFile( const char* filename, const bool ignoreColor MESHINFO << filename << ": " << nPlyElems << " elements, file type = " << fileType << ", version = " << version << endl; #endif - char *textureFile = NULL; + + std::string textureFile; for( int i = 0; i < nComments; i++ ) { if( equal_strings( comments[i], "modified by flipply" ) ) @@ -321,38 +323,11 @@ osg::Node* VertexData::readPlyFile( const char* filename, const bool ignoreColor if (strncmp(comments[i], "TextureFile",11)==0) { textureFile = comments[i]+12; - char * path = new char[strlen(const_cast(filename)) + 1 + strlen(comments[i])]; - if (textureFile[0] == '\\' || textureFile[0] == '/' || textureFile[1] == ':') + if (!osgDB::isAbsolutePath(textureFile)) { - // texture filename is absolute - strcpy(path, textureFile); + textureFile = osgDB::concatPaths(osgDB::getFilePath(filename), textureFile); } - else - { - // texture filename is relative - // add directory of ply file - strcpy(path, const_cast(filename)); - char *pp = path + strlen(path); - while (pp >= path) - { - if (*pp == '\\' || *pp == '/') - { - pp++; - *pp = '\0'; - break; - } - pp--; - } - if (pp == path - 1) - { - pp++; - *pp = '\0'; - } - strcat(path, textureFile); - } - textureFile = path; } - } for( int i = 0; i < nPlyElems; ++i ) { @@ -563,11 +538,11 @@ osg::Node* VertexData::readPlyFile( const char* filename, const bool ignoreColor // set flage true to activate the vertex buffer object of drawable geom->setUseVertexBufferObjects(true); - osg::Image *image = NULL; - if (textureFile && (image = osgDB::readImageFile(textureFile)) != NULL) + osg::ref_ptr image; + if (!textureFile.empty() && (image = osgDB::readRefImageFile(textureFile)) != NULL) { osg::Texture2D *texture = new osg::Texture2D; - texture->setImage(image); + texture->setImage(image.get()); texture->setResizeNonPowerOfTwoHint(false); osg::TexEnv *texenv = new osg::TexEnv; @@ -576,7 +551,6 @@ osg::Node* VertexData::readPlyFile( const char* filename, const bool ignoreColor osg::StateSet *stateset = geom->getOrCreateStateSet(); stateset->setTextureAttributeAndModes(0, texture, osg::StateAttribute::ON); stateset->setTextureAttribute(0, texenv); - delete[] textureFile; } osg::Geode* geode = new osg::Geode; From 3459e8f4fd5d21594d3684dc432f7422f94c3e8e Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Tue, 31 Oct 2017 15:55:24 +0000 Subject: [PATCH 193/327] Fixed Coverity Scan reported memory leaks --- src/osgPlugins/tga/ReaderWriterTGA.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/osgPlugins/tga/ReaderWriterTGA.cpp b/src/osgPlugins/tga/ReaderWriterTGA.cpp index b1e3ad6a4..256beb603 100644 --- a/src/osgPlugins/tga/ReaderWriterTGA.cpp +++ b/src/osgPlugins/tga/ReaderWriterTGA.cpp @@ -360,8 +360,14 @@ int *numComponents_ret) { case 1: /* colormap, uncompressed */ { - if (colormapLen == 0 || indexsize == 0) { + if (colormapLen == 0 || indexsize == 0) + { tgaerror = ERR_UNSUPPORTED; /* colormap missing or empty */ + + if (colormap) delete [] colormap; + delete [] buffer; + delete [] linebuf; + return NULL; } unsigned char * formattedMap = new unsigned char[colormapLen * format]; From 95eb5e2ad6f5c15154093a50910da262deaf61b3 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Tue, 31 Oct 2017 16:46:42 +0000 Subject: [PATCH 194/327] Replace c char array with std::string to address Coverity scan reported issue --- src/osgPlugins/stl/ReaderWriterSTL.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/osgPlugins/stl/ReaderWriterSTL.cpp b/src/osgPlugins/stl/ReaderWriterSTL.cpp index b9697f1de..9e23d1b00 100644 --- a/src/osgPlugins/stl/ReaderWriterSTL.cpp +++ b/src/osgPlugins/stl/ReaderWriterSTL.cpp @@ -400,12 +400,12 @@ const float StlColorDepth = float(StlColorSize); // 2^5 - 1 // Magics files have a header with a "COLOR=" field giving the color of the whole model bool fileComesFromMagics(FILE *fp, osg::Vec4& magicsColor) { - char header[80]; + std::string header(80, 0); const float magicsColorDepth = 255.f; ::rewind(fp); - if (fread((void*) &header, sizeof(header), 1, fp) != 1) + if (fread((void*) &(*header.begin()), header.size(), 1, fp) != 1) return false; if (::fseek(fp, sizeof_StlHeader, SEEK_SET)!=0) @@ -414,8 +414,7 @@ bool fileComesFromMagics(FILE *fp, osg::Vec4& magicsColor) } std::string magicsColorPattern ("COLOR="); - std::string headerStr = std::string(header); - if(size_t colorFieldPos = headerStr.find(magicsColorPattern) != std::string::npos) + if(size_t colorFieldPos = header.find(magicsColorPattern) != std::string::npos) { int colorIndex = colorFieldPos + magicsColorPattern.size() - 1; float r = (uint8_t)header[colorIndex] / magicsColorDepth; From 47c4ef510d02ddbee4b78a0023ec31b6f215efc5 Mon Sep 17 00:00:00 2001 From: Julien Valentin Date: Tue, 31 Oct 2017 18:00:06 +0100 Subject: [PATCH 195/327] update example to use a common program --- .../osganimationhardware.cpp | 122 +++++++----------- 1 file changed, 47 insertions(+), 75 deletions(-) diff --git a/examples/osganimationhardware/osganimationhardware.cpp b/examples/osganimationhardware/osganimationhardware.cpp index 03735b2da..a377bbd4d 100644 --- a/examples/osganimationhardware/osganimationhardware.cpp +++ b/examples/osganimationhardware/osganimationhardware.cpp @@ -42,27 +42,22 @@ static unsigned int getRandomValueinRange(unsigned int v) } -//osg::ref_ptr program; +osg::ref_ptr CommonProgram; // show how to override the default RigTransformHardware for customized usage struct MyRigTransformHardware : public osgAnimation::RigTransformHardware { - + int _maxmatrix; + MyRigTransformHardware() : _maxmatrix(99){} virtual bool init(osgAnimation::RigGeometry& rig) { - if(!rig.getSkeleton() && !rig.getParents().empty()) + if(_perVertexInfluences.empty()) { - osgAnimation::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()); + prepareData(rig); + return false; } + if(!rig.getSkeleton()) + return false; + osgAnimation::BoneMapVisitor mapVisitor; rig.getSkeleton()->accept(mapVisitor); osgAnimation::BoneMap boneMap = mapVisitor.getBoneMap(); @@ -72,6 +67,7 @@ struct MyRigTransformHardware : public osgAnimation::RigTransformHardware 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; @@ -81,86 +77,62 @@ struct MyRigTransformHardware : public osgAnimation::RigTransformHardware // copy shallow from source geometry to rig rig.copyFrom(source); - osg::ref_ptr program ; osg::ref_ptr vertexshader; osg::ref_ptr stateset = rig.getOrCreateStateSet(); + if(!CommonProgram.valid()){ + CommonProgram = new osg::Program; + CommonProgram->setName("HardwareSkinning"); - //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) + //set default source if _shader is not user setted + if (!vertexshader.valid()) + { + vertexshader = osg::Shader::readShaderFile(osg::Shader::VERTEX,"skinning.vert"); + } + + 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) { - vertexshader=program->getShader(i); - program->removeShader(vertexshader); - + std::stringstream ss; + ss << _maxmatrix;//getMatrixPaletteUniform()->getNumElements(); + str.replace(start, toreplace.size(), ss.str()); + vertexshader->setShaderSource(str); } - } - 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,"shaders/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; } - else - { - OSG_INFO<< "MAX_MATRIX not found in Shader! " << str << std::endl; - } - OSG_INFO << "Shader " << str << std::endl; + CommonProgram->addShader(vertexshader.get()); } - - unsigned int attribIndex = 11; unsigned int nbAttribs = getNumVertexAttrib(); - if(nbAttribs==0) - OSG_WARN << "nbAttribs== " << nbAttribs << std::endl; for (unsigned int i = 0; i < nbAttribs; i++) { std::stringstream ss; ss << "boneWeight" << i; - program->addBindAttribLocation(ss.str(), attribIndex + i); - - if(getVertexAttrib(i)->getNumElements()!=_nbVertices) - OSG_WARN << "getVertexAttrib== " << getVertexAttrib(i)->getNumElements() << std::endl; - rig.setVertexAttribArray(attribIndex + i, getVertexAttrib(i)); + CommonProgram->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(getMatrixPaletteUniform()); - stateset->removeAttribute(osg::StateAttribute::PROGRAM); - if(!stateset->getAttribute(osg::StateAttribute::PROGRAM)) - stateset->setAttributeAndModes(program.get()); + stateset->removeUniform("matrixPalette"); + stateset->addUniform(_uniformMatrixPalette); + + stateset->setAttribute(CommonProgram.get()); _needInit = false; return true; From 061e52b89fb33d34ee1b6ad9648875cbb8338c79 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Tue, 31 Oct 2017 17:02:31 +0000 Subject: [PATCH 196/327] Fixed Coverity Scan reported issue --- src/osgPlugins/md2/ReaderWriterMD2.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/osgPlugins/md2/ReaderWriterMD2.cpp b/src/osgPlugins/md2/ReaderWriterMD2.cpp index dd9d6bf73..c10399520 100644 --- a/src/osgPlugins/md2/ReaderWriterMD2.cpp +++ b/src/osgPlugins/md2/ReaderWriterMD2.cpp @@ -165,7 +165,8 @@ load_md2 (const char *filename, const osgDB::ReaderWriter::Options* options) return NULL; } - mapbase = malloc (st.st_size); + mapbase = malloc (st.st_size+1); + memset(mapbase, 0, st.st_size+1); if (!mapbase) { close (file_fd); From 14f50ab31ce0f2332803ff747533a7e47f7a58d9 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Tue, 31 Oct 2017 17:39:34 +0000 Subject: [PATCH 197/327] Fixed CovertiScan reported uninitialized member variable --- src/osgText/Glyph.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/osgText/Glyph.cpp b/src/osgText/Glyph.cpp index 7c1dba18a..ed8c7120b 100644 --- a/src/osgText/Glyph.cpp +++ b/src/osgText/Glyph.cpp @@ -56,6 +56,7 @@ using namespace std; // GlyphTexture // GlyphTexture::GlyphTexture(): + _shaderTechnique(GREYSCALE), _usedY(0), _partUsedX(0), _partUsedY(0) From 6a2bd1f898cbcb5959af1d6d17df13e961d591cd Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Tue, 31 Oct 2017 17:43:39 +0000 Subject: [PATCH 198/327] Added missing initializers --- src/osg/GLExtensions.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/osg/GLExtensions.cpp b/src/osg/GLExtensions.cpp index ac57e8b2f..77984a202 100644 --- a/src/osg/GLExtensions.cpp +++ b/src/osg/GLExtensions.cpp @@ -946,6 +946,10 @@ GLExtensions::GLExtensions(unsigned int in_contextID): setGLExtensionFuncPtr(glTexSubImage3D, "glTexSubImage3D","glTexSubImage3DEXT", validContext); setGLExtensionFuncPtr(glCompressedTexImage3D, "glCompressedTexImage3D","glCompressedTexImage3DARB", validContext); setGLExtensionFuncPtr(glCompressedTexSubImage3D, "glCompressedTexSubImage3D","glCompressedTexSubImage3DARB", validContext); + + setGLExtensionFuncPtr(glTexImage3DMultisample, "glTexImage3DMultisample", validContext); + setGLExtensionFuncPtr(glGetMultisamplefv, "glGetMultisamplefv", validContext); + setGLExtensionFuncPtr(glCopyTexSubImage3D, "glCopyTexSubImage3D","glCopyTexSubImage3DEXT", validContext); setGLExtensionFuncPtr(glBeginConditionalRender, "glBeginConditionalRender", "glBeginConditionalRenderARB"); setGLExtensionFuncPtr(glEndConditionalRender, "glEndConditionalRender", "glEndConditionalRenderARB"); From c242ad4497fe334e20f4b13a344677a63adabee2 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Tue, 31 Oct 2017 17:55:59 +0000 Subject: [PATCH 199/327] Fixed unititialized memory variables and improved readability by adding spacing where appropriate --- include/osg/PrimitiveSetIndirect | 119 +++++++++++++++++++++++-------- 1 file changed, 91 insertions(+), 28 deletions(-) diff --git a/include/osg/PrimitiveSetIndirect b/include/osg/PrimitiveSetIndirect index 8ede4471c..bd724dab0 100644 --- a/include/osg/PrimitiveSetIndirect +++ b/include/osg/PrimitiveSetIndirect @@ -415,31 +415,48 @@ class OSG_EXPORT MultiDrawElementsIndirectUShort : public DrawElementsIndirectUS { public: MultiDrawElementsIndirectUShort(GLenum mode = 0/*,unsigned int firstCommand = 0, GLsizei stride = 0*/) : - DrawElementsIndirectUShort(mode),_count(0) { _primitiveType=(Type(MultiDrawElementsUShortIndirectPrimitiveType)); } + DrawElementsIndirectUShort(mode), + _count(0) + { + _primitiveType=(Type(MultiDrawElementsUShortIndirectPrimitiveType)); + } MultiDrawElementsIndirectUShort(const MultiDrawElementsIndirectUShort& mdi,const CopyOp& copyop=CopyOp::SHALLOW_COPY) : - DrawElementsIndirectUShort(mdi,copyop),_count(mdi._count) {} + DrawElementsIndirectUShort(mdi,copyop), + _count(mdi._count) + { + } + /** * \param mode One of osg::PrimitiveSet::Mode. Determines the type of primitives used. * \param no Number of intended elements. This will be the size of the underlying vector. * \param ptr Pointer to a GLunsigned int to copy index data from. */ MultiDrawElementsIndirectUShort(GLenum mode, unsigned int no, const GLushort* ptr) : - DrawElementsIndirectUShort(mode,no,ptr) - {_primitiveType=(Type(MultiDrawElementsUShortIndirectPrimitiveType));} + DrawElementsIndirectUShort(mode,no,ptr), + _count(0) + { + _primitiveType=(Type(MultiDrawElementsUShortIndirectPrimitiveType)); + } /** * \param mode One of osg::PrimitiveSet::Mode. Determines the type of primitives used. * \param no Number of intended elements. This will be the size of the underlying vector. */ MultiDrawElementsIndirectUShort(GLenum mode, unsigned int no) : - DrawElementsIndirectUShort(mode,no) - {_primitiveType=(Type(MultiDrawElementsUShortIndirectPrimitiveType));} + DrawElementsIndirectUShort(mode,no), + _count(0) + { + _primitiveType=(Type(MultiDrawElementsUShortIndirectPrimitiveType)); + } template MultiDrawElementsIndirectUShort(GLenum mode, InputIterator first,InputIterator last) : - DrawElementsIndirectUShort(mode,first,last) - {_primitiveType=(Type(MultiDrawElementsUShortIndirectPrimitiveType));} + DrawElementsIndirectUShort(mode,first,last), + _count(0) + { + _primitiveType=(Type(MultiDrawElementsUShortIndirectPrimitiveType)); + } virtual osg::Object* cloneType() const { return new MultiDrawElementsIndirectUShort(); } virtual osg::Object* clone(const osg::CopyOp& copyop) const { return new MultiDrawElementsIndirectUShort(*this,copyop); } @@ -467,31 +484,49 @@ class OSG_EXPORT MultiDrawElementsIndirectUByte : public DrawElementsIndirectUBy { public: MultiDrawElementsIndirectUByte(GLenum mode = 0) : - DrawElementsIndirectUByte(mode),_count(0) { _primitiveType=(Type(MultiDrawElementsUByteIndirectPrimitiveType)); } + DrawElementsIndirectUByte(mode), + _count(0) + { + _primitiveType=(Type(MultiDrawElementsUByteIndirectPrimitiveType)); + + } MultiDrawElementsIndirectUByte(const MultiDrawElementsIndirectUByte& mdi,const CopyOp& copyop=CopyOp::SHALLOW_COPY) : - DrawElementsIndirectUByte(mdi,copyop),_count(mdi._count) {} + DrawElementsIndirectUByte(mdi,copyop), + _count(mdi._count) + { + } + /** * \param mode One of osg::PrimitiveSet::Mode. Determines the type of primitives used. * \param no Number of intended elements. This will be the size of the underlying vector. * \param ptr Pointer to a GLunsigned int to copy index data from. */ MultiDrawElementsIndirectUByte(GLenum mode, unsigned int no, const GLubyte* ptr) : - DrawElementsIndirectUByte(mode,no,ptr) - {_primitiveType=(Type(MultiDrawElementsUByteIndirectPrimitiveType));} + DrawElementsIndirectUByte(mode,no,ptr), + _count(0) + { + _primitiveType=(Type(MultiDrawElementsUByteIndirectPrimitiveType)); + } /** * \param mode One of osg::PrimitiveSet::Mode. Determines the type of primitives used. * \param no Number of intended elements. This will be the size of the underlying vector. */ MultiDrawElementsIndirectUByte(GLenum mode, unsigned int no) : - DrawElementsIndirectUByte(mode,no) - {_primitiveType=(Type(MultiDrawElementsUByteIndirectPrimitiveType));} + DrawElementsIndirectUByte(mode,no), + _count(0) + { + _primitiveType=(Type(MultiDrawElementsUByteIndirectPrimitiveType)); + } template MultiDrawElementsIndirectUByte(GLenum mode, InputIterator first,InputIterator last) : - DrawElementsIndirectUByte(mode,first,last) - {_primitiveType=(Type(MultiDrawElementsUByteIndirectPrimitiveType));} + DrawElementsIndirectUByte(mode,first,last), + _count(0) + { + _primitiveType=(Type(MultiDrawElementsUByteIndirectPrimitiveType)); + } virtual osg::Object* cloneType() const { return new MultiDrawElementsIndirectUByte(); } virtual osg::Object* clone(const osg::CopyOp& copyop) const { return new MultiDrawElementsIndirectUByte(*this,copyop); } @@ -517,31 +552,47 @@ class OSG_EXPORT MultiDrawElementsIndirectUInt : public DrawElementsIndirectUInt { public: MultiDrawElementsIndirectUInt(GLenum mode = 0) : - DrawElementsIndirectUInt(mode),_count(0) { _primitiveType=(Type(MultiDrawElementsUIntIndirectPrimitiveType)); } + DrawElementsIndirectUInt(mode), + _count(0) + { + _primitiveType=(Type(MultiDrawElementsUIntIndirectPrimitiveType)); + } MultiDrawElementsIndirectUInt(const MultiDrawElementsIndirectUInt& mdi,const CopyOp& copyop=CopyOp::SHALLOW_COPY) : - DrawElementsIndirectUInt(mdi,copyop),_count(mdi._count) {} + DrawElementsIndirectUInt(mdi,copyop), + _count(mdi._count) + {} + /** * \param mode One of osg::PrimitiveSet::Mode. Determines the type of primitives used. * \param no Number of intended elements. This will be the size of the underlying vector. * \param ptr Pointer to a GLunsigned int to copy index data from. */ MultiDrawElementsIndirectUInt(GLenum mode, unsigned int no, const GLuint* ptr) : - DrawElementsIndirectUInt(mode,no,ptr) - {_primitiveType=(Type(MultiDrawElementsUIntIndirectPrimitiveType));} + DrawElementsIndirectUInt(mode,no,ptr), + _count(0) + { + _primitiveType=(Type(MultiDrawElementsUIntIndirectPrimitiveType)); + } /** * \param mode One of osg::PrimitiveSet::Mode. Determines the type of primitives used. * \param no Number of intended elements. This will be the size of the underlying vector. */ MultiDrawElementsIndirectUInt(GLenum mode, unsigned int no) : - DrawElementsIndirectUInt(mode,no) - {_primitiveType=(Type(MultiDrawElementsUIntIndirectPrimitiveType));} + DrawElementsIndirectUInt(mode,no), + _count(0) + { + _primitiveType=(Type(MultiDrawElementsUIntIndirectPrimitiveType)); + } template MultiDrawElementsIndirectUInt(GLenum mode, InputIterator first,InputIterator last) : - DrawElementsIndirectUInt(mode,first,last) - {_primitiveType=(Type(MultiDrawElementsUIntIndirectPrimitiveType));} + DrawElementsIndirectUInt(mode,first,last), + _count(0) + { + _primitiveType=(Type(MultiDrawElementsUIntIndirectPrimitiveType)); + } virtual osg::Object* cloneType() const { return new MultiDrawElementsIndirectUInt(); } virtual osg::Object* clone(const osg::CopyOp& copyop) const { return new MultiDrawElementsIndirectUInt(*this,copyop); } @@ -572,13 +623,19 @@ public: DrawArraysIndirect(GLenum mode=0, unsigned int firstcommand = 0, GLsizei stride = 0) : osg::PrimitiveSet(Type(DrawArraysIndirectPrimitiveType), mode), - _firstCommand(firstcommand), _stride(stride) { setIndirectCommandArray(new DefaultIndirectCommandDrawArrays); } + _firstCommand(firstcommand), + _stride(stride) + { + setIndirectCommandArray(new DefaultIndirectCommandDrawArrays); + } DrawArraysIndirect(const DrawArraysIndirect& dal,const CopyOp& copyop=CopyOp::SHALLOW_COPY) : osg::PrimitiveSet(dal,copyop), _firstCommand(dal._firstCommand), _stride(dal._stride), - _indirectCommandArray((DefaultIndirectCommandDrawArrays*)copyop( dal._indirectCommandArray.get())) {} + _indirectCommandArray((DefaultIndirectCommandDrawArrays*)copyop( dal._indirectCommandArray.get())) + { + } virtual osg::Object* cloneType() const { return new DrawArraysIndirect(); } virtual osg::Object* clone(const osg::CopyOp& copyop) const { return new DrawArraysIndirect(*this,copyop); } @@ -635,10 +692,16 @@ class OSG_EXPORT MultiDrawArraysIndirect : public DrawArraysIndirect public: MultiDrawArraysIndirect(GLenum mode=0, unsigned int firstcommand = 0, unsigned int count = 0, GLsizei stride = 0) : - osg::DrawArraysIndirect(mode, firstcommand, stride), _count(count) { _primitiveType=Type(MultiDrawArraysIndirectPrimitiveType); } + osg::DrawArraysIndirect(mode, firstcommand, stride), + _count(count) + { + _primitiveType=Type(MultiDrawArraysIndirectPrimitiveType); + } MultiDrawArraysIndirect(const MultiDrawArraysIndirect& dal,const CopyOp& copyop=CopyOp::SHALLOW_COPY) : - osg::DrawArraysIndirect(dal,copyop), _count(dal._count) {} + osg::DrawArraysIndirect(dal,copyop), + _count(dal._count) + {} virtual osg::Object* cloneType() const { return new MultiDrawArraysIndirect(); } virtual osg::Object* clone(const osg::CopyOp& copyop) const { return new MultiDrawArraysIndirect(*this,copyop); } From fb175eed14876b36571202b96456477471190a5d Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 1 Nov 2017 11:35:05 +0000 Subject: [PATCH 200/327] Fixed Coverity Scane reported issue. --- src/osgPlugins/3ds/ReaderWriter3DS.cpp | 23 +++++++++++++++-------- src/osgPlugins/3ds/lib3ds/lib3ds_mesh.c | 10 ++++++++++ 2 files changed, 25 insertions(+), 8 deletions(-) diff --git a/src/osgPlugins/3ds/ReaderWriter3DS.cpp b/src/osgPlugins/3ds/ReaderWriter3DS.cpp index 3c1d89c20..aeae272ad 100644 --- a/src/osgPlugins/3ds/ReaderWriter3DS.cpp +++ b/src/osgPlugins/3ds/ReaderWriter3DS.cpp @@ -436,7 +436,7 @@ void ReaderWriter3DS::ReaderObject::addDrawableFromFace(osg::Geode * geode, Face // Transforms points by matrix if 'matrix' is not NULL // Creates a Geode and Geometry (as parent,child) and adds the Geode to 'parent' parameter iff 'parent' is non-NULL // Returns ptr to the Geode -osg::Node* ReaderWriter3DS::ReaderObject::processMesh(StateSetMap& drawStateMap,osg::Group* parent,Lib3dsMesh* mesh, const osg::Matrix * matrix) +osg::Node* ReaderWriter3DS::ReaderObject::processMesh(StateSetMap& drawStateMap, osg::Group* parent, Lib3dsMesh* mesh, const osg::Matrix * matrix) { typedef std::vector MaterialFaceMap; MaterialFaceMap materialFaceMap; @@ -605,13 +605,17 @@ osg::Node* ReaderWriter3DS::ReaderObject::processNode(StateSetMap& drawStateMap, // if noMatrixTransforms is not set, we create a transform node for the mesh's matrix osg::Group* meshTransform=NULL; - if ((noMatrixTransforms==false) && meshAppliedMatPtr) { // we are allowed to have, and need another matrixtransform + if ((noMatrixTransforms==false) && meshAppliedMatPtr) + { + // we are allowed to have, and need another matrixtransform meshTransform=new osg::MatrixTransform(meshMat); meshAppliedMatPtr=NULL; // since meshTransform applies it meshTransform->setName("3DSMeshMatrix"); if (group) group->addChild(meshTransform); - } else { + } + else + { meshTransform=group; // don't need the meshTransform node - note group can be NULL } @@ -619,18 +623,21 @@ osg::Node* ReaderWriter3DS::ReaderObject::processNode(StateSetMap& drawStateMap, { // add our geometry to group (where our children already are) // creates geometry under modifier node - processMesh(drawStateMap,meshTransform,mesh,meshAppliedMatPtr); + processMesh(drawStateMap, meshTransform, mesh, meshAppliedMatPtr); return group; } else { // didn't use group for children, return a ptr directly to the Geode for this mesh // there is no group node but may have a meshTransform node to hold the meshes matrix - if (meshTransform) { - processMesh(drawStateMap,meshTransform,mesh,meshAppliedMatPtr); + if (meshTransform) + { + processMesh(drawStateMap, meshTransform, mesh, meshAppliedMatPtr); return meshTransform; - } else { // no group or meshTransform nodes - create a new Geode and return that - return processMesh(drawStateMap,NULL,mesh,meshAppliedMatPtr); + } + else + { // no group or meshTransform nodes - create a new Geode and return that + return processMesh(drawStateMap, NULL, mesh, meshAppliedMatPtr); } } diff --git a/src/osgPlugins/3ds/lib3ds/lib3ds_mesh.c b/src/osgPlugins/3ds/lib3ds/lib3ds_mesh.c index 99f340003..e4c9775a6 100644 --- a/src/osgPlugins/3ds/lib3ds/lib3ds_mesh.c +++ b/src/osgPlugins/3ds/lib3ds/lib3ds_mesh.c @@ -170,7 +170,17 @@ lib3ds_mesh_calculate_vertex_normals(Lib3dsMesh *mesh, float (*normals)[3]) { } fl = (Lib3dsFaces**)calloc(sizeof(Lib3dsFaces*), mesh->nvertices); + if (!fl) + { + return; + } + fa = (Lib3dsFaces*)malloc(sizeof(Lib3dsFaces) * 3 * mesh->nfaces); + if (!fa) + { + free(fl); + return; + } for (i = 0; i < mesh->nfaces; ++i) { for (j = 0; j < 3; ++j) { From 51a9c66856971cce660baa87ac80c5c9505693f6 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 1 Nov 2017 13:32:47 +0000 Subject: [PATCH 201/327] Added OSG_ENVVAR_SUPPORTED cmake control and bool osg::getEnvVar(const char* name, T& value, ...) conviniece funcions to make it easier to implement optinal getenv reading code. --- CMakeLists.txt | 4 ++ include/osg/EnvVar | 101 +++++++++++++++++++++++++++++++++++++++++++++ src/osg/Config.in | 1 + 3 files changed, 106 insertions(+) create mode 100644 include/osg/EnvVar diff --git a/CMakeLists.txt b/CMakeLists.txt index 16c20b47a..4c58f7cd4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -468,6 +468,10 @@ OPTION(OSG_PROVIDE_READFILE "Set to ON for include/osgDB/ReadFile to provide the OPTION(OSG_USE_REF_PTR_IMPLICIT_OUTPUT_CONVERSION "Set to ON to use the ref_ptr<> T* operator() output conversion. " ON) OPTION(OSG_USE_REF_PTR_SAFE_DEREFERENCE "Set to ON to throw an exception whenever ref_ptr<> is dereferenced or called. " OFF) +OPTION(OSG_ENVVAR_SUPPORTED "Set to ON to build OpenSceneGraph with the OSG_ENVVAR_SUPPOERTED #define enabled to enable use of getenv() related functions." ON) + + + # Map the OPENGL_PROFILE to OSG_GL*_AVAILABLE settings SET(OPENGL_PROFILE "GL2" CACHE STRING "OpenGL Profile to use, choose from GL1, GL2, GL3, GLES1, GLES2, GLES3") diff --git a/include/osg/EnvVar b/include/osg/EnvVar new file mode 100644 index 000000000..5a8cb043a --- /dev/null +++ b/include/osg/EnvVar @@ -0,0 +1,101 @@ +/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2017 Robert Osfield + * + * This library is open source and may be redistributed and/or modified under + * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or + * (at your option) any later version. The full license is in LICENSE file + * included with this distribution, and on the openscenegraph.org website. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * OpenSceneGraph Public License for more details. +*/ + +#ifndef OSG_EnvVar +#define OSG_EnvVar 1 + +#include + +#ifdef OSG_ENVVAR_SUPPORTED + #include +#endif + +namespace osg { + +template +bool getEnvVar(const char* name, T& value) +{ +#ifdef OSG_ENVVAR_SUPPORTED + const char* ptr = getenv(name); + if (!ptr) return false; + + std::istringstream str(ptr); + str >> value; + return !str.fail(); +#else + return false; +#endif +} + +template<> +bool getEnvVar(const char* name, std::string& value) +{ +#ifdef OSG_ENVVAR_SUPPORTED + const char* ptr = getenv(name); + if (!ptr) return false; + + value = ptr; + return true; +#else + return false; +#endif +} + +template +bool getEnvVar(const char* name, T1& value1, T2& value2) +{ +#ifdef OSG_ENVVAR_SUPPORTED + const char* ptr = getenv(name); + if (!ptr) return false; + + std::istringstream str(ptr); + str >> value1 >> value2; + return !str.fail(); +#else + return false; +#endif +} + +template +bool getEnvVar(const char* name, T1& value1, T2& value2, T3& value3) +{ +#ifdef OSG_ENVVAR_SUPPORTED + const char* ptr = getenv(name); + if (!ptr) return false; + + std::istringstream str(ptr); + str >> value1 >> value2 >> value3; + return !str.fail(); +#else + return false; +#endif +} + +template +bool getEnvVar(const char* name, T1& value1, T2& value2, T3& value3, T4& value4) +{ +#ifdef OSG_ENVVAR_SUPPORTED + const char* ptr = getenv(name); + if (!ptr) return false; + + std::istringstream str(ptr); + str >> value1 >> value2 >> value3 >> value4; + return !str.fail(); +#else + return false; +#endif +} + +} + +# endif diff --git a/src/osg/Config.in b/src/osg/Config.in index 3d52f9ca3..8f4c23359 100644 --- a/src/osg/Config.in +++ b/src/osg/Config.in @@ -34,5 +34,6 @@ #cmakedefine OSG_DISABLE_MSVC_WARNINGS #cmakedefine OSG_PROVIDE_READFILE #cmakedefine OSG_USE_DEPRECATED_API +#cmakedefine OSG_ENVVAR_SUPPORTED #endif From fbb7270e55fa42179f0e2ac5e3804e7744e7bf23 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 1 Nov 2017 13:54:15 +0000 Subject: [PATCH 202/327] Replaced getenv(..) usage with osg::getEnvVar(..) --- src/osgViewer/Viewer.cpp | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/src/osgViewer/Viewer.cpp b/src/osgViewer/Viewer.cpp index 8371f6ef6..7908e7460 100644 --- a/src/osgViewer/Viewer.cpp +++ b/src/osgViewer/Viewer.cpp @@ -34,6 +34,8 @@ #include #include +#include + #include #include @@ -495,26 +497,18 @@ void Viewer::realize() // no windows are already set up so set up a default view - const char* ptr = 0; - if ((ptr = getenv("OSG_CONFIG_FILE")) != 0) + std::string value; + if (osg::getEnvVar("OSG_CONFIG_FILE", value)) { - readConfiguration(ptr); + readConfiguration(value); } else { int screenNum = -1; - if ((ptr = getenv("OSG_SCREEN")) != 0) - { - if (strlen(ptr)!=0) screenNum = atoi(ptr); - else screenNum = -1; - } + osg::getEnvVar("OSG_SCREEN", screenNum); int x = -1, y = -1, width = -1, height = -1; - if ((ptr = getenv("OSG_WINDOW")) != 0) - { - std::istringstream iss(ptr); - iss >> x >> y >> width >> height; - } + osg::getEnvVar("OSG_WINDOW", x, y, width, height); if (width>0 && height>0) { From e59ad870448613a92664b1b76d57bf9fede22fde Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 1 Nov 2017 14:16:54 +0000 Subject: [PATCH 203/327] Made template function inline to avoid multiple declaration issues --- include/osg/EnvVar | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/include/osg/EnvVar b/include/osg/EnvVar index 5a8cb043a..71c1f172f 100644 --- a/include/osg/EnvVar +++ b/include/osg/EnvVar @@ -23,7 +23,7 @@ namespace osg { template -bool getEnvVar(const char* name, T& value) +inline bool getEnvVar(const char* name, T& value) { #ifdef OSG_ENVVAR_SUPPORTED const char* ptr = getenv(name); @@ -38,7 +38,7 @@ bool getEnvVar(const char* name, T& value) } template<> -bool getEnvVar(const char* name, std::string& value) +inline bool getEnvVar(const char* name, std::string& value) { #ifdef OSG_ENVVAR_SUPPORTED const char* ptr = getenv(name); @@ -52,7 +52,7 @@ bool getEnvVar(const char* name, std::string& value) } template -bool getEnvVar(const char* name, T1& value1, T2& value2) +inline bool getEnvVar(const char* name, T1& value1, T2& value2) { #ifdef OSG_ENVVAR_SUPPORTED const char* ptr = getenv(name); @@ -67,7 +67,7 @@ bool getEnvVar(const char* name, T1& value1, T2& value2) } template -bool getEnvVar(const char* name, T1& value1, T2& value2, T3& value3) +inline bool getEnvVar(const char* name, T1& value1, T2& value2, T3& value3) { #ifdef OSG_ENVVAR_SUPPORTED const char* ptr = getenv(name); @@ -82,7 +82,7 @@ bool getEnvVar(const char* name, T1& value1, T2& value2, T3& value3) } template -bool getEnvVar(const char* name, T1& value1, T2& value2, T3& value3, T4& value4) +inline bool getEnvVar(const char* name, T1& value1, T2& value2, T3& value3, T4& value4) { #ifdef OSG_ENVVAR_SUPPORTED const char* ptr = getenv(name); From 3b85aa35dfc453b696da93e56907fc43bc430b32 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 1 Nov 2017 14:45:27 +0000 Subject: [PATCH 204/327] Moved from getenv to osg::getEnvVar usage --- src/osgViewer/GraphicsWindowWin32.cpp | 7 +++--- src/osgViewer/ViewerBase.cpp | 35 +++++++++++++-------------- src/osgViewer/ViewerEventHandlers.cpp | 13 +++------- 3 files changed, 25 insertions(+), 30 deletions(-) diff --git a/src/osgViewer/GraphicsWindowWin32.cpp b/src/osgViewer/GraphicsWindowWin32.cpp index 05ed74b71..b1cb6ce9d 100644 --- a/src/osgViewer/GraphicsWindowWin32.cpp +++ b/src/osgViewer/GraphicsWindowWin32.cpp @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -1314,10 +1315,10 @@ void GraphicsWindowWin32::init() _applyWorkaroundForMultimonitorMultithreadNVidiaWin32Issues = true; #endif - const char* str = getenv("OSG_WIN32_NV_MULTIMON_MULTITHREAD_WORKAROUND"); - if (str) + std::string str; + if (osg::getEnvVar("OSG_WIN32_NV_MULTIMON_MULTITHREAD_WORKAROUND", str)) { - _applyWorkaroundForMultimonitorMultithreadNVidiaWin32Issues = (strcmp(str, "on")==0 || strcmp(str, "ON")==0 || strcmp(str, "On")==0 ); + _applyWorkaroundForMultimonitorMultithreadNVidiaWin32Issues = (str=="on") || (str=="ON") || (str=="On"); } } diff --git a/src/osgViewer/ViewerBase.cpp b/src/osgViewer/ViewerBase.cpp index 508889188..4881bf7a2 100644 --- a/src/osgViewer/ViewerBase.cpp +++ b/src/osgViewer/ViewerBase.cpp @@ -18,6 +18,7 @@ #include #include +#include #include #include @@ -37,6 +38,7 @@ static osg::ApplicationUsageProxy ViewerBase_e2(osg::ApplicationUsage::ENVIRONME static osg::ApplicationUsageProxy ViewerBase_e3(osg::ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_WINDOW x y width height","Set the default window dimensions that windows should open up on."); static osg::ApplicationUsageProxy ViewerBase_e4(osg::ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_RUN_FRAME_SCHEME","Frame rate manage scheme that viewer run should use, ON_DEMAND or CONTINUOUS (default)."); static osg::ApplicationUsageProxy ViewerBase_e5(osg::ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_RUN_MAX_FRAME_RATE","Set the maximum number of frame as second that viewer run. 0.0 is default and disables an frame rate capping."); +static osg::ApplicationUsageProxy ViewerBase_e6(osg::ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_RUN_FRAME_COUNT", "Set the maximum number of frames to run the viewer run method."); using namespace osgViewer; @@ -68,18 +70,14 @@ void ViewerBase::viewerBaseInit() _runFrameScheme = CONTINUOUS; _runMaxFrameRate = 0.0f; - const char* str = getenv("OSG_RUN_FRAME_SCHEME"); - if (str) + std::string str; + if (osg::getEnvVar("OSG_RUN_FRAME_SCHEME", str)) { - if (strcmp(str, "ON_DEMAND")==0) _runFrameScheme = ON_DEMAND; - else if (strcmp(str, "CONTINUOUS")==0) _runFrameScheme = CONTINUOUS; + if (str=="ON_DEMAND") _runFrameScheme = ON_DEMAND; + else if (str=="CONTINUOUS") _runFrameScheme = CONTINUOUS; } - str = getenv("OSG_RUN_MAX_FRAME_RATE"); - if (str) - { - _runMaxFrameRate = osg::asciiToDouble(str); - } + osg::getEnvVar("OSG_RUN_MAX_FRAME_RATE", _runMaxFrameRate); _useConfigureAffinity = true; } @@ -215,13 +213,14 @@ void ViewerBase::setThreadingModel(ThreadingModel threadingModel) ViewerBase::ThreadingModel ViewerBase::suggestBestThreadingModel() { - const char* str = getenv("OSG_THREADING"); - if (str) + std::string str; + osg::getEnvVar("OSG_THREADING", str); + if (!str.empty()) { - if (strcmp(str,"SingleThreaded")==0) return SingleThreaded; - else if (strcmp(str,"CullDrawThreadPerContext")==0) return CullDrawThreadPerContext; - else if (strcmp(str,"DrawThreadPerContext")==0) return DrawThreadPerContext; - else if (strcmp(str,"CullThreadPerCameraDrawThreadPerContext")==0) return CullThreadPerCameraDrawThreadPerContext; + if (str=="SingleThreaded") return SingleThreaded; + else if (str=="CullDrawThreadPerContext") return CullDrawThreadPerContext; + else if (str=="DrawThreadPerContext") return DrawThreadPerContext; + else if (str=="CullThreadPerCameraDrawThreadPerContext") return CullThreadPerCameraDrawThreadPerContext; } Contexts contexts; @@ -690,10 +689,10 @@ int ViewerBase::run() realize(); } - const char* run_frame_count_str = getenv("OSG_RUN_FRAME_COUNT"); - unsigned int runTillFrameNumber = run_frame_count_str==0 ? osg::UNINITIALIZED_FRAME_NUMBER : atoi(run_frame_count_str); + unsigned int runTillFrameNumber = osg::UNINITIALIZED_FRAME_NUMBER; + osg::getEnvVar("OSG_RUN_FRAME_COUNT", runTillFrameNumber); - while(!done() && (run_frame_count_str==0 || getViewerFrameStamp()->getFrameNumber()getFrameNumber()0.0 ? 1.0/_runMaxFrameRate : 0.0; osg::Timer_t startFrameTick = osg::Timer::instance()->tick(); diff --git a/src/osgViewer/ViewerEventHandlers.cpp b/src/osgViewer/ViewerEventHandlers.cpp index 41e02e1bc..43d7d8b39 100644 --- a/src/osgViewer/ViewerEventHandlers.cpp +++ b/src/osgViewer/ViewerEventHandlers.cpp @@ -25,6 +25,7 @@ #include #include #include +#include #include #include @@ -407,15 +408,9 @@ RecordCameraPathHandler::RecordCameraPathHandler(const std::string& filename, fl _animStartTime(0), _lastFrameTime(osg::Timer::instance()->tick()) { - const char* str = getenv("OSG_RECORD_CAMERA_PATH_FPS"); - if (str) - { - _interval = 1.0f / osg::asciiToDouble(str); - } - else - { - _interval = 1.0f / fps; - } + osg::getEnvVar("OSG_RECORD_CAMERA_PATH_FPS", fps); + + _interval = 1.0f / fps; } void RecordCameraPathHandler::getUsage(osg::ApplicationUsage &usage) const From 0e7e06349e7e3f7c4a924c370b43fd5536ce28b7 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 1 Nov 2017 16:43:32 +0000 Subject: [PATCH 205/327] Added safety check for getenv parsing to prevent overflow attacks via getenv. --- include/osg/EnvVar | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/include/osg/EnvVar b/include/osg/EnvVar index 71c1f172f..ddfd6a0e1 100644 --- a/include/osg/EnvVar +++ b/include/osg/EnvVar @@ -22,6 +22,13 @@ namespace osg { +inline unsigned int getClampedLength(const char* str, unsigned int maxNumChars=4096) +{ + unsigned int i = 0; + while(i inline bool getEnvVar(const char* name, T& value) { @@ -29,7 +36,7 @@ inline bool getEnvVar(const char* name, T& value) const char* ptr = getenv(name); if (!ptr) return false; - std::istringstream str(ptr); + std::istringstream str(std::string(ptr, getClampedLength(ptr))); str >> value; return !str.fail(); #else @@ -44,7 +51,7 @@ inline bool getEnvVar(const char* name, std::string& value) const char* ptr = getenv(name); if (!ptr) return false; - value = ptr; + value.assign(ptr, getClampedLength(ptr)); return true; #else return false; @@ -58,7 +65,7 @@ inline bool getEnvVar(const char* name, T1& value1, T2& value2) const char* ptr = getenv(name); if (!ptr) return false; - std::istringstream str(ptr); + std::istringstream str(std::string(ptr, getClampedLength(ptr))); str >> value1 >> value2; return !str.fail(); #else @@ -73,7 +80,7 @@ inline bool getEnvVar(const char* name, T1& value1, T2& value2, T3& value3) const char* ptr = getenv(name); if (!ptr) return false; - std::istringstream str(ptr); + std::istringstream str(std::string(ptr, getClampedLength(ptr))); str >> value1 >> value2 >> value3; return !str.fail(); #else @@ -88,7 +95,7 @@ inline bool getEnvVar(const char* name, T1& value1, T2& value2, T3& value3, T4& const char* ptr = getenv(name); if (!ptr) return false; - std::istringstream str(ptr); + std::istringstream str(std::string(ptr, getClampedLength(ptr))); str >> value1 >> value2 >> value3 >> value4; return !str.fail(); #else From 338b0e2b7b51efc8eabf3167b32d4061f884e83b Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 1 Nov 2017 17:38:33 +0000 Subject: [PATCH 206/327] Moved getenv usage across to safer osg::getEnvVar() usage --- include/osg/EnvVar | 10 ++++++++++ src/osg/GLExtensions.cpp | 21 +++++++++++---------- src/osg/GraphicsContext.cpp | 7 ++++--- src/osg/Notify.cpp | 6 +++--- src/osg/Program.cpp | 1 - src/osg/State.cpp | 18 +++++++++++------- 6 files changed, 39 insertions(+), 24 deletions(-) diff --git a/include/osg/EnvVar b/include/osg/EnvVar index ddfd6a0e1..6ef49266a 100644 --- a/include/osg/EnvVar +++ b/include/osg/EnvVar @@ -17,6 +17,7 @@ #include #ifdef OSG_ENVVAR_SUPPORTED + #include #include #endif @@ -29,6 +30,15 @@ inline unsigned int getClampedLength(const char* str, unsigned int maxNumChars=4 return i; } +inline std::string getEnvVar(const char* name) +{ + std::string value; + const char* ptr = getenv(name); + if (ptr) value.assign(ptr, getClampedLength(ptr)); + return value; + } + + template inline bool getEnvVar(const char* name, T& value) { diff --git a/src/osg/GLExtensions.cpp b/src/osg/GLExtensions.cpp index 77984a202..882fe96ab 100644 --- a/src/osg/GLExtensions.cpp +++ b/src/osg/GLExtensions.cpp @@ -15,6 +15,8 @@ #include #include #include +#include +#include #include #include @@ -65,6 +67,9 @@ static osg::buffered_object s_gluExtensionSetList; static osg::buffered_object s_gluRendererList; static osg::buffered_value s_gluInitializedList; +static ApplicationUsageProxy GLEXtension_e0(ApplicationUsage::ENVIRONMENTAL_VARIABLE, "OSG_GL_EXTENSION_DISABLE ", "Use space deliminarted list of GL extensions to disable associated GL extensions"); +static ApplicationUsageProxy GLEXtension_e1(ApplicationUsage::ENVIRONMENTAL_VARIABLE, "OSG_MAX_TEXTURE_SIZE ", "Clamp the maximum GL texture size to specified value."); + float osg::getGLVersionNumber() { // needs to be extended to do proper things with subversions like 1.5.1, etc. @@ -308,8 +313,7 @@ void osg::setGLExtensionDisableString(const std::string& disableString) std::string& osg::getGLExtensionDisableString() { - static const char* envVar = getenv("OSG_GL_EXTENSION_DISABLE"); - static std::string s_GLExtensionDisableString(envVar?envVar:"Nothing defined"); + static std::string s_GLExtensionDisableString(getEnvVar("OSG_GL_EXTENSION_DISABLE")); return s_GLExtensionDisableString; } @@ -901,15 +905,12 @@ GLExtensions::GLExtensions(unsigned int in_contextID): if (validContext) glGetIntegerv(GL_MAX_TEXTURE_SIZE,&maxTextureSize); char *ptr; - if( (ptr = getenv("OSG_MAX_TEXTURE_SIZE")) != 0) + + GLint osg_max_size = maxTextureSize; + + if( (getEnvVar("OSG_MAX_TEXTURE_SIZE", osg_max_size)) && osg_max_size #include #include +#include #include #include @@ -153,10 +154,10 @@ std::string GraphicsContext::ScreenIdentifier::displayName() const void GraphicsContext::ScreenIdentifier::readDISPLAY() { - const char* ptr = 0; - if ((ptr=getenv("DISPLAY")) != 0) + std::string str; + if (getEnvVar("DISPLAY", str)) { - setScreenIdentifier(ptr); + setScreenIdentifier(str); } } diff --git a/src/osg/Notify.cpp b/src/osg/Notify.cpp index e562aea4d..6ca85b37e 100644 --- a/src/osg/Notify.cpp +++ b/src/osg/Notify.cpp @@ -12,6 +12,7 @@ */ #include #include +#include #include #include #include @@ -140,9 +141,8 @@ struct NotifySingleton _notifyLevel = osg::NOTICE; // Default value - char* OSGNOTIFYLEVEL=getenv("OSG_NOTIFY_LEVEL"); - if (!OSGNOTIFYLEVEL) OSGNOTIFYLEVEL=getenv("OSGNOTIFYLEVEL"); - if(OSGNOTIFYLEVEL) + std::string OSGNOTIFYLEVEL; + if(getEnvVar("OSG_NOTIFY_LEVEL", OSGNOTIFYLEVEL) || getEnvVar("OSGNOTIFYLEVEL", OSGNOTIFYLEVEL)) { std::string stringOSGNOTIFYLEVEL(OSGNOTIFYLEVEL); diff --git a/src/osg/Program.cpp b/src/osg/Program.cpp index 85c49a37d..68fadaf0c 100644 --- a/src/osg/Program.cpp +++ b/src/osg/Program.cpp @@ -516,7 +516,6 @@ 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(); diff --git a/src/osg/State.cpp b/src/osg/State.cpp index 05933aa30..5ed4f277e 100644 --- a/src/osg/State.cpp +++ b/src/osg/State.cpp @@ -18,6 +18,7 @@ #include #include #include +#include #include #include @@ -75,14 +76,17 @@ State::State(): _checkGLErrors = ONCE_PER_FRAME; - const char* str = getenv("OSG_GL_ERROR_CHECKING"); - if (str && (strcmp(str,"ONCE_PER_ATTRIBUTE")==0 || strcmp(str,"ON")==0 || strcmp(str,"on")==0)) + std::string str; + if (getEnvVar("OSG_GL_ERROR_CHECKING", str)) { - _checkGLErrors = ONCE_PER_ATTRIBUTE; - } - else if(str && (strcmp(str, "OFF") == 0 || strcmp(str, "off") == 0)) - { - _checkGLErrors = NEVER_CHECK_GL_ERRORS; + if (str=="ONCE_PER_ATTRIBUTE" || str=="ON" || str=="on") + { + _checkGLErrors = ONCE_PER_ATTRIBUTE; + } + else if (str=="OFF" || str=="off") + { + _checkGLErrors = NEVER_CHECK_GL_ERRORS; + } } _currentActiveTextureUnit=0; From 239b0faa4c18ddfbc2678cb97c18adb16636684f Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Thu, 2 Nov 2017 10:00:28 +0000 Subject: [PATCH 207/327] Replaced getenv calls with safer osg::getEnvVar usage --- src/osg/DisplaySettings.cpp | 216 ++++++++++++++---------------------- src/osg/GLExtensions.cpp | 14 ++- 2 files changed, 95 insertions(+), 135 deletions(-) diff --git a/src/osg/DisplaySettings.cpp b/src/osg/DisplaySettings.cpp index 9c1f3c75b..c63e66715 100644 --- a/src/osg/DisplaySettings.cpp +++ b/src/osg/DisplaySettings.cpp @@ -16,6 +16,7 @@ #include #include #include +#include #include #include @@ -391,222 +392,182 @@ static ApplicationUsageProxy DisplaySetting_e33(ApplicationUsage::ENVIRONMENTAL_ void DisplaySettings::readEnvironmentalVariables() { - const char* ptr = 0; - - if ((ptr = getenv("OSG_DISPLAY_TYPE")) != 0) + std::string value; + if (getEnvVar("OSG_DISPLAY_TYPE", value)) { - if (strcmp(ptr,"MONITOR")==0) + if (value=="MONITOR") { _displayType = MONITOR; } else - if (strcmp(ptr,"POWERWALL")==0) + if (value=="POWERWALL") { _displayType = POWERWALL; } else - if (strcmp(ptr,"REALITY_CENTER")==0) + if (value=="REALITY_CENTER") { _displayType = REALITY_CENTER; } else - if (strcmp(ptr,"HEAD_MOUNTED_DISPLAY")==0) + if (value=="HEAD_MOUNTED_DISPLAY") { _displayType = HEAD_MOUNTED_DISPLAY; } } - if( (ptr = getenv("OSG_STEREO_MODE")) != 0) + if (getEnvVar("OSG_STEREO_MODE", value)) { - if (strcmp(ptr,"QUAD_BUFFER")==0) + if (value=="QUAD_BUFFER") { _stereoMode = QUAD_BUFFER; } - else if (strcmp(ptr,"ANAGLYPHIC")==0) + else if (value=="ANAGLYPHIC") { _stereoMode = ANAGLYPHIC; } - else if (strcmp(ptr,"HORIZONTAL_SPLIT")==0) + else if (value=="HORIZONTAL_SPLIT") { _stereoMode = HORIZONTAL_SPLIT; } - else if (strcmp(ptr,"VERTICAL_SPLIT")==0) + else if (value=="VERTICAL_SPLIT") { _stereoMode = VERTICAL_SPLIT; } - else if (strcmp(ptr,"LEFT_EYE")==0) + else if (value=="LEFT_EYE") { _stereoMode = LEFT_EYE; } - else if (strcmp(ptr,"RIGHT_EYE")==0) + else if (value=="RIGHT_EYE") { _stereoMode = RIGHT_EYE; } - else if (strcmp(ptr,"HORIZONTAL_INTERLACE")==0) + else if (value=="HORIZONTAL_INTERLACE") { _stereoMode = HORIZONTAL_INTERLACE; } - else if (strcmp(ptr,"VERTICAL_INTERLACE")==0) + else if (value=="VERTICAL_INTERLACE") { _stereoMode = VERTICAL_INTERLACE; } - else if (strcmp(ptr,"CHECKERBOARD")==0) + else if (value=="CHECKERBOARD") { _stereoMode = CHECKERBOARD; } } - if( (ptr = getenv("OSG_STEREO")) != 0) + if (getEnvVar("OSG_STEREO", value)) { - if (strcmp(ptr,"OFF")==0) + if (value=="OFF") { _stereo = false; } else - if (strcmp(ptr,"ON")==0) + if (value=="ON") { _stereo = true; } } - if( (ptr = getenv("OSG_EYE_SEPARATION")) != 0) - { - _eyeSeparation = osg::asciiToFloat(ptr); - } + getEnvVar("OSG_EYE_SEPARATION", _eyeSeparation); + getEnvVar("OSG_SCREEN_WIDTH", _screenWidth); + getEnvVar("OSG_SCREEN_HEIGHT", _screenHeight); + getEnvVar("OSG_SCREEN_DISTANCE", _screenDistance); - if( (ptr = getenv("OSG_SCREEN_WIDTH")) != 0) + if (getEnvVar("OSG_SPLIT_STEREO_HORIZONTAL_EYE_MAPPING", value)) { - _screenWidth = osg::asciiToFloat(ptr); - } - - if( (ptr = getenv("OSG_SCREEN_HEIGHT")) != 0) - { - _screenHeight = osg::asciiToFloat(ptr); - } - - if( (ptr = getenv("OSG_SCREEN_DISTANCE")) != 0) - { - _screenDistance = osg::asciiToFloat(ptr); - } - - if( (ptr = getenv("OSG_SPLIT_STEREO_HORIZONTAL_EYE_MAPPING")) != 0) - { - if (strcmp(ptr,"LEFT_EYE_LEFT_VIEWPORT")==0) + if (value=="LEFT_EYE_LEFT_VIEWPORT") { _splitStereoHorizontalEyeMapping = LEFT_EYE_LEFT_VIEWPORT; } else - if (strcmp(ptr,"LEFT_EYE_RIGHT_VIEWPORT")==0) + if (value=="LEFT_EYE_RIGHT_VIEWPORT") { _splitStereoHorizontalEyeMapping = LEFT_EYE_RIGHT_VIEWPORT; } } - if( (ptr = getenv("OSG_SPLIT_STEREO_HORIZONTAL_SEPARATION")) != 0) - { - _splitStereoHorizontalSeparation = atoi(ptr); - } + getEnvVar("OSG_SPLIT_STEREO_HORIZONTAL_SEPARATION", _splitStereoHorizontalSeparation); - if( (ptr = getenv("OSG_SPLIT_STEREO_VERTICAL_EYE_MAPPING")) != 0) + if (getEnvVar("OSG_SPLIT_STEREO_VERTICAL_EYE_MAPPING", value)) { - if (strcmp(ptr,"LEFT_EYE_TOP_VIEWPORT")==0) + if (value=="LEFT_EYE_TOP_VIEWPORT") { _splitStereoVerticalEyeMapping = LEFT_EYE_TOP_VIEWPORT; } else - if (strcmp(ptr,"LEFT_EYE_BOTTOM_VIEWPORT")==0) + if (value=="LEFT_EYE_BOTTOM_VIEWPORT") { _splitStereoVerticalEyeMapping = LEFT_EYE_BOTTOM_VIEWPORT; } } - if( (ptr = getenv("OSG_SPLIT_STEREO_AUTO_ADJUST_ASPECT_RATIO")) != 0) + if (getEnvVar("OSG_SPLIT_STEREO_AUTO_ADJUST_ASPECT_RATIO", value)) { - if (strcmp(ptr,"OFF")==0) + if (value=="OFF") { _splitStereoAutoAdjustAspectRatio = false; } else - if (strcmp(ptr,"ON")==0) + if (value=="ON") { _splitStereoAutoAdjustAspectRatio = true; } } - if( (ptr = getenv("OSG_SPLIT_STEREO_VERTICAL_SEPARATION")) != 0) - { - _splitStereoVerticalSeparation = atoi(ptr); - } + getEnvVar("OSG_SPLIT_STEREO_VERTICAL_SEPARATION", _splitStereoVerticalSeparation); - if( (ptr = getenv("OSG_MAX_NUMBER_OF_GRAPHICS_CONTEXTS")) != 0) - { - _maxNumOfGraphicsContexts = atoi(ptr); - } + getEnvVar("OSG_MAX_NUMBER_OF_GRAPHICS_CONTEXTS", _maxNumOfGraphicsContexts); - if( (ptr = getenv("OSG_COMPILE_CONTEXTS")) != 0) + if (getEnvVar("OSG_COMPILE_CONTEXTS", value)) { - if (strcmp(ptr,"OFF")==0) + if (value=="OFF") { _compileContextsHint = false; } else - if (strcmp(ptr,"ON")==0) + if (value=="ON") { _compileContextsHint = true; } } - if( (ptr = getenv("OSG_SERIALIZE_DRAW_DISPATCH")) != 0) + if (getEnvVar("OSG_SERIALIZE_DRAW_DISPATCH", value)) { - if (strcmp(ptr,"OFF")==0) + if (value=="OFF") { _serializeDrawDispatch = false; } else - if (strcmp(ptr,"ON")==0) + if (value=="ON") { _serializeDrawDispatch = true; } } - if( (ptr = getenv("OSG_USE_SCENEVIEW_FOR_STEREO")) != 0) + if (getEnvVar("OSG_USE_SCENEVIEW_FOR_STEREO", value)) { - if (strcmp(ptr,"OFF")==0) + if (value=="OFF") { _useSceneViewForStereoHint = false; } else - if (strcmp(ptr,"ON")==0) + if (value=="ON") { _useSceneViewForStereoHint = true; } } - if( (ptr = getenv("OSG_NUM_DATABASE_THREADS")) != 0) - { - _numDatabaseThreadsHint = atoi(ptr); - } + getEnvVar("OSG_NUM_DATABASE_THREADS", _numDatabaseThreadsHint); - if( (ptr = getenv("OSG_NUM_HTTP_DATABASE_THREADS")) != 0) - { - _numHttpDatabaseThreadsHint = atoi(ptr); - } + getEnvVar("OSG_NUM_HTTP_DATABASE_THREADS", _numHttpDatabaseThreadsHint); - if( (ptr = getenv("OSG_MULTI_SAMPLES")) != 0) - { - _numMultiSamples = atoi(ptr); - } + getEnvVar("OSG_MULTI_SAMPLES", _numMultiSamples); - if( (ptr = getenv("OSG_TEXTURE_POOL_SIZE")) != 0) - { - _maxTexturePoolSize = atoi(ptr); - } + getEnvVar("OSG_TEXTURE_POOL_SIZE", _maxTexturePoolSize); - if( (ptr = getenv("OSG_BUFFER_OBJECT_POOL_SIZE")) != 0) - { - _maxBufferObjectPoolSize = atoi(ptr); - } + getEnvVar("OSG_BUFFER_OBJECT_POOL_SIZE", _maxBufferObjectPoolSize); { // Read implicit buffer attachments combinations for both render and resolve mask @@ -642,71 +603,65 @@ void DisplaySettings::readEnvironmentalVariables() } } - if( (ptr = getenv("OSG_GL_VERSION")) != 0 || (ptr = getenv("OSG_GL_CONTEXT_VERSION")) != 0) + if (getEnvVar("OSG_GL_VERSION", value) || getEnvVar("OSG_GL_CONTEXT_VERSION", value)) { - _glContextVersion = ptr; + _glContextVersion = value; } - if( (ptr = getenv("OSG_GL_CONTEXT_FLAGS")) != 0) - { - _glContextFlags = atoi(ptr); - } + getEnvVar("OSG_GL_CONTEXT_FLAGS", _glContextFlags); - if( (ptr = getenv("OSG_GL_CONTEXT_PROFILE_MASK")) != 0) - { - _glContextProfileMask = atoi(ptr); - } + getEnvVar("OSG_GL_CONTEXT_PROFILE_MASK", _glContextProfileMask); - if ((ptr = getenv("OSG_SWAP_METHOD")) != 0) + if (getEnvVar("OSG_SWAP_METHOD", value)) { - if (strcmp(ptr,"DEFAULT")==0) + if (value=="DEFAULT") { _swapMethod = SWAP_DEFAULT; } else - if (strcmp(ptr,"EXCHANGE")==0) + if (value=="EXCHANGE") { _swapMethod = SWAP_EXCHANGE; } else - if (strcmp(ptr,"COPY")==0) + if (value=="COPY") { _swapMethod = SWAP_COPY; } else - if (strcmp(ptr,"UNDEFINED")==0) + if (value=="UNDEFINED") { _swapMethod = SWAP_UNDEFINED; } } - if ((ptr = getenv("OSG_SYNC_SWAP_BUFFERS")) != 0) + if (getEnvVar("OSG_SYNC_SWAP_BUFFERS", value)) { - if (strcmp(ptr,"OFF")==0) + if (value=="OFF") { _syncSwapBuffers = 0; } else - if (strcmp(ptr,"ON")==0) + if (value=="ON") { _syncSwapBuffers = 1; } else { - _syncSwapBuffers = atoi(ptr); + _syncSwapBuffers = atoi(value.c_str()); } } - if ((ptr = getenv("OSG_VERTEX_BUFFER_HINT")) != 0) + if (getEnvVar("OSG_VERTEX_BUFFER_HINT", value)) { - if (strcmp(ptr,"VERTEX_BUFFER_OBJECT")==0 || strcmp(ptr,"VBO")==0) + if (value=="VERTEX_BUFFER_OBJECT" || value=="VBO") { OSG_NOTICE<<"OSG_VERTEX_BUFFER_HINT set to VERTEX_BUFFER_OBJECT"<= 1.2f); isTextureStorageEnabled = validContext && ((glVersion >= 4.2f) || isGLExtensionSupported(contextID, "GL_ARB_texture_storage")); - if ( (ptr = getenv("OSG_GL_TEXTURE_STORAGE")) != 0 && isTextureStorageEnabled) - { - if (strcmp(ptr,"OFF")==0 || strcmp(ptr,"DISABLE")==0 ) isTextureStorageEnabled = false; - else isTextureStorageEnabled = true; - } + if (isTextureStorageEnabled) + { + std::string value; + if (getEnvVar("OSG_GL_TEXTURE_STORAGE", value)) + { + if (value=="OFF" || value=="DISABLE") isTextureStorageEnabled = false; + else isTextureStorageEnabled = true; + } + } // Texture3D extensions isTexture3DFast = validContext && (OSG_GL3_FEATURES || isGLExtensionSupported(contextID,"GL_EXT_texture3D")); From aa744edaccf319db57f6b0789d2f6fb8c0469c7d Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Thu, 2 Nov 2017 10:02:34 +0000 Subject: [PATCH 208/327] Fixed warning --- src/osg/GLExtensions.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/osg/GLExtensions.cpp b/src/osg/GLExtensions.cpp index a9cc93726..5cb230db8 100644 --- a/src/osg/GLExtensions.cpp +++ b/src/osg/GLExtensions.cpp @@ -904,10 +904,7 @@ GLExtensions::GLExtensions(unsigned int in_contextID): maxTextureSize=0; if (validContext) glGetIntegerv(GL_MAX_TEXTURE_SIZE,&maxTextureSize); - char *ptr; - GLint osg_max_size = maxTextureSize; - if( (getEnvVar("OSG_MAX_TEXTURE_SIZE", osg_max_size)) && osg_max_size Date: Thu, 2 Nov 2017 10:43:41 +0000 Subject: [PATCH 209/327] Replaced getenv usage with safer osg::getEnvVar --- src/osg/ApplicationUsage.cpp | 15 +++++++++++---- src/osg/CullSettings.cpp | 17 +++++++---------- src/osg/DisplaySettings.cpp | 36 ++++++++++++++++++------------------ 3 files changed, 36 insertions(+), 32 deletions(-) diff --git a/src/osg/ApplicationUsage.cpp b/src/osg/ApplicationUsage.cpp index ad2404089..26e4510ec 100644 --- a/src/osg/ApplicationUsage.cpp +++ b/src/osg/ApplicationUsage.cpp @@ -17,6 +17,7 @@ #include #include #include +#include #include #include @@ -317,10 +318,16 @@ void ApplicationUsage::writeEnvironmentSettings(std::ostream& output) std::string::size_type len = citr->first.find_first_of("\n\r\t "); if (len == std::string::npos) len = citr->first.size(); line.replace(optionPos,len,citr->first.substr(0,len)); - const char *cp = getenv(citr->first.substr(0, len).c_str()); - if (!cp) cp = "[not set]"; - else if (!*cp) cp = "[set]"; - line += std::string(cp) + "\n"; + + std::string value; + if (getEnvVar(citr->first.substr(0, len).c_str(), value)) + { + line += "[set]\n"; + } + else + { + line += "[not set]\n"; + } output << line; } diff --git a/src/osg/CullSettings.cpp b/src/osg/CullSettings.cpp index 370191787..78122bbb5 100644 --- a/src/osg/CullSettings.cpp +++ b/src/osg/CullSettings.cpp @@ -16,6 +16,7 @@ #include #include #include +#include #include @@ -97,25 +98,21 @@ void CullSettings::readEnvironmentalVariables() { OSG_INFO<<"CullSettings::readEnvironmentalVariables()"< lock(_valueMapMutex); @@ -1122,12 +1122,12 @@ bool DisplaySettings::getValue(const std::string& name, std::string& value, bool return true; } - if (!use_getenv_fallback) return false; + if (!use_env_fallback) return false; - const char* str = getenv(name.c_str()); - if (str) + std::string str; + if (getEnvVar(name.c_str(), str)) { - OSG_INFO<<"DisplaySettings::getValue("< Date: Thu, 2 Nov 2017 11:42:25 +0000 Subject: [PATCH 210/327] Cleaned up getEnvVar usage --- src/osgViewer/ViewerBase.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/osgViewer/ViewerBase.cpp b/src/osgViewer/ViewerBase.cpp index 4881bf7a2..9184ff79a 100644 --- a/src/osgViewer/ViewerBase.cpp +++ b/src/osgViewer/ViewerBase.cpp @@ -214,8 +214,7 @@ void ViewerBase::setThreadingModel(ThreadingModel threadingModel) ViewerBase::ThreadingModel ViewerBase::suggestBestThreadingModel() { std::string str; - osg::getEnvVar("OSG_THREADING", str); - if (!str.empty()) + if (osg::getEnvVar("OSG_THREADING", str)) { if (str=="SingleThreaded") return SingleThreaded; else if (str=="CullDrawThreadPerContext") return CullDrawThreadPerContext; From 1bf2db24f2b5fd4aea815a2d3aa2d713117ffe93 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Thu, 2 Nov 2017 11:48:39 +0000 Subject: [PATCH 211/327] Moved memset to after check for null memory pointer --- src/osgPlugins/md2/ReaderWriterMD2.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/osgPlugins/md2/ReaderWriterMD2.cpp b/src/osgPlugins/md2/ReaderWriterMD2.cpp index c10399520..f2dc98909 100644 --- a/src/osgPlugins/md2/ReaderWriterMD2.cpp +++ b/src/osgPlugins/md2/ReaderWriterMD2.cpp @@ -166,13 +166,14 @@ load_md2 (const char *filename, const osgDB::ReaderWriter::Options* options) } mapbase = malloc (st.st_size+1); - memset(mapbase, 0, st.st_size+1); if (!mapbase) { close (file_fd); return NULL; } + memset(mapbase, 0, st.st_size+1); + if (read(file_fd, mapbase, st.st_size) != st.st_size) { close (file_fd); From 281aae8eea7c14bf490bf8fae2d39546ba63e240 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Thu, 2 Nov 2017 11:51:03 +0000 Subject: [PATCH 212/327] Fixed copy and paste error --- src/osgTerrain/GeometryPool.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/osgTerrain/GeometryPool.cpp b/src/osgTerrain/GeometryPool.cpp index e028aa99d..c69781f44 100644 --- a/src/osgTerrain/GeometryPool.cpp +++ b/src/osgTerrain/GeometryPool.cpp @@ -846,7 +846,7 @@ void SharedGeometry::compileGLObjects(osg::RenderInfo& renderInfo) const osg::BufferObject* ebo = _drawElements->getElementBufferObject(); osg::GLBufferObject* ebo_glBufferObject = ebo->getOrCreateGLBufferObject(contextID); - if (ebo_glBufferObject && vbo_glBufferObject->isDirty()) + if (ebo_glBufferObject && ebo_glBufferObject->isDirty()) { // OSG_NOTICE<<"Compile buffer "<compileBuffer(); From a07105d6c54e828f1823647ff6a5492941b99fc1 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Thu, 2 Nov 2017 16:39:32 +0000 Subject: [PATCH 213/327] Changed the key binding for opening and editor to edit presentation to 'E' and to trigger update the presentation by pressing 'e' --- src/osgPresentation/SlideEventHandler.cpp | 31 ++++++++++++----------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/src/osgPresentation/SlideEventHandler.cpp b/src/osgPresentation/SlideEventHandler.cpp index d88ba4c3f..8e2ff0b8c 100644 --- a/src/osgPresentation/SlideEventHandler.cpp +++ b/src/osgPresentation/SlideEventHandler.cpp @@ -1231,7 +1231,22 @@ bool SlideEventHandler::handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIAction return true; } - else if (ea.getKey()=='U') + return false; + } + case(osgGA::GUIEventAdapter::KEYUP): + { + if (ea.getKey()=='h') + { + _hold = false; + return true; + } + else if (ea.getKey()=='e') + { + // reload presentation to reflect changes from editor + setRequestReload(true); + return true; + } + else if (ea.getKey()=='E') { char* editor = getenv("P3D_EDITOR"); if (!editor) editor = getenv("EDITOR"); @@ -1252,20 +1267,6 @@ bool SlideEventHandler::handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIAction return false; } - case(osgGA::GUIEventAdapter::KEYUP): - { - if (ea.getKey()=='h') - { - _hold = false; - return true; - } - else if (ea.getKey()=='u') - { - setRequestReload(true); - return true; - } - return false; - } default: return false; } From 6f924f84bac55f6517de07dc985c717d91aadc90 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Thu, 2 Nov 2017 18:39:11 +0000 Subject: [PATCH 214/327] Fuxed missing initializers --- src/osgUtil/LineSegmentIntersector.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/osgUtil/LineSegmentIntersector.cpp b/src/osgUtil/LineSegmentIntersector.cpp index 08faade5e..65b61c8be 100644 --- a/src/osgUtil/LineSegmentIntersector.cpp +++ b/src/osgUtil/LineSegmentIntersector.cpp @@ -69,6 +69,8 @@ struct IntersectFunctor IntersectFunctor(): _primitiveIndex(0), + _length(0.0), + _inverse_length(0.0), _hit(false) { } From 7dd03202361a0ee5bb751e6cf19417ba2fbd04b4 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Thu, 2 Nov 2017 18:43:05 +0000 Subject: [PATCH 215/327] Added check for a valud positions pointer --- src/osgPlugins/gles/GeometryCleaner | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/osgPlugins/gles/GeometryCleaner b/src/osgPlugins/gles/GeometryCleaner index 41310281a..adcef5703 100644 --- a/src/osgPlugins/gles/GeometryCleaner +++ b/src/osgPlugins/gles/GeometryCleaner @@ -39,12 +39,15 @@ public: } else { osg::Vec3Array* positions = dynamic_cast(geometry.getVertexArray()); - SubGeometry cleaned(geometry, - clean(*positions, getTriangles(geometry), 3), - clean(*positions, getLines(geometry), 2), - clean(*positions, getWireframe(geometry), 2), - clean(*positions, getPoints(geometry), 1)); - _clean.push_back(cleaned.geometry()); + if (positions) + { + SubGeometry cleaned(geometry, + clean(*positions, getTriangles(geometry), 3), + clean(*positions, getLines(geometry), 2), + clean(*positions, getWireframe(geometry), 2), + clean(*positions, getPoints(geometry), 1)); + _clean.push_back(cleaned.geometry()); + } } return _clean; From 6d65768dabe8ea1a115dc3767fb24401db0f8e39 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Fri, 3 Nov 2017 09:49:50 +0000 Subject: [PATCH 216/327] Added an explict null termination of buffer to address Coverity Scan reported issue --- src/osgPlugins/md2/ReaderWriterMD2.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/osgPlugins/md2/ReaderWriterMD2.cpp b/src/osgPlugins/md2/ReaderWriterMD2.cpp index f2dc98909..7d4f4fb2d 100644 --- a/src/osgPlugins/md2/ReaderWriterMD2.cpp +++ b/src/osgPlugins/md2/ReaderWriterMD2.cpp @@ -172,8 +172,6 @@ load_md2 (const char *filename, const osgDB::ReaderWriter::Options* options) return NULL; } - memset(mapbase, 0, st.st_size+1); - if (read(file_fd, mapbase, st.st_size) != st.st_size) { close (file_fd); @@ -181,6 +179,9 @@ load_md2 (const char *filename, const osgDB::ReaderWriter::Options* options) return NULL; } + // set the last value in the mapbase to 0 to make sure the buffer is null terminated for later string reads from it + ((char*)mapbase)[st.st_size] = 0; + if (g_md2NormalsArray == NULL) { g_md2NormalsArray = new osg::Vec3Array; for (int i = 0; i < NUMVERTEXNORMALS; i++) From 24f8a01f17f1b59bdc6d2fb5d48ece139c1453e5 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Fri, 3 Nov 2017 09:55:42 +0000 Subject: [PATCH 217/327] Added check for malloc returning a valid pointer --- src/osgPlugins/3ds/lib3ds/lib3ds_file.c | 55 +++++++++++++------------ 1 file changed, 29 insertions(+), 26 deletions(-) diff --git a/src/osgPlugins/3ds/lib3ds/lib3ds_file.c b/src/osgPlugins/3ds/lib3ds/lib3ds_file.c index d9cbb0b71..3a0a66fef 100644 --- a/src/osgPlugins/3ds/lib3ds/lib3ds_file.c +++ b/src/osgPlugins/3ds/lib3ds/lib3ds_file.c @@ -549,35 +549,38 @@ kfdata_read(Lib3dsFile *file, Lib3dsIo *io) { { Lib3dsNode **nodes = (Lib3dsNode **)malloc(num_nodes * sizeof(Lib3dsNode*)); - unsigned i; - Lib3dsNode *p, *q, *parent; + if (nodes) + { + unsigned i; + Lib3dsNode *p, *q, *parent; - p = file->nodes; - for (i = 0; i < num_nodes; ++i) { - nodes[i] = p; - p = p->next; - } - qsort(nodes, num_nodes, sizeof(Lib3dsNode*), compare_node_id); - - p = last; - while (p) { - q = (Lib3dsNode *)p->user_ptr; - if (p->user_id != 65535) { - parent = *(Lib3dsNode**)bsearch(&p->user_id, nodes, num_nodes, sizeof(Lib3dsNode*), compare_node_id2); - if (parent) { - q->next = p->next; - p->next = parent->childs; - p->parent = parent; - parent->childs = p; - } else { - /* TODO: warning */ - } + p = file->nodes; + for (i = 0; i < num_nodes; ++i) { + nodes[i] = p; + p = p->next; } - p->user_id = 0; - p->user_ptr = NULL; - p = q; + qsort(nodes, num_nodes, sizeof(Lib3dsNode*), compare_node_id); + + p = last; + while (p) { + q = (Lib3dsNode *)p->user_ptr; + if (p->user_id != 65535) { + parent = *(Lib3dsNode**)bsearch(&p->user_id, nodes, num_nodes, sizeof(Lib3dsNode*), compare_node_id2); + if (parent) { + q->next = p->next; + p->next = parent->childs; + p->parent = parent; + parent->childs = p; + } else { + /* TODO: warning */ + } + } + p->user_id = 0; + p->user_ptr = NULL; + p = q; + } + free(nodes); } - free(nodes); } lib3ds_chunk_read_end(&c, io); From f7f76a1029be2e92e5d6834d8d40da6df9409db5 Mon Sep 17 00:00:00 2001 From: Julien Valentin Date: Sat, 4 Nov 2017 17:28:14 +0100 Subject: [PATCH 218/327] following guidance from OpenGL Common Mistakes: mipmaps should be upload with glTexImage2D and not glTexSubImage2D --- src/osg/Texture.cpp | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/src/osg/Texture.cpp b/src/osg/Texture.cpp index 25782619f..d43b0d665 100644 --- a/src/osg/Texture.cpp +++ b/src/osg/Texture.cpp @@ -2298,9 +2298,8 @@ void Texture::applyTexImage2D_load(State& state, GLenum target, const Image* ima if (height == 0) height = 1; - glTexSubImage2D( target, k, - 0, 0, - width, height, + glTexImage2D( target, k, _internalFormat, + width, height, _borderWidth, (GLenum)image->getPixelFormat(), (GLenum)image->getDataType(), dataPtr + image->getMipmapOffset(k)); @@ -2603,12 +2602,11 @@ void Texture::applyTexImage2D_subload(State& state, GLenum target, const Image* if (height == 0) height = 1; - glTexSubImage2D( target, k, - 0, 0, - width, height, - (GLenum)image->getPixelFormat(), - (GLenum)image->getDataType(), - dataPtr + image->getMipmapOffset(k)); + glTexImage2D( target, k, _internalFormat, + width, height, _borderWidth, + (GLenum)image->getPixelFormat(), + (GLenum)image->getDataType(), + dataPtr + image->getMipmapOffset(k)); width >>= 1; height >>= 1; From 01c68ba5e5eb2f9a2715ef35fbf4b2fb3f6ccd96 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Mon, 6 Nov 2017 19:53:38 +0000 Subject: [PATCH 219/327] Temporary workaround for the regression of intersection tests with osgText::Text. Added a local vertex array that is transformed by the last applied text matrix. --- src/osgText/Text.cpp | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/src/osgText/Text.cpp b/src/osgText/Text.cpp index 46c857639..a22d7396f 100644 --- a/src/osgText/Text.cpp +++ b/src/osgText/Text.cpp @@ -1259,7 +1259,24 @@ void Text::accept(osg::Drawable::ConstAttributeFunctor& af) const void Text::accept(osg::PrimitiveFunctor& pf) const { - pf.setVertexArray(_coords->size(), &(_coords->front())); + if (!_coords || _coords->empty()) return; + + // short term fix/workaround for _coords being transformed by a local matrix before rendering, so we need to replicate this was doing tasks like intersection testing. + osg::ref_ptr vertices = _coords; + if (!_matrix.isIdentity()) + { + vertices = new osg::Vec3Array; + vertices->resize(_coords->size()); + for(Vec3Array::iterator sitr = _coords->begin(), ditr = vertices->begin(); + sitr != _coords->end(); + ++sitr, ++ditr) + { + *ditr = *sitr * _matrix; + } + } + + pf.setVertexArray(vertices->size(), &(vertices->front())); + for(TextureGlyphQuadMap::const_iterator titr=_textureGlyphQuadMap.begin(); titr!=_textureGlyphQuadMap.end(); ++titr) From 74226e5904f5f7ea6a81999d977f55a3a7e52655 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Mon, 6 Nov 2017 20:49:23 +0000 Subject: [PATCH 220/327] Added Pawel's origin commit message into the osggpucull source as it examples a lot about how the example works --- examples/osggpucull/osggpucull.cpp | 131 +++++++++++++++++++++++++++++ 1 file changed, 131 insertions(+) diff --git a/examples/osggpucull/osggpucull.cpp b/examples/osggpucull/osggpucull.cpp index 4b87433b6..7b8bd8a1d 100644 --- a/examples/osggpucull/osggpucull.cpp +++ b/examples/osggpucull/osggpucull.cpp @@ -13,6 +13,137 @@ * */ + /** osggpucull example. + + A geometry instancing rendering algorithm consisting of two consequent phases : + + - first phase is a GLSL shader performing object culling and LOD picking ( a culling shader ). + Every culled object is represented as GL_POINT in the input osg::Geometry. + The output of the culling shader is a set of object LODs that need to be rendered. + The output is stored in texture buffer objects. No pixel is drawn to the screen + because GL_RASTERIZER_DISCARD mode is used. + + - second phase draws osg::Geometry containing merged LODs using glDrawArraysIndirect() + function. Information about quantity of instances to render, its positions and other + parameters is sourced from texture buffer objects filled in the first phase. + + The example uses various OpenGL 4.2 features such as texture buffer objects, + atomic counters, image units and functions defined in GL_ARB_shader_image_load_store + extension to achieve its goal and thus will not work on graphic cards with older OpenGL + versions. + + The example was tested on Linux and Windows with NVidia 570 and 580 cards. + The tests on AMD cards were not conducted ( due to lack of it ). + The tests were performed using OSG revision 14088. + + The main advantages of this rendering method : + - instanced rendering capable of drawing thousands of different objects with + almost no CPU intervention ( cull and draw times are close to 0 ms ). + - input objects may be sourced from any OSG graph ( for example - information about + object points may be stored in a PagedLOD graph. This way we may cover the whole + countries with trees, buildings and other objects ). + Furthermore if we create osgDB plugins that generate data on the fly, we may + generate information for every grass blade for that country. + - every object may have its own parameters and thus may be distinct from other objects + of the same type. + - relatively low memory footprint ( single object information is stored in a few + vertex attributes ). + - no GPU->CPU roundtrip typical for such methods ( method uses atomic counters + and glDrawArraysIndirect() function instead of OpenGL queries. This way + information about quantity of rendered objects never goes back to CPU. + The typical GPU->CPU roundtrip cost is about 2 ms ). + - this example also shows how to render dynamic objects ( objects that may change + its position ) with moving parts ( like car wheels or airplane propellers ) . + The obvious extension to that dynamic method would be the animated crowd rendering. + - rendered objects may be easily replaced ( there is no need to process the whole + OSG graphs, because these graphs store only positional information ). + + The main disadvantages of a method : + - the maximum quantity of objects to render must be known beforehand + ( because texture buffer objects holding data between phases have constant size ). + - OSG statistics are flawed ( they don't know anymore how many objects are drawn ). + - osgUtil::Intersection does not work + + Example application may be used to make some performance tests, so below you + will find some extended parameter description : + --skip-dynamic - skip rendering of dynamic objects if you only want to + observe static object statistics + --skip-static - the same for static objects + --dynamic-area-size - size of the area for dynamic rendering. Default = 1000 meters + ( square 1000m x 1000m ). Along with density defines + how many dynamic objects is there in the example. + --static-area-size - the same for static objects. Default = 2000 meters + ( square 2000m x 2000m ). + + Example application defines some parameters (density, LOD ranges, object's triangle count). + You may manipulate its values using below described modifiers: + --density-modifier - density modifier in percent. Default = 100%. + Density ( along with LOD ranges ) defines maximum + quantity of rendered objects. registerType() function + accepts maximum density ( in objects per square kilometer ) + as its parameter. + --lod-modifier - defines the LOD ranges. Default = 100%. + --triangle-modifier - defines the number of triangles in finally rendered objects. + Default = 100 %. + --instances-per-cell - for static rendering the application builds OSG graph using + InstanceCell class ( this class is a modified version of Cell class + from osgforest example - it builds simple quadtree from a list + of static instances ). This parameter defines maximum number + of instances in a single osg::Group in quadtree. + If, for example, you modify it to value=100, you will see + really big cull time in OSG statistics ( because resulting + tree generated by InstanceCell will be very deep ). + Default value = 4096 . + --export-objects - write object geometries and quadtree of instances to osgt files + for later analysis. + --use-multi-draw - use glMultiDrawArraysIndirect() instead of glDrawArraysIndirect() in a + draw shader. Thanks to this we may render all ( different ) objects + using only one draw call. Requires OpenGL version 4.3. + + This application is inspired by Daniel Rákos work : "GPU based dynamic geometry LOD" that + may be found under this address : http://rastergrid.com/blog/2010/10/gpu-based-dynamic-geometry-lod/ + There are however some differences : + - Daniel Rákos uses GL queries to count objects to render, while this example + uses atomic counters ( no GPU->CPU roundtrip ) + - this example does not use transform feedback buffers to store intermediate data + ( it uses texture buffer objects instead ). + - I use only the vertex shader to cull objects, whereas Daniel Rákos uses vertex shader + and geometry shader ( because only geometry shader can send more than one primitive + to transform feedback buffers ). + - objects in the example are drawn using glDrawArraysIndirect() function, + instead of glDrawElementsInstanced(). + + Finally there are some things to consider/discuss : + - the whole algorithm exploits nice OpenGL feature that any GL buffer + may be bound as any type of buffer ( in our example a buffer is once bound + as a texture buffer object, and later is bound as GL_DRAW_INDIRECT_BUFFER ). + osg::TextureBuffer class has one handy method to do that trick ( bindBufferAs() ), + and new primitive sets use osg::TextureBuffer as input. + For now I added new primitive sets to example ( DrawArraysIndirect and + MultiDrawArraysIndirect defined in examples/osggpucull/DrawIndirectPrimitiveSet.h ), + but if Robert will accept its current implementations ( I mean - primitive + sets that have osg::TextureBuffer in constructor ), I may add it to + osg/include/PrimitiveSet header. + - I used BufferTemplate class writen and published by Aurelien in submission forum + some time ago. For some reason this class never got into osg/include, but is + really needed during creation of UBOs, TBOs, and possibly SSBOs in the future. + I added std::vector specialization to that template class. + - I needed to create similar osg::Geometries with variable number of vertices + ( to create different LODs in my example ). For this reason I've written + some code allowing me to create osg::Geometries from osg::Shape descendants. + This code may be found in ShapeToGeometry.* files. Examples of use are in + osggpucull.cpp . The question is : should this code stay in example, or should + it be moved to osgUtil ? + - this remark is important for NVidia cards on Linux and Windows : if + you have "Sync to VBlank" turned ON in nvidia-settings and you want to see + real GPU times in OSG statistics window, you must set the power management + settings to "Prefer maximum performance", because when "Adaptive mode" is used, + the graphic card's clock may be slowed down by the driver during program execution + ( On Linux when OpenGL application starts in adaptive mode, clock should work + as fast as possible, but after one minute of program execution, the clock slows down ). + This happens when GPU time in OSG statistics window is shorter than 3 ms. +*/ + #include #include #include From baf6945a7a507c7d325476df80fab2729d6c93e0 Mon Sep 17 00:00:00 2001 From: Julien Valentin Date: Wed, 8 Nov 2017 15:40:11 +0100 Subject: [PATCH 221/327] add funcs to read Object from a GZ stream --- src/osgPlugins/gz/ReaderWriterGZ.cpp | 63 +++++++++++++++++++++++++++- 1 file changed, 62 insertions(+), 1 deletion(-) diff --git a/src/osgPlugins/gz/ReaderWriterGZ.cpp b/src/osgPlugins/gz/ReaderWriterGZ.cpp index 8a917742e..477390407 100644 --- a/src/osgPlugins/gz/ReaderWriterGZ.cpp +++ b/src/osgPlugins/gz/ReaderWriterGZ.cpp @@ -45,7 +45,7 @@ class ReaderWriterGZ : public osgDB::ReaderWriter ~ReaderWriterGZ(); - virtual const char* className() const { return "HTTP Protocol Model Reader"; } + virtual const char* className() const { return "GZ Archive Reader/Writer"; } virtual ReadResult openArchive(const std::string& fileName,ArchiveStatus status, unsigned int , const Options* options) const { @@ -77,6 +77,67 @@ class ReaderWriterGZ : public osgDB::ReaderWriter ReadResult readFile(ObjectType objectType, const std::string& fullFileName, const osgDB::ReaderWriter::Options* options) const; + ///return the reader for fullFileName and a outuncompessed stream fetching this file in the archive + osgDB::ReaderWriter *getStreamAndReader(std::stringstream& outuncompessed, std::istream& fin, const std::string& fullFileName) const { + std::string ext = osgDB::getLowerCaseFileExtension(fullFileName); + osgDB::ReaderWriter* rw = 0; + rw = osgDB::Registry::instance()->getReaderWriterForExtension(ext); + std::string baseFileName = osgDB::getNameLessExtension(fullFileName); + std::string baseExt = osgDB::getLowerCaseFileExtension(baseFileName); + rw = osgDB::Registry::instance()->getReaderWriterForExtension(baseExt); + OSG_INFO<getPluginStringData("STREAM_FILENAME"); + std::string ext = osgDB::getLowerCaseFileExtension(fullFileName); + if (!acceptsExtension(ext)) return ReadResult::FILE_NOT_HANDLED; + if (osgDB::containsServerAddress(fullFileName)) return ReadResult::FILE_NOT_HANDLED; + std::stringstream decstream; + osgDB::ReaderWriter* rw = getStreamAndReader(decstream, fin, fullFileName); + return readFile(IMAGE, rw, decstream, local_opt); + } + + virtual ReadResult readHeightField(std::istream& fin,const osgDB::ReaderWriter::Options* local_opt=NULL) const { + std::string fullFileName = local_opt->getPluginStringData("STREAM_FILENAME"); + std::string ext = osgDB::getLowerCaseFileExtension(fullFileName); + if (!acceptsExtension(ext)) return ReadResult::FILE_NOT_HANDLED; + if (osgDB::containsServerAddress(fullFileName)) return ReadResult::FILE_NOT_HANDLED; + std::stringstream decstream; + osgDB::ReaderWriter* rw = getStreamAndReader(decstream, fin, fullFileName); + return readFile(HEIGHTFIELD, rw, decstream, local_opt); + } + + virtual ReadResult readNode(std::istream& fin,const osgDB::ReaderWriter::Options* local_opt=NULL) const { + std::string fullFileName = local_opt->getPluginStringData("STREAM_FILENAME"); + std::string ext = osgDB::getLowerCaseFileExtension(fullFileName); + if (!acceptsExtension(ext)) return ReadResult::FILE_NOT_HANDLED; + if (osgDB::containsServerAddress(fullFileName)) return ReadResult::FILE_NOT_HANDLED; + std::stringstream decstream; + osgDB::ReaderWriter* rw = getStreamAndReader(decstream, fin, fullFileName); + return readFile(NODE, rw, decstream, local_opt); + } + + virtual ReadResult readObject(std::istream& fin,const osgDB::ReaderWriter::Options* local_opt=NULL) const { + std::string fullFileName = local_opt->getPluginStringData("STREAM_FILENAME"); + std::string ext = osgDB::getLowerCaseFileExtension(fullFileName); + if (!acceptsExtension(ext)) return ReadResult::FILE_NOT_HANDLED; + if (osgDB::containsServerAddress(fullFileName)) return ReadResult::FILE_NOT_HANDLED; + std::stringstream decstream; + osgDB::ReaderWriter* rw = getStreamAndReader(decstream, fin, fullFileName); + return readFile(OBJECT, rw, decstream, local_opt); + } + virtual ReadResult readArchive(std::istream& fin,const osgDB::ReaderWriter::Options* local_opt=NULL) const { + std::string fullFileName = local_opt->getPluginStringData("STREAM_FILENAME"); + std::string ext = osgDB::getLowerCaseFileExtension(fullFileName); + if (!acceptsExtension(ext)) return ReadResult::FILE_NOT_HANDLED; + if (osgDB::containsServerAddress(fullFileName)) return ReadResult::FILE_NOT_HANDLED; + std::stringstream decstream; + osgDB::ReaderWriter* rw = getStreamAndReader(decstream, fin, fullFileName); + return readFile(ARCHIVE, rw, decstream, local_opt); + } virtual WriteResult writeObject(const osg::Object& obj, const std::string& fileName, const osgDB::ReaderWriter::Options* options) const From 79afe82774c25f1cce9fd390dc64dfc6141c424f Mon Sep 17 00:00:00 2001 From: Julien Valentin Date: Wed, 8 Nov 2017 15:57:34 +0100 Subject: [PATCH 222/327] replace string with stringstream (avoid a string copy at read) --- src/osgPlugins/gz/ReaderWriterGZ.cpp | 36 ++++++++++++++-------------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/src/osgPlugins/gz/ReaderWriterGZ.cpp b/src/osgPlugins/gz/ReaderWriterGZ.cpp index 477390407..5e8a5bdf3 100644 --- a/src/osgPlugins/gz/ReaderWriterGZ.cpp +++ b/src/osgPlugins/gz/ReaderWriterGZ.cpp @@ -81,11 +81,11 @@ class ReaderWriterGZ : public osgDB::ReaderWriter osgDB::ReaderWriter *getStreamAndReader(std::stringstream& outuncompessed, std::istream& fin, const std::string& fullFileName) const { std::string ext = osgDB::getLowerCaseFileExtension(fullFileName); osgDB::ReaderWriter* rw = 0; - rw = osgDB::Registry::instance()->getReaderWriterForExtension(ext); - std::string baseFileName = osgDB::getNameLessExtension(fullFileName); - std::string baseExt = osgDB::getLowerCaseFileExtension(baseFileName); - rw = osgDB::Registry::instance()->getReaderWriterForExtension(baseExt); - OSG_INFO<getReaderWriterForExtension( ext ); + std::string baseFileName = osgDB::getNameLessExtension( fullFileName ); + std::string baseExt = osgDB::getLowerCaseFileExtension( baseFileName ); + rw = osgDB::Registry::instance()->getReaderWriterForExtension( baseExt ); + OSG_INFO<< className() << "::getStreamAndReader:" << baseExt << " ReaderWriter " << rw < Date: Fri, 10 Nov 2017 12:41:21 +0000 Subject: [PATCH 223/327] Fixed crash in copy constructor due to copy and paste/typo. --- src/osgAnimation/RigGeometry.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/osgAnimation/RigGeometry.cpp b/src/osgAnimation/RigGeometry.cpp index 6884b6c12..1f3764b48 100644 --- a/src/osgAnimation/RigGeometry.cpp +++ b/src/osgAnimation/RigGeometry.cpp @@ -67,7 +67,7 @@ RigGeometry::RigGeometry() RigGeometry::RigGeometry(const RigGeometry& b, const osg::CopyOp& copyop) : osg::Geometry(b,copyop), _geometry(b._geometry), - _rigTransformImplementation(osg::clone(_rigTransformImplementation.get(), copyop)), + _rigTransformImplementation(osg::clone(b._rigTransformImplementation.get(), copyop)), _vertexInfluenceMap(b._vertexInfluenceMap), _needToComputeMatrix(b._needToComputeMatrix) { From 821ca4e5cd821c6891f069850a0b928a2f3a1bcf Mon Sep 17 00:00:00 2001 From: OpenSceneGraph git repository Date: Fri, 10 Nov 2017 16:58:29 +0000 Subject: [PATCH 224/327] Revert " following guidance from OpenGL Common Mistakes:" --- src/osg/Texture.cpp | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/osg/Texture.cpp b/src/osg/Texture.cpp index d43b0d665..25782619f 100644 --- a/src/osg/Texture.cpp +++ b/src/osg/Texture.cpp @@ -2298,8 +2298,9 @@ void Texture::applyTexImage2D_load(State& state, GLenum target, const Image* ima if (height == 0) height = 1; - glTexImage2D( target, k, _internalFormat, - width, height, _borderWidth, + glTexSubImage2D( target, k, + 0, 0, + width, height, (GLenum)image->getPixelFormat(), (GLenum)image->getDataType(), dataPtr + image->getMipmapOffset(k)); @@ -2602,11 +2603,12 @@ void Texture::applyTexImage2D_subload(State& state, GLenum target, const Image* if (height == 0) height = 1; - glTexImage2D( target, k, _internalFormat, - width, height, _borderWidth, - (GLenum)image->getPixelFormat(), - (GLenum)image->getDataType(), - dataPtr + image->getMipmapOffset(k)); + glTexSubImage2D( target, k, + 0, 0, + width, height, + (GLenum)image->getPixelFormat(), + (GLenum)image->getDataType(), + dataPtr + image->getMipmapOffset(k)); width >>= 1; height >>= 1; From dfec052eb983c10467faeae16c9cb7dca5b45379 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Fri, 10 Nov 2017 17:12:20 +0000 Subject: [PATCH 225/327] Fixed handling of GL_TEXTURE_CUBE_MAP when using glTextureStorage. --- src/osg/Texture.cpp | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/osg/Texture.cpp b/src/osg/Texture.cpp index 25782619f..752cb22d9 100644 --- a/src/osg/Texture.cpp +++ b/src/osg/Texture.cpp @@ -2286,7 +2286,17 @@ void Texture::applyTexImage2D_load(State& state, GLenum target, const Image* ima if(useTexStorrage) { - extensions->glTexStorage2D(target, numMipmapLevels, sizedInternalFormat, width, height); + if (getTextureTarget()==GL_TEXTURE_CUBE_MAP) + { + if (target==GL_TEXTURE_CUBE_MAP_POSITIVE_X) + { + extensions->glTexStorage2D(GL_TEXTURE_CUBE_MAP, numMipmapLevels, sizedInternalFormat, width, height); + } + } + else + { + extensions->glTexStorage2D(target, numMipmapLevels, sizedInternalFormat, width, height); + } if( !compressed_image ) { From eb061d9acc4f048ab2913af66afb8e0a35b5c6d7 Mon Sep 17 00:00:00 2001 From: Andreas Ekstrand Date: Sat, 11 Nov 2017 10:19:09 +0000 Subject: [PATCH 226/327] I have implemented readObject to make loading objects from SceneLoader in the LWS plugin work. I'm not sure about other implications from changes leading up to this problem (readRefFile instead of readNodeFile in SceneLoader) but this fix works for me. --- src/osgPlugins/lwo/ReaderWriterLWO.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/osgPlugins/lwo/ReaderWriterLWO.cpp b/src/osgPlugins/lwo/ReaderWriterLWO.cpp index 5bd5b08f2..779bf7c34 100644 --- a/src/osgPlugins/lwo/ReaderWriterLWO.cpp +++ b/src/osgPlugins/lwo/ReaderWriterLWO.cpp @@ -56,6 +56,11 @@ public: virtual const char* className() const { return "Lightwave Object Reader"; } + virtual ReadResult readObject(const std::string& file, const osgDB::ReaderWriter::Options* options) const + { + return readNode(file, options); + } + virtual ReadResult readNode(const std::string& file, const osgDB::ReaderWriter::Options* options) const { std::string ext = osgDB::getLowerCaseFileExtension(file); From ee118c872f1d4fa0ad2ab7a0b96bf2279bc3d925 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Sat, 11 Nov 2017 11:17:34 +0000 Subject: [PATCH 227/327] Restructed the ref counting of the rawImageRec structure so that it's done with a separate refImageRec struct so it doesn't interfer with the writing of the rawImageRec as a header when writing to .rgb --- src/osgPlugins/rgb/ReaderWriterRGB.cpp | 131 +++++++++++++------------ 1 file changed, 68 insertions(+), 63 deletions(-) diff --git a/src/osgPlugins/rgb/ReaderWriterRGB.cpp b/src/osgPlugins/rgb/ReaderWriterRGB.cpp index 63d144955..ffaad7026 100644 --- a/src/osgPlugins/rgb/ReaderWriterRGB.cpp +++ b/src/osgPlugins/rgb/ReaderWriterRGB.cpp @@ -39,7 +39,7 @@ using namespace osg; typedef unsigned int size_pos; -struct rawImageRec : public osg::Referenced +struct rawImageRec { rawImageRec(): imagic(0), @@ -59,7 +59,7 @@ struct rawImageRec : public osg::Referenced { } - virtual ~rawImageRec() + ~rawImageRec() { if (tmp) delete [] tmp; if (tmpR) delete [] tmpR; @@ -131,6 +131,11 @@ struct rawImageRec : public osg::Referenced } }; +struct refImageRec : public rawImageRec, public osg::Referenced +{ +}; + + static void ConvertShort(unsigned short *array, long length) { unsigned long b1, b2; @@ -163,7 +168,7 @@ static void ConvertLong(GLuint *array, long length) -static osg::ref_ptr RawImageOpen(std::istream& fin) +static osg::ref_ptr RawImageOpen(std::istream& fin) { union { @@ -173,7 +178,7 @@ static osg::ref_ptr RawImageOpen(std::istream& fin) int x; - osg::ref_ptr raw = new rawImageRec; + osg::ref_ptr raw = new refImageRec; if (raw == NULL) { OSG_WARN<< "Out of memory!"<< std::endl; @@ -278,27 +283,27 @@ static osg::ref_ptr RawImageOpen(std::istream& fin) } -static void RawImageGetRow(rawImageRec *raw, unsigned char *buf, int y, int z) +static void RawImageGetRow(rawImageRec& raw, unsigned char *buf, int y, int z) { unsigned char *iPtr, *oPtr; unsigned short pixel; int count, done = 0; unsigned short *tempShort; - if ((raw->type & 0xFF00) == 0x0100) + if ((raw.type & 0xFF00) == 0x0100) { - size_pos pos = raw->rowStart[static_cast(y)+static_cast(z)*static_cast(raw->sizeY)]; + size_pos pos = raw.rowStart[static_cast(y)+static_cast(z)*static_cast(raw.sizeY)]; - size_pos amount = raw->rowSize[static_cast(y)+static_cast(z)*static_cast(raw->sizeY)]; + size_pos amount = raw.rowSize[static_cast(y)+static_cast(z)*static_cast(raw.sizeY)]; - raw->file->seekg(pos, std::ios::beg); - raw->file->read((char*)raw->tmp, amount); + raw.file->seekg(pos, std::ios::beg); + raw.file->read((char*)raw.tmp, amount); - iPtr = raw->tmp; + iPtr = raw.tmp; oPtr = buf; while (!done) { - if (raw->bpc == 1) + if (raw.bpc == 1) pixel = *iPtr++; else { @@ -308,15 +313,15 @@ static void RawImageGetRow(rawImageRec *raw, unsigned char *buf, int y, int z) iPtr = reinterpret_cast(tempShort); } - if(raw->bpc != 1) + if(raw.bpc != 1) ConvertShort(&pixel, 1); count = (int)(pixel & 0x7F); // limit the count value to the remiaing row size - if ((static_cast(raw->sizeX)*static_cast(raw->bpc)) <= (oPtr - buf)) + if ((static_cast(raw.sizeX)*static_cast(raw.bpc)) <= (oPtr - buf)) { - count = static_cast(raw->sizeX) - (oPtr - buf) / static_cast(raw->bpc); + count = static_cast(raw.sizeX) - (oPtr - buf) / static_cast(raw.bpc); } if (count<=0) @@ -329,7 +334,7 @@ static void RawImageGetRow(rawImageRec *raw, unsigned char *buf, int y, int z) { while (count--) { - if(raw->bpc == 1) + if(raw.bpc == 1) *oPtr++ = *iPtr++; else{ tempShort = reinterpret_cast(iPtr); @@ -348,7 +353,7 @@ static void RawImageGetRow(rawImageRec *raw, unsigned char *buf, int y, int z) } else { - if (raw->bpc == 1) + if (raw.bpc == 1) { pixel = *iPtr++; } @@ -359,11 +364,11 @@ static void RawImageGetRow(rawImageRec *raw, unsigned char *buf, int y, int z) tempShort++; iPtr = reinterpret_cast(tempShort); } - if(raw->bpc != 1) + if(raw.bpc != 1) ConvertShort(&pixel, 1); while (count--) { - if(raw->bpc == 1) + if(raw.bpc == 1) *oPtr++ = pixel; else { @@ -379,87 +384,87 @@ static void RawImageGetRow(rawImageRec *raw, unsigned char *buf, int y, int z) else { size_pos pos = static_cast(512)+ - (static_cast(y)*static_cast(raw->sizeX)*static_cast(raw->bpc))+ - (static_cast(z)*static_cast(raw->sizeX)*static_cast(raw->sizeY)*static_cast(raw->bpc)); + (static_cast(y)*static_cast(raw.sizeX)*static_cast(raw.bpc))+ + (static_cast(z)*static_cast(raw.sizeX)*static_cast(raw.sizeY)*static_cast(raw.bpc)); - size_pos amount = static_cast(raw->sizeX)*static_cast(raw->bpc); + size_pos amount = static_cast(raw.sizeX)*static_cast(raw.bpc); - raw->file->seekg(pos,std::ios::beg); - raw->file->read((char*)buf, amount); - if(raw->swapFlag && raw->bpc != 1){ - ConvertShort(reinterpret_cast(buf), raw->sizeX); + raw.file->seekg(pos,std::ios::beg); + raw.file->read((char*)buf, amount); + if(raw.swapFlag && raw.bpc != 1){ + ConvertShort(reinterpret_cast(buf), raw.sizeX); } } } -static void RawImageGetData(rawImageRec *raw, unsigned char **data ) +static void RawImageGetData(rawImageRec& raw, unsigned char **data ) { unsigned char *ptr; int i, j; unsigned short *tempShort; // // round the width to a factor 4 - // int width = (int)(floorf((float)raw->sizeX/4.0f)*4.0f); - // if (width!=raw->sizeX) width += 4; + // int width = (int)(floorf((float)raw.sizeX/4.0f)*4.0f); + // if (width!=raw.sizeX) width += 4; // byte aligned. - OSG_INFO<<"raw->sizeX = "<sizeX<sizeY = "<sizeY<sizeZ = "<sizeZ<bpc = "<bpc<addShader(vertexshader.get()); } + unsigned int nbAttribs = getNumVertexAttrib(); for (unsigned int i = 0; i < nbAttribs; i++) { @@ -144,6 +146,7 @@ struct MyRigTransformHardware : public osgAnimation::RigTransformHardware struct SetupRigGeometry : public osg::NodeVisitor { bool _hardware; + SetupRigGeometry( bool hardware = true) : osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN), _hardware(hardware) {} void apply(osg::Geode& geode) @@ -156,7 +159,8 @@ struct SetupRigGeometry : public osg::NodeVisitor if (_hardware) { osgAnimation::RigGeometry* rig = dynamic_cast(&geom); - if (rig){ + if (rig) + { rig->setRigTransformImplementation(new MyRigTransformHardware); osgAnimation::MorphGeometry *morph=dynamic_cast(rig->getSourceGeometry()); if(morph)morph->setMorphTransformImplementation(new osgAnimation::MorphTransformHardware); @@ -266,7 +270,6 @@ int main (int argc, char* argv[]) { for (double j = 0.0; j < yChar; j++) { - osg::ref_ptr c = createCharacterInstance(root.get(), hardware); osg::MatrixTransform* tr = new osg::MatrixTransform; tr->setMatrix(osg::Matrix::translate( 2.0 * (i - xChar * .5), @@ -278,7 +281,6 @@ int main (int argc, char* argv[]) } std::cout << "created " << xChar * yChar << " instance" << std::endl; - return viewer.run(); } From ca5ce00783cad46abbc4e95e10cc7ed85a1eb5c4 Mon Sep 17 00:00:00 2001 From: OpenSceneGraph git repository Date: Sat, 11 Nov 2017 12:29:45 +0000 Subject: [PATCH 230/327] coding style/readability fixes --- include/osgAnimation/AnimationManagerBase | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/include/osgAnimation/AnimationManagerBase b/include/osgAnimation/AnimationManagerBase index 15b4617ab..0c5b8ec36 100644 --- a/include/osgAnimation/AnimationManagerBase +++ b/include/osgAnimation/AnimationManagerBase @@ -43,9 +43,10 @@ namespace osgAnimation AnimationList& getAnimationList() { return _animations;} //uniformisation of the API - inline Animation * getRegisteredAnimation(unsigned int i){return _animations[i].get();} - inline unsigned int getNumRegisteredAnimations()const{return _animations.size();} - inline void addRegisteredAnimation(Animation* animation){ + inline Animation * getRegisteredAnimation(unsigned int i) { return _animations[i].get();} + inline unsigned int getNumRegisteredAnimations() const { return _animations.size();} + inline void addRegisteredAnimation(Animation* animation) + { _needToLink = true; _animations.push_back(animation); buildTargetReference(); @@ -59,7 +60,6 @@ namespace osgAnimation this Operation must be done each frame */ void clearTargets(); - LinkVisitor* getOrCreateLinkVisitor(); void setLinkVisitor(LinkVisitor*); From b23cc720379ec7623b5f121160e2fac62194e49a Mon Sep 17 00:00:00 2001 From: OpenSceneGraph git repository Date: Sat, 11 Nov 2017 12:33:44 +0000 Subject: [PATCH 231/327] coding style/readability fixes --- src/osgAnimation/MorphGeometry.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/osgAnimation/MorphGeometry.cpp b/src/osgAnimation/MorphGeometry.cpp index 5f499716c..964ff35a2 100644 --- a/src/osgAnimation/MorphGeometry.cpp +++ b/src/osgAnimation/MorphGeometry.cpp @@ -63,7 +63,8 @@ UpdateMorph::UpdateMorph(const UpdateMorph& apc,const osg::CopyOp& copyop) : osg::Object(apc, copyop), osg::Callback(apc, copyop), AnimationUpdateCallback(apc, copyop) -{_targetNames=apc._targetNames; +{ + _targetNames=apc._targetNames; } UpdateMorph::UpdateMorph(const std::string& name) : AnimationUpdateCallback(name) @@ -106,8 +107,6 @@ void UpdateMorph::operator()(osg::Node* node, osg::NodeVisitor* nv) traverse(node,nv); } - - bool UpdateMorph::needLink() const { // the idea is to return true if nothing is linked From 8ee8550aac8d94f6df581844bc08f5cf84cb897f Mon Sep 17 00:00:00 2001 From: OpenSceneGraph git repository Date: Sat, 11 Nov 2017 12:42:34 +0000 Subject: [PATCH 232/327] Fix of incorrect Program assignment bug and coding style --- src/osgAnimation/MorphTransformHardware.cpp | 105 ++++++++++++-------- 1 file changed, 63 insertions(+), 42 deletions(-) diff --git a/src/osgAnimation/MorphTransformHardware.cpp b/src/osgAnimation/MorphTransformHardware.cpp index a275d5680..ad2a6859d 100644 --- a/src/osgAnimation/MorphTransformHardware.cpp +++ b/src/osgAnimation/MorphTransformHardware.cpp @@ -54,7 +54,8 @@ bool MorphTransformHardware::init(MorphGeometry& morphGeometry) } osg::Vec3Array* normal = dynamic_cast(morphGeometry.getNormalArray()); bool normalmorphable = morphGeometry.getMorphNormals() && normal&&(normal->getBinding()==osg::Array::BIND_PER_VERTEX); - if(!normalmorphable) { + if(!normalmorphable) + { OSG_WARN << "MorphTransformHardware::morph geometry "<( normal->clone(osg::CopyOp::DEEP_COPY_ARRAYS))); } } + ///end check morphGeometry.setVertexArray(morphGeometry.getVertexSource()); morphGeometry.setNormalArray(morphGeometry.getNormalSource(),osg::Array::BIND_PER_VERTEX); @@ -72,25 +74,32 @@ bool MorphTransformHardware::init(MorphGeometry& morphGeometry) //create one TBO for all morphtargets (pack vertex/normal) osg::Vec3Array * morphTargets=new osg::Vec3Array ; MorphGeometry::MorphTargetList & morphlist=morphGeometry.getMorphTargetList(); - for(MorphGeometry::MorphTargetList::const_iterator curmorph=morphlist.begin(); curmorph!=morphlist.end(); ++curmorph) { + for(MorphGeometry::MorphTargetList::const_iterator curmorph=morphlist.begin(); curmorph!=morphlist.end(); ++curmorph) + { const osg::Geometry * morphtargetgeom= curmorph->getGeometry() ; const osg::Vec3Array *varray=(osg::Vec3Array*)morphtargetgeom->getVertexArray(); const osg::Vec3Array *narray=(osg::Vec3Array*)morphtargetgeom->getNormalArray(); - if(morphGeometry.getMethod()==MorphGeometry::RELATIVE){ - for(unsigned int i=0; igetNumElements(); ++i) { + if(morphGeometry.getMethod()==MorphGeometry::RELATIVE) + { + for(unsigned int i=0; igetNumElements(); ++i) + { morphTargets->push_back( (*varray)[i]); morphTargets->push_back( (*narray)[i]); } - }else{ + } + else + { //convert to RELATIVE as it involve less math in the VS than NORMALIZED const osg::Vec3Array *ovarray=(osg::Vec3Array*)morphGeometry.getVertexArray(); const osg::Vec3Array *onarray=(osg::Vec3Array*)morphGeometry.getNormalArray(); - for(unsigned int i=0; igetNumElements(); ++i) { + for(unsigned int i=0; igetNumElements(); ++i) + { morphTargets->push_back( (*varray)[i]- (*ovarray)[i] ); morphTargets->push_back( (*narray)[i]- (*onarray)[i] ); } } } + osg::TextureBuffer * morphTargetsTBO=new osg::TextureBuffer(); morphTargetsTBO->setBufferData(morphTargets); morphTargetsTBO->setInternalFormat( GL_RGB32F_ARB ); @@ -110,56 +119,66 @@ bool MorphTransformHardware::init(MorphGeometry& morphGeometry) 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){ + { + if(program->getShader(i)->getType()==osg::Shader::VERTEX) + { // vertexshader=program->getShader(i); program->removeShader(vertexshader); } - }else { - - } program = new osg::Program; + } + } + + if (!program) + { + program = new osg::Program; + } + program->setName("HardwareMorphing"); //set default source if _shader is not user setted - if (!vertexshader.valid()){ + if (!vertexshader.valid()) + { if (!_shader.valid()) vertexshader = osg::Shader::readShaderFile(osg::Shader::VERTEX,"morphing.vert"); - else vertexshader=_shader; + else + vertexshader=_shader; } - - if (!vertexshader.valid()) { + 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_MORPHWEIGHT"); - std::size_t start = str.find(toreplace); - if (std::string::npos == start){ - ///perhaps remanance from previous init (if saved after init) so reload shader - vertexshader = osg::Shader::readShaderFile(osg::Shader::VERTEX,"morphing.vert"); - if (!vertexshader.valid()) { - OSG_WARN << "RigTransformHardware can't load VertexShader" << std::endl; - return false; + std::string str = vertexshader->getShaderSource(); + std::string toreplace = std::string("MAX_MORPHWEIGHT"); + std::size_t start = str.find(toreplace); + if (std::string::npos == start) + { + // perhaps remanance from previous init (if saved after init) so reload shader + vertexshader = osg::Shader::readShaderFile(osg::Shader::VERTEX,"morphing.vert"); + if (!vertexshader.valid()) + { + OSG_WARN << "RigTransformHardware can't load VertexShader" << std::endl; + return false; + } + str = vertexshader->getShaderSource(); + start = str.find(toreplace); } - str = vertexshader->getShaderSource(); - start = str.find(toreplace); + if (std::string::npos != start) + { + std::stringstream ss; + ss << _uniformTargetsWeight->getNumElements(); + str.replace(start, toreplace.size(), ss.str()); + vertexshader->setShaderSource(str); + } + else + { + OSG_WARN << "MAX_MORPHWEIGHT not found in Shader! " << str << std::endl; + } + OSG_INFO << "Shader " << str << std::endl; } - if (std::string::npos != start) { - std::stringstream ss; - ss << _uniformTargetsWeight->getNumElements(); - str.replace(start, toreplace.size(), ss.str()); - vertexshader->setShaderSource(str); - } - else - { - OSG_WARN << "MAX_MORPHWEIGHT not found in Shader! " << str << std::endl; - } - OSG_INFO << "Shader " << str << std::endl; - } - - program->addShader(vertexshader.get()); //morphGeometry.setStateSet((osg::StateSet *) osg::CopyOp()(source.getOrCreateStateSet())); @@ -174,18 +193,20 @@ bool MorphTransformHardware::init(MorphGeometry& morphGeometry) _needInit = false; return true; } + void MorphTransformHardware::operator()(MorphGeometry& geom) { - if (_needInit) - if (!init(geom)) - return; + if (_needInit && !init(geom)) return; + if (geom.isDirty()) { ///upload new morph weights each update via uniform int curimorph=0; MorphGeometry::MorphTargetList & morphlist=geom.getMorphTargetList(); for(MorphGeometry::MorphTargetList::const_iterator curmorph=morphlist.begin(); curmorph!=morphlist.end(); ++curmorph) + { _uniformTargetsWeight->setElement(curimorph++, curmorph->getWeight()); + } _uniformTargetsWeight->dirty(); geom.dirty(false); } From a5f6e4b0c43e1a795b37a6b1a6b13c697d61a101 Mon Sep 17 00:00:00 2001 From: OpenSceneGraph git repository Date: Sat, 11 Nov 2017 12:45:55 +0000 Subject: [PATCH 233/327] Small readability improvements --- include/osgAnimation/VertexInfluence | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/osgAnimation/VertexInfluence b/include/osgAnimation/VertexInfluence index 256d9c198..1bf1e6e01 100644 --- a/include/osgAnimation/VertexInfluence +++ b/include/osgAnimation/VertexInfluence @@ -65,7 +65,7 @@ namespace osgAnimation void cullInfluenceCountPerVertex(unsigned int maxnumbonepervertex, float minweight=0, bool renormalize=true); //compute PerVertexInfluenceList - void computePerVertexInfluenceList(std::vector& perVertexInfluenceList, unsigned int numvert)const; + void computePerVertexInfluenceList(std::vector& perVertexInfluenceList, unsigned int numvert) const; /// map a set of boneinfluence to a list of vertex indices sharing this set class VertexGroup: public std::pair @@ -77,7 +77,7 @@ namespace osgAnimation }; /// compute the minimal VertexGroup Set in which vertices shares the same influence set - void computeMinimalVertexGroupList(std::vector&uniqVertexGroupList, unsigned int numvert)const; + void computeMinimalVertexGroupList(std::vector&uniqVertexGroupList, unsigned int numvert) const; //Experimental removal of unexpressed bone from the skeleton void removeUnexpressedBones(Skeleton &skel) const; From f59efe0bfe0f15b9748530cff36df0730dd5b33e Mon Sep 17 00:00:00 2001 From: OpenSceneGraph git repository Date: Sat, 11 Nov 2017 12:46:48 +0000 Subject: [PATCH 234/327] Code readability improvement --- src/osgAnimation/AnimationManagerBase.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/osgAnimation/AnimationManagerBase.cpp b/src/osgAnimation/AnimationManagerBase.cpp index 24209d08b..237b44203 100644 --- a/src/osgAnimation/AnimationManagerBase.cpp +++ b/src/osgAnimation/AnimationManagerBase.cpp @@ -105,6 +105,7 @@ void AnimationManagerBase::removeRegisteredAnimation(Animation* animation) { unregisterAnimation(animation); } + void AnimationManagerBase::unregisterAnimation(Animation* animation) { AnimationList::iterator it = std::find(_animations.begin(), _animations.end(), animation); From 8e55ed59235cec296d2690ce54795b1a185d7684 Mon Sep 17 00:00:00 2001 From: OpenSceneGraph git repository Date: Sat, 11 Nov 2017 12:54:28 +0000 Subject: [PATCH 235/327] Code readability improvements --- src/osgAnimation/RigTransformSoftware.cpp | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/osgAnimation/RigTransformSoftware.cpp b/src/osgAnimation/RigTransformSoftware.cpp index 35993817a..56f6c6477 100644 --- a/src/osgAnimation/RigTransformSoftware.cpp +++ b/src/osgAnimation/RigTransformSoftware.cpp @@ -91,9 +91,12 @@ void RigTransformSoftware::buildMinimumUpdateSet( const RigGeometry&rig ) vg.getVertices().push_back(vertexID); } } + _uniqVertexGroupList.reserve(unifyBuffer.size()); for (UnifyBoneGroup::const_iterator it = unifyBuffer.begin(); it != unifyBuffer.end(); ++it) + { _uniqVertexGroupList.push_back(it->second); + } OSG_INFO << "uniq groups " << _uniqVertexGroupList.size() << " for " << rig.getName() << std::endl; } @@ -144,6 +147,7 @@ bool RigTransformSoftware::init(RigGeometry&rig) if(!rig.getSkeleton()) return false; + ///get bonemap from skeleton BoneMapVisitor mapVisitor; rig.getSkeleton()->accept(mapVisitor); @@ -175,6 +179,7 @@ bool RigTransformSoftware::init(RigGeometry&rig) localid2bone.push_back(0); continue; } + Bone* bone = bmit->second.get(); localid2bone.push_back(bone); } @@ -226,15 +231,14 @@ void RigTransformSoftware::VertexGroup::normalize() void RigTransformSoftware::operator()(RigGeometry& geom) { - if (_needInit) - if (!init(geom)) - return; + if (_needInit && !init(geom)) return; if (!geom.getSourceGeometry()) { OSG_WARN << this << " RigTransformSoftware no source geometry found on RigGeometry" << std::endl; return; } + osg::Geometry& source = *geom.getSourceGeometry(); osg::Geometry& destination = geom; @@ -247,11 +251,9 @@ void RigTransformSoftware::operator()(RigGeometry& geom) compute(geom.getMatrixFromSkeletonToGeometry(), geom.getInvMatrixFromSkeletonToGeometry(), &positionSrc->front(), - &positionDst->front()); + &positionDst->front()); positionDst->dirty(); - - if (normalSrc ) { computeNormal(geom.getMatrixFromSkeletonToGeometry(), From 4977939c054a93e1f90c7f7e2fa447965e21e2e0 Mon Sep 17 00:00:00 2001 From: OpenSceneGraph git repository Date: Sat, 11 Nov 2017 12:58:52 +0000 Subject: [PATCH 236/327] Code readability improvements --- src/osgAnimation/VertexInfluence.cpp | 57 ++++++++++++++++++++-------- 1 file changed, 42 insertions(+), 15 deletions(-) diff --git a/src/osgAnimation/VertexInfluence.cpp b/src/osgAnimation/VertexInfluence.cpp index 1f77be6aa..e2d9482e8 100644 --- a/src/osgAnimation/VertexInfluence.cpp +++ b/src/osgAnimation/VertexInfluence.cpp @@ -50,6 +50,7 @@ void VertexInfluenceMap::normalize(unsigned int numvert) } } + unsigned int vertid = 0; for(std::vector::iterator itvert = localstore.begin(); itvert != localstore.end(); @@ -64,7 +65,9 @@ void VertexInfluenceMap::normalize(unsigned int numvert) { float mult = 1.0/weights.first; for (std::vector::iterator itf = weights.second.begin(); itf != weights.second.end(); ++itf) + { **itf *= mult; + } } } @@ -86,7 +89,10 @@ void VertexInfluenceMap::cullInfluenceCountPerVertex(unsigned int numbonepervert { 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)); + else if(inf.second>minweight) + { + tempVec2Bones[inf.first].insert(BoneWeight(bonename, inf.second)); + } } } this->clear(); @@ -99,7 +105,10 @@ void VertexInfluenceMap::cullInfluenceCountPerVertex(unsigned int numbonepervert if(renormalize) { for(BoneWeightOrdered::iterator bwit = bwset.begin(); bwit != bwset.end(); ++bwit) + { sum += bwit->second; + } + if(sum > 1e-4) { sum = 1.0f/sum; @@ -119,7 +128,6 @@ void VertexInfluenceMap::cullInfluenceCountPerVertex(unsigned int numbonepervert inf.push_back(VertexIndexWeight(mapit->first,bwit->second)); inf.setName(bwit->first); } - } } } @@ -134,6 +142,7 @@ void VertexInfluenceMap::computePerVertexInfluenceList(std::vector { - bool operator()(const BoneWeight& b0, - const BoneWeight& b1) const + bool operator()(const BoneWeight& b0, const BoneWeight& b1) const { if (b0.first < b1.first) return true; else if (b0.first > b1.first) return false; + return (b0.second < b1.second); } }; @@ -193,16 +202,22 @@ void VertexInfluenceMap::computeMinimalVertexGroupList(std::vector& BoneWeightList &boneweightlist = *it; // sort the vector to have a consistent key std::sort(boneweightlist.begin(), boneweightlist.end(), SortByNameAndWeight()); + // we use the vector as key to differentiate group UnifyBoneGroup::iterator result = unifyBuffer.find(boneweightlist); if (result == unifyBuffer.end()) + { unifyBuffer[boneweightlist].setBoneWeights(boneweightlist); + } + unifyBuffer[boneweightlist].vertIDs().push_back(vertexID); } + if(vertex2Bones.size() == unifyBuffer.size()) { OSG_WARN << "VertexInfluenceMap::computeMinimalVertexGroupList is useless no duplicate VertexGroup" << std::endl; } + uniqVertexGroupList.reserve(unifyBuffer.size()); for (UnifyBoneGroup::iterator it = unifyBuffer.begin(); it != unifyBuffer.end(); ++it) { @@ -234,10 +249,13 @@ void CollectRigVisitor::apply(osg::Geometry& node) _map.push_back(rig); } -bool recursiveisUsefull( Bone* bone, std::set foundnames) { - for(unsigned int i=0; igetNumChildren(); ++i) { +bool recursiveisUsefull( Bone* bone, std::set foundnames) +{ + for(unsigned int i=0; igetNumChildren(); ++i) + { Bone* child = dynamic_cast< Bone* >(bone->getChild(i)); - if(child){ + if(child) + { if( foundnames.find(child->getName()) != foundnames.end() ) return true; if( recursiveisUsefull(child,foundnames) ) @@ -262,16 +280,20 @@ void VertexInfluenceMap::removeUnexpressedBones(Skeleton &skel) const Bone* child, *par; std::set usebones; - for(RigList::iterator rigit = rigs.begin(); rigit != rigs.end(); ++rigit) { + for(RigList::iterator rigit = rigs.begin(); rigit != rigs.end(); ++rigit) + { for(VertexInfluenceMap::iterator mapit = (*rigit)->getInfluenceMap()->begin(); - mapit != (*rigit)->getInfluenceMap()->end(); - ++mapit) { + mapit != (*rigit)->getInfluenceMap()->end(); + ++mapit) + { usebones.insert((*mapit).first); } } - for(BoneMap::iterator bmit = boneMap.begin(); bmit != boneMap.end();) { - if(usebones.find(bmit->second->getName()) == usebones.end()) { + for(BoneMap::iterator bmit = boneMap.begin(); bmit != boneMap.end();) + { + if(usebones.find(bmit->second->getName()) == usebones.end()) + { if( !(par = bmit->second->getBoneParent()) ) { ++bmit; @@ -280,7 +302,8 @@ void VertexInfluenceMap::removeUnexpressedBones(Skeleton &skel) const Bone * bone2rm = bmit->second.get(); - if( recursiveisUsefull(bone2rm,usebones)) { + if( recursiveisUsefull(bone2rm,usebones)) + { ++bmit; continue; } @@ -301,7 +324,9 @@ void VertexInfluenceMap::removeUnexpressedBones(Skeleton &skel) const } } for(unsigned int i=0; iremoveChild(nodes[i]); + } par->removeChild(bone2rm); ///rebuild bonemap after bone removal @@ -311,8 +336,10 @@ void VertexInfluenceMap::removeUnexpressedBones(Skeleton &skel) const bmit = boneMap.begin(); } - else ++bmit; + else + { + ++bmit; + } } OSG_WARN<<"Number of bone removed "< Date: Sat, 11 Nov 2017 13:00:56 +0000 Subject: [PATCH 237/327] Code readability improvements --- src/osgAnimation/VertexInfluence.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/osgAnimation/VertexInfluence.cpp b/src/osgAnimation/VertexInfluence.cpp index e2d9482e8..75a7b22a6 100644 --- a/src/osgAnimation/VertexInfluence.cpp +++ b/src/osgAnimation/VertexInfluence.cpp @@ -47,14 +47,13 @@ void VertexInfluenceMap::normalize(unsigned int numvert) 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) + itvert != localstore.end(); + ++itvert, ++vertid) { PerVertWeights & weights = *itvert; if(weights.first< 1e-4) @@ -317,12 +316,14 @@ void VertexInfluenceMap::removeUnexpressedBones(Skeleton &skel) const { if( (child = dynamic_cast(bone2rm->getChild(numchild))) ) { - if(par!=child &&child!=bone2rm) { + if(par!=child &&child!=bone2rm) + { par->addChild(child); nodes.push_back(child); } } } + for(unsigned int i=0; iremoveChild(nodes[i]); From 3567e3100944c233b2f14d42baae1272be3295f6 Mon Sep 17 00:00:00 2001 From: OpenSceneGraph git repository Date: Sat, 11 Nov 2017 13:04:34 +0000 Subject: [PATCH 238/327] Added versioning to the new serialization additions --- .../serializers/osgAnimation/AnimationManagerBase.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/osgWrappers/serializers/osgAnimation/AnimationManagerBase.cpp b/src/osgWrappers/serializers/osgAnimation/AnimationManagerBase.cpp index 49a788fc5..65ec91c3c 100644 --- a/src/osgWrappers/serializers/osgAnimation/AnimationManagerBase.cpp +++ b/src/osgWrappers/serializers/osgAnimation/AnimationManagerBase.cpp @@ -77,9 +77,13 @@ REGISTER_OBJECT_WRAPPER( osgAnimation_AnimationManagerBase, { ADD_USER_SERIALIZER( Animations ); // _animations ADD_BOOL_SERIALIZER( AutomaticLink, true ); // _automaticLink + + { + UPDATE_TO_VERSION_SCOPED( 152 ) - ADD_METHOD_OBJECT( "getRegisteredAnimation", osgAnimation_AnimationManagerBasegetAnimation ); - ADD_METHOD_OBJECT( "getNumRegisteredAnimations", osgAnimation_AnimationManagerBasegetnumAnimations ); + ADD_METHOD_OBJECT( "getRegisteredAnimation", osgAnimation_AnimationManagerBasegetAnimation ); + ADD_METHOD_OBJECT( "getNumRegisteredAnimations", osgAnimation_AnimationManagerBasegetnumAnimations ); + } } } #undef OBJECT_CAST From 729680714c538c79a9dd034bb8e138a44d3b21b2 Mon Sep 17 00:00:00 2001 From: OpenSceneGraph git repository Date: Sat, 11 Nov 2017 13:08:42 +0000 Subject: [PATCH 239/327] Readbility improvements and updating version to 152 --- .../serializers/osgAnimation/RigTransform.cpp | 64 +++++++++++-------- 1 file changed, 38 insertions(+), 26 deletions(-) diff --git a/src/osgWrappers/serializers/osgAnimation/RigTransform.cpp b/src/osgWrappers/serializers/osgAnimation/RigTransform.cpp index 5b69cdcd1..4eb5f3341 100644 --- a/src/osgWrappers/serializers/osgAnimation/RigTransform.cpp +++ b/src/osgWrappers/serializers/osgAnimation/RigTransform.cpp @@ -7,52 +7,64 @@ #include #include -namespace wrap_osgAnimationRigTransform{ - REGISTER_OBJECT_WRAPPER( osgAnimation_RigTransform, +namespace wrap_osgAnimationRigTransform +{ + REGISTER_OBJECT_WRAPPER( osgAnimation_RigTransform, NULL, osgAnimation::RigTransform, "osg::Object osgAnimation::RigTransform" ){} } -namespace wrap_osgAnimationRigTransformSoftWare{ - REGISTER_OBJECT_WRAPPER( osgAnimation_RigTransformSoftware, + +namespace wrap_osgAnimationRigTransformSoftWare +{ + REGISTER_OBJECT_WRAPPER( osgAnimation_RigTransformSoftware, new osgAnimation::RigTransformSoftware, osgAnimation::RigTransformSoftware, "osg::Object osgAnimation::RigTransform osgAnimation::RigTransformSoftware" ){} } -namespace wrap_osgAnimationRigTransformHardWare{ - REGISTER_OBJECT_WRAPPER( osgAnimation_RigTransformHardware, + +namespace wrap_osgAnimationRigTransformHardWare +{ + REGISTER_OBJECT_WRAPPER( osgAnimation_RigTransformHardware, new osgAnimation::RigTransformHardware, osgAnimation::RigTransformHardware, - "osg::Object osgAnimation::RigTransform osgAnimation::RigTransformHardware" ){ - { - UPDATE_TO_VERSION_SCOPED(150) - ADD_OBJECT_SERIALIZER(Shader, osg::Shader, NULL); - ADD_UINT_SERIALIZER(FirstVertexAttributeTarget, RIGTRANSHW_DEFAULT_FIRST_VERTATTRIB_TARGETTED); - } - } + "osg::Object osgAnimation::RigTransform osgAnimation::RigTransformHardware" ) + { + { + UPDATE_TO_VERSION_SCOPED(152) + ADD_OBJECT_SERIALIZER(Shader, osg::Shader, NULL); + ADD_UINT_SERIALIZER(FirstVertexAttributeTarget, RIGTRANSHW_DEFAULT_FIRST_VERTATTRIB_TARGETTED); + } + } } -namespace wrap_osgAnimationMorphTransform{ - REGISTER_OBJECT_WRAPPER( osgAnimation_MorphTransform, +namespace wrap_osgAnimationMorphTransform +{ + REGISTER_OBJECT_WRAPPER( osgAnimation_MorphTransform, NULL, osgAnimation::MorphTransform, "osg::Object osgAnimation::MorphTransform" ){} } -namespace wrap_osgAnimationMorphTransformSoftWare{ - REGISTER_OBJECT_WRAPPER( osgAnimation_MorphTransformSoftware, + +namespace wrap_osgAnimationMorphTransformSoftWare +{ + REGISTER_OBJECT_WRAPPER( osgAnimation_MorphTransformSoftware, new osgAnimation::MorphTransformSoftware, osgAnimation::MorphTransformSoftware, "osg::Object osgAnimation::MorphTransform osgAnimation::MorphTransformSoftware" ){} } -namespace wrap_osgAnimationMorphTransformHardware{ - REGISTER_OBJECT_WRAPPER( osgAnimation_MorphTransformHardware, + +namespace wrap_osgAnimationMorphTransformHardware +{ + REGISTER_OBJECT_WRAPPER( osgAnimation_MorphTransformHardware, new osgAnimation::MorphTransformHardware, osgAnimation::MorphTransformHardware, - "osg::Object osgAnimation::MorphTransform osgAnimation::MorphTransformHardware" ){ - { - UPDATE_TO_VERSION_SCOPED(150) - ADD_OBJECT_SERIALIZER(Shader, osg::Shader, NULL); - ADD_UINT_SERIALIZER(ReservedTextureUnit, MORPHTRANSHW_DEFAULTMORPHTEXTUREUNIT); - } - } + "osg::Object osgAnimation::MorphTransform osgAnimation::MorphTransformHardware" + { + { + UPDATE_TO_VERSION_SCOPED(152) + ADD_OBJECT_SERIALIZER(Shader, osg::Shader, NULL); + ADD_UINT_SERIALIZER(ReservedTextureUnit, MORPHTRANSHW_DEFAULTMORPHTEXTUREUNIT); + } + } } From 8d5a9e84fc0b562b5abab23ac68df56d605e4c88 Mon Sep 17 00:00:00 2001 From: OpenSceneGraph git repository Date: Sat, 11 Nov 2017 13:27:43 +0000 Subject: [PATCH 240/327] Build fix --- src/osgWrappers/serializers/osgAnimation/RigTransform.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/osgWrappers/serializers/osgAnimation/RigTransform.cpp b/src/osgWrappers/serializers/osgAnimation/RigTransform.cpp index 4eb5f3341..61d4fbd88 100644 --- a/src/osgWrappers/serializers/osgAnimation/RigTransform.cpp +++ b/src/osgWrappers/serializers/osgAnimation/RigTransform.cpp @@ -59,7 +59,7 @@ 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") { { UPDATE_TO_VERSION_SCOPED(152) From cba8559137ee05e2476667b0ce02d1f7de9050b4 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Sat, 11 Nov 2017 14:50:55 +0000 Subject: [PATCH 241/327] Updated SO version to 152 to reflect the resent API changes to osgAnimation. --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4c58f7cd4..79b25311d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -116,7 +116,7 @@ PROJECT(OpenSceneGraph) SET(OPENSCENEGRAPH_MAJOR_VERSION 3) SET(OPENSCENEGRAPH_MINOR_VERSION 5) SET(OPENSCENEGRAPH_PATCH_VERSION 8) -SET(OPENSCENEGRAPH_SOVERSION 151) +SET(OPENSCENEGRAPH_SOVERSION 152) # set to 0 when not a release candidate, non zero means that any generated # git tags will be treated as release candidates of given number From a811de2ba7b842034cc6b721abcfc8faf5eac17a Mon Sep 17 00:00:00 2001 From: Andre Normann Date: Mon, 13 Nov 2017 10:24:31 +0000 Subject: [PATCH 242/327] Attached is a fix in GLExtension, which is based on latest git version, that fixes the usage of uniform buffer objects on macOS. Under macOS core OpenGL features aren't exported as extension. OpenGL 3.1 includes the GL_ARB_uniform_buffer_object as core feature for example. On macOS a simple osg::isGLExtensionSupported() call would fail. It is required to use the isGLExtensionOrVersionSupported() method. This is what my fix does. --- src/osg/GLExtensions.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/osg/GLExtensions.cpp b/src/osg/GLExtensions.cpp index 5cb230db8..507f42e5b 100644 --- a/src/osg/GLExtensions.cpp +++ b/src/osg/GLExtensions.cpp @@ -468,13 +468,13 @@ GLExtensions::GLExtensions(unsigned int in_contextID): isVertexShaderSupported = validContext && (shadersBuiltIn || osg::isGLExtensionSupported(contextID,"GL_ARB_vertex_shader")); isFragmentShaderSupported = validContext && (shadersBuiltIn || osg::isGLExtensionSupported(contextID,"GL_ARB_fragment_shader")); isLanguage100Supported = validContext && (shadersBuiltIn || osg::isGLExtensionSupported(contextID,"GL_ARB_shading_language_100")); - isGeometryShader4Supported = validContext && (osg::isGLExtensionSupported(contextID,"GL_EXT_geometry_shader4") || osg::isGLExtensionSupported(contextID,"GL_OES_geometry_shader")); - isGpuShader4Supported = validContext && osg::isGLExtensionSupported(contextID,"GL_EXT_gpu_shader4"); - areTessellationShadersSupported = validContext && (osg::isGLExtensionSupported(contextID, "GL_ARB_tessellation_shader") || osg::isGLExtensionSupported(contextID,"GL_OES_tessellation_shader")); - isUniformBufferObjectSupported = validContext && osg::isGLExtensionSupported(contextID,"GL_ARB_uniform_buffer_object"); - isGetProgramBinarySupported = validContext && osg::isGLExtensionSupported(contextID,"GL_ARB_get_program_binary"); - isGpuShaderFp64Supported = validContext && osg::isGLExtensionSupported(contextID,"GL_ARB_gpu_shader_fp64"); - isShaderAtomicCountersSupported = validContext && osg::isGLExtensionSupported(contextID,"GL_ARB_shader_atomic_counters"); + isGeometryShader4Supported = validContext && (osg::isGLExtensionSupported(contextID,"GL_EXT_geometry_shader4") || osg::isGLExtensionSupported(contextID,"GL_OES_geometry_shader") || osg::isGLExtensionOrVersionSupported(contextID,"GL_ARB_geometry_shader4", 3.2f)); + isGpuShader4Supported = validContext && osg::isGLExtensionOrVersionSupported(contextID,"GL_EXT_gpu_shader4", 3.0f); + areTessellationShadersSupported = validContext && (osg::isGLExtensionOrVersionSupported(contextID, "GL_ARB_tessellation_shader", 4.0f) || osg::isGLExtensionSupported(contextID,"GL_OES_tessellation_shader")); + isUniformBufferObjectSupported = validContext && osg::isGLExtensionOrVersionSupported(contextID,"GL_ARB_uniform_buffer_object", 3.1f); + isGetProgramBinarySupported = validContext && osg::isGLExtensionOrVersionSupported(contextID,"GL_ARB_get_program_binary", 4.1f); + isGpuShaderFp64Supported = validContext && osg::isGLExtensionOrVersionSupported(contextID,"GL_ARB_gpu_shader_fp64", 4.0f); + isShaderAtomicCountersSupported = validContext && osg::isGLExtensionOrVersionSupported(contextID,"GL_ARB_shader_atomic_counters", 4.2f); isRectangleSupported = validContext && (OSG_GL3_FEATURES || From d98d9c9e72558ffbeb08685bf9096e3040944fcf Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Mon, 13 Nov 2017 12:49:33 +0000 Subject: [PATCH 243/327] FIxed two CoverityScan detected memory leaks --- src/osgAnimation/MorphTransformHardware.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/osgAnimation/MorphTransformHardware.cpp b/src/osgAnimation/MorphTransformHardware.cpp index ad2a6859d..b960ef650 100644 --- a/src/osgAnimation/MorphTransformHardware.cpp +++ b/src/osgAnimation/MorphTransformHardware.cpp @@ -100,12 +100,12 @@ bool MorphTransformHardware::init(MorphGeometry& morphGeometry) } } - osg::TextureBuffer * morphTargetsTBO=new osg::TextureBuffer(); + osg::ref_ptr morphTargetsTBO=new osg::TextureBuffer(); morphTargetsTBO->setBufferData(morphTargets); morphTargetsTBO->setInternalFormat( GL_RGB32F_ARB ); //create TBO Texture handle - osg::Uniform * morphTBOHandle=new osg::Uniform(osg::Uniform::SAMPLER_BUFFER,"morphTargets"); + osg::ref_ptr morphTBOHandle=new osg::Uniform(osg::Uniform::SAMPLER_BUFFER,"morphTargets"); morphTBOHandle->set((int)_reservedTextureUnit); //create dynamic uniform for morphtargets animation weights From 9c605ba9beaca8d5ff90f269a9450533418cf1c0 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Mon, 13 Nov 2017 13:06:12 +0000 Subject: [PATCH 244/327] Fixed CoverityScan reported errors --- .../serializers/osgAnimation/AnimationManagerBase.cpp | 5 ++--- .../serializers/osgAnimation/BasicAnimationManager.cpp | 8 ++++---- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/osgWrappers/serializers/osgAnimation/AnimationManagerBase.cpp b/src/osgWrappers/serializers/osgAnimation/AnimationManagerBase.cpp index 65ec91c3c..64d738da7 100644 --- a/src/osgWrappers/serializers/osgAnimation/AnimationManagerBase.cpp +++ b/src/osgWrappers/serializers/osgAnimation/AnimationManagerBase.cpp @@ -43,7 +43,7 @@ struct osgAnimation_AnimationManagerBasegetnumAnimations : public osgDB::MethodO virtual bool run(void* objectPtr, osg::Parameters& inputParameters, osg::Parameters& outputParameters) const { osgAnimation::AnimationManagerBase* group = dynamic_cast(reinterpret_cast(objectPtr)); - outputParameters.push_back(new osg::UIntValueObject("return",group->getNumRegisteredAnimations())); + if (group) outputParameters.push_back(new osg::UIntValueObject("return",group->getNumRegisteredAnimations())); return true; } }; @@ -64,8 +64,7 @@ struct osgAnimation_AnimationManagerBasegetAnimation : public osgDB::MethodObjec if (uivo) index = uivo->getValue(); } osgAnimation::AnimationManagerBase* group = dynamic_cast(reinterpret_cast(objectPtr)); - outputParameters.push_back(group->getRegisteredAnimation(index)); - + if (group) outputParameters.push_back(group->getRegisteredAnimation(index)); return true; } diff --git a/src/osgWrappers/serializers/osgAnimation/BasicAnimationManager.cpp b/src/osgWrappers/serializers/osgAnimation/BasicAnimationManager.cpp index 8aef704c8..8cb63e2d3 100644 --- a/src/osgWrappers/serializers/osgAnimation/BasicAnimationManager.cpp +++ b/src/osgWrappers/serializers/osgAnimation/BasicAnimationManager.cpp @@ -15,7 +15,7 @@ struct BasicAnimationManagerIsplaying : public osgDB::MethodObject osgAnimation::Animation* child = dynamic_cast(inputParameters[0].get()); if (!child) return false; osgAnimation::BasicAnimationManager* group = dynamic_cast(reinterpret_cast(objectPtr)); - outputParameters.push_back(new osg::BoolValueObject("return", group->isPlaying(child))); + id (group) outputParameters.push_back(new osg::BoolValueObject("return", group->isPlaying(child))); return true; } }; @@ -28,7 +28,7 @@ struct BasicAnimationManagerfindAnimation : public osgDB::MethodObject osgAnimation::Animation* child = dynamic_cast(inputParameters[0].get()); if (!child) return false; osgAnimation::BasicAnimationManager* group = dynamic_cast(reinterpret_cast(objectPtr)); - outputParameters.push_back(new osg::BoolValueObject("return",group->findAnimation(child))); + id (group) outputParameters.push_back(new osg::BoolValueObject("return",group->findAnimation(child))); return true; } }; @@ -41,7 +41,7 @@ struct BasicAnimationManagerPlayanimation : public osgDB::MethodObject osgAnimation::Animation* child = dynamic_cast(inputParameters[0].get()); if (!child) return false; osgAnimation::BasicAnimationManager* group = dynamic_cast(reinterpret_cast(objectPtr)); - group->playAnimation(child); + id (group) group->playAnimation(child); return true; } }; @@ -54,7 +54,7 @@ struct BasicAnimationManagerStopanimation : public osgDB::MethodObject osgAnimation::Animation* child = dynamic_cast(inputParameters[0].get()); if (!child) return false; osgAnimation::BasicAnimationManager* group = dynamic_cast(reinterpret_cast(objectPtr)); - group->stopAnimation(child); + id (group) group->stopAnimation(child); return true; } }; From 49a5fdbd1fd31f88b0f4cf554779a1a7e26e518a Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Mon, 13 Nov 2017 13:08:39 +0000 Subject: [PATCH 245/327] Fixed typo --- .../serializers/osgAnimation/BasicAnimationManager.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/osgWrappers/serializers/osgAnimation/BasicAnimationManager.cpp b/src/osgWrappers/serializers/osgAnimation/BasicAnimationManager.cpp index 8cb63e2d3..e69869b5a 100644 --- a/src/osgWrappers/serializers/osgAnimation/BasicAnimationManager.cpp +++ b/src/osgWrappers/serializers/osgAnimation/BasicAnimationManager.cpp @@ -15,7 +15,7 @@ struct BasicAnimationManagerIsplaying : public osgDB::MethodObject osgAnimation::Animation* child = dynamic_cast(inputParameters[0].get()); if (!child) return false; osgAnimation::BasicAnimationManager* group = dynamic_cast(reinterpret_cast(objectPtr)); - id (group) outputParameters.push_back(new osg::BoolValueObject("return", group->isPlaying(child))); + if (group) outputParameters.push_back(new osg::BoolValueObject("return", group->isPlaying(child))); return true; } }; @@ -28,7 +28,7 @@ struct BasicAnimationManagerfindAnimation : public osgDB::MethodObject osgAnimation::Animation* child = dynamic_cast(inputParameters[0].get()); if (!child) return false; osgAnimation::BasicAnimationManager* group = dynamic_cast(reinterpret_cast(objectPtr)); - id (group) outputParameters.push_back(new osg::BoolValueObject("return",group->findAnimation(child))); + if (group) outputParameters.push_back(new osg::BoolValueObject("return",group->findAnimation(child))); return true; } }; @@ -41,7 +41,7 @@ struct BasicAnimationManagerPlayanimation : public osgDB::MethodObject osgAnimation::Animation* child = dynamic_cast(inputParameters[0].get()); if (!child) return false; osgAnimation::BasicAnimationManager* group = dynamic_cast(reinterpret_cast(objectPtr)); - id (group) group->playAnimation(child); + if (group) group->playAnimation(child); return true; } }; @@ -54,7 +54,7 @@ struct BasicAnimationManagerStopanimation : public osgDB::MethodObject osgAnimation::Animation* child = dynamic_cast(inputParameters[0].get()); if (!child) return false; osgAnimation::BasicAnimationManager* group = dynamic_cast(reinterpret_cast(objectPtr)); - id (group) group->stopAnimation(child); + if (group) group->stopAnimation(child); return true; } }; From 41dda781eee11675490f8e97b009e432321e72fe Mon Sep 17 00:00:00 2001 From: Raymond de Vries Date: Tue, 14 Nov 2017 10:38:18 +0000 Subject: [PATCH 246/327] attached fixes for configuring and building the osgPlugin exr with Visual Studio and using out-of-the-box builds of ilmbase and openexr, i.e. without manual/extra config for using these 2 libs with the OSG. Previously, the assumption was made that ilmbase and openexr were installed in a common directory and hence the header files and libs were both found in that common directory. That is not consistent with other libs and this submission makes it consistent and therefore the OSG configures out of the box. I made this work for ilmbase-2.1.0.tar.gz / openexr-2.1.0.tar.gz and ilmbase-2.2.0.tar.gz / openexr-2.2.0.tar.gz --- CMakeLists.txt | 1 + CMakeModules/FindOpenEXR.cmake | 13 +++---- CMakeModules/Findilmbase.cmake | 63 +++++++++++++++++++++++++++++++ src/osgPlugins/exr/CMakeLists.txt | 3 +- 4 files changed, 71 insertions(+), 9 deletions(-) create mode 100644 CMakeModules/Findilmbase.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 79b25311d..396a959f8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -742,6 +742,7 @@ IF(ANDROID) ELSE() # Common to all platforms except android: FIND_PACKAGE(Freetype) + FIND_PACKAGE(ilmbase) FIND_PACKAGE(Inventor) FIND_PACKAGE(Jasper) FIND_PACKAGE(OpenEXR) diff --git a/CMakeModules/FindOpenEXR.cmake b/CMakeModules/FindOpenEXR.cmake index 743df98fb..233be972b 100644 --- a/CMakeModules/FindOpenEXR.cmake +++ b/CMakeModules/FindOpenEXR.cmake @@ -28,7 +28,7 @@ FIND_PATH(OPENEXR_INCLUDE_DIR OpenEXR/ImfIO.h # example: OPENEXR_FIND_VAR(OPENEXR_IlmImf_LIBRARY IlmImf) MACRO(OPENEXR_FIND_VAR varname libname) FIND_LIBRARY( ${varname} - NAMES ${libname} + NAMES ${libname} ${libname}-2_1 ${libname}-2_2 PATHS $ENV{OPENEXR_DIR}/lib $ENV{OPENEXR_DIR} @@ -52,13 +52,10 @@ MACRO(OPENEXR_FIND libname) ENDMACRO(OPENEXR_FIND) OPENEXR_FIND(IlmImf) -OPENEXR_FIND(IlmThread) -OPENEXR_FIND(Iex) -OPENEXR_FIND(Half) SET(OPENEXR_FOUND "NO") -IF(OPENEXR_INCLUDE_DIR AND OPENEXR_IlmImf_LIBRARY AND OPENEXR_IlmThread_LIBRARY AND OPENEXR_Iex_LIBRARY AND OPENEXR_Half_LIBRARY) - SET(OPENEXR_LIBRARIES ${OPENEXR_IlmImf_LIBRARY} ${OPENEXR_IlmThread_LIBRARY} ${OPENEXR_Half_LIBRARY} ${OPENEXR_Iex_LIBRARY} ) - SET(OPENEXR_LIBRARIES_VARS OPENEXR_IlmImf_LIBRARY OPENEXR_IlmThread_LIBRARY OPENEXR_Half_LIBRARY OPENEXR_Iex_LIBRARY ) +IF(OPENEXR_INCLUDE_DIR AND OPENEXR_IlmImf_LIBRARY) + SET(OPENEXR_LIBRARIES ${OPENEXR_IlmImf_LIBRARY} ) + SET(OPENEXR_LIBRARIES_VARS OPENEXR_IlmImf_LIBRARY ) SET(OPENEXR_FOUND "YES") -ENDIF(OPENEXR_INCLUDE_DIR AND OPENEXR_IlmImf_LIBRARY AND OPENEXR_IlmThread_LIBRARY AND OPENEXR_Iex_LIBRARY AND OPENEXR_Half_LIBRARY) +ENDIF(OPENEXR_INCLUDE_DIR AND OPENEXR_IlmImf_LIBRARY) diff --git a/CMakeModules/Findilmbase.cmake b/CMakeModules/Findilmbase.cmake new file mode 100644 index 000000000..4b076c7c9 --- /dev/null +++ b/CMakeModules/Findilmbase.cmake @@ -0,0 +1,63 @@ +# Locate ILMBASE +# This module defines +# ILMBASE_LIBRARY +# ILMBASE_FOUND, if false, do not try to link to ILMBASE +# ILMBASE_INCLUDE_DIR, where to find the headers +# +# $ILMBASE_DIR is an environment variable that would +# correspond to the ./configure --prefix=$ILMBASE_DIR +# +# Created by Robert Osfield. + + +FIND_PATH(ILMBASE_INCLUDE_DIR OpenEXR/ImathVec.h + $ENV{ILMBASE_DIR}/include + $ENV{ILMBASE_DIR} + ~/Library/Frameworks + /Library/Frameworks + /usr/local/include + /usr/include + /sw/include # Fink + /opt/local/include # DarwinPorts + /opt/csw/include # Blastwave + /opt/include + /usr/freeware/include +) + +# Macro to find ilmbase libraries +# example: ILMBASE_FIND_VAR(OPENEXR_IlmThread_LIBRARY IlmThread) +MACRO(ILMBASE_FIND_VAR varname libname) + FIND_LIBRARY( ${varname} + NAMES ${libname} ${libname}-2_1 ${libname}-2_2 + PATHS + $ENV{ILMBASE_DIR}/lib + $ENV{ILMBASE_DIR} + ~/Library/Frameworks + /Library/Frameworks + /usr/local/lib + /usr/lib + /sw/lib + /opt/local/lib + /opt/csw/lib + /opt/lib + /usr/freeware/lib64 + ) +ENDMACRO(ILMBASE_FIND_VAR) + +# Macro to find exr libraries (and debug versions) +# example: ILMBASE_FIND(OPENEXR_IlmThread_LIBRARY IlmThread) +MACRO(ILMBASE_FIND libname) + ILMBASE_FIND_VAR(ILMBASE_${libname}_LIBRARY ${libname}) + ILMBASE_FIND_VAR(ILMBASE_${libname}_LIBRARY_DEBUG ${libname}d) +ENDMACRO(ILMBASE_FIND) + +ILMBASE_FIND(IlmThread) +ILMBASE_FIND(Iex) +ILMBASE_FIND(Half) + +SET(ILMBASE_FOUND "NO") +IF(ILMBASE_INCLUDE_DIR AND ILMBASE_IlmThread_LIBRARY AND ILMBASE_Iex_LIBRARY AND ILMBASE_Half_LIBRARY) + SET(ILMBASE_LIBRARIES ${ILMBASE_IlmThread_LIBRARY} ${ILMBASE_Half_LIBRARY} ${ILMBASE_Iex_LIBRARY} ) + SET(ILMBASE_LIBRARIES_VARS ILMBASE_IlmThread_LIBRARY ILMBASE_Half_LIBRARY ILMBASE_Iex_LIBRARY ) + SET(ILMBASE_FOUND "YES") +ENDIF(ILMBASE_INCLUDE_DIR AND ILMBASE_IlmThread_LIBRARY AND ILMBASE_Iex_LIBRARY AND ILMBASE_Half_LIBRARY) diff --git a/src/osgPlugins/exr/CMakeLists.txt b/src/osgPlugins/exr/CMakeLists.txt index 56ef8e0e4..e2ed9bb65 100644 --- a/src/osgPlugins/exr/CMakeLists.txt +++ b/src/osgPlugins/exr/CMakeLists.txt @@ -1,8 +1,9 @@ +INCLUDE_DIRECTORIES( ${ILMBASE_INCLUDE_DIR}/OpenEXR ) INCLUDE_DIRECTORIES( ${OPENEXR_INCLUDE_DIR}/OpenEXR ) SET(TARGET_SRC ReaderWriterEXR.cpp ) -SET(TARGET_LIBRARIES_VARS ${OPENEXR_LIBRARIES_VARS} ZLIB_LIBRARIES) +SET(TARGET_LIBRARIES_VARS ${OPENEXR_LIBRARIES_VARS} ${ILMBASE_LIBRARIES_VARS} ZLIB_LIBRARIES) IF(CMAKE_COMPILER_IS_GNUCXX) # Remove -Wshadow flag as it barfs on ffmoeg headers From c95a5486b17c22b2b2ed0b52b56a3f48964afc1c Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Tue, 14 Nov 2017 15:04:05 +0000 Subject: [PATCH 247/327] Updated ChangeLog and AUTHORS file for 3.5.8 dev release --- AUTHORS.txt | 40 +- ChangeLog | 585 +++++++++++++++++++++++ applications/osgversion/Contributors.cpp | 2 + 3 files changed, 607 insertions(+), 20 deletions(-) diff --git a/AUTHORS.txt b/AUTHORS.txt index 9f299c9ce..b03c1700a 100644 --- a/AUTHORS.txt +++ b/AUTHORS.txt @@ -8,11 +8,11 @@ Robert Osfield Stephan Huber Paul Martz Farshid Lashkari -Mathias Frhlich +Mathias Fröhlich Laurens Voerman Marco Jez Wang Rui -Jean-Sbastien Guay +Jean-Sébastien Guay Ulrich Hertlein Mike Weiblen Sukender @@ -65,11 +65,11 @@ Norman Vine Chris Denham Sherman Wilcox Serge Lages -Romano Jos Magacho da Silva +Romano José Magacho da Silva Mourad Boufarguine Alberto Farre Glenn Waldron -Andr Garneau +André Garneau Adrian Egli Sebastian Messerschmidt Randall Hopper @@ -84,7 +84,7 @@ Michael Gronager Martin Naylor Joakim Simonsson David Spilling -Daniel Sjlie +Daniel Sjölie Bryan Thrall Andreas Ekstrand Rafa Gaitan @@ -122,7 +122,7 @@ Gordon Tomlinson Frederic Marmond Frederic Bouvier Carlo Camporesi -Bjrn Blissing +Björn Blissing Alexander Sinditskiy Vladimir Chebaev Thibault Genessay @@ -141,10 +141,11 @@ Uwe Woessner Tony Horrobin Thom DeCarlo Tatsuhiro Nishioka -Tanguy Fautr +Tanguy Fautré Sean Spicer Ryan Kawicki Richard Schmidt +Raymond de Vries Peter Hrenka Paul de Repentigny Nikolaus Hanekamp @@ -201,7 +202,7 @@ Phil Atkin Pawel Ksiezopolski Patrick Neary Nathan Monteleone -Miha Ravelj +Miha Rav¨elj Miguel Escriva Mattias Linde Mark Sciabica @@ -233,8 +234,8 @@ Christian Ruzicka Christian Buchner Charles Cole Blake Williams -Bjrn Hein -Aurlien Chatelain +Björn Hein +Aurélien Chatelain Antoine Hue Andrew Bettison Andreas Henne @@ -254,7 +255,6 @@ Stephan Eilemann Stanislav Blinov Sergey Polischuk Roni Zanolli -Raymond de Vries Ralf Kern Piotr Gwiazdowski Pierre Haritchabalet @@ -264,7 +264,7 @@ Paul Obermeier Nguyen Van Truong Nathan Cournia Morten Haukness -Morn Pistorius +Morné Pistorius Michael Mc Donnell Michael Henheffer Michael Guerrero @@ -297,7 +297,7 @@ Guillaume Taze Guillaume Chouvenc Giuseppe Donvito Gill Peacegood -Giampaolo Vigan +Giampaolo Viganò Gerrick Bivins George Tarantilis Ferdi Smit @@ -305,7 +305,7 @@ Eduardo Poyart Edgar Ellis Dmitry Marakasov Dimi Christopoulos -Diane Delalle +Diane Delallée David Longest David Ergo Daniel Trstenjak @@ -337,7 +337,7 @@ Vasily Radostev Valery Bickov Valeriy Dubov Vaclav Bilek -Tyge Lvset +Tyge Løvset Troy Yee Torben Dannahauer Tony Vasile @@ -387,7 +387,7 @@ Piotr Rak Pierre Bourdin Philipp Svehla Philipp Siemoleit -Philipp Mchler +Philipp Mächler Philip Lamb Petr Salinger Peter Bear @@ -412,7 +412,7 @@ Nick Thu Nick Black Mojtaba Fathi Mirko Viviani -Mikkel Gjl +Mikkel Gjøl Mike Krus Mike Garrity Mick Thu @@ -465,7 +465,7 @@ Juan Hernando Josh Portway Jonathan Greig John Tan -John Hedstrm +John Hedström John Grant John Farrier John Donovan @@ -524,11 +524,11 @@ David Jung Danny Valente Daniel Stien Dan Minor -Csar L. B. Silveira +César L. B. Silveira Cyril Brulebois Curtis Rubel Cory Slep -Clment Bsch +Clément B½sch Clay Fowler Claus Steuer Chuck Sembroski diff --git a/ChangeLog b/ChangeLog index 97e0ca86a..34bd19c33 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,7 +1,316 @@ +Tue, 14 Nov 2017 10:38:18 +0000 +Author : Raymond de Vries +attached fixes for configuring and building the osgPlugin exr with Visual Studio and using out-of-the-box builds of ilmbase and openexr, i.e. without manual/extra config for using these 2 libs with the OSG.Previously, the assumption was made that ilmbase and openexr were installed in a common directory and hence the header files and libs were both found in that common directory. That is not consistent with other libs and this submission makes it consistent and therefore the OSG configures out of the box. I made this work for ilmbase-2.1.0.tar.gz / openexr-2.1.0.tar.gz and ilmbase-2.2.0.tar.gz / openexr-2.2.0.tar.gz + + +Mon, 13 Nov 2017 13:08:39 +0000 +Author : Robert Osfield +Fixed typo + +Mon, 13 Nov 2017 13:06:12 +0000 +Author : Robert Osfield +Fixed CoverityScan reported errors + +Mon, 13 Nov 2017 12:49:33 +0000 +Author : Robert Osfield +FIxed two CoverityScan detected memory leaks + +Mon, 13 Nov 2017 10:24:31 +0000 +Author : Andre Normann +Attached is a fix in GLExtension, which is based on latest git version, that fixes the usage of uniform buffer objects on macOS. Under macOS core OpenGL features aren't exported as extension. OpenGL 3.1 includes the GL_ARB_uniform_buffer_object as core feature for example. On macOS a simple osg::isGLExtensionSupported() call would fail. It is required to use the isGLExtensionOrVersionSupported() method. This is what my fix does. + +Sat, 11 Nov 2017 14:50:55 +0000 +Author : Robert Osfield +Updated SO version to 152 to reflect the resent API changes to osgAnimation. + +Sat, 11 Nov 2017 14:43:10 +0000 +Author : OpenSceneGraph git repository +Merge pull request #382 from openscenegraph/osganimationOsganimation improvements + +Sat, 11 Nov 2017 13:27:43 +0000 +Author : OpenSceneGraph git repository +Build fix + +Sat, 11 Nov 2017 13:08:42 +0000 +Author : OpenSceneGraph git repository +Readbility improvements and updating version to 152 + +Sat, 11 Nov 2017 13:04:34 +0000 +Author : OpenSceneGraph git repository +Added versioning to the new serialization additions + +Sat, 11 Nov 2017 13:00:56 +0000 +Author : OpenSceneGraph git repository +Code readability improvements + +Sat, 11 Nov 2017 12:58:52 +0000 +Author : OpenSceneGraph git repository +Code readability improvements + +Sat, 11 Nov 2017 12:54:28 +0000 +Author : OpenSceneGraph git repository +Code readability improvements + +Sat, 11 Nov 2017 12:46:48 +0000 +Author : OpenSceneGraph git repository +Code readability improvement + +Sat, 11 Nov 2017 12:45:55 +0000 +Author : OpenSceneGraph git repository +Small readability improvements + +Sat, 11 Nov 2017 12:42:34 +0000 +Author : OpenSceneGraph git repository +Fix of incorrect Program assignment bug and coding style + +Sat, 11 Nov 2017 12:33:44 +0000 +Author : OpenSceneGraph git repository +coding style/readability fixes + +Sat, 11 Nov 2017 12:29:45 +0000 +Author : OpenSceneGraph git repository +coding style/readability fixes + +Sat, 11 Nov 2017 12:27:56 +0000 +Author : OpenSceneGraph git repository +coding style/readability fixes + +Sat, 11 Nov 2017 12:24:27 +0000 +Author : OpenSceneGraph git repository +coding style fix + +Sat, 11 Nov 2017 11:17:34 +0000 +Author : Robert Osfield +Restructed the ref counting of the rawImageRec structure so that it's done with a separate refImageRec struct so it doesn't interfer with the writing of the rawImageRec as a header when writing to .rgb + +Sat, 11 Nov 2017 10:19:09 +0000 +Author : Andreas Ekstrand +I have implemented readObject to make loading objects from SceneLoader in the LWS plugin work. I'm not sure about other implications from changes leading up to this problem (readRefFile instead of readNodeFile in SceneLoader) but this fix works for me. + +Fri, 10 Nov 2017 17:12:20 +0000 +Author : Robert Osfield +Fixed handling of GL_TEXTURE_CUBE_MAP when using glTextureStorage. + +Fri, 10 Nov 2017 17:00:52 +0000 +Author : OpenSceneGraph git repository +Merge pull request #381 from openscenegraph/revert-379-osganimbugfixRevert " following guidance from OpenGL Common Mistakes:" + +Fri, 10 Nov 2017 16:58:29 +0000 +Author : OpenSceneGraph git repository +Revert " following guidance from OpenGL Common Mistakes:" + +Fri, 10 Nov 2017 14:49:54 +0000 +Author : OpenSceneGraph git repository +Merge pull request #379 from mp3butcher/osganimbugfixFixed handling of mipmaps + +Fri, 10 Nov 2017 13:36:52 +0000 +Author : OpenSceneGraph git repository +Merge pull request #380 from mp3butcher/MDI7add funcs to read GZ Objects from a stream + +Fri, 10 Nov 2017 12:41:21 +0000 +Author : Robert Osfield +Fixed crash in copy constructor due to copy and paste/typo. + +Wed, 8 Nov 2017 15:57:34 +0100 +Author : Julien Valentin +replace string with stringstream (avoid a string copy at read) + +Wed, 8 Nov 2017 15:40:11 +0100 +Author : Julien Valentin +add funcs to read Object from a GZ stream + +Mon, 6 Nov 2017 20:49:23 +0000 +Author : Robert Osfield +Added Pawel's origin commit message into the osggpucull source as it examples a lot about how the example works + +Mon, 6 Nov 2017 19:53:38 +0000 +Author : Robert Osfield +Temporary workaround for the regression of intersection tests with osgText::Text. Added a local vertex array that is transformed by the last applied text matrix. + +Sat, 4 Nov 2017 17:28:14 +0100 +Author : Julien Valentin + following guidance from OpenGL Common Mistakes: mipmaps should be upload with glTexImage2D and not glTexSubImage2D + +Fri, 3 Nov 2017 09:55:42 +0000 +Author : Robert Osfield +Added check for malloc returning a valid pointer + +Fri, 3 Nov 2017 09:49:50 +0000 +Author : Robert Osfield +Added an explict null termination of buffer to address Coverity Scan reported issue + +Thu, 2 Nov 2017 18:43:05 +0000 +Author : Robert Osfield +Added check for a valud positions pointer + +Thu, 2 Nov 2017 18:39:11 +0000 +Author : Robert Osfield +Fuxed missing initializers + +Thu, 2 Nov 2017 16:39:32 +0000 +Author : Robert Osfield +Changed the key binding for opening and editor to edit presentation to 'E' and to trigger update the presentation by pressing 'e' + +Thu, 2 Nov 2017 11:51:03 +0000 +Author : Robert Osfield +Fixed copy and paste error + +Thu, 2 Nov 2017 11:48:39 +0000 +Author : Robert Osfield +Moved memset to after check for null memory pointer + +Thu, 2 Nov 2017 11:42:25 +0000 +Author : Robert Osfield +Cleaned up getEnvVar usage + +Thu, 2 Nov 2017 10:43:41 +0000 +Author : Robert Osfield +Replaced getenv usage with safer osg::getEnvVar + +Thu, 2 Nov 2017 10:02:34 +0000 +Author : Robert Osfield +Fixed warning + +Thu, 2 Nov 2017 10:00:28 +0000 +Author : Robert Osfield +Replaced getenv calls with safer osg::getEnvVar usage + +Wed, 1 Nov 2017 17:38:33 +0000 +Author : Robert Osfield +Moved getenv usage across to safer osg::getEnvVar() usage + +Wed, 1 Nov 2017 16:43:32 +0000 +Author : Robert Osfield +Added safety check for getenv parsing to prevent overflow attacks via getenv. + +Wed, 1 Nov 2017 14:45:27 +0000 +Author : Robert Osfield +Moved from getenv to osg::getEnvVar usage + +Wed, 1 Nov 2017 14:16:54 +0000 +Author : Robert Osfield +Made template function inline to avoid multiple declaration issues + +Wed, 1 Nov 2017 13:54:15 +0000 +Author : Robert Osfield +Replaced getenv(..) usage with osg::getEnvVar(..) + +Wed, 1 Nov 2017 13:32:47 +0000 +Author : Robert Osfield +Added OSG_ENVVAR_SUPPORTED cmake control and bool osg::getEnvVar(const char* name, T& value, ...) conviniece funcions to make it easier to implement optinal getenv reading code. + +Wed, 1 Nov 2017 11:35:05 +0000 +Author : Robert Osfield +Fixed Coverity Scane reported issue. + +Tue, 31 Oct 2017 17:59:13 +0000 +Author : OpenSceneGraph git repository +Merge pull request #378 from mp3butcher/osganimationupdate osganimationhardware example to use a common program + +Tue, 31 Oct 2017 17:55:59 +0000 +Author : Robert Osfield +Fixed unititialized memory variables and improved readability by adding spacing where appropriate + +Tue, 31 Oct 2017 17:43:39 +0000 +Author : Robert Osfield +Added missing initializers + +Tue, 31 Oct 2017 17:39:34 +0000 +Author : Robert Osfield +Fixed CovertiScan reported uninitialized member variable + +Tue, 31 Oct 2017 17:02:31 +0000 +Author : Robert Osfield +Fixed Coverity Scan reported issue + +Tue, 31 Oct 2017 18:00:06 +0100 +Author : Julien Valentin +update example to use a common program + +Tue, 31 Oct 2017 16:46:42 +0000 +Author : Robert Osfield +Replace c char array with std::string to address Coverity scan reported issue + +Tue, 31 Oct 2017 15:55:24 +0000 +Author : Robert Osfield +Fixed Coverity Scan reported memory leaks + +Tue, 31 Oct 2017 15:47:49 +0000 +Author : Robert Osfield +Fixed Coverity reported memory leak + +Tue, 31 Oct 2017 14:55:41 +0000 +Author : Robert Osfield +Reinstated two stage OSX build, and disabled part of the coverity_scan build to attempt to get it running without timeout. + +Tue, 31 Oct 2017 12:32:45 +0000 +Author : Robert Osfield +Upped the number of threads used in build to try and improve build speed + +Tue, 31 Oct 2017 10:01:52 +0000 +Author : Robert Osfield +Simplified build for OSX now that trais builds are running faster. + +Mon, 30 Oct 2017 15:53:56 +0000 +Author : Robert Osfield +Merge branch 'master' into osganimation + +Mon, 30 Oct 2017 14:36:41 +0000 +Author : Robert Osfield +From Raymond de Vires, added support for 2018 and 2016 versions of FBX. + +Mon, 30 Oct 2017 14:36:41 +0000 +Author : Robert Osfield +From Raymond de Vires, added support for 2018 and 2016 versions of FBX. + +Mon, 30 Oct 2017 14:22:10 +0000 +Author : Robert Osfield +From Raymond de Vires, Windows build fix + +Mon, 30 Oct 2017 14:05:45 +0000 +Author : Robert Osfield +Updated ChangeLog and AUTHORS + +Mon, 30 Oct 2017 13:40:50 +0000 +Author : Robert Osfield +Quitened down the DisplaySettings::setShaderHint() output for NONE. + Mon, 30 Oct 2017 09:32:04 +0000 Author : Robert Osfield Merged support for StateSet::DefineList from shader_pipeline branch +Mon, 30 Oct 2017 08:37:19 +0000 +Author : OpenSceneGraph git repository +Merge pull request #375 from mp3butcher/osganimationreformat AStyle (with codeblocks) + +Fri, 27 Oct 2017 21:02:43 +0200 +Author : Julien Valentin +reformat with the help of AStyle reformat tool (codeblocks) + +Fri, 27 Oct 2017 18:14:04 +0100 +Author : Robert Osfield +Fixed build error when building wiht OSG_USE_REF_PTR_IMPLICIT_OUTPUT_CONVERSION=OFF + +Fri, 27 Oct 2017 17:15:38 +0100 +Author : OpenSceneGraph git repository +Merge pull request #374 from mp3butcher/osganimationfix InfluenceMap "remove useless bones" method + +Fri, 27 Oct 2017 17:14:43 +0100 +Author : OpenSceneGraph git repository +Merge branch 'osganimation' into osganimation + +Fri, 27 Oct 2017 14:19:13 +0100 +Author : Robert Osfield +Fixed build errors when compiling with OSG_USE_REF_PTR_IMPLICIT_OUTPUT_CONVERSION set to OFF + +Fri, 27 Oct 2017 14:41:29 +0200 +Author : Julien Valentin +fix InfluenceMap "remove useless bones" method + +Fri, 27 Oct 2017 13:48:52 +0100 +Author : Robert Osfield +Build fix for when compiling with OSG_USE_REF_PTR_IMPLICIT_OUTPUT_CONVERSION set to OFF + Fri, 27 Oct 2017 13:48:52 +0100 Author : Robert Osfield Build fix for when compiling with OSG_USE_REF_PTR_IMPLICIT_OUTPUT_CONVERSION set to OFF @@ -14,6 +323,10 @@ Fri, 27 Oct 2017 13:17:47 +0100 Author : Robert Osfield From Farshid Lashkari, "fix for the Collada loader to check for some NULL attributes." +Fri, 27 Oct 2017 12:54:10 +0100 +Author : Robert Osfield +Merge branch 'master' into osganimation + Fri, 27 Oct 2017 09:33:24 +0100 Author : OpenSceneGraph git repository Merge pull request #373 from LaurensVoerman/noStdMaxuse osg::maximum, not std::max @@ -301,6 +614,14 @@ Fri, 6 Oct 2017 14:33:07 +0300 Author : Konstantin S. Matveyev VertexAttribDivisor compare function fix: index must be compared +Thu, 5 Oct 2017 16:56:30 +0100 +Author : Robert Osfield +Improved the readability of recent changes by adding spaces, {} and moving { onto separate lines to keep things consistent with the rest of the OSG. + +Thu, 5 Oct 2017 16:43:54 +0100 +Author : OpenSceneGraph git repository +Merge pull request #357 from mp3butcher/osganimationfix normalization bug (happen too early ) + Thu, 5 Oct 2017 16:31:45 +0100 Author : OpenSceneGraph git repository Merge pull request #354 from eligovision/OpenSceneGraph_intersectionLineSegmentIntersector fixed: intersection ratio remaped to the range… @@ -345,6 +666,13 @@ Wed, 4 Oct 2017 18:06:42 +0100 Author : Robert Osfield Improvements to the Signed Distance Field implementation. +Wed, 4 Oct 2017 05:42:33 +0200 +Author : Julien Valentin +fix normalization bug (happen too early )minor bug + +bla + + Fri, 29 Sep 2017 20:21:13 +0100 Author : Robert Osfield Simplified and improved the glyph margin computation and usage @@ -538,6 +866,10 @@ Wed, 6 Sep 2017 10:40:05 +0100 Author : Robert Osfield To control the GlyphTexture Min/MagFilter values Added --min and --mag filter with LINEAR, NEAREST and LINEAR_MIPMAP_LINER options for values +Mon, 4 Sep 2017 15:35:01 +0100 +Author : OpenSceneGraph git repository +Merge pull request #340 from mp3butcher/osganimationadd a new method on VertexInfluenceMap and the serializer for MorphTransforfHW + Mon, 4 Sep 2017 15:21:26 +0100 Author : OpenSceneGraph git repository Merge pull request #344 from eligovision/OpenSceneGraph_text3dText3D dynamic changing fix @@ -546,6 +878,10 @@ Mon, 4 Sep 2017 15:20:54 +0100 Author : OpenSceneGraph git repository Merge pull request #345 from eligovision/OpenSceneGraph_example_text3dexample_osgtext3d: more options for testing +Mon, 4 Sep 2017 12:04:37 +0200 +Author : Julien Valentin +add DSO scope in modified XXXTransformHardware serializers + Mon, 4 Sep 2017 11:44:30 +0300 Author : Konstantin S. Matveyev example_osgtext3d: more options for testing @@ -558,18 +894,90 @@ Mon, 4 Sep 2017 08:36:49 +0100 Author : OpenSceneGraph git repository Merge pull request #341 from scrawl/cullingactive_fixLineSegmentIntersector: respect the 'cullingActive' flag for bounding box check +Mon, 4 Sep 2017 02:27:54 +0200 +Author : Julien Valentin +cleanup + +Sun, 3 Sep 2017 17:37:06 +0200 +Author : Julien Valentin +make preparedata skeleton independant (as it was with the Rig::buildInfluenceSet) no more divergence with master i think + Sun, 3 Sep 2017 14:15:36 +0000 Author : scrawl LineSegmentIntersector: respect the 'cullingActive' flag when testing drawable bounding box +Fri, 1 Sep 2017 20:03:05 +0200 +Author : Julien Valentin +Merge remote-tracking branch 'upstream/master' into osganimation + +Fri, 1 Sep 2017 19:13:01 +0200 +Author : Julien Valentin +update serializer with new properties + +Fri, 1 Sep 2017 18:08:37 +0200 +Author : Julien Valentin +add MorphTransformHardware serializer + +Fri, 1 Sep 2017 18:04:32 +0200 +Author : Julien Valentin +Merge remote-tracking branch 'upstream/osganimation' into osganimation + +Fri, 1 Sep 2017 17:48:28 +0200 +Author : Julien Valentin +add void InfluenceMap::removeUnexpressedBones(Skeleton &skel) const; a bit experimental but work well without further process on my test set + +Fri, 1 Sep 2017 16:46:38 +0100 +Author : OpenSceneGraph git repository +Merge pull request #338 from mp3butcher/osganimationclean and bugfix + Fri, 1 Sep 2017 15:50:47 +0100 Author : OpenSceneGraph git repository Merge pull request #337 from mp3butcher/osganimbugfixfix a bug in how vertexattributes are filled +Fri, 1 Sep 2017 16:23:49 +0200 +Author : Julien Valentin +remove utility classes BoneWeight and IndexWeight in order to avoid unnecessary symbols (but decrease a bit clarity of the code) + +Fri, 1 Sep 2017 15:12:10 +0200 +Author : Julien Valentin +cleanup + +Fri, 1 Sep 2017 01:43:00 +0200 +Author : Julien Valentin +a functional cleanup + +Thu, 31 Aug 2017 16:35:05 +0200 +Author : Julien Valentin +clean and bugfixes + +Thu, 31 Aug 2017 14:32:39 +0100 +Author : OpenSceneGraph git repository +Merge pull request #333 from mp3butcher/osganimationosgAnimation: change animationdata owner from riggeometry to rigtransformimplementations + +Thu, 31 Aug 2017 13:49:27 +0200 +Author : Julien Valentin +few cleanup + +Thu, 31 Aug 2017 13:30:24 +0200 +Author : Julien Valentin +revert s/VertexIndexWeight/IndexWeight/ + +Thu, 31 Aug 2017 13:29:42 +0200 +Author : Julien Valentin +fix example + Wed, 30 Aug 2017 23:15:01 +0200 Author : Julien Valentin fix a bug in how vertexattributes are filled +Wed, 30 Aug 2017 23:01:21 +0200 +Author : Julien Valentin +I found the damn bug in RigTransformHW + +Wed, 30 Aug 2017 20:36:34 +0200 +Author : Julien Valentin +rehabilit an init method to ensure morphing po setted before skinning po in case of rigeom source that are morphgeom + Wed, 30 Aug 2017 17:43:29 +0100 Author : Robert Osfield Added --shader filename command line parsing and associated set up of osg::Program to allow shaders to be passed into example to customize rendering @@ -582,6 +990,34 @@ Wed, 30 Aug 2017 16:21:03 +0100 Author : Robert Osfield Added osgText::Font::s/getGlyphInterval(int) and GlyphTexture::s/getGlyphInterval(int) and internal support for clmapping positions of glyph images an defined intervals, defaults to 1. +Wed, 30 Aug 2017 17:07:11 +0200 +Author : Julien Valentin +add parameter to XXXTranformHW to customize reserved texture attribs and vertex attribs + +Wed, 30 Aug 2017 15:46:19 +0200 +Author : Julien Valentin +add a guard (if dirty) on uniform update + +Wed, 30 Aug 2017 15:13:54 +0200 +Author : Julien Valentin +readd VertexInfluence whenever it's bad named and kinda useless + +Wed, 30 Aug 2017 14:59:31 +0200 +Author : Julien Valentin +readd buildVertexInfluenceSet for backward compat + +Wed, 30 Aug 2017 13:21:32 +0200 +Author : Julien Valentin +cleanup + +Wed, 30 Aug 2017 12:55:45 +0200 +Author : Julien Valentin +uncomment normalization in rigtransformxxx + +Wed, 30 Aug 2017 12:09:54 +0200 +Author : Julien Valentin +add and comment out normlization in rigtransformXXX + Wed, 30 Aug 2017 10:50:26 +0100 Author : Robert Osfield Added --margin texel_width and --margin-ration ratio to control the spacing between glyphs in the font. @@ -590,6 +1026,10 @@ Wed, 30 Aug 2017 10:16:18 +0100 Author : Robert Osfield Added --test command line option that sets up all the sizes and font settings required for a useufl unit test. +Wed, 30 Aug 2017 11:12:17 +0200 +Author : Julien Valentin +refactor: remove totally VertexInfluence (renamed BoneInfluenceList) everywhere + Tue, 29 Aug 2017 17:32:14 +0100 Author : Robert Osfield Removed debug messages @@ -598,6 +1038,26 @@ Tue, 29 Aug 2017 17:19:26 +0100 Author : Robert Osfield Added TextSettings struct to manage values used to set up the text. with the addition of following command line parameters: --outline // enable outlne --shadow // enable shadow --offset ratio // set the backdrop offset --text-color r g b a // set the text body color --bd-color r g b a // set the shadow/outline color --bg-color r g b a // window background color -o filename // write create subgraph to disk using specified filename +Tue, 29 Aug 2017 17:32:19 +0200 +Author : Julien Valentin +swap priority in BonePtrWeight comparator< yeild the same VG set + +Tue, 29 Aug 2017 17:24:35 +0200 +Author : Julien Valentin +cleanup + +Tue, 29 Aug 2017 15:10:05 +0200 +Author : Julien Valentin +remove virtual qualifier for deprecated method + +Tue, 29 Aug 2017 14:47:56 +0200 +Author : Julien Valentin +add MorphTransformHW for RigGeometry sources that are MorphGeometry + +Tue, 29 Aug 2017 14:11:44 +0200 +Author : Julien Valentin +set defaut implementation at creation + Tue, 29 Aug 2017 13:48:06 +0100 Author : Robert Osfield Added --ortho command line option to toggle use of orthographic camera or default perspective one @@ -617,14 +1077,106 @@ Under macOS the glValidateProgram reports too many false negatives (errors) abou An appropriate place to call glValidateProgram would be right before you make a real render call. » +Tue, 29 Aug 2017 02:55:40 +0200 +Author : Julien Valentin +few refactoring and fixes + +Tue, 29 Aug 2017 00:34:26 +0200 +Author : Julien Valentin +readd the 2 methods in InfluenceMap just in case + +Tue, 29 Aug 2017 00:09:38 +0200 +Author : Julien Valentin +cleanup + +Tue, 29 Aug 2017 00:07:07 +0200 +Author : Julien Valentin +remove VertexInfluenceSet + +Mon, 28 Aug 2017 18:42:22 +0200 +Author : Julien Valentin +add 2 method to VertexInfluenceMap: normalize and cullInfluenceCountPerVertex + +Mon, 28 Aug 2017 18:27:23 +0200 +Author : Julien Valentin +comply with refactoring + +Mon, 28 Aug 2017 18:16:30 +0200 +Author : Julien Valentin +total removal of the old path + +Mon, 28 Aug 2017 18:02:52 +0200 +Author : Julien Valentin +remove default order for BoneWeight and restore old sort func (behaviors differs) + Mon, 28 Aug 2017 16:28:30 +0100 Author : OpenSceneGraph git repository Merge pull request #332 from denyskoch/fix-boundingsphere-inequality-operatorFix flawed BoundingSphere inequality operator +Mon, 28 Aug 2017 17:13:48 +0200 +Author : Julien Valentin +clean unused + +Mon, 28 Aug 2017 17:13:23 +0200 +Author : Julien Valentin +fix the example + +Mon, 28 Aug 2017 16:46:01 +0200 +Author : Julien Valentin +remove old path and add few fixes + +Mon, 28 Aug 2017 16:02:00 +0200 +Author : Julien Valentin +minor fixes removed unused + +Mon, 28 Aug 2017 15:59:13 +0200 +Author : Julien Valentin +reroot to rigtransform::prepareData old path to rig::buildvertexinfluence + +Mon, 28 Aug 2017 15:44:09 +0200 +Author : Julien Valentin +remove unused + +Mon, 28 Aug 2017 15:41:14 +0200 +Author : Julien Valentin +add prepareData for RigTransformHW + +Mon, 28 Aug 2017 15:40:04 +0200 +Author : Julien Valentin +minor changes+fix + +Mon, 28 Aug 2017 15:27:46 +0200 +Author : Julien Valentin +add default constructor for IndexWeight with invalid indices + +Mon, 28 Aug 2017 14:25:12 +0200 +Author : Julien Valentin +add prepareData for rigttransform software + Mon, 28 Aug 2017 14:34:39 +0200 Author : Denys Koch Fix flawed BoundingSphere inequality operator +Mon, 28 Aug 2017 14:23:15 +0200 +Author : Julien Valentin +few refactoring + +Mon, 28 Aug 2017 13:18:37 +0100 +Author : OpenSceneGraph git repository +Merge pull request #331 from mp3butcher/osganimationOsganimation fix a bug introduced when readding transformsoftwareMethod + +Mon, 28 Aug 2017 13:34:06 +0200 +Author : Julien Valentin +Merge remote-tracking branch 'upstream/osganimation' into osganimation + +Mon, 28 Aug 2017 05:22:14 +0200 +Author : Julien Valentin +fix a bug introduced when readding transformsoftwareMethod + +Mon, 28 Aug 2017 10:28:18 +0100 +Author : Robert Osfield +Merge branch 'osganimation' of https://github.com/mp3butcher/OpenSceneGraph into osganimation + Mon, 28 Aug 2017 10:02:27 +0100 Author : OpenSceneGraph git repository Merge pull request #330 from mathieu/ProgramFixFunctionAvailableCoreProfileosg::Program::isFixedFunction() should'nt return true if fixed function unavailable @@ -633,6 +1185,22 @@ Mon, 28 Aug 2017 09:44:10 +0200 Author : Mathieu MARACHE osg::Program::isFixedFunction() should'nt return true fixed function is unavailable, even if _shaderList.empty() is true +Mon, 28 Aug 2017 05:22:14 +0200 +Author : Julien Valentin +fix a bug introduced when readding transformsoftwareMethod + +Mon, 28 Aug 2017 05:17:17 +0200 +Author : Julien Valentin +add a new prepareData method to the interface + +Mon, 28 Aug 2017 04:51:52 +0200 +Author : Julien Valentin +MorphTransformHardware using TBO added + +Mon, 28 Aug 2017 04:42:51 +0200 +Author : Julien Valentin +readd virtual void transformSoftwareMethod() for retrocompatibity + Sun, 27 Aug 2017 18:08:09 +0100 Author : OpenSceneGraph git repository Merge pull request #327 from kornerr/masterFix Emscripten build errors @@ -641,6 +1209,23 @@ Sun, 27 Aug 2017 18:07:21 +0100 Author : OpenSceneGraph git repository Merge pull request #328 from scrawl/group-docsFix docs for Group::addChild to match implementation +Sun, 27 Aug 2017 02:14:12 +0200 +Author : Julien Valentin +replace VertexInfluence to BoneInfluenceList and VertexIndexWeight to IndexWeightfix in example + + +Sun, 27 Aug 2017 00:10:52 +0200 +Author : Julien Valentin +remove unused code and remove a commented section + +Sat, 26 Aug 2017 23:05:52 +0200 +Author : Julien Valentin +update serializers + +Sat, 26 Aug 2017 20:37:10 +0200 +Author : Julien Valentin +refactoring and fixes only change in design: decouplage between MorphGeometry and MorphTransform technique no real change in behavior (i hope) + Sat, 26 Aug 2017 19:25:00 +0300 Author : Michael Kapelko Fix Emscripten build errors diff --git a/applications/osgversion/Contributors.cpp b/applications/osgversion/Contributors.cpp index bce3f9f66..5948a45d0 100644 --- a/applications/osgversion/Contributors.cpp +++ b/applications/osgversion/Contributors.cpp @@ -277,6 +277,8 @@ const char* invalidNames[] = "PrimitiveFunctor", "OpenMW", "StreamOperator", + "SceneLoader", + "OpenGL", "FindLIBLAS" }; From d60b9714fe163f29caad8f2e6191804fbca7069e Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Mon, 20 Nov 2017 12:49:20 +0000 Subject: [PATCH 248/327] Moved the version to 3.5.9 and the version setting code to top of CMake file --- CMakeLists.txt | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 396a959f8..46cb0f32b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,3 +1,15 @@ +# +# OpenSceneGraph CMake build file +# +SET(OPENSCENEGRAPH_MAJOR_VERSION 3) +SET(OPENSCENEGRAPH_MINOR_VERSION 5) +SET(OPENSCENEGRAPH_PATCH_VERSION 9) +SET(OPENSCENEGRAPH_SOVERSION 152) + + +# set to 0 when not a release candidate, non zero means that any generated +# git tags will be treated as release candidates of given number +SET(OPENSCENEGRAPH_RELEASE_CANDIDATE 0) set(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS TRUE) set_property(GLOBAL PROPERTY USE_FOLDERS ON) @@ -113,15 +125,6 @@ ENDIF() PROJECT(OpenSceneGraph) -SET(OPENSCENEGRAPH_MAJOR_VERSION 3) -SET(OPENSCENEGRAPH_MINOR_VERSION 5) -SET(OPENSCENEGRAPH_PATCH_VERSION 8) -SET(OPENSCENEGRAPH_SOVERSION 152) - -# set to 0 when not a release candidate, non zero means that any generated -# git tags will be treated as release candidates of given number -SET(OPENSCENEGRAPH_RELEASE_CANDIDATE 0) - SET(OPENSCENEGRAPH_VERSION ${OPENSCENEGRAPH_MAJOR_VERSION}.${OPENSCENEGRAPH_MINOR_VERSION}.${OPENSCENEGRAPH_PATCH_VERSION}) SET(OSG_PLUGINS osgPlugins-${OPENSCENEGRAPH_VERSION}) From e0eb4fbda81dce2ef5033f6213043f3c2a3caa95 Mon Sep 17 00:00:00 2001 From: Andre Normann Date: Tue, 21 Nov 2017 13:54:45 +0100 Subject: [PATCH 249/327] Fixed missing initialization of B_ and N_ in constructor --- src/osgUtil/TangentSpaceGenerator.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/osgUtil/TangentSpaceGenerator.cpp b/src/osgUtil/TangentSpaceGenerator.cpp index a57988e12..027e8be8a 100644 --- a/src/osgUtil/TangentSpaceGenerator.cpp +++ b/src/osgUtil/TangentSpaceGenerator.cpp @@ -12,8 +12,8 @@ TangentSpaceGenerator::TangentSpaceGenerator() N_(new osg::Vec4Array) { T_->setBinding(osg::Array::BIND_PER_VERTEX); T_->setNormalize(false); - B_->setBinding(osg::Array::BIND_PER_VERTEX); T_->setNormalize(false); - N_->setBinding(osg::Array::BIND_PER_VERTEX); T_->setNormalize(false); + B_->setBinding(osg::Array::BIND_PER_VERTEX); B_->setNormalize(false); + N_->setBinding(osg::Array::BIND_PER_VERTEX); N_->setNormalize(false); } TangentSpaceGenerator::TangentSpaceGenerator(const TangentSpaceGenerator ©, const osg::CopyOp ©op) From 7f97b9f999e48a5766de8820f83e594ae45a4641 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Tue, 21 Nov 2017 13:41:57 +0000 Subject: [PATCH 250/327] Added Text::getCharacterCorners(...) method to help applications that want to find out the positions of characters being rendered. --- include/osgText/Text | 4 ++++ include/osgText/TextBase | 8 ++++---- src/osgText/Text.cpp | 15 +++++++++++++++ 3 files changed, 23 insertions(+), 4 deletions(-) diff --git a/include/osgText/Text b/include/osgText/Text index ab5e547a0..2bd443f19 100644 --- a/include/osgText/Text +++ b/include/osgText/Text @@ -182,9 +182,13 @@ public: virtual void accept(osg::PrimitiveFunctor& pf) const; + /** Get the coordinates of the character corners in local coordinates. Use Text::getMatrix() or Text::computeMatrix(..) to get the transform into model coordinates (see TextBase header.) */ + bool getCharacterCorners(unsigned int index, osg::Vec3& bottomLeft, osg::Vec3& bottomRight, osg::Vec3& topLef, osg::Vec3& topRight) const; + /** Resize any per context GLObject buffers to specified size. */ virtual void resizeGLObjectBuffers(unsigned int maxSize); + /** If State is non-zero, this function releases OpenGL objects for * the specified graphics context. Otherwise, releases OpenGL objexts * for all graphics contexts. */ diff --git a/include/osgText/TextBase b/include/osgText/TextBase index d75e41ff2..f262a0593 100644 --- a/include/osgText/TextBase +++ b/include/osgText/TextBase @@ -279,10 +279,12 @@ public: void getCoord(unsigned int i, osg::Vec2& c) const { c.set((*_coords)[i].x(), (*_coords)[i].y()); } void getCoord(unsigned int i, osg::Vec3& c) const { c = (*_coords)[i]; } - - /** Get the internal matrix used to provide positioning of text.*/ + /** Get the cached internal matrix used to provide positioning of text. The cached matrix is originally computed by computeMatrix(..). */ const osg::Matrix& getMatrix() const { return _matrix; } + /** compute the matrix that positions the text in model space for the given viewpoint.*/ + bool computeMatrix(osg::Matrix& matrix, osg::State* state=0) const; + protected: virtual ~TextBase(); @@ -295,8 +297,6 @@ protected: osg::VertexArrayState* createVertexArrayState(osg::RenderInfo& renderInfo) const; - bool computeMatrix(osg::Matrix& matrix, osg::State* state=0) const; - void positionCursor(const osg::Vec2 & endOfLine_coords, osg::Vec2 & cursor, unsigned int linelength); String::iterator computeLastCharacterOnLine(osg::Vec2& cursor, String::iterator first,String::iterator last); void computePositions(); diff --git a/src/osgText/Text.cpp b/src/osgText/Text.cpp index a22d7396f..6a2d2f96c 100644 --- a/src/osgText/Text.cpp +++ b/src/osgText/Text.cpp @@ -1301,6 +1301,21 @@ void Text::accept(osg::PrimitiveFunctor& pf) const } } +bool Text::getCharacterCorners(unsigned int index, osg::Vec3& bottomLeft, osg::Vec3& bottomRight, osg::Vec3& topLeft, osg::Vec3& topRight) const +{ + if (_coords) return false; + + if ((index*4+4)>static_cast(_coords->size())) return false; + + unsigned int base = index*4; + topLeft = (*_coords)[base]; + bottomLeft = (*_coords)[base+1]; + bottomRight = (*_coords)[base+2]; + topRight = (*_coords)[base+3]; + + return true; +} + void Text::resizeGLObjectBuffers(unsigned int maxSize) { TextBase::resizeGLObjectBuffers(maxSize); From 13c593ce0eddeec0852a45109cf06fe0d31345f9 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Tue, 21 Nov 2017 13:59:51 +0000 Subject: [PATCH 251/327] Fixed typo --- include/osgText/Text | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/osgText/Text b/include/osgText/Text index 2bd443f19..b2ae9c695 100644 --- a/include/osgText/Text +++ b/include/osgText/Text @@ -183,7 +183,7 @@ public: /** Get the coordinates of the character corners in local coordinates. Use Text::getMatrix() or Text::computeMatrix(..) to get the transform into model coordinates (see TextBase header.) */ - bool getCharacterCorners(unsigned int index, osg::Vec3& bottomLeft, osg::Vec3& bottomRight, osg::Vec3& topLef, osg::Vec3& topRight) const; + bool getCharacterCorners(unsigned int index, osg::Vec3& bottomLeft, osg::Vec3& bottomRight, osg::Vec3& topLeft, osg::Vec3& topRight) const; /** Resize any per context GLObject buffers to specified size. */ virtual void resizeGLObjectBuffers(unsigned int maxSize); From 80d1de783235830e5476a2d1050bda75338cf349 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 22 Nov 2017 11:05:17 +0000 Subject: [PATCH 252/327] Removed use of local static to avoid threading issue. --- src/osgPlugins/dxf/dxfReader.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/osgPlugins/dxf/dxfReader.cpp b/src/osgPlugins/dxf/dxfReader.cpp index 9a8c9ceb6..bce713b72 100644 --- a/src/osgPlugins/dxf/dxfReader.cpp +++ b/src/osgPlugins/dxf/dxfReader.cpp @@ -85,7 +85,7 @@ bool readerText::success(bool inSuccess, string type) bool readerText::getTrimmedLine(std::ifstream& f) { - static string line = ""; + std::string line; if (getline(f, line, _delim)) { ++_lineCount; _str.clear(); From 93a5213b995d6e89db0b42365ea89f9555189c7b Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Mon, 27 Nov 2017 10:32:02 +0000 Subject: [PATCH 253/327] Build fix --- examples/osgvnc/osgvnc.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/osgvnc/osgvnc.cpp b/examples/osgvnc/osgvnc.cpp index 35089afb9..52d424178 100644 --- a/examples/osgvnc/osgvnc.cpp +++ b/examples/osgvnc/osgvnc.cpp @@ -54,7 +54,7 @@ int main(int argc,char** argv) { } - std::string url, username, password; + std::string url, username; while (arguments.read("--login", url, username, password)) { osgDB::Registry::instance()->getOrCreateAuthenticationMap()->addAuthenticationDetails( @@ -71,7 +71,7 @@ int main(int argc,char** argv) if (!password.empty()) { - const osgDB::AuthenticationMap* authenticationMap = osgDB::Registry::instance()->getOrCreateAuthenticationMap(); + osgDB::AuthenticationMap* authenticationMap = osgDB::Registry::instance()->getOrCreateAuthenticationMap(); const osgDB::AuthenticationDetails* details = authenticationMap->getAuthenticationDetails(hostname); if (details == NULL) { From a72a929d1208b567f0443e2cd0b58f0128e8b2e2 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Mon, 27 Nov 2017 11:05:31 +0000 Subject: [PATCH 254/327] Fixed build issues when compiling with OSG_PROVIDE_READFILE to OFF --- examples/osgdeferred/osgdeferred.cpp | 12 ++++++------ examples/osgtext3D/osgtext3D.cpp | 4 +++- examples/osgviewerFLTK/osgviewerFLTK.cpp | 2 +- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/examples/osgdeferred/osgdeferred.cpp b/examples/osgdeferred/osgdeferred.cpp index 2343c438e..e7bbbf7e5 100644 --- a/examples/osgdeferred/osgdeferred.cpp +++ b/examples/osgdeferred/osgdeferred.cpp @@ -188,12 +188,12 @@ osg::ref_ptr createSceneRoom() { // Room. osg::ref_ptr room = new osg::MatrixTransform; - osg::ref_ptr roomModel = osgDB::readNodeFile("simpleroom.osgt"); + osg::ref_ptr roomModel = osgDB::readRefNodeFile("simpleroom.osgt"); room->addChild(roomModel); room->setMatrix(osg::Matrix::translate(0, 0, 1)); // Torus. osg::ref_ptr torus = new osg::MatrixTransform; - osg::ref_ptr torusModel = osgDB::readNodeFile("torus.osgt"); + osg::ref_ptr torusModel = osgDB::readRefNodeFile("torus.osgt"); torus->addChild(torusModel); setAnimationPath(torus, osg::Vec3(0, 0, 15), 6, 16); // Torus2. @@ -240,7 +240,7 @@ osg::Geode *createScreenQuad(float width, osg::Texture2D *createTexture(const std::string &fileName) { osg::ref_ptr texture = new osg::Texture2D; - texture->setImage(osgDB::readImageFile(fileName)); + texture->setImage(osgDB::readRefImageFile(fileName)); texture->setWrap(osg::Texture2D::WRAP_S, osg::Texture2D::REPEAT); texture->setWrap(osg::Texture2D::WRAP_T, osg::Texture2D::REPEAT); texture->setFilter(osg::Texture::MIN_FILTER, osg::Texture::LINEAR_MIPMAP_LINEAR); @@ -292,8 +292,8 @@ osg::ref_ptr setShaderProgram(osg::ref_ptr pass, const std::string& frag) { osg::ref_ptr program = new osg::Program; - program->addShader(osgDB::readShaderFile(vert)); - program->addShader(osgDB::readShaderFile(frag)); + program->addShader(osgDB::readRefShaderFile(vert)); + program->addShader(osgDB::readRefShaderFile(frag)); osg::ref_ptr ss = pass->getOrCreateStateSet(); ss->setAttributeAndModes( program.get(), @@ -313,7 +313,7 @@ int main() // Shadowed scene. osg::ref_ptr shadowMap = new osgShadow::SoftShadowMap; shadowMap->setJitteringScale(16); - shadowMap->addShader(osgDB::readShaderFile("shaders/pass1Shadow.frag")); + shadowMap->addShader(osgDB::readRefShaderFile("shaders/pass1Shadow.frag")); shadowMap->setLight(light.get()); osg::ref_ptr shadowedScene = new osgShadow::ShadowedScene; shadowedScene->setShadowTechnique(shadowMap.get()); diff --git a/examples/osgtext3D/osgtext3D.cpp b/examples/osgtext3D/osgtext3D.cpp index 62197139b..15bdbfdc2 100644 --- a/examples/osgtext3D/osgtext3D.cpp +++ b/examples/osgtext3D/osgtext3D.cpp @@ -250,7 +250,9 @@ int main(int argc, char** argv) } if (arguments.read("--add-axes")) - group->addChild(osgDB::readNodeFile("axes.osgt")); + { + group->addChild(osgDB::readRefNodeFile("axes.osgt")); + } std::string mode; if (arguments.read("--character-size-mode", mode)) diff --git a/examples/osgviewerFLTK/osgviewerFLTK.cpp b/examples/osgviewerFLTK/osgviewerFLTK.cpp index e43e9d539..3210148de 100644 --- a/examples/osgviewerFLTK/osgviewerFLTK.cpp +++ b/examples/osgviewerFLTK/osgviewerFLTK.cpp @@ -140,7 +140,7 @@ int main( int argc, char **argv ) osg::ArgumentParser arguments(&argc, argv); // load the scene. - osg::ref_ptr loadedModel = osgDB::readNodeFiles(arguments); + osg::ref_ptr loadedModel = osgDB::readRefNodeFiles(arguments); if (!loadedModel) { std::cout << argv[0] <<": No data loaded." << std::endl; From 9fc63d7613e593465977e9d18755a486acae63eb Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Mon, 27 Nov 2017 11:10:48 +0000 Subject: [PATCH 255/327] Fixes for building with OSG_PROVIDE_READFILE to OFF --- examples/osgmovie/osgmovie.cpp | 2 +- examples/osgviewerWX/osgviewerWX.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/osgmovie/osgmovie.cpp b/examples/osgmovie/osgmovie.cpp index 833a76091..523822ee2 100644 --- a/examples/osgmovie/osgmovie.cpp +++ b/examples/osgmovie/osgmovie.cpp @@ -438,7 +438,7 @@ int main(int argc, char** argv) if (arguments.read("-devices") || arguments.read("--devices")) { // Force load QuickTime plugin, probe video capability, exit - osgDB::readImageFile("devices.live"); + osgDB::readRefImageFile("devices.live"); return 1; } #endif diff --git a/examples/osgviewerWX/osgviewerWX.cpp b/examples/osgviewerWX/osgviewerWX.cpp index c4a198a4d..aa6678638 100644 --- a/examples/osgviewerWX/osgviewerWX.cpp +++ b/examples/osgviewerWX/osgviewerWX.cpp @@ -69,7 +69,7 @@ bool wxOsgApp::OnInit() // load the scene. wxString fname(argv[1]); - osg::ref_ptr loadedModel = osgDB::readNodeFile(std::string(fname.mb_str())); + osg::ref_ptr loadedModel = osgDB::readRefNodeFile(std::string(fname.mb_str())); if (!loadedModel) { std::cout << argv[0] <<": No data loaded." << std::endl; From 66eeabd7d093f78e5ce2d55a290e4c22000b0acf Mon Sep 17 00:00:00 2001 From: Jordi Date: Mon, 27 Nov 2017 15:48:50 +0100 Subject: [PATCH 256/327] Removes custom code added for sketchfab channel compression that should not be there --- src/osgPlugins/osgjs/Animation.cpp | 20 -------------------- src/osgPlugins/osgjs/CMakeLists.txt | 4 ---- 2 files changed, 24 deletions(-) diff --git a/src/osgPlugins/osgjs/Animation.cpp b/src/osgPlugins/osgjs/Animation.cpp index 40af1ed47..a14352d1d 100644 --- a/src/osgPlugins/osgjs/Animation.cpp +++ b/src/osgPlugins/osgjs/Animation.cpp @@ -240,16 +240,6 @@ static void addJSONChannel(osgAnimation::Channel* channel, JSONObject& anim, Wri } } -#ifdef USE_COMPRESSED_CHANNELS - { - osgAnimation::Vec3usLinearChannel* c = dynamic_cast(channel); - if (c) { - if (addJSONChannel("osgAnimation.Vec3LerpChannelCompressed", c, true, anim, writer, parent)) - return; - } - } -#endif - { osgAnimation::QuatSphericalLinearChannel* c = dynamic_cast(channel); if (c) { @@ -258,16 +248,6 @@ static void addJSONChannel(osgAnimation::Channel* channel, JSONObject& anim, Wri } } -#ifdef USE_COMPRESSED_CHANNELS - { - osgAnimation::Vec3usSphericalLinearChannel* c = dynamic_cast(channel); - if (c) { - if (addJSONChannel("osgAnimation.QuatSlerpChannelCompressed", c, true, anim, writer, parent)) - return; - } - } -#endif - { osgAnimation::FloatCubicBezierChannel* c = dynamic_cast(channel); if (c) { diff --git a/src/osgPlugins/osgjs/CMakeLists.txt b/src/osgPlugins/osgjs/CMakeLists.txt index 980f644b9..2c6673119 100644 --- a/src/osgPlugins/osgjs/CMakeLists.txt +++ b/src/osgPlugins/osgjs/CMakeLists.txt @@ -16,10 +16,6 @@ SET(TARGET_H WriteVisitor ) -IF($ENV{SKETCHFAB_BUILD}) - ADD_DEFINITIONS(-DUSE_COMPRESSED_CHANNELS) -ENDIF() - #### end var setup ### SET(TARGET_ADDED_LIBRARIES osgAnimation From cb2c48d01511ad2af1b3d461d472a908d793ba2b Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Mon, 27 Nov 2017 15:40:21 +0000 Subject: [PATCH 257/327] Added template addShader() method to make it easier to pass ref_ptr --- include/osgShadow/ShadowMap | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/osgShadow/ShadowMap b/include/osgShadow/ShadowMap index cec66ac20..535ba9c4c 100644 --- a/include/osgShadow/ShadowMap +++ b/include/osgShadow/ShadowMap @@ -68,6 +68,8 @@ class OSGSHADOW_EXPORT ShadowMap : public ShadowTechnique /** Add a shader to internal list, will be used instead of the default ones */ inline void addShader(osg::Shader* shader) { _shaderList.push_back(shader); } + template void addShader( const osg::ref_ptr& shader ) { addShader(shader.get()); } + /** Reset internal shader list */ inline void clearShaderList() { _shaderList.clear(); } From 06302a10823b56a86de133e829a5023ef3d1e410 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Mon, 27 Nov 2017 15:41:54 +0000 Subject: [PATCH 258/327] Replaced read*File() usage to readRef*File() --- examples/osgtransferfunction/osgtransferfunction.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/examples/osgtransferfunction/osgtransferfunction.cpp b/examples/osgtransferfunction/osgtransferfunction.cpp index aad85e3e5..fe9e4813f 100644 --- a/examples/osgtransferfunction/osgtransferfunction.cpp +++ b/examples/osgtransferfunction/osgtransferfunction.cpp @@ -407,13 +407,12 @@ int main(int argc, char ** argv) osg::ArgumentParser arguments(&argc, argv); #if 0 - osg::ref_ptr myobject = new MyClass; myobject->getOrCreateUserDataContainer()->addUserObject(new osg::CallbackObject("myMethod")); myobject->myMethod(); - osg::ref_ptr se = osgDB::readFile("ScriptEngine.lua"); - osg::ref_ptr script = osgDB::readFile("script.lua"); + osg::ref_ptr se = osgDB::readRefFile("ScriptEngine.lua"); + osg::ref_ptr script = osgDB::readRefFile("script.lua"); osg::ref_ptr copyobject = new MyClass; copyobject->getOrCreateUserDataContainer()->addUserObject(new MyScriptCallback(se.get(), script.get(), "myMethod")); @@ -421,7 +420,7 @@ int main(int argc, char ** argv) #endif #if 0 - osg::ref_ptr object = osgDB::readNodeFile("load.lua"); + osg::ref_ptr object = osgDB::readRefNodeFile("load.lua"); if (object.valid()) { osg::CallbackObject* co = osg::getCallbackObject(object.get(), "method"); From bc4a9d9dd0158e1e99d0ca1d1d95ef204220a560 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Mon, 27 Nov 2017 15:44:11 +0000 Subject: [PATCH 259/327] Refactored the MergeGeometry::mergeGroup(..) method to avoid O(N^2) issue with using removeChildren() on groups with very large numbers of children. --- src/osgUtil/Optimizer.cpp | 109 ++++++++++++-------------------------- 1 file changed, 33 insertions(+), 76 deletions(-) diff --git a/src/osgUtil/Optimizer.cpp b/src/osgUtil/Optimizer.cpp index e1602223a..dbdff4ea5 100644 --- a/src/osgUtil/Optimizer.cpp +++ b/src/osgUtil/Optimizer.cpp @@ -1618,7 +1618,7 @@ void Optimizer::CombineLODsVisitor::combineLODs() struct LessGeometry { - bool operator() (const osg::Geometry* lhs,const osg::Geometry* rhs) const + bool operator() (const osg::ref_ptr& lhs,const osg::ref_ptr& rhs) const { if (lhs->getStateSet()getStateSet()) return true; if (rhs->getStateSet()getStateSet()) return false; @@ -1714,7 +1714,7 @@ struct LessGeometry struct LessGeometryPrimitiveType { - bool operator() (const osg::Geometry* lhs,const osg::Geometry* rhs) const + bool operator() (const osg::ref_ptr& lhs,const osg::ref_ptr& rhs) const { for(unsigned int i=0; igetNumPrimitiveSets() && igetNumPrimitiveSets(); @@ -1792,45 +1792,39 @@ bool Optimizer::MergeGeometryVisitor::mergeGroup(osg::Group& group) if (group.getNumChildren()>=2) { - typedef std::vector DuplicateList; - typedef std::vector< osg::ref_ptr > DrawableList; - typedef std::map GeometryDuplicateMap; + typedef std::vector< osg::ref_ptr > DuplicateList; + typedef std::vector< osg::ref_ptr > Nodes; + typedef std::map< osg::ref_ptr ,DuplicateList,LessGeometry> GeometryDuplicateMap; typedef std::vector MergeList; GeometryDuplicateMap geometryDuplicateMap; - DrawableList standardDrawables; + Nodes standardChildren; unsigned int i; for(i=0;iasDrawable(); - if (drawable) + osg::Node* child = group.getChild(i); + osg::Geometry* geom = child->asGeometry(); + if (geom) { - osg::Geometry* geom = drawable->asGeometry(); - if (geom) + if (!geometryContainsSharedArrays(*geom) && + geom->getDataVariance()!=osg::Object::DYNAMIC && + isOperationPermissibleForObject(geom)) { - //geom->computeCorrectBindingsAndArraySizes(); - - if (!geometryContainsSharedArrays(*geom) && - geom->getDataVariance()!=osg::Object::DYNAMIC && - isOperationPermissibleForObject(geom)) - { - geometryDuplicateMap[geom].push_back(geom); - } - else - { - standardDrawables.push_back(drawable); - } + geometryDuplicateMap[geom].push_back(geom); } else { - standardDrawables.push_back(drawable); + standardChildren.push_back(geom); } } + else + { + standardChildren.push_back(child); + } } -#if 1 // first try to group geometries with the same properties // (i.e. array types) to avoid loss of data during merging MergeList mergeListChecked; // List of drawables just before merging, grouped by "compatibility" and vertex limit @@ -1860,7 +1854,7 @@ bool Optimizer::MergeGeometryVisitor::mergeGroup(osg::Group& group) dupItr!=itr->second.end(); ++dupItr) { - osg::Geometry* geomToPush = *dupItr; + osg::Geometry* geomToPush = dupItr->get(); // try to group geomToPush with another geometry MergeList::iterator eachMergeList=mergeListTmp.begin(); @@ -1946,6 +1940,16 @@ bool Optimizer::MergeGeometryVisitor::mergeGroup(osg::Group& group) if (needToDoMerge) { + // to avoid performance issues associated with incrementally removing a large number children, we remove them all and add back the ones we need. + group.removeChildren(0, group.getNumChildren()); + + for(Nodes::iterator itr = standardChildren.begin(); + itr != standardChildren.end(); + ++itr) + { + group.addChild(*itr); + } + // now do the merging of geometries for(MergeList::iterator mitr = mergeList.begin(); mitr != mergeList.end(); @@ -1954,65 +1958,18 @@ bool Optimizer::MergeGeometryVisitor::mergeGroup(osg::Group& group) DuplicateList& duplicateList = *mitr; if (duplicateList.size()>1) { - osg::Geometry* lhs = duplicateList.front(); + osg::ref_ptr lhs = duplicateList.front(); + group.addChild(lhs.get()); + for(DuplicateList::iterator ditr = duplicateList.begin()+1; ditr != duplicateList.end(); ++ditr) { - mergeGeometry(*lhs,**ditr); - - group.removeChild(*ditr); + mergeGeometry(*lhs, **ditr); } } } } - -#else - // don't merge geometry if its above a maximum number of vertices. - for(GeometryDuplicateMap::iterator itr=geometryDuplicateMap.begin(); - itr!=geometryDuplicateMap.end(); - ++itr) - { - if (itr->second.size()>1) - { - std::sort(itr->second.begin(),itr->second.end(),LessGeometryPrimitiveType()); - osg::Geometry* lhs = itr->second[0]; - for(DuplicateList::iterator dupItr=itr->second.begin()+1; - dupItr!=itr->second.end(); - ++dupItr) - { - - osg::Geometry* rhs = *dupItr; - - if (lhs->getVertexArray() && lhs->getVertexArray()->getNumElements()>=_targetMaximumNumberOfVertices) - { - lhs = rhs; - continue; - } - - if (rhs->getVertexArray() && rhs->getVertexArray()->getNumElements()>=_targetMaximumNumberOfVertices) - { - continue; - } - - if (lhs->getVertexArray() && rhs->getVertexArray() && - (lhs->getVertexArray()->getNumElements()+rhs->getVertexArray()->getNumElements())>=_targetMaximumNumberOfVertices) - { - continue; - } - - if (mergeGeometry(*lhs,*rhs)) - { - geode.removeDrawable(rhs); - - static int co = 0; - OSG_INFO<<"merged and removed Geometry "<<++co< Date: Mon, 27 Nov 2017 18:27:13 +0000 Subject: [PATCH 260/327] Added support for .cs, .compute, .tctrlm .teval extensions in the GLSL plugin --- src/osgDB/Registry.cpp | 7 +++++++ src/osgPlugins/glsl/ReaderWriterGLSL.cpp | 4 ++++ 2 files changed, 11 insertions(+) diff --git a/src/osgDB/Registry.cpp b/src/osgDB/Registry.cpp index 4b609af61..32852cfeb 100644 --- a/src/osgDB/Registry.cpp +++ b/src/osgDB/Registry.cpp @@ -307,6 +307,13 @@ Registry::Registry() addFileExtensionAlias("vert", "glsl"); addFileExtensionAlias("frag", "glsl"); addFileExtensionAlias("geom", "glsl"); + addFileExtensionAlias("tctrl", "glsl"); + addFileExtensionAlias("teval", "glsl"); + addFileExtensionAlias("compute", "glsl"); + addFileExtensionAlias("vs", "glsl"); + addFileExtensionAlias("fs", "glsl"); + addFileExtensionAlias("cs", "glsl"); + addFileExtensionAlias("gs", "glsl"); addFileExtensionAlias("js", "V8"); diff --git a/src/osgPlugins/glsl/ReaderWriterGLSL.cpp b/src/osgPlugins/glsl/ReaderWriterGLSL.cpp index 60c4842a4..2f69cae90 100644 --- a/src/osgPlugins/glsl/ReaderWriterGLSL.cpp +++ b/src/osgPlugins/glsl/ReaderWriterGLSL.cpp @@ -24,6 +24,10 @@ class ReaderWriterGLSL : public osgDB::ReaderWriter supportsExtension("tctrl","OpenGL Shader Language format"); supportsExtension("teval","OpenGL Shader Language format"); supportsExtension("compute","OpenGL Shader Language format"); + supportsExtension("cs","OpenGL Shader Language format"); + supportsExtension("gs","OpenGL Shader Language format"); + supportsExtension("vs","OpenGL Shader Language format"); + supportsExtension("fs","OpenGL Shader Language format"); } virtual const char* className() const { return "GLSL Shader Reader"; } From 34336931fa2993b06df87d68548baf2129aca217 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Mon, 27 Nov 2017 18:28:15 +0000 Subject: [PATCH 261/327] Deprecated the osg::Shader::reaDShaderFile() and osg::Shader::loadShaderSourceFromFile() methods. Programmers should use osgDB::readRefShaderFile()/readShaderFile() instead. --- include/osg/Shader | 9 ++++----- src/osg/Shader.cpp | 4 ++-- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/include/osg/Shader b/include/osg/Shader index fdfbc3f7e..4347cf9a5 100644 --- a/include/osg/Shader +++ b/include/osg/Shader @@ -162,14 +162,13 @@ class OSG_EXPORT Shader : public osg::Object /** Get the const Shader's ShaderBinary, return NULL if none is assigned. */ const ShaderBinary* getShaderBinary() const { return _shaderBinary.get(); } - - /** Read shader source from file and then constructor shader of specified type. - * Return the resulting Shader or 0 if no valid shader source could be read.*/ +#ifdef OSG_USE_DEPRECATED_API + /** Deorecated use osgDB::readRefShaderFile().*/ static Shader* readShaderFile( Type type, const std::string& fileName ); - /** Load the Shader's source code text from a file. */ + /** Deorecated use osgDB::readRefShaderFile(). */ bool loadShaderSourceFromFile( const std::string& fileName ); - +#endif /** The code injection map used when generating the main shader during main shader composition.*/ typedef std::multimap CodeInjectionMap; diff --git a/src/osg/Shader.cpp b/src/osg/Shader.cpp index 4a4309ccd..2b8481e42 100644 --- a/src/osg/Shader.cpp +++ b/src/osg/Shader.cpp @@ -314,7 +314,7 @@ void Shader::setShaderSource( const std::string& sourceText ) dirtyShader(); } - +#ifdef OSG_USE_DEPRECATED_API Shader* Shader::readShaderFile( Type type, const std::string& fileName ) { ref_ptr shader = new Shader(type); @@ -348,7 +348,7 @@ bool Shader::loadShaderSourceFromFile( const std::string& fileName ) delete [] text; return true; } - +#endif const char* Shader::getTypename() const { From 284f91b3e0aabc3441bd4f0a5422060bb18ed647 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Mon, 27 Nov 2017 18:38:37 +0000 Subject: [PATCH 262/327] Replaced deprecated osg::Shader::reaDShaderFile()/loadShaderFromSource() usage --- examples/osgSSBO/osgSSBO.cpp | 29 +++++++--------- .../osganimationhardware.cpp | 2 +- examples/osggameoflife/GameOfLifePass.cpp | 8 ++--- examples/osgshaders/GL2Scene.cpp | 7 ++-- examples/osgstereomatch/StereoMultipass.cpp | 34 ++++++++++++++----- examples/osgstereomatch/StereoPass.cpp | 10 ++++-- examples/osgwidgetshader/osgwidgetshader.cpp | 12 ++----- src/osgAnimation/MorphTransformHardware.cpp | 9 +++-- src/osgAnimation/RigTransformHardware.cpp | 4 +-- src/osgSim/OverlayNode.cpp | 5 +-- .../deprecated-dotosg/osg/Shader.cpp | 5 +-- 11 files changed, 64 insertions(+), 61 deletions(-) diff --git a/examples/osgSSBO/osgSSBO.cpp b/examples/osgSSBO/osgSSBO.cpp index e357acac8..637f466bc 100644 --- a/examples/osgSSBO/osgSSBO.cpp +++ b/examples/osgSSBO/osgSSBO.cpp @@ -200,15 +200,10 @@ public: ComputeNode() { - const char* envOsgFilePath = getenv("OSG_FILE_PATH"); - std::stringstream computeshaderpath; computeshaderpath << envOsgFilePath << "/shaders/osgssboComputeShader.cs"; - _computeShaderSourcePath = computeshaderpath.str(); - std::stringstream vertexshaderpath; vertexshaderpath << envOsgFilePath << "/shaders/osgssboVertexShader.vs"; - _vertexShaderSourcePath = vertexshaderpath.str(); - std::stringstream geometryshaderpath; geometryshaderpath << envOsgFilePath << "/shaders/osgssboGeometryShader.gs"; - _geometryShaderSourcePath = geometryshaderpath.str(); - std::stringstream fragmentshaderpath; fragmentshaderpath << envOsgFilePath << "/shaders/osgssboFragmentShader.fs"; - _fragmentShaderSourcePath = fragmentshaderpath.str(); + _computeShaderSourcePath = "shaders/osgssboComputeShader.cs"; + _vertexShaderSourcePath = "shaders/osgssboVertexShader.vs"; + _geometryShaderSourcePath = "shaders/osgssboGeometryShader.gs"; + _fragmentShaderSourcePath = "shaders/osgssboFragmentShader.fs"; } }; @@ -243,7 +238,7 @@ public: if (_computeNode->_computeShader.valid()) { runningSource = _computeNode->_computeShader->getShaderSource(); - reloadedshader = osg::Shader::readShaderFile(osg::Shader::COMPUTE, _computeNode->_computeShaderSourcePath); + reloadedshader = osgDB::readRefShaderFile(osg::Shader::COMPUTE, _computeNode->_computeShaderSourcePath); reloadedstring = reloadedshader->getShaderSource(); if (!osgDB::equalCaseInsensitive(runningSource.c_str(), reloadedstring.c_str())) @@ -258,7 +253,7 @@ public: { runningSource = _computeNode->_vertexShader->getShaderSource(); - reloadedshader = osg::Shader::readShaderFile(osg::Shader::VERTEX, _computeNode->_vertexShaderSourcePath); + reloadedshader = osgDB::readRefShaderFile(osg::Shader::VERTEX, _computeNode->_vertexShaderSourcePath); reloadedstring = reloadedshader->getShaderSource(); if (!osgDB::equalCaseInsensitive(runningSource.c_str(), reloadedstring.c_str())) @@ -274,7 +269,7 @@ public: if (_computeNode->_geometryShader.valid()) { runningSource = _computeNode->_geometryShader->getShaderSource(); - reloadedshader = osg::Shader::readShaderFile(osg::Shader::GEOMETRY, _computeNode->_geometryShaderSourcePath); + reloadedshader = osgDB::readRefShaderFile(osg::Shader::GEOMETRY, _computeNode->_geometryShaderSourcePath); reloadedstring = reloadedshader->getShaderSource(); if (!osgDB::equalCaseInsensitive(runningSource.c_str(), reloadedstring.c_str())) @@ -288,7 +283,7 @@ public: if (_computeNode->_fragmentShader.valid()) { runningSource = _computeNode->_fragmentShader->getShaderSource(); - reloadedshader = osg::Shader::readShaderFile(osg::Shader::FRAGMENT, _computeNode->_fragmentShaderSourcePath); + reloadedshader = osgDB::readRefShaderFile(osg::Shader::FRAGMENT, _computeNode->_fragmentShaderSourcePath); reloadedstring = reloadedshader->getShaderSource(); if (!osgDB::equalCaseInsensitive(runningSource.c_str(), reloadedstring.c_str())) @@ -517,13 +512,13 @@ void ComputeNode::addComputationResultsRenderTree() _computationResultsRenderProgram = new osg::Program; - _vertexShader = osg::Shader::readShaderFile(osg::Shader::VERTEX, _vertexShaderSourcePath); + _vertexShader = osgDB::readRefShaderFile(osg::Shader::VERTEX, _vertexShaderSourcePath); _computationResultsRenderProgram->addShader(_vertexShader.get()); - _geometryShader = osg::Shader::readShaderFile(osg::Shader::GEOMETRY, _geometryShaderSourcePath); + _geometryShader = osgDB::readRefShaderFile(osg::Shader::GEOMETRY, _geometryShaderSourcePath); _computationResultsRenderProgram->addShader(_geometryShader.get()); - _fragmentShader = osg::Shader::readShaderFile(osg::Shader::FRAGMENT, _fragmentShaderSourcePath); + _fragmentShader = osgDB::readRefShaderFile(osg::Shader::FRAGMENT, _fragmentShaderSourcePath); _computationResultsRenderProgram->addShader(_fragmentShader.get()); @@ -628,7 +623,7 @@ void ComputeNode::initComputingSetup() _computeProgram = new osg::Program; _computeProgram->setComputeGroups((NUM_ELEMENTS_X / WORK_GROUP_SIZE) <= 1 ? 1 : (NUM_ELEMENTS_X / WORK_GROUP_SIZE), (NUM_ELEMENTS_Y / WORK_GROUP_SIZE) <= 1 ? 1 : (NUM_ELEMENTS_Y / WORK_GROUP_SIZE), 1); - _computeShader = osg::Shader::readShaderFile(osg::Shader::COMPUTE, _computeShaderSourcePath); + _computeShader = osgDB::readRefShaderFile(osg::Shader::COMPUTE, _computeShaderSourcePath); _computeProgram->addShader(_computeShader.get()); setDataVariance(osg::Object::DYNAMIC); diff --git a/examples/osganimationhardware/osganimationhardware.cpp b/examples/osganimationhardware/osganimationhardware.cpp index f8d7be4da..1cb05473f 100644 --- a/examples/osganimationhardware/osganimationhardware.cpp +++ b/examples/osganimationhardware/osganimationhardware.cpp @@ -87,7 +87,7 @@ struct MyRigTransformHardware : public osgAnimation::RigTransformHardware //set default source if _shader is not user setted if (!vertexshader.valid()) { - vertexshader = osg::Shader::readShaderFile(osg::Shader::VERTEX,"skinning.vert"); + vertexshader = osgDB::readRefShaderFile(osg::Shader::VERTEX,"skinning.vert"); } if (!vertexshader.valid()) diff --git a/examples/osggameoflife/GameOfLifePass.cpp b/examples/osggameoflife/GameOfLifePass.cpp index 0cab6f16f..1e3490917 100644 --- a/examples/osggameoflife/GameOfLifePass.cpp +++ b/examples/osggameoflife/GameOfLifePass.cpp @@ -18,6 +18,7 @@ #include "GameOfLifePass.h" #include +#include #include ProcessPass::ProcessPass(osg::TextureRectangle *in_tex, @@ -110,16 +111,13 @@ void ProcessPass::setupCamera() void ProcessPass::setShader(std::string filename) { - std::string foundFile = osgDB::findDataFile(filename); - if (foundFile.empty()) + osg::ref_ptr fshader = osgDB::readRefShaderFile(osg::Shader::FRAGMENT, filename); + if (!fshader) { osg::notify(osg::NOTICE)<<"Could not file shader file: "< fshader = new osg::Shader( osg::Shader::FRAGMENT ); - fshader->loadShaderSourceFromFile(foundFile); - _FragmentProgram = 0; _FragmentProgram = new osg::Program; diff --git a/examples/osgshaders/GL2Scene.cpp b/examples/osgshaders/GL2Scene.cpp index f06592983..17a38e8e2 100644 --- a/examples/osgshaders/GL2Scene.cpp +++ b/examples/osgshaders/GL2Scene.cpp @@ -37,7 +37,6 @@ #include #include #include -#include #include #include @@ -141,10 +140,10 @@ ModelInstance() static void LoadShaderSource( osg::Shader* shader, const std::string& fileName ) { - std::string fqFileName = osgDB::findDataFile(fileName); - if( fqFileName.length() != 0 ) + osg::ref_ptr loaded_shader = osgDB::readRefShaderFile(fileName); + if (loaded_shader) { - shader->loadShaderSourceFromFile( fqFileName.c_str() ); + shader->setShaderSource( loaded_shader->getShaderSource() ); } else { diff --git a/examples/osgstereomatch/StereoMultipass.cpp b/examples/osgstereomatch/StereoMultipass.cpp index 90a71ba24..9601be94f 100644 --- a/examples/osgstereomatch/StereoMultipass.cpp +++ b/examples/osgstereomatch/StereoMultipass.cpp @@ -19,7 +19,7 @@ */ #include "StereoMultipass.h" -#include +#include #include SubtractPass::SubtractPass(osg::TextureRectangle *left_tex, @@ -132,8 +132,12 @@ void SubtractPass::createOutputTextures() void SubtractPass::setShader(std::string filename) { - osg::ref_ptr fshader = new osg::Shader( osg::Shader::FRAGMENT ); - fshader->loadShaderSourceFromFile(osgDB::findDataFile(filename)); + osg::ref_ptr fshader = osgDB::readRefShaderFile( osg::Shader::FRAGMENT, filename); + if (!fshader) + { + OSG_NOTICE<<"Warning: could not file shader file : "< fshader = new osg::Shader( osg::Shader::FRAGMENT ); - fshader->loadShaderSourceFromFile(osgDB::findDataFile(filename)); + osg::ref_ptr fshader = osgDB::readRefShaderFile( osg::Shader::FRAGMENT, filename); + if (!fshader) + { + OSG_NOTICE<<"Warning: could not file shader file : "< fshader = new osg::Shader( osg::Shader::FRAGMENT ); - fshader->loadShaderSourceFromFile(osgDB::findDataFile(filename)); + osg::ref_ptr fshader = osgDB::readRefShaderFile( osg::Shader::FRAGMENT, filename); + if (!fshader) + { + OSG_NOTICE<<"Warning: could not file shader file : "< fshader = new osg::Shader( osg::Shader::FRAGMENT ); - fshader->loadShaderSourceFromFile(osgDB::findDataFile(filename)); + osg::ref_ptr fshader = osgDB::readRefShaderFile( osg::Shader::FRAGMENT, filename); + if (!fshader) + { + OSG_NOTICE<<"Warning: could not file shader file : "< +#include #include StereoPass::StereoPass(osg::TextureRectangle *left_tex, @@ -129,8 +129,12 @@ void StereoPass::createOutputTextures() void StereoPass::setShader(std::string filename) { - osg::ref_ptr fshader = new osg::Shader( osg::Shader::FRAGMENT ); - fshader->loadShaderSourceFromFile(osgDB::findDataFile(filename)); + osg::ref_ptr fshader = osgDB::readRefShaderFile( osg::Shader::FRAGMENT, filename); + if (!fshader) + { + OSG_NOTICE<<"Warning: could not file shader file : "< +#include #include #include #include @@ -60,15 +60,9 @@ int main(int, char**) osg::Program* program = new osg::Program(); - program->addShader(osg::Shader::readShaderFile( - osg::Shader::VERTEX, - osgDB::findDataFile("osgWidget/osgwidgetshader-vert.glsl") - )); - program->addShader(osg::Shader::readShaderFile( - osg::Shader::FRAGMENT, - osgDB::findDataFile("osgWidget/osgwidgetshader-frag.glsl") - )); + program->addShader(osgDB::readRefShaderFile( osg::Shader::VERTEX, "osgWidget/osgwidgetshader-vert.glsl" ) ); + program->addShader(osgDB::readRefShaderFile( osg::Shader::FRAGMENT, "osgWidget/osgwidgetshader-frag.glsl" ) ); canvas->getGeode()->getOrCreateStateSet()->setAttribute(program); diff --git a/src/osgAnimation/MorphTransformHardware.cpp b/src/osgAnimation/MorphTransformHardware.cpp index b960ef650..f13ea715e 100644 --- a/src/osgAnimation/MorphTransformHardware.cpp +++ b/src/osgAnimation/MorphTransformHardware.cpp @@ -16,6 +16,7 @@ #include #include #include +#include #include using namespace osgAnimation; @@ -137,10 +138,8 @@ bool MorphTransformHardware::init(MorphGeometry& morphGeometry) //set default source if _shader is not user setted if (!vertexshader.valid()) { - if (!_shader.valid()) - vertexshader = osg::Shader::readShaderFile(osg::Shader::VERTEX,"morphing.vert"); - else - vertexshader=_shader; + if (!_shader.valid()) vertexshader = osgDB::readRefShaderFile(osg::Shader::VERTEX,"morphing.vert"); + else vertexshader=_shader; } if (!vertexshader.valid()) @@ -157,7 +156,7 @@ bool MorphTransformHardware::init(MorphGeometry& morphGeometry) if (std::string::npos == start) { // perhaps remanance from previous init (if saved after init) so reload shader - vertexshader = osg::Shader::readShaderFile(osg::Shader::VERTEX,"morphing.vert"); + vertexshader = osgDB::readRefShaderFile(osg::Shader::VERTEX,"morphing.vert"); if (!vertexshader.valid()) { OSG_WARN << "RigTransformHardware can't load VertexShader" << std::endl; diff --git a/src/osgAnimation/RigTransformHardware.cpp b/src/osgAnimation/RigTransformHardware.cpp index 38d592a55..1ccff5a16 100644 --- a/src/osgAnimation/RigTransformHardware.cpp +++ b/src/osgAnimation/RigTransformHardware.cpp @@ -16,6 +16,7 @@ #include #include #include +#include #include using namespace osgAnimation; @@ -315,8 +316,7 @@ bool RigTransformHardware::init(RigGeometry& rig) //set default source if _shader is not user setted if (!vertexshader.valid()) { - if (!_shader.valid()) - vertexshader = osg::Shader::readShaderFile(osg::Shader::VERTEX,"skinning.vert"); + if (!_shader.valid()) vertexshader = osgDB::readRefShaderFile(osg::Shader::VERTEX,"skinning.vert"); else vertexshader = _shader; } diff --git a/src/osgSim/OverlayNode.cpp b/src/osgSim/OverlayNode.cpp index dbd2e0be2..343d20878 100644 --- a/src/osgSim/OverlayNode.cpp +++ b/src/osgSim/OverlayNode.cpp @@ -19,6 +19,7 @@ #include #include +#include #include #include @@ -1028,7 +1029,7 @@ OverlayNode::OverlayData* OverlayNode::getOverlayData(osgUtil::CullVisitor* cv) std::string vertexShaderFile = osgDB::findDataFile("shaders/overlay_perspective_rtt.vert"); if (!vertexShaderFile.empty()) { - program->addShader(osg::Shader::readShaderFile(osg::Shader::VERTEX, vertexShaderFile)); + program->addShader(osgDB::readRefShaderFile(osg::Shader::VERTEX, vertexShaderFile)); } else { @@ -1119,7 +1120,7 @@ OverlayNode::OverlayData* OverlayNode::getOverlayData(osgUtil::CullVisitor* cv) std::string fragmentShaderFile = osgDB::findDataFile("shaders/overlay_perspective_main.frag"); if (!fragmentShaderFile.empty()) { - overlayData->_mainSubgraphProgram->addShader(osg::Shader::readShaderFile(osg::Shader::FRAGMENT, fragmentShaderFile)); + overlayData->_mainSubgraphProgram->addShader(osgDB::readRefShaderFile(osg::Shader::FRAGMENT, fragmentShaderFile)); } else { diff --git a/src/osgWrappers/deprecated-dotosg/osg/Shader.cpp b/src/osgWrappers/deprecated-dotosg/osg/Shader.cpp index 8ea9d5a49..9c27f720f 100644 --- a/src/osgWrappers/deprecated-dotosg/osg/Shader.cpp +++ b/src/osgWrappers/deprecated-dotosg/osg/Shader.cpp @@ -47,10 +47,7 @@ bool Shader_readLocalData(Object& obj, Input& fr) { osg::ref_ptr s = osgDB::readRefShaderFile(fr[1].getStr(), fr.getOptions()); - if(s.get()) - shader.setShaderSource(s->getShaderSource()); - else - shader.loadShaderSourceFromFile( osgDB::findDataFile(fr[1].getStr()) ); + if(s.get()) shader.setShaderSource(s->getShaderSource()); fr += 2; iteratorAdvanced = true; From 117045170dbc1fc065499e0fc751b968180cc4bf Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Tue, 28 Nov 2017 15:31:39 +0000 Subject: [PATCH 263/327] To the GLSL shader plugin added support forL #pragma include shaderfile.glsl To enable easier reuse of shaders --- src/osgPlugins/glsl/ReaderWriterGLSL.cpp | 124 ++++++++++++++++++----- 1 file changed, 98 insertions(+), 26 deletions(-) diff --git a/src/osgPlugins/glsl/ReaderWriterGLSL.cpp b/src/osgPlugins/glsl/ReaderWriterGLSL.cpp index 2f69cae90..9d471decd 100644 --- a/src/osgPlugins/glsl/ReaderWriterGLSL.cpp +++ b/src/osgPlugins/glsl/ReaderWriterGLSL.cpp @@ -32,48 +32,115 @@ class ReaderWriterGLSL : public osgDB::ReaderWriter virtual const char* className() const { return "GLSL Shader Reader"; } - osg::Shader* processIncludes( const osg::Shader* shader, const Options* options ) const + void processIncludes( osg::Shader& shader, const Options* options ) const { - std::string code = shader->getShaderSource(); + std::string code = shader.getShaderSource(); + std::string startOfIncludeMarker("// Start of include code : "); + std::string endOfIncludeMarker("// End of include code : "); + std::string failedLoadMarker("// Failed to load include code : "); + + #if defined(__APPLE__) + std::string endOfLine("\r"); + #elif defined(_WIN32) + std::string endOfLine("\r\n"); + #else + std::string endOfLine("\n"); + #endif + std::string::size_type pos = 0; - - static std::string::size_type includeLen = 8; - - while( ( pos = code.find( "#include", pos ) ) != std::string::npos ) + std::string::size_type pragma_pos = 0; + std::string::size_type include_pos = 0; + while( (pos !=std::string::npos) && (((pragma_pos=code.find( "#pragma", pos )) != std::string::npos) || (include_pos=code.find( "#include", pos )) != std::string::npos)) { - // we found an include - std::string::size_type pos2 = code.find_first_not_of( " ", pos + includeLen ); + pos = (pragma_pos!= std::string::npos) ? pragma_pos : include_pos; - if ( ( pos2 == std::string::npos ) || ( code[ pos2 ] != '\"' ) ) + std::string::size_type start_of_pragma_line = pos; + std::string::size_type end_of_line = code.find_first_of("\n\r", pos ); + + if (pragma_pos!= std::string::npos) { - // error, bail out - return NULL; + // we have #pragma usage so skip to the start of the first non white space + pos = code.find_first_not_of(" \t", pos+7 ); + if (pos==std::string::npos) break; + + + // check for include part of #pragma imclude usage + if (code.compare(pos, 7, "include")!=0) + { + pos = end_of_line; + continue; + } + + // found include entry so skip to next non white space + pos = code.find_first_not_of(" \t", pos+7 ); + if (pos==std::string::npos) break; + } + else + { + // we have #include usage so skip to next non white space + pos = code.find_first_not_of(" \t", pos+8 ); + if (pos==std::string::npos) break; } - // we found an " - std::string::size_type pos3 = code.find( "\"", pos2 + 1 ); - if ( pos3 == std::string::npos ) + std::string::size_type num_characters = (end_of_line==std::string::npos) ? code.size()-pos : end_of_line-pos; + if (num_characters==0) continue; + + // prune trailing white space + while(num_characters>0 && (code[pos+num_characters-1]==' ' || code[pos+num_characters-1]=='\t')) --num_characters; + + if (code[pos]=='\"') { - return NULL; + if (code[pos+num_characters-1]!='\"') + { + num_characters -= 1; + } + else + { + num_characters -= 2; + } + + ++pos; } - const std::string filename = code.substr( pos2 + 1, pos3 - pos2 - 1 ); + std::string filename(code, pos, num_characters); - osg::ref_ptr innerShader = osgDB::readRefShaderFile( shader->getType(), filename, options ); + code.erase(start_of_pragma_line, (end_of_line==std::string::npos) ? code.size()-start_of_pragma_line : end_of_line-start_of_pragma_line); + pos = start_of_pragma_line; - if ( !innerShader.valid() ) + osg::ref_ptr innerShader = osgDB::readRefShaderFile( filename, options ); + + if (innerShader.valid()) { - return NULL; + if (!startOfIncludeMarker.empty()) + { + code.insert(pos, startOfIncludeMarker); pos += startOfIncludeMarker.size(); + code.insert(pos, filename); pos += filename.size(); + code.insert(pos, endOfLine); pos += endOfLine.size(); + } + + code.insert(pos, innerShader->getShaderSource() ); pos += innerShader->getShaderSource().size(); + + if (!endOfIncludeMarker.empty()) + { + code.insert(pos, endOfIncludeMarker); pos += endOfIncludeMarker.size(); + code.insert(pos, filename); pos += filename.size(); + code.insert(pos, endOfLine); pos += endOfLine.size(); + } + } + else + { + if (!failedLoadMarker.empty()) + { + code.insert(pos, failedLoadMarker); pos += failedLoadMarker.size(); + code.insert(pos, filename); pos += filename.size(); + code.insert(pos, endOfLine); pos += endOfLine.size(); + } } - - code.replace( pos, pos3 - pos + 1, innerShader->getShaderSource() ); - - pos += innerShader->getShaderSource().size(); } - return new osg::Shader( shader->getType(), code ); + shader.setShaderSource(code); } virtual ReadResult readObject(std::istream& fin,const Options* options) const @@ -108,8 +175,10 @@ class ReaderWriterGLSL : public osgDB::ReaderWriter if (options->getOptionString().find("compute")!=std::string::npos) shader->setType(osg::Shader::COMPUTE); } + processIncludes( *shader, options ); + // return valid shader - return processIncludes( shader.get(), options ); + return shader.get(); } virtual ReadResult readShader(const std::string& file, const osgDB::ReaderWriter::Options* options) const @@ -120,9 +189,12 @@ class ReaderWriterGLSL : public osgDB::ReaderWriter std::string fileName = osgDB::findDataFile( file, options ); if (fileName.empty()) return ReadResult::FILE_NOT_FOUND; + osg::ref_ptr local_opt = options ? static_cast(options->clone(osg::CopyOp::SHALLOW_COPY)) : new Options; + local_opt->getDatabasePathList().push_front(osgDB::getFilePath(fileName)); + osgDB::ifstream istream(fileName.c_str(), std::ios::in | std::ios::binary); if(!istream) return ReadResult::FILE_NOT_HANDLED; - ReadResult rr = readShader(istream, options); + ReadResult rr = readShader(istream, local_opt); if(rr.validShader()) { osg::Shader* shader = rr.getShader(); From bf1b4ec2bbdf052444cbd5608dd60ec03bb09437 Mon Sep 17 00:00:00 2001 From: Julien Valentin Date: Tue, 28 Nov 2017 17:30:04 +0100 Subject: [PATCH 264/327] add ComputeDispatch class revoke glDispatch in PCProgram::useProgram update example --- .../osgcomputeshaders/osgcomputeshaders.cpp | 6 +-- include/osg/ComputeDispatch | 48 +++++++++++++++++++ src/osg/CMakeLists.txt | 2 + src/osg/ComputeDispatch.cpp | 12 +++++ src/osg/Program.cpp | 4 -- .../serializers/osg/ComputeDispatch.cpp | 36 ++++++++++++++ 6 files changed, 100 insertions(+), 8 deletions(-) create mode 100644 include/osg/ComputeDispatch create mode 100644 src/osg/ComputeDispatch.cpp create mode 100644 src/osgWrappers/serializers/osg/ComputeDispatch.cpp diff --git a/examples/osgcomputeshaders/osgcomputeshaders.cpp b/examples/osgcomputeshaders/osgcomputeshaders.cpp index 87073cfe5..7d87a7472 100644 --- a/examples/osgcomputeshaders/osgcomputeshaders.cpp +++ b/examples/osgcomputeshaders/osgcomputeshaders.cpp @@ -20,7 +20,7 @@ // This example can work only if GL version is 4.3 or greater #include -#include +#include #include #include #include @@ -57,14 +57,12 @@ int main( int argc, char** argv ) // The compute shader can't work with other kinds of shaders // It also requires the work group numbers. Setting them to 0 will disable the compute shader osg::ref_ptr computeProg = new osg::Program; - computeProg->setComputeGroups( 512/16, 512/16, 1 ); computeProg->addShader( new osg::Shader(osg::Shader::COMPUTE, computeSrc) ); // Create a node for outputting to the texture. // It is OK to have just an empty node here, but seems inbuilt uniforms like osg_FrameTime won't work then. // TODO: maybe we can have a custom drawable which also will implement glMemoryBarrier? - osg::ref_ptr sourceNode = osgDB::readRefNodeFile("axes.osgt"); - if ( !sourceNode ) sourceNode = new osg::Node; + osg::ref_ptr sourceNode = new osg::ComputeDispatch(512/16, 512/16, 1 ); sourceNode->setDataVariance( osg::Object::DYNAMIC ); sourceNode->getOrCreateStateSet()->setAttributeAndModes( computeProg.get() ); sourceNode->getOrCreateStateSet()->addUniform( new osg::Uniform("targetTex", (int)0) ); diff --git a/include/osg/ComputeDispatch b/include/osg/ComputeDispatch new file mode 100644 index 000000000..605011060 --- /dev/null +++ b/include/osg/ComputeDispatch @@ -0,0 +1,48 @@ +/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2014 Robert Osfield + * Copyright (C) 2017 Julien Valentin + * + * This library is open source and may be redistributed and/or modified under + * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or + * (at your option) any later version. The full license is in LICENSE file + * included with this distribution, and on the openscenegraph.org website. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * OpenSceneGraph Public License for more details. +*/ + +#ifndef OSG_COMPUTEDISPATCH +#define OSG_COMPUTEDISPATCH 1 + +#include + +#include + +namespace osg{ + class OSG_EXPORT ComputeDispatch : public osg::Drawable + { + public: + ComputeDispatch(GLint numGroupsX=0, GLint numGroupsY=0, GLint numGroupsZ=0 ): + Drawable(), + _numGroupsX(numGroupsX), + _numGroupsY(numGroupsY), + _numGroupsZ(numGroupsZ) + {} + + ComputeDispatch(const ComputeDispatch&,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY); + + META_Node(osg, ComputeDispatch); + + + virtual void drawImplementation(RenderInfo& renderInfo) const; + /** Set/get compute shader work groups */ + void setComputeGroups( GLint numGroupsX, GLint numGroupsY, GLint numGroupsZ ) { _numGroupsX=numGroupsX,_numGroupsY=numGroupsY, _numGroupsZ=numGroupsZ; } + void getComputeGroups( GLint& numGroupsX, GLint& numGroupsY, GLint& numGroupsZ ) const{ numGroupsX=_numGroupsX; numGroupsY=_numGroupsY; numGroupsZ=_numGroupsZ; } + protected: + GLint _numGroupsX, _numGroupsY, _numGroupsZ; + + }; +} +#endif + diff --git a/src/osg/CMakeLists.txt b/src/osg/CMakeLists.txt index 845306551..5fc119403 100644 --- a/src/osg/CMakeLists.txt +++ b/src/osg/CMakeLists.txt @@ -55,6 +55,7 @@ SET(TARGET_H ${HEADER_PATH}/ColorMaski ${HEADER_PATH}/ColorMatrix ${HEADER_PATH}/ComputeBoundsVisitor + ${HEADER_PATH}/ComputeDispatch ${HEADER_PATH}/ContextData ${HEADER_PATH}/ConvexPlanarOccluder ${HEADER_PATH}/ConvexPlanarPolygon @@ -267,6 +268,7 @@ SET(TARGET_SRC ColorMaski.cpp ColorMatrix.cpp ComputeBoundsVisitor.cpp + ComputeDispatch.cpp ContextData.cpp ConvexPlanarOccluder.cpp ConvexPlanarPolygon.cpp diff --git a/src/osg/ComputeDispatch.cpp b/src/osg/ComputeDispatch.cpp new file mode 100644 index 000000000..75791b68f --- /dev/null +++ b/src/osg/ComputeDispatch.cpp @@ -0,0 +1,12 @@ +#include +using namespace osg; + + +ComputeDispatch::ComputeDispatch(const ComputeDispatch&o,const osg::CopyOp& copyop): Drawable(o,copyop), _numGroupsX(o._numGroupsX), _numGroupsY(o._numGroupsY), _numGroupsZ(o._numGroupsZ) +{ + +} + +void ComputeDispatch::drawImplementation(RenderInfo& renderInfo) const{ + renderInfo.getState()->get()->glDispatchCompute(_numGroupsX, _numGroupsY, _numGroupsZ); +} diff --git a/src/osg/Program.cpp b/src/osg/Program.cpp index 68fadaf0c..f42fe3826 100644 --- a/src/osg/Program.cpp +++ b/src/osg/Program.cpp @@ -1108,8 +1108,4 @@ Program::ProgramBinary* Program::PerContextProgram::compileProgramBinary(osg::St void Program::PerContextProgram::useProgram() const { _extensions->glUseProgram( _glProgramHandle ); - if ( _program->_numGroupsX>0 && _program->_numGroupsY>0 && _program->_numGroupsZ>0 ) - { - _extensions->glDispatchCompute( _program->_numGroupsX, _program->_numGroupsY, _program->_numGroupsZ ); - } } diff --git a/src/osgWrappers/serializers/osg/ComputeDispatch.cpp b/src/osgWrappers/serializers/osg/ComputeDispatch.cpp new file mode 100644 index 000000000..d77533a5d --- /dev/null +++ b/src/osgWrappers/serializers/osg/ComputeDispatch.cpp @@ -0,0 +1,36 @@ +#include +#include +#include +#include + +// _numGroupsX/Y/Z +static bool checkComputeGroups( const osg::ComputeDispatch& attr ) +{ + GLint numX = 0, numY = 0, numZ = 0; + attr.getComputeGroups( numX, numY, numZ ); + return numX>0 && numY>0 && numZ>0; +} + +static bool readComputeGroups( osgDB::InputStream& is, osg::ComputeDispatch& attr ) +{ + GLint numX = 0, numY = 0, numZ = 0; + is >> numX >> numY >> numZ; + attr.setComputeGroups( numX, numY, numZ ); + return true; +} + +static bool writeComputeGroups( osgDB::OutputStream& os, const osg::ComputeDispatch& attr ) +{ + GLint numX = 0, numY = 0, numZ = 0; + attr.getComputeGroups( numX, numY, numZ ); + os << numX << numY << numZ << std::endl; + return true; +} + +REGISTER_OBJECT_WRAPPER( ComputeDispatch, + new osg::ComputeDispatch, + osg::ComputeDispatch, + "osg::Object osg::Node osg::Drawable osg::ComputeDispatch" ) +{ + ADD_USER_SERIALIZER( ComputeGroups ); // _numGroupsX/Y/Z +} From 195df4f811d774286644ccda58c202fb5a8f7b3d Mon Sep 17 00:00:00 2001 From: Julien Valentin Date: Tue, 28 Nov 2017 17:39:32 +0100 Subject: [PATCH 265/327] numgroup removed but introduce a reto compatibility bug in Program serializer hope nobody use it --- include/osg/Program | 10 ------- src/osg/Program.cpp | 30 +-------------------- src/osgWrappers/serializers/osg/Program.cpp | 28 ------------------- 3 files changed, 1 insertion(+), 67 deletions(-) diff --git a/include/osg/Program b/include/osg/Program index 36aa7ed2f..e9e26829f 100644 --- a/include/osg/Program +++ b/include/osg/Program @@ -103,10 +103,6 @@ class OSG_EXPORT Program : public osg::StateAttribute void setParameter( GLenum pname, GLint value ); GLint getParameter( GLenum pname ) const; - /** Set/get compute shader work groups */ - void setComputeGroups( GLint numGroupsX, GLint numGroupsY, GLint numGroupsZ ); - void getComputeGroups( GLint& numGroupsX, GLint& numGroupsY, GLint& numGroupsZ ) const; - /** Add an attribute location binding. */ void addBindAttribLocation( const std::string& name, GLuint index ); @@ -439,12 +435,6 @@ class OSG_EXPORT Program : public osg::StateAttribute GLint _geometryInputType; GLint _geometryOutputType; - - /** Parameter maintained with glDispatchCompute */ - GLint _numGroupsX; - GLint _numGroupsY; - GLint _numGroupsZ; - /**TransformFeedBack**/ GLenum _feedbackmode; std::vector _feedbackout; diff --git a/src/osg/Program.cpp b/src/osg/Program.cpp index f42fe3826..b41d27b81 100644 --- a/src/osg/Program.cpp +++ b/src/osg/Program.cpp @@ -92,8 +92,7 @@ void Program::ProgramBinary::assign(unsigned int size, const unsigned char* data Program::Program() : _geometryVerticesOut(1), _geometryInputType(GL_TRIANGLES), - _geometryOutputType(GL_TRIANGLE_STRIP), - _numGroupsX(0), _numGroupsY(0), _numGroupsZ(0), _feedbackmode(GL_SEPARATE_ATTRIBS) + _geometryOutputType(GL_TRIANGLE_STRIP), _feedbackmode(GL_SEPARATE_ATTRIBS) { } @@ -133,10 +132,6 @@ Program::Program(const Program& rhs, const osg::CopyOp& copyop): _geometryInputType = rhs._geometryInputType; _geometryOutputType = rhs._geometryOutputType; - _numGroupsX = rhs._numGroupsX; - _numGroupsY = rhs._numGroupsY; - _numGroupsZ = rhs._numGroupsZ; - _feedbackmode=rhs._feedbackmode; _feedbackout=rhs._feedbackout; } @@ -173,15 +168,6 @@ int Program::compare(const osg::StateAttribute& sa) const if( _geometryOutputType < rhs._geometryOutputType ) return -1; if( rhs._geometryOutputType < _geometryOutputType ) return 1; - if( _numGroupsX < rhs._numGroupsX ) return -1; - if( rhs._numGroupsX < _numGroupsX ) return 1; - - if( _numGroupsY < rhs._numGroupsY ) return -1; - if( rhs._numGroupsY < _numGroupsY ) return 1; - - if( _numGroupsZ < rhs._numGroupsZ ) return -1; - if( rhs._numGroupsZ < _numGroupsZ ) return 1; - if(_feedbackout0 && numY>0 && numZ>0; -} - -static bool readComputeGroups( osgDB::InputStream& is, osg::Program& attr ) -{ - GLint numX = 0, numY = 0, numZ = 0; - is >> numX >> numY >> numZ; - attr.setComputeGroups( numX, numY, numZ ); - return true; -} - -static bool writeComputeGroups( osgDB::OutputStream& os, const osg::Program& attr ) -{ - GLint numX = 0, numY = 0, numZ = 0; - attr.getComputeGroups( numX, numY, numZ ); - os << numX << numY << numZ << std::endl; - return true; -} static bool checkBindUniformBlock( const osg::Program& node ) { @@ -190,11 +167,6 @@ REGISTER_OBJECT_WRAPPER( Program, ADD_USER_SERIALIZER( GeometryInputType ); // _geometryInputType ADD_USER_SERIALIZER( GeometryOutputType ); // _geometryOutputType - { - UPDATE_TO_VERSION_SCOPED( 95 ) - ADD_USER_SERIALIZER( ComputeGroups ); // _numGroupsX/Y/Z - } - { UPDATE_TO_VERSION_SCOPED( 116 ) ADD_USER_SERIALIZER( FeedBackVaryingsName ); From 5ad22dc4af622afed71896edd12d2e171411c754 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Tue, 28 Nov 2017 18:04:26 +0000 Subject: [PATCH 266/327] Quitened down debug output --- src/osgViewer/ViewerBase.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/osgViewer/ViewerBase.cpp b/src/osgViewer/ViewerBase.cpp index 9184ff79a..c03f1f0b8 100644 --- a/src/osgViewer/ViewerBase.cpp +++ b/src/osgViewer/ViewerBase.cpp @@ -86,7 +86,8 @@ void ViewerBase::configureAffinity() { unsigned int numProcessors = OpenThreads::GetNumberOfProcessors(); - OSG_NOTICE<<"ViewerBase::configureAffinity() numProcessors="< Date: Tue, 28 Nov 2017 18:08:08 +0000 Subject: [PATCH 268/327] Quietened down debug output --- src/osg/State.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/osg/State.cpp b/src/osg/State.cpp index 5ed4f277e..ba9e143e5 100644 --- a/src/osg/State.cpp +++ b/src/osg/State.cpp @@ -202,8 +202,8 @@ void State::initializeExtensionProcs() _forceVertexArrayObject = true; } - OSG_NOTICE<<"_forceVertexArrayObject = "<<_forceVertexArrayObject< loadedModel = osgDB::readNodeFile(newModel.filename); + osg::ref_ptr loadedModel = osgDB::readRefNodeFile(newModel.filename); if (loadedModel == 0) { osg::notify(osg::ALWAYS)<<"Model not loaded"< loadedModel = osgDB::readNodeFile(newModel.filename); + osg::ref_ptr loadedModel = osgDB::readRefNodeFile(newModel.filename); if (loadedModel == 0) { osg::notify(osg::ALWAYS)<<"Model not loaded"< node = fc->getInputFileName().empty() ? 0 : osgDB::readNodeFile(fc->getInputFileName()); + osg::ref_ptr node; + if (!fc->getInputFileName().empty()) + { + osgDB::readRefNodeFile(fc->getInputFileName()); + } if (node.valid()) { cp->setToModel(node.get()); @@ -522,7 +526,7 @@ int main( int argc, char **argv ) gsc::CaptureSettings* fc = itr->get(); screenShot->_frameCapture = fc; - osg::ref_ptr model = osgDB::readNodeFile(fc->getInputFileName()); + osg::ref_ptr model = osgDB::readRefNodeFile(fc->getInputFileName()); if (!model) break; viewer.setSceneData(model.get()); diff --git a/examples/osgstaticviewer/osgstaticviewer.cpp b/examples/osgstaticviewer/osgstaticviewer.cpp index 80983bc70..e01a99cbe 100644 --- a/examples/osgstaticviewer/osgstaticviewer.cpp +++ b/examples/osgstaticviewer/osgstaticviewer.cpp @@ -170,7 +170,7 @@ int main(int argc, char** argv) } // load the data - osg::ref_ptr loadedModel = osgDB::readNodeFiles(arguments); + osg::ref_ptr loadedModel = osgDB::readRefNodeFiles(arguments); if (!loadedModel) { std::cout << arguments.getApplicationName() <<": No data loaded" << std::endl; diff --git a/examples/osgviewerCocoa/ViewerCocoa.mm b/examples/osgviewerCocoa/ViewerCocoa.mm index 84333c449..ea24ba825 100644 --- a/examples/osgviewerCocoa/ViewerCocoa.mm +++ b/examples/osgviewerCocoa/ViewerCocoa.mm @@ -1193,7 +1193,7 @@ A -respondsToSelector: check has been used to provide compatibility with previou // int number_of_files = [file_names count]; // Exercise for the reader: Try loading all files in the array NSString* single_file = [file_names objectAtIndex:0]; - osg::ref_ptr loaded_model = osgDB::readNodeFile([single_file fileSystemRepresentation]); + osg::ref_ptr loaded_model = osgDB::readRefNodeFile([single_file fileSystemRepresentation]); if(!loaded_model) { NSLog(@"File: %@ failed to load", single_file); @@ -1212,7 +1212,7 @@ A -respondsToSelector: check has been used to provide compatibility with previou return NO; } NSString* file_path = [file_url path]; - osg::ref_ptr loaded_model = osgDB::readNodeFile([file_path fileSystemRepresentation]); + osg::ref_ptr loaded_model = osgDB::readRefNodeFile([file_path fileSystemRepresentation]); if(!loaded_model) { NSLog(@"URL: %@ failed to load, %@", file_url, file_path); diff --git a/examples/osgviewerFOX/FOX_OSG_MDIView.cpp b/examples/osgviewerFOX/FOX_OSG_MDIView.cpp index df6124e2e..9dccc0791 100644 --- a/examples/osgviewerFOX/FOX_OSG_MDIView.cpp +++ b/examples/osgviewerFOX/FOX_OSG_MDIView.cpp @@ -39,7 +39,7 @@ FOX_OSG_MDIView::FOX_OSG_MDIView(FXMDIClient *p, const FXString &name, viewer->setKeyEventSetsDone(0); // load the scene. - osg::ref_ptr loadedModel = osgDB::readNodeFile("cow.osgt"); + osg::ref_ptr loadedModel = osgDB::readRefNodeFile("cow.osgt"); if (!loadedModel) { return ; diff --git a/examples/osgviewerGTK/osgviewerGTK.cpp b/examples/osgviewerGTK/osgviewerGTK.cpp index 8c77071d5..810ba3b82 100644 --- a/examples/osgviewerGTK/osgviewerGTK.cpp +++ b/examples/osgviewerGTK/osgviewerGTK.cpp @@ -69,7 +69,7 @@ class ExampleOSGGTKDrawingArea : public OSGGTKDrawingArea { if(gtk_dialog_run(GTK_DIALOG(of)) == GTK_RESPONSE_ACCEPT) { char* file = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(of)); - osg::ref_ptr model = osgDB::readNodeFile(file); + osg::ref_ptr model = osgDB::readRefNodeFile(file); if(model.valid()) { setSceneData(model.get()); @@ -170,7 +170,7 @@ int main(int argc, char** argv) { if(da.createWidget(640, 480)) { if(argc >= 2) { - osg::ref_ptr model = osgDB::readNodeFile(argv[1]); + osg::ref_ptr model = osgDB::readRefNodeFile(argv[1]); if(model.valid()) da.setSceneData(model.get()); } diff --git a/examples/osgviewerIPhone/iphoneViewerAppDelegate.mm b/examples/osgviewerIPhone/iphoneViewerAppDelegate.mm index 05654eee9..fc328b2c3 100644 --- a/examples/osgviewerIPhone/iphoneViewerAppDelegate.mm +++ b/examples/osgviewerIPhone/iphoneViewerAppDelegate.mm @@ -337,7 +337,7 @@ private: _root->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF | osg::StateAttribute::OVERRIDE); //load and attach scene model - osg::ref_ptr model = osgDB::readNodeFile(osgDB::findDataFile("lz.osg")); + osg::ref_ptr model = osgDB::readRefNodeFile(osgDB::findDataFile("lz.osg")); if (!model) { osg::Geode* geode = new osg::Geode(); osg::ShapeDrawable* drawable = new osg::ShapeDrawable(new osg::Box(osg::Vec3(0,0,0), 1)); From 994c38c0c77d16f7403298a615fa4742dd38500d Mon Sep 17 00:00:00 2001 From: Julien Valentin Date: Tue, 28 Nov 2017 20:03:40 +0100 Subject: [PATCH 270/327] adapt SSBO example for ComputeDispatch but have strange runtime errors: 0(100) : error C7623: implicit narrowing of type from "vec3" to "float" 0(108) : error C7623: implicit narrowing of type from "vec3" to "float" --- examples/osgSSBO/osgSSBO.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/examples/osgSSBO/osgSSBO.cpp b/examples/osgSSBO/osgSSBO.cpp index 637f466bc..5ce2ec07c 100644 --- a/examples/osgSSBO/osgSSBO.cpp +++ b/examples/osgSSBO/osgSSBO.cpp @@ -10,7 +10,7 @@ #include #include #include -#include +#include #include #include #include @@ -167,6 +167,7 @@ class ComputeNode : public osg::PositionAttitudeTransform public: + osg::ref_ptr _computeDispatch; osg::ref_ptr _computeProgram; osg::ref_ptr _computeShader; //compute and write position data in SSBO @@ -204,6 +205,8 @@ public: _vertexShaderSourcePath = "shaders/osgssboVertexShader.vs"; _geometryShaderSourcePath = "shaders/osgssboGeometryShader.gs"; _fragmentShaderSourcePath = "shaders/osgssboFragmentShader.fs"; + _computeDispatch=new osg::ComputeDispatch(); + addChild(_computeDispatch); } }; @@ -622,7 +625,7 @@ void ComputeNode::initComputingSetup() { _computeProgram = new osg::Program; - _computeProgram->setComputeGroups((NUM_ELEMENTS_X / WORK_GROUP_SIZE) <= 1 ? 1 : (NUM_ELEMENTS_X / WORK_GROUP_SIZE), (NUM_ELEMENTS_Y / WORK_GROUP_SIZE) <= 1 ? 1 : (NUM_ELEMENTS_Y / WORK_GROUP_SIZE), 1); + _computeDispatch->setComputeGroups((NUM_ELEMENTS_X / WORK_GROUP_SIZE) <= 1 ? 1 : (NUM_ELEMENTS_X / WORK_GROUP_SIZE), (NUM_ELEMENTS_Y / WORK_GROUP_SIZE) <= 1 ? 1 : (NUM_ELEMENTS_Y / WORK_GROUP_SIZE), 1); _computeShader = osgDB::readRefShaderFile(osg::Shader::COMPUTE, _computeShaderSourcePath); _computeProgram->addShader(_computeShader.get()); From 739303b3d968811fac206123e5f1707ca0861218 Mon Sep 17 00:00:00 2001 From: Julien Valentin Date: Tue, 28 Nov 2017 20:31:09 +0100 Subject: [PATCH 271/327] override compile and createVAS in order to do nothing --- include/osg/ComputeDispatch | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/include/osg/ComputeDispatch b/include/osg/ComputeDispatch index 605011060..2a3725bc1 100644 --- a/include/osg/ComputeDispatch +++ b/include/osg/ComputeDispatch @@ -34,11 +34,16 @@ namespace osg{ META_Node(osg, ComputeDispatch); + virtual void compileGLObjects(RenderInfo& renderInfo) const {return;} + + virtual VertexArrayState* createVertexArrayState(RenderInfo& renderInfo) const { return 0; } virtual void drawImplementation(RenderInfo& renderInfo) const; + /** Set/get compute shader work groups */ void setComputeGroups( GLint numGroupsX, GLint numGroupsY, GLint numGroupsZ ) { _numGroupsX=numGroupsX,_numGroupsY=numGroupsY, _numGroupsZ=numGroupsZ; } void getComputeGroups( GLint& numGroupsX, GLint& numGroupsY, GLint& numGroupsZ ) const{ numGroupsX=_numGroupsX; numGroupsY=_numGroupsY; numGroupsZ=_numGroupsZ; } + protected: GLint _numGroupsX, _numGroupsY, _numGroupsZ; From 021dca0072c2372ee8b09a707b8ec0db727e2ade Mon Sep 17 00:00:00 2001 From: OpenSceneGraph git repository Date: Wed, 29 Nov 2017 08:14:44 +0000 Subject: [PATCH 272/327] Cleaned up code layout --- include/osg/ComputeDispatch | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/include/osg/ComputeDispatch b/include/osg/ComputeDispatch index 2a3725bc1..411d8de32 100644 --- a/include/osg/ComputeDispatch +++ b/include/osg/ComputeDispatch @@ -23,7 +23,7 @@ namespace osg{ class OSG_EXPORT ComputeDispatch : public osg::Drawable { public: - ComputeDispatch(GLint numGroupsX=0, GLint numGroupsY=0, GLint numGroupsZ=0 ): + ComputeDispatch(GLint numGroupsX=0, GLint numGroupsY=0, GLint numGroupsZ=0): Drawable(), _numGroupsX(numGroupsX), _numGroupsY(numGroupsY), @@ -34,14 +34,16 @@ namespace osg{ META_Node(osg, ComputeDispatch); - virtual void compileGLObjects(RenderInfo& renderInfo) const {return;} + virtual void compileGLObjects(RenderInfo& renderInfo) const {} virtual VertexArrayState* createVertexArrayState(RenderInfo& renderInfo) const { return 0; } virtual void drawImplementation(RenderInfo& renderInfo) const; - /** Set/get compute shader work groups */ - void setComputeGroups( GLint numGroupsX, GLint numGroupsY, GLint numGroupsZ ) { _numGroupsX=numGroupsX,_numGroupsY=numGroupsY, _numGroupsZ=numGroupsZ; } + /** Set compute shader work groups */ + void setComputeGroups( GLint numGroupsX, GLint numGroupsY, GLint numGroupsZ ) { _numGroupsX=numGroupsX; _numGroupsY=numGroupsY; _numGroupsZ=numGroupsZ; } + + /** Get compute shader work groups */ void getComputeGroups( GLint& numGroupsX, GLint& numGroupsY, GLint& numGroupsZ ) const{ numGroupsX=_numGroupsX; numGroupsY=_numGroupsY; numGroupsZ=_numGroupsZ; } protected: From cd0744ddfa9025cc0721b03b205b997969a9d079 Mon Sep 17 00:00:00 2001 From: OpenSceneGraph git repository Date: Wed, 29 Nov 2017 08:16:53 +0000 Subject: [PATCH 273/327] Cleaned up code layout --- src/osg/ComputeDispatch.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/osg/ComputeDispatch.cpp b/src/osg/ComputeDispatch.cpp index 75791b68f..c689bd95b 100644 --- a/src/osg/ComputeDispatch.cpp +++ b/src/osg/ComputeDispatch.cpp @@ -1,12 +1,16 @@ #include + using namespace osg; - -ComputeDispatch::ComputeDispatch(const ComputeDispatch&o,const osg::CopyOp& copyop): Drawable(o,copyop), _numGroupsX(o._numGroupsX), _numGroupsY(o._numGroupsY), _numGroupsZ(o._numGroupsZ) +ComputeDispatch::ComputeDispatch(const ComputeDispatch&o,const osg::CopyOp& copyop): + Drawable(o,copyop), + _numGroupsX(o._numGroupsX), + _numGroupsY(o._numGroupsY), + _numGroupsZ(o._numGroupsZ) { - } -void ComputeDispatch::drawImplementation(RenderInfo& renderInfo) const{ +void ComputeDispatch::drawImplementation(RenderInfo& renderInfo) const +{ renderInfo.getState()->get()->glDispatchCompute(_numGroupsX, _numGroupsY, _numGroupsZ); } From cf05cd5bf3dec0c2a56c000ca94423697ffc8c08 Mon Sep 17 00:00:00 2001 From: Mathieu Date: Wed, 29 Nov 2017 11:05:53 +0100 Subject: [PATCH 274/327] Make the culling be disables at the drawable level not at the geode level --- src/osgPlugins/logo/ReaderWriterLOGO.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/osgPlugins/logo/ReaderWriterLOGO.cpp b/src/osgPlugins/logo/ReaderWriterLOGO.cpp index 0af8a20a7..2ca9fd318 100644 --- a/src/osgPlugins/logo/ReaderWriterLOGO.cpp +++ b/src/osgPlugins/logo/ReaderWriterLOGO.cpp @@ -321,7 +321,7 @@ class LOGOReaderWriter : public osgDB::ReaderWriter if( ld->hasLogos() ) geode->addDrawable( ld ); - geode->setCullingActive(false); + ld->setCullingActive(false); return geode; } }; From c0a276e85023927cd056a28a028523ff709b8492 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 29 Nov 2017 10:11:35 +0000 Subject: [PATCH 275/327] Added back in serializer support for comput dispatch groups to retain backwards compatibility. --- src/osgWrappers/serializers/osg/Program.cpp | 29 +++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/src/osgWrappers/serializers/osg/Program.cpp b/src/osgWrappers/serializers/osg/Program.cpp index 13195c87d..74e0342c3 100644 --- a/src/osgWrappers/serializers/osg/Program.cpp +++ b/src/osgWrappers/serializers/osg/Program.cpp @@ -121,6 +121,25 @@ static bool writeFeedBackMode( osgDB::OutputStream& os, const osg::Program& attr os << attr.getTransformFeedBackMode()<< std::endl; return true; } +// _numGroupsX/Y/Z +static bool checkComputeGroups( const osg::Program& attr ) +{ + return false; +} + +static bool readComputeGroups( osgDB::InputStream& is, osg::Program& attr ) +{ + GLint numX = 0, numY = 0, numZ = 0; + is >> numX >> numY >> numZ; + return true; +} + +static bool writeComputeGroups( osgDB::OutputStream& os, const osg::Program& attr ) +{ + GLint numX = 0, numY = 0, numZ = 0; + os << numX << numY << numZ << std::endl; + return true; +} static bool checkBindUniformBlock( const osg::Program& node ) { @@ -167,6 +186,16 @@ REGISTER_OBJECT_WRAPPER( Program, ADD_USER_SERIALIZER( GeometryInputType ); // _geometryInputType ADD_USER_SERIALIZER( GeometryOutputType ); // _geometryOutputType + { + UPDATE_TO_VERSION_SCOPED( 95 ) + ADD_USER_SERIALIZER( ComputeGroups ); // _numGroupsX/Y/Z + } + + { + UPDATE_TO_VERSION_SCOPED( 153 ) + REMOVE_SERIALIZER( ComputeGroups ); + } + { UPDATE_TO_VERSION_SCOPED( 116 ) ADD_USER_SERIALIZER( FeedBackVaryingsName ); From 28af946c4b8d30e7159dbd9e08de5c6e1a436899 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 29 Nov 2017 10:40:20 +0000 Subject: [PATCH 276/327] Bummped the SO version --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 46cb0f32b..78179e94c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,7 +4,7 @@ SET(OPENSCENEGRAPH_MAJOR_VERSION 3) SET(OPENSCENEGRAPH_MINOR_VERSION 5) SET(OPENSCENEGRAPH_PATCH_VERSION 9) -SET(OPENSCENEGRAPH_SOVERSION 152) +SET(OPENSCENEGRAPH_SOVERSION 153) # set to 0 when not a release candidate, non zero means that any generated From 03434b20cf012f17f80359cd51e35a09ee4b67ba Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 29 Nov 2017 12:22:03 +0000 Subject: [PATCH 277/327] Added mapping of GLSL file extension to shader Type. --- src/osgPlugins/glsl/ReaderWriterGLSL.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/osgPlugins/glsl/ReaderWriterGLSL.cpp b/src/osgPlugins/glsl/ReaderWriterGLSL.cpp index 9d471decd..3713befd3 100644 --- a/src/osgPlugins/glsl/ReaderWriterGLSL.cpp +++ b/src/osgPlugins/glsl/ReaderWriterGLSL.cpp @@ -203,11 +203,15 @@ class ReaderWriterGLSL : public osgDB::ReaderWriter { // set type based on filename extension, where possible if (ext == "frag") shader->setType(osg::Shader::FRAGMENT); + if (ext == "fs") shader->setType(osg::Shader::FRAGMENT); if (ext == "vert") shader->setType(osg::Shader::VERTEX); + if (ext == "vs") shader->setType(osg::Shader::VERTEX); if (ext == "geom") shader->setType(osg::Shader::GEOMETRY); + if (ext == "gs") shader->setType(osg::Shader::GEOMETRY); if (ext == "tctrl") shader->setType(osg::Shader::TESSCONTROL); if (ext == "teval") shader->setType(osg::Shader::TESSEVALUATION); if (ext == "compute") shader->setType(osg::Shader::COMPUTE); + if (ext == "cs") shader->setType(osg::Shader::COMPUTE); } } return rr; From a6069c3226a42d6ef29348b9e3ddd8adb5e147fd Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 29 Nov 2017 14:22:31 +0000 Subject: [PATCH 278/327] Introduced Drawable::CreateVertexArrayStateCallback to enable customization of how VertexArrayState objects. Added public accessors to the Drawable::VertexArrayStateList. --- include/osg/ComputeDispatch | 4 +-- include/osg/Drawable | 50 ++++++++++++++++++++++++++++-- include/osg/Geometry | 2 +- include/osgParticle/ParticleSystem | 2 +- include/osgTerrain/GeometryPool | 2 +- include/osgText/TextBase | 2 +- src/osg/Drawable.cpp | 6 ++-- src/osg/Geometry.cpp | 2 +- src/osgParticle/ParticleSystem.cpp | 2 +- src/osgTerrain/GeometryPool.cpp | 2 +- src/osgText/TextBase.cpp | 2 +- 11 files changed, 62 insertions(+), 14 deletions(-) diff --git a/include/osg/ComputeDispatch b/include/osg/ComputeDispatch index 411d8de32..5e0ac6ffe 100644 --- a/include/osg/ComputeDispatch +++ b/include/osg/ComputeDispatch @@ -34,9 +34,9 @@ namespace osg{ META_Node(osg, ComputeDispatch); - virtual void compileGLObjects(RenderInfo& renderInfo) const {} + virtual void compileGLObjects(RenderInfo&) const {} - virtual VertexArrayState* createVertexArrayState(RenderInfo& renderInfo) const { return 0; } + virtual VertexArrayState* createVertexArrayStateImplememtation(RenderInfo&) const { return 0; } virtual void drawImplementation(RenderInfo& renderInfo) const; diff --git a/include/osg/Drawable b/include/osg/Drawable index acae9d2c3..9547659f5 100644 --- a/include/osg/Drawable +++ b/include/osg/Drawable @@ -278,7 +278,53 @@ class OSG_EXPORT Drawable : public Node */ virtual void compileGLObjects(RenderInfo& renderInfo) const; - virtual VertexArrayState* createVertexArrayState(RenderInfo& renderInfo) const; + + /** Callback class for overriding the default Drawable::createCreateVertexArrayStateImplementation().*/ + struct CreateVertexArrayStateCallback : public virtual osg::Object + { + CreateVertexArrayStateCallback() {} + + CreateVertexArrayStateCallback(const CreateVertexArrayStateCallback& rhs,const CopyOp& copyop): + Object(rhs, copyop) {} + + META_Object(osg, CreateVertexArrayStateCallback); + + /** do customized createVertexArrayState .*/ + virtual osg::VertexArrayState* createVertexArrayStateImplementation(osg::RenderInfo& renderInfo, const osg::Drawable* drawable) const + { + return drawable->createVertexArrayStateImplementation(renderInfo); + } + }; + + + /** Set the callback to override the default Drawable::createCreateVertexArrayStateImplementation().*/ + void setCreateVertexArrayStateCallback(CreateVertexArrayStateCallback* cb) { _createVertexArrayStateCallback = cb; } + + /** Get the callback that overrides the default Drawable::createCreateVertexArrayStateImplementation().*/ + CreateVertexArrayStateCallback* getCreateVertexArrayStateCallback() { return _createVertexArrayStateCallback.get(); } + + /** Get the const callback that overrides the default Drawable::createCreateVertexArrayStateImplementation().*/ + const CreateVertexArrayStateCallback* getCreateVertexArrayStateCallback() const { return _createVertexArrayStateCallback.get(); } + + + /** Craeate tje VertexArrayState object used to track vertex array and vertex array object state. This method will be called automatically during rendering setup so users should not call this themselves.*/ + inline VertexArrayState* createVertexArrayState(RenderInfo& renderInfo) const + { + if (_createVertexArrayStateCallback.valid()) return _createVertexArrayStateCallback->createVertexArrayStateImplementation(renderInfo, this); + else return createVertexArrayStateImplementation(renderInfo); + } + + /** Implementaion of Craeate tje VertexArrayState object.*/ + virtual VertexArrayState* createVertexArrayStateImplementation(RenderInfo& renderInfo) const; + + typedef buffered_object< osg::ref_ptr > VertexArrayStateList; + + void setVertexArrayStateList(VertexArrayStateList& vasl) { _vertexArrayStateList = vasl; } + + VertexArrayStateList& getVertexArrayStateList() { return _vertexArrayStateList; } + + const VertexArrayStateList& getVertexArrayStateList() const { return _vertexArrayStateList; } + /** Set whether to use a mutex to ensure ref() and unref() are thread safe.*/ @@ -491,10 +537,10 @@ class OSG_EXPORT Drawable : public Node typedef osg::buffered_value GLObjectList; mutable GLObjectList _globjList; - typedef buffered_object< osg::ref_ptr > VertexArrayStateList; mutable VertexArrayStateList _vertexArrayStateList; ref_ptr _drawCallback; + ref_ptr _createVertexArrayStateCallback; }; #ifdef INLINE_DRAWABLE_DRAW diff --git a/include/osg/Geometry b/include/osg/Geometry index dd1094859..1fb8caea3 100644 --- a/include/osg/Geometry +++ b/include/osg/Geometry @@ -233,7 +233,7 @@ class OSG_EXPORT Geometry : public Drawable bool _containsDeprecatedData; - virtual VertexArrayState* createVertexArrayState(RenderInfo& renderInfo) const; + virtual VertexArrayState* createVertexArrayStateImplementation(RenderInfo& renderInfo) const; public: diff --git a/include/osgParticle/ParticleSystem b/include/osgParticle/ParticleSystem index 4348cb075..099549501 100644 --- a/include/osgParticle/ParticleSystem +++ b/include/osgParticle/ParticleSystem @@ -265,7 +265,7 @@ namespace osgParticle * for all graphics contexts. */ virtual void releaseGLObjects(osg::State* state=0) const; - virtual osg::VertexArrayState* createVertexArrayState(osg::RenderInfo& renderInfo) const; + virtual osg::VertexArrayState* createVertexArrayStateImplemenation(osg::RenderInfo& renderInfo) const; void adjustEstimatedMaxNumOfParticles(int delta) { _estimatedMaxNumOfParticles += delta; } diff --git a/include/osgTerrain/GeometryPool b/include/osgTerrain/GeometryPool index bb8e1e34b..06fec359a 100644 --- a/include/osgTerrain/GeometryPool +++ b/include/osgTerrain/GeometryPool @@ -66,7 +66,7 @@ class OSGTERRAIN_EXPORT SharedGeometry : public osg::Drawable const VertexToHeightFieldMapping& getVertexToHeightFieldMapping() const { return _vertexToHeightFieldMapping; } - osg::VertexArrayState* createVertexArrayState(osg::RenderInfo& renderInfo) const; + osg::VertexArrayState* createVertexArrayStateImplemenation(osg::RenderInfo& renderInfo) const; void compileGLObjects(osg::RenderInfo& renderInfo) const; diff --git a/include/osgText/TextBase b/include/osgText/TextBase index f262a0593..a674e3bd4 100644 --- a/include/osgText/TextBase +++ b/include/osgText/TextBase @@ -295,7 +295,7 @@ protected: void initArraysAndBuffers(); - osg::VertexArrayState* createVertexArrayState(osg::RenderInfo& renderInfo) const; + osg::VertexArrayState* createVertexArrayStateImplementation(osg::RenderInfo& renderInfo) const; void positionCursor(const osg::Vec2 & endOfLine_coords, osg::Vec2 & cursor, unsigned int linelength); String::iterator computeLastCharacterOnLine(osg::Vec2& cursor, String::iterator first,String::iterator last); diff --git a/src/osg/Drawable.cpp b/src/osg/Drawable.cpp index 857e4546d..f82df9df0 100644 --- a/src/osg/Drawable.cpp +++ b/src/osg/Drawable.cpp @@ -249,7 +249,8 @@ Drawable::Drawable(const Drawable& drawable,const CopyOp& copyop): _supportsVertexBufferObjects(drawable._supportsVertexBufferObjects), _useVertexBufferObjects(drawable._useVertexBufferObjects), _useVertexArrayObject(drawable._useVertexArrayObject), - _drawCallback(drawable._drawCallback) + _drawCallback(drawable._drawCallback), + _createVertexArrayStateCallback(drawable._createVertexArrayStateCallback) { setStateSet(copyop(drawable._stateset.get())); } @@ -696,8 +697,9 @@ void Drawable::draw(RenderInfo& renderInfo) const #endif -VertexArrayState* Drawable::createVertexArrayState(RenderInfo& renderInfo) const +VertexArrayState* Drawable::createVertexArrayStateImplementation(RenderInfo& renderInfo) const { + OSG_NOTICE<<"VertexArrayState* Drawable::createVertexArrayStateImplementation(RenderInfo& renderInfo) const "<assignAllDispatchers(); return vos; diff --git a/src/osg/Geometry.cpp b/src/osg/Geometry.cpp index aff29211b..30b1bd9b9 100644 --- a/src/osg/Geometry.cpp +++ b/src/osg/Geometry.cpp @@ -720,7 +720,7 @@ void Geometry::releaseGLObjects(State* state) const } -VertexArrayState* Geometry::createVertexArrayState(RenderInfo& renderInfo) const +VertexArrayState* Geometry::createVertexArrayStateImplementation(RenderInfo& renderInfo) const { State& state = *renderInfo.getState(); diff --git a/src/osgParticle/ParticleSystem.cpp b/src/osgParticle/ParticleSystem.cpp index c20bef1d5..fc9fec13f 100644 --- a/src/osgParticle/ParticleSystem.cpp +++ b/src/osgParticle/ParticleSystem.cpp @@ -657,7 +657,7 @@ void osgParticle::ParticleSystem::releaseGLObjects(osg::State* state) const } } -osg::VertexArrayState* osgParticle::ParticleSystem::createVertexArrayState(osg::RenderInfo& renderInfo) const +osg::VertexArrayState* osgParticle::ParticleSystem::createVertexArrayStateImplemenation(osg::RenderInfo& renderInfo) const { osg::State& state = *renderInfo.getState(); diff --git a/src/osgTerrain/GeometryPool.cpp b/src/osgTerrain/GeometryPool.cpp index c69781f44..760579440 100644 --- a/src/osgTerrain/GeometryPool.cpp +++ b/src/osgTerrain/GeometryPool.cpp @@ -796,7 +796,7 @@ SharedGeometry::~SharedGeometry() { } -osg::VertexArrayState* SharedGeometry::createVertexArrayState(osg::RenderInfo& renderInfo) const +osg::VertexArrayState* SharedGeometry::createVertexArrayStateImplemenation(osg::RenderInfo& renderInfo) const { osg::State& state = *renderInfo.getState(); diff --git a/src/osgText/TextBase.cpp b/src/osgText/TextBase.cpp index 6fbf2e5ba..3d9534903 100644 --- a/src/osgText/TextBase.cpp +++ b/src/osgText/TextBase.cpp @@ -109,7 +109,7 @@ void TextBase::initArraysAndBuffers() _texcoords->setBufferObject(_vbo.get()); } -osg::VertexArrayState* TextBase::createVertexArrayState(osg::RenderInfo& renderInfo) const +osg::VertexArrayState* TextBase::createVertexArrayStateImplementation(osg::RenderInfo& renderInfo) const { State& state = *renderInfo.getState(); From d3815759a9e70d2fda1f72d0d8c277a8f12cf73f Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 29 Nov 2017 14:44:00 +0000 Subject: [PATCH 279/327] Fixed build with OSG_USE_REF_PTR_IMPLICIT_OUTPUT_CONVERSION set to OFF --- src/osgPlugins/glsl/ReaderWriterGLSL.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/osgPlugins/glsl/ReaderWriterGLSL.cpp b/src/osgPlugins/glsl/ReaderWriterGLSL.cpp index 3713befd3..a836a0cf0 100644 --- a/src/osgPlugins/glsl/ReaderWriterGLSL.cpp +++ b/src/osgPlugins/glsl/ReaderWriterGLSL.cpp @@ -194,7 +194,7 @@ class ReaderWriterGLSL : public osgDB::ReaderWriter osgDB::ifstream istream(fileName.c_str(), std::ios::in | std::ios::binary); if(!istream) return ReadResult::FILE_NOT_HANDLED; - ReadResult rr = readShader(istream, local_opt); + ReadResult rr = readShader(istream, local_opt.get()); if(rr.validShader()) { osg::Shader* shader = rr.getShader(); From 85a79f53d72b0f5e4ea5715240a922210dfe1abf Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 29 Nov 2017 14:49:00 +0000 Subject: [PATCH 280/327] Updated ChangeLog and AUTHORS for 3.5.9 dev release --- AUTHORS.txt | 2 +- ChangeLog | 168 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 169 insertions(+), 1 deletion(-) diff --git a/AUTHORS.txt b/AUTHORS.txt index b03c1700a..36d546850 100644 --- a/AUTHORS.txt +++ b/AUTHORS.txt @@ -1,4 +1,4 @@ -OpenSceneGraph Library 3.5.8 +OpenSceneGraph Library 3.5.9 568 Contributors: diff --git a/ChangeLog b/ChangeLog index 34bd19c33..7d75e6a5d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,171 @@ +Wed, 29 Nov 2017 14:44:00 +0000 +Author : Robert Osfield +Fixed build with OSG_USE_REF_PTR_IMPLICIT_OUTPUT_CONVERSION set to OFF + +Wed, 29 Nov 2017 14:22:31 +0000 +Author : Robert Osfield +Introduced Drawable::CreateVertexArrayStateCallback to enable customization of how VertexArrayState objects.Added public accessors to the Drawable::VertexArrayStateList. + + +Wed, 29 Nov 2017 12:22:03 +0000 +Author : Robert Osfield +Added mapping of GLSL file extension to shader Type. + +Wed, 29 Nov 2017 10:40:42 +0000 +Author : Robert Osfield +Merge branch 'master' of https://github.com/openscenegraph/OpenSceneGraph + +Wed, 29 Nov 2017 10:40:20 +0000 +Author : Robert Osfield +Bummped the SO version + +Wed, 29 Nov 2017 10:38:52 +0000 +Author : OpenSceneGraph git repository +Merge pull request #394 from mathieu/masterMake the culling be disabled at the drawable level + +Wed, 29 Nov 2017 10:14:16 +0000 +Author : Robert Osfield +Merge branch 'mp3butcher-ComputeDispatch' + +Wed, 29 Nov 2017 10:11:35 +0000 +Author : Robert Osfield +Added back in serializer support for comput dispatch groups to retain backwards compatibility. + +Wed, 29 Nov 2017 11:05:53 +0100 +Author : Mathieu +Make the culling be disables at the drawable level not at the geode level + +Wed, 29 Nov 2017 09:30:56 +0000 +Author : Robert Osfield +Merge branch 'ComputeDispatch' of https://github.com/mp3butcher/OpenSceneGraph into mp3butcher-ComputeDispatch + +Wed, 29 Nov 2017 08:16:53 +0000 +Author : OpenSceneGraph git repository +Cleaned up code layout + +Wed, 29 Nov 2017 08:14:44 +0000 +Author : OpenSceneGraph git repository +Cleaned up code layout + +Wed, 29 Nov 2017 08:09:01 +0000 +Author : OpenSceneGraph git repository +Merge pull request #390 from filnet/readrefreplace more read*File() usage to readRef*File() + +Tue, 28 Nov 2017 20:31:09 +0100 +Author : Julien Valentin +override compile and createVAS in order to do nothing + +Tue, 28 Nov 2017 20:03:40 +0100 +Author : Julien Valentin +adapt SSBO example for ComputeDispatch but have strange runtime errors: 0(100) : error C7623: implicit narrowing of type from "vec3" to "float" 0(108) : error C7623: implicit narrowing of type from "vec3" to "float" + +Tue, 28 Nov 2017 19:51:31 +0100 +Author : Philippe Renon +replace more read*File() usage to readRef*File() + +Tue, 28 Nov 2017 18:08:08 +0000 +Author : Robert Osfield +Quietened down debug output + +Tue, 28 Nov 2017 18:05:59 +0000 +Author : Robert Osfield +Quietened down debug output + +Tue, 28 Nov 2017 18:04:26 +0000 +Author : Robert Osfield +Quitened down debug output + +Tue, 28 Nov 2017 17:39:32 +0100 +Author : Julien Valentin +numgroup removed but introduce a reto compatibility bug in Program serializer hope nobody use it + +Tue, 28 Nov 2017 17:30:04 +0100 +Author : Julien Valentin +add ComputeDispatch class revoke glDispatch in PCProgram::useProgram update example + +Tue, 28 Nov 2017 15:31:39 +0000 +Author : Robert Osfield +To the GLSL shader plugin added support forL #pragma include shaderfile.glsl + +To enable easier reuse of shaders + + +Mon, 27 Nov 2017 18:38:37 +0000 +Author : Robert Osfield +Replaced deprecated osg::Shader::reaDShaderFile()/loadShaderFromSource() usage + +Mon, 27 Nov 2017 18:36:41 +0000 +Author : Robert Osfield +Merge branch 'master' of https://github.com/openscenegraph/OpenSceneGraph + +Mon, 27 Nov 2017 18:28:15 +0000 +Author : Robert Osfield +Deprecated the osg::Shader::reaDShaderFile() and osg::Shader::loadShaderSourceFromFile() methods. Programmers should use osgDB::readRefShaderFile()/readShaderFile() instead. + +Mon, 27 Nov 2017 18:27:13 +0000 +Author : Robert Osfield +Added support for .cs, .compute, .tctrlm .teval extensions in the GLSL plugin + +Mon, 27 Nov 2017 15:54:39 +0000 +Author : OpenSceneGraph git repository +Merge pull request #387 from jtorresfabra/remove_custom_codeRemoves custom code added for sketchfab channel compression that shou… + +Mon, 27 Nov 2017 15:44:11 +0000 +Author : Robert Osfield +Refactored the MergeGeometry::mergeGroup(..) method to avoid O(N^2) issue with using removeChildren() on groups with very large numbers of children. + +Mon, 27 Nov 2017 15:41:54 +0000 +Author : Robert Osfield +Replaced read*File() usage to readRef*File() + +Mon, 27 Nov 2017 15:40:21 +0000 +Author : Robert Osfield +Added template addShader() method to make it easier to pass ref_ptr + +Mon, 27 Nov 2017 15:48:50 +0100 +Author : Jordi +Removes custom code added for sketchfab channel compression that should not be there + +Mon, 27 Nov 2017 11:10:48 +0000 +Author : Robert Osfield +Fixes for building with OSG_PROVIDE_READFILE to OFF + +Mon, 27 Nov 2017 11:05:31 +0000 +Author : Robert Osfield +Fixed build issues when compiling with OSG_PROVIDE_READFILE to OFF + +Mon, 27 Nov 2017 10:32:02 +0000 +Author : Robert Osfield +Build fix + +Wed, 22 Nov 2017 11:05:17 +0000 +Author : Robert Osfield +Removed use of local static to avoid threading issue. + +Tue, 21 Nov 2017 14:01:14 +0000 +Author : OpenSceneGraph git repository +Merge pull request #383 from anormann1974/patch-1Fixed missing initialization of B_ and N_ in constructor + +Tue, 21 Nov 2017 13:59:51 +0000 +Author : Robert Osfield +Fixed typo + +Tue, 21 Nov 2017 13:41:57 +0000 +Author : Robert Osfield +Added Text::getCharacterCorners(...) method to help applications that want to find out the positions of characters being rendered. + +Tue, 21 Nov 2017 13:54:45 +0100 +Author : Andre Normann +Fixed missing initialization of B_ and N_ in constructor + +Mon, 20 Nov 2017 12:49:20 +0000 +Author : Robert Osfield +Moved the version to 3.5.9 and the version setting code to top of CMake file + +Tue, 14 Nov 2017 15:04:05 +0000 +Author : Robert Osfield +Updated ChangeLog and AUTHORS file for 3.5.8 dev release + Tue, 14 Nov 2017 10:38:18 +0000 Author : Raymond de Vries attached fixes for configuring and building the osgPlugin exr with Visual Studio and using out-of-the-box builds of ilmbase and openexr, i.e. without manual/extra config for using these 2 libs with the OSG.Previously, the assumption was made that ilmbase and openexr were installed in a common directory and hence the header files and libs were both found in that common directory. That is not consistent with other libs and this submission makes it consistent and therefore the OSG configures out of the box. I made this work for ilmbase-2.1.0.tar.gz / openexr-2.1.0.tar.gz and ilmbase-2.2.0.tar.gz / openexr-2.2.0.tar.gz From 4af66f6897bef68817f42356af4a8272d2fc2a26 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 29 Nov 2017 15:06:53 +0000 Subject: [PATCH 281/327] Update version to 3.5.10 --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 78179e94c..f05d9f6ec 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,7 +3,7 @@ # SET(OPENSCENEGRAPH_MAJOR_VERSION 3) SET(OPENSCENEGRAPH_MINOR_VERSION 5) -SET(OPENSCENEGRAPH_PATCH_VERSION 9) +SET(OPENSCENEGRAPH_PATCH_VERSION 10) SET(OPENSCENEGRAPH_SOVERSION 153) From a16702627ac3c2e82104f810f9d1f8ad031927e7 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 29 Nov 2017 21:20:10 +0000 Subject: [PATCH 282/327] Typo fix --- include/osgTerrain/GeometryPool | 2 +- src/osgTerrain/GeometryPool.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/osgTerrain/GeometryPool b/include/osgTerrain/GeometryPool index 06fec359a..026cc01c5 100644 --- a/include/osgTerrain/GeometryPool +++ b/include/osgTerrain/GeometryPool @@ -66,7 +66,7 @@ class OSGTERRAIN_EXPORT SharedGeometry : public osg::Drawable const VertexToHeightFieldMapping& getVertexToHeightFieldMapping() const { return _vertexToHeightFieldMapping; } - osg::VertexArrayState* createVertexArrayStateImplemenation(osg::RenderInfo& renderInfo) const; + osg::VertexArrayState* createVertexArrayStateImplementation(osg::RenderInfo& renderInfo) const; void compileGLObjects(osg::RenderInfo& renderInfo) const; diff --git a/src/osgTerrain/GeometryPool.cpp b/src/osgTerrain/GeometryPool.cpp index 760579440..45b00fef9 100644 --- a/src/osgTerrain/GeometryPool.cpp +++ b/src/osgTerrain/GeometryPool.cpp @@ -796,7 +796,7 @@ SharedGeometry::~SharedGeometry() { } -osg::VertexArrayState* SharedGeometry::createVertexArrayStateImplemenation(osg::RenderInfo& renderInfo) const +osg::VertexArrayState* SharedGeometry::createVertexArrayStateImplementation(osg::RenderInfo& renderInfo) const { osg::State& state = *renderInfo.getState(); From e8f7eeb5dcdd2296e5341a86f95734c1717fcbc5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Blissing?= Date: Thu, 30 Nov 2017 12:47:57 +0100 Subject: [PATCH 283/327] Removed unnecessary define in FileUtils The define of _WIN32_WINNT was added to handle an error case from MinGW ,as described in commit 712ca432196cd797cc3c265adb2847465551461f This was later giving warnings and thus undefined for MinGW by commit 3bf6fb1778687c45d389b91675b55f709ef1f67b Since the two operations cancel each other out, they should be removed. --- src/osgDB/FileNameUtils.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/osgDB/FileNameUtils.cpp b/src/osgDB/FileNameUtils.cpp index 383638e93..34b740a86 100644 --- a/src/osgDB/FileNameUtils.cpp +++ b/src/osgDB/FileNameUtils.cpp @@ -19,9 +19,6 @@ #include #ifdef WIN32 -#if !defined(__MINGW32__) - #define _WIN32_WINNT 0x0500 -#endif #include #endif From 09eefd79736cde57ed108c781259e9c201805746 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Blissing?= Date: Thu, 30 Nov 2017 12:53:24 +0100 Subject: [PATCH 284/327] Added script to identify Windows version Added script to identify the Windows version used to compile the source. Currently the windows version for Windows NT is hard coded into the source. By running this CMake script the _WIN32_WINNT preprocessor variable gets set to the corresponding windows version. --- CMakeLists.txt | 4 ++++ CMakeModules/OsgDetermineWinVersion.cmake | 22 +++++++++++++++++++ .../osgViewer/api/Win32/GraphicsHandleWin32 | 11 +++++++++- 3 files changed, 36 insertions(+), 1 deletion(-) create mode 100644 CMakeModules/OsgDetermineWinVersion.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index f05d9f6ec..2bb3196b7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -344,6 +344,10 @@ ENDIF() IF(WIN32 AND NOT ANDROID) + # Check window version + INCLUDE (OsgDetermineWinVersion) + get_WIN32_WINNT(WIN_VERSION) + ADD_DEFINITIONS(-D_WIN32_WINNT=${WIN_VERSION}) IF(MSVC) # This option is to enable the /MP switch for Visual Studio 2005 and above compilers diff --git a/CMakeModules/OsgDetermineWinVersion.cmake b/CMakeModules/OsgDetermineWinVersion.cmake new file mode 100644 index 000000000..dbf9554a9 --- /dev/null +++ b/CMakeModules/OsgDetermineWinVersion.cmake @@ -0,0 +1,22 @@ +# - If Windows is used, this script sets the variable WIN32_WINNT to the corresponding windows version + +if (WIN32) + message(STATUS "Checking windows version...") + macro(get_WIN32_WINNT version) + if (CMAKE_SYSTEM_VERSION) + set(ver ${CMAKE_SYSTEM_VERSION}) + string(REGEX MATCH "^([0-9]+).([0-9])" ver ${ver}) + string(REGEX MATCH "^([0-9]+)" verMajor ${ver}) + # Check for Windows 10, b/c we'll need to convert to hex 'A'. + if ("${verMajor}" MATCHES "10") + set(verMajor "A") + string(REGEX REPLACE "^([0-9]+)" ${verMajor} ver ${ver}) + endif ("${verMajor}" MATCHES "10") + # Remove all remaining '.' characters. + string(REPLACE "." "" ver ${ver}) + # Prepend each digit with a zero. + string(REGEX REPLACE "([0-9A-Z])" "0\\1" ver ${ver}) + set(${version} "0x${ver}") + endif(CMAKE_SYSTEM_VERSION) + endmacro(get_WIN32_WINNT) +endif(WIN32) \ No newline at end of file diff --git a/include/osgViewer/api/Win32/GraphicsHandleWin32 b/include/osgViewer/api/Win32/GraphicsHandleWin32 index f6ac8fa28..5959e6bf2 100644 --- a/include/osgViewer/api/Win32/GraphicsHandleWin32 +++ b/include/osgViewer/api/Win32/GraphicsHandleWin32 @@ -16,8 +16,17 @@ #include +// Fallback if not correctly detected in CMake macro #ifndef _WIN32_WINNT -#define _WIN32_WINNT 0x0500 +//#define _WIN32_WINNT 0x0A00 // Windows 10 +//#define _WIN32_WINNT 0x0603 // Windows 8.1 +//#define _WIN32_WINNT 0x0602 // Windows 8 +//#define _WIN32_WINNT 0x0601 // Windows 7 +//#define _WIN32_WINNT 0x0600 // Windows Server 2008 +//#define _WIN32_WINNT 0x0600 // Windows Vista +//#define _WIN32_WINNT 0x0502 // Windows Server 2003 with SP1, Windows XP with SP2 +//#define _WIN32_WINNT 0x0501 // Windows Server 2003, Windows XP +#define _WIN32_WINNT 0x0500 // Windows NT #endif #include From 9fac39c5e09cc6157fe77dca8810b329ad8e43f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Blissing?= Date: Thu, 30 Nov 2017 13:00:54 +0100 Subject: [PATCH 285/327] Applications declared DPI-aware in the Windows environment Applications that run on a Windows computer with desktop scaling enabled gets scaled incorrectly since windows assumes that applications are DPI-unaware unless declared otherwise. This change declares the application DPI-aware, thus not automatically scaled by the operating system. The corresponding library call requires Windows 8.1 or later. --- src/osgViewer/GraphicsWindowWin32.cpp | 35 +++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/src/osgViewer/GraphicsWindowWin32.cpp b/src/osgViewer/GraphicsWindowWin32.cpp index b1cb6ce9d..6905a8856 100644 --- a/src/osgViewer/GraphicsWindowWin32.cpp +++ b/src/osgViewer/GraphicsWindowWin32.cpp @@ -144,6 +144,26 @@ static CloseTouchInputHandleFunc *closeTouchInputHandleFunc = NULL; static GetTouchInputInfoFunc *getTouchInputInfoFunc = NULL; static GetPointerTypeFunc *getPointerTypeFunc = NULL; +// DPI Awareness +#if(WINVER >= 0x0603) + +#ifndef DPI_ENUMS_DECLARED + +typedef enum PROCESS_DPI_AWARENESS { + PROCESS_DPI_UNAWARE = 0, + PROCESS_SYSTEM_DPI_AWARE = 1, + PROCESS_PER_MONITOR_DPI_AWARE = 2 +} PROCESS_DPI_AWARENESS; + +#endif // DPI_ENUMS_DECLARED + +typedef +BOOL +(WINAPI SetProcessDpiAwarenessFunc( + PROCESS_DPI_AWARENESS dpi_awareness)); + +static SetProcessDpiAwarenessFunc *setProcessDpiAwareness = NULL; +#endif @@ -765,6 +785,21 @@ Win32WindowingSystem::Win32WindowingSystem() FreeLibrary( hModule); } } + + +#if(WINVER >= 0x0603) + // For Windows 8.1 and higher + // + // Per monitor DPI aware.This app checks for the DPI when it is created and adjusts the scale factor + // whenever the DPI changes.These applications are not automatically scaled by the system. + HMODULE hModuleShore = LoadLibrary("Shcore"); + if (hModuleShore) { + setProcessDpiAwareness = (SetProcessDpiAwarenessFunc *) GetProcAddress(hModuleShore, "SetProcessDpiAwareness"); + if (setProcessDpiAwareness) { + (*setProcessDpiAwareness)(PROCESS_DPI_AWARENESS::PROCESS_PER_MONITOR_DPI_AWARE); + } + } +#endif } Win32WindowingSystem::~Win32WindowingSystem() From 05b0f142c8c9c7c1e4a4b7f164b1345889501f76 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Thu, 30 Nov 2017 12:48:47 +0000 Subject: [PATCH 286/327] Quieted down dubug output --- src/osgPlugins/lua/LuaScriptEngine.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/osgPlugins/lua/LuaScriptEngine.cpp b/src/osgPlugins/lua/LuaScriptEngine.cpp index 15be805d1..5488d065d 100644 --- a/src/osgPlugins/lua/LuaScriptEngine.cpp +++ b/src/osgPlugins/lua/LuaScriptEngine.cpp @@ -4074,21 +4074,21 @@ void LuaScriptEngine::addPaths(const osgDB::FilePathList& paths) std::string path = lua_tostring( _lua, -1 ); lua_pop( _lua, 1 ); - OSG_NOTICE<<"LuaScriptEngine::addPaths() original package.path = "< Date: Thu, 30 Nov 2017 14:12:05 +0000 Subject: [PATCH 287/327] Added return to last line --- CMakeModules/OsgDetermineWinVersion.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeModules/OsgDetermineWinVersion.cmake b/CMakeModules/OsgDetermineWinVersion.cmake index dbf9554a9..9d7a0619d 100644 --- a/CMakeModules/OsgDetermineWinVersion.cmake +++ b/CMakeModules/OsgDetermineWinVersion.cmake @@ -19,4 +19,4 @@ if (WIN32) set(${version} "0x${ver}") endif(CMAKE_SYSTEM_VERSION) endmacro(get_WIN32_WINNT) -endif(WIN32) \ No newline at end of file +endif(WIN32) From 75af025c5579eef64c316366c3ca635031c04586 Mon Sep 17 00:00:00 2001 From: Marc Helbling Date: Fri, 1 Dec 2017 12:26:00 +0100 Subject: [PATCH 288/327] Improve SharedArrayOptimizer When an array is shared within and outside a geometry, it's still worth it and safe to recreate the reference within each individual geometry. --- src/osgUtil/MeshOptimizers.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/osgUtil/MeshOptimizers.cpp b/src/osgUtil/MeshOptimizers.cpp index 52ff810b7..7f95113bc 100644 --- a/src/osgUtil/MeshOptimizers.cpp +++ b/src/osgUtil/MeshOptimizers.cpp @@ -1207,8 +1207,8 @@ void SharedArrayOptimizer::findDuplicatedUVs(const osg::Geometry& geometry) for(unsigned int id = 0 ; id != geometry.getNumTexCoordArrays() ; ++ id) { const osg::Array* channel = geometry.getTexCoordArray(id); - // test if array is shared outside the geometry - if(channel && static_cast(channel->referenceCount()) == arrayPointerCounter[channel]) + // test if array is shared inside the geometry + if(channel && arrayPointerCounter[channel] > 1) { std::map::const_iterator reference = references.find(channel); if(reference == references.end()) From 59f841bc20265f9440303ff9b5aa7696a4336c99 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Sat, 2 Dec 2017 16:20:34 +0000 Subject: [PATCH 289/327] Fixes for cppcheck reported issues --- src/osg/glu/libtess/memalloc.cpp | 11 ----------- src/osg/glu/libtess/memalloc.h | 6 ------ src/osgDB/InputStream.cpp | 7 ++++++- 3 files changed, 6 insertions(+), 18 deletions(-) diff --git a/src/osg/glu/libtess/memalloc.cpp b/src/osg/glu/libtess/memalloc.cpp index b4527ea2c..e33f289d4 100644 --- a/src/osg/glu/libtess/memalloc.cpp +++ b/src/osg/glu/libtess/memalloc.cpp @@ -39,17 +39,6 @@ int __gl_memInit( size_t /*maxFast*/ ) { #ifndef NO_MALLOPT /* mallopt( M_MXFAST, maxFast );*/ -#ifdef MEMORY_DEBUG - mallopt( M_DEBUG, 1 ); -#endif #endif return 1; } - -#ifdef MEMORY_DEBUG -void *__gl_memAlloc( size_t n ) -{ - return memset( malloc( n ), 0xa5, n ); -} -#endif - diff --git a/src/osg/glu/libtess/memalloc.h b/src/osg/glu/libtess/memalloc.h index c2f969b8b..e495a1e7c 100644 --- a/src/osg/glu/libtess/memalloc.h +++ b/src/osg/glu/libtess/memalloc.h @@ -41,14 +41,8 @@ #define memFree free #define memInit __gl_memInit -/*extern void __gl_memInit( size_t );*/ extern int __gl_memInit( size_t ); -#ifndef MEMORY_DEBUG #define memAlloc malloc -#else -#define memAlloc __gl_memAlloc -extern void * __gl_memAlloc( size_t ); -#endif #endif diff --git a/src/osgDB/InputStream.cpp b/src/osgDB/InputStream.cpp index e1cdb734d..4b3b8c2e2 100644 --- a/src/osgDB/InputStream.cpp +++ b/src/osgDB/InputStream.cpp @@ -709,7 +709,12 @@ osg::ref_ptr InputStream::readImage(bool readFromExternal) char* data = new char[size]; if ( !data ) throwException( "InputStream::readImage() Out of memory." ); - if ( getException() ) return NULL; + + if ( getException() ) + { + delete [] data; + return NULL; + } readCharArray( data, size ); image = new osg::Image; From da68d32482c29a6283321d1a380cfbf67d9cd394 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Sat, 2 Dec 2017 16:35:16 +0000 Subject: [PATCH 290/327] Improved readaibility of text by removing redundent indirection. --- src/osgUtil/ReversePrimitiveFunctor.cpp | 66 ++++++++++++------------- 1 file changed, 32 insertions(+), 34 deletions(-) diff --git a/src/osgUtil/ReversePrimitiveFunctor.cpp b/src/osgUtil/ReversePrimitiveFunctor.cpp index 10723c4ad..34959db69 100644 --- a/src/osgUtil/ReversePrimitiveFunctor.cpp +++ b/src/osgUtil/ReversePrimitiveFunctor.cpp @@ -20,9 +20,8 @@ osg::PrimitiveSet * drawElementsTemplate(GLenum mode,GLsizei count, const typena { if (indices==0 || count==0) return NULL; - Type * dePtr = new Type(mode); - Type & de = *dePtr; - de.reserve(count); + Type * primitives = new Type(mode); + primitives->reserve(count); typedef const typename Type::value_type* IndexPointer; @@ -34,9 +33,9 @@ osg::PrimitiveSet * drawElementsTemplate(GLenum mode,GLsizei count, const typena for (IndexPointer iptr=indices; iptrpush_back(*(iptr)); + primitives->push_back(*(iptr+2)); + primitives->push_back(*(iptr+1)); } break; } @@ -46,10 +45,10 @@ osg::PrimitiveSet * drawElementsTemplate(GLenum mode,GLsizei count, const typena IndexPointer ilast = &indices[count - 3]; for (IndexPointer iptr = indices; iptrpush_back(*(iptr)); + primitives->push_back(*(iptr+3)); + primitives->push_back(*(iptr+2)); + primitives->push_back(*(iptr+1)); } break; } @@ -59,19 +58,19 @@ osg::PrimitiveSet * drawElementsTemplate(GLenum mode,GLsizei count, const typena IndexPointer ilast = &indices[count]; for (IndexPointer iptr = indices; iptrpush_back(*(iptr+1)); + primitives->push_back(*(iptr)); } break; } case (GL_TRIANGLE_FAN): { - de.push_back(*indices); + primitives->push_back(*indices); IndexPointer iptr = indices + 1; IndexPointer ilast = &indices[count]; - de.resize(count); - std::reverse_copy(iptr, ilast, de.begin() + 1); + primitives->resize(count); + std::reverse_copy(iptr, ilast, primitives->begin() + 1); break; } @@ -83,8 +82,8 @@ osg::PrimitiveSet * drawElementsTemplate(GLenum mode,GLsizei count, const typena { IndexPointer iptr = indices; IndexPointer ilast = &indices[count]; - de.resize(count); - std::reverse_copy(iptr, ilast, de.begin()); + primitives->resize(count); + std::reverse_copy(iptr, ilast, primitives->begin()); break; } @@ -92,7 +91,7 @@ osg::PrimitiveSet * drawElementsTemplate(GLenum mode,GLsizei count, const typena break; } - return &de; + return primitives; } namespace osgUtil { @@ -101,9 +100,8 @@ void ReversePrimitiveFunctor::drawArrays(GLenum mode, GLint first, GLsizei count { if (count==0) return ; - osg::DrawElementsUInt * dePtr = new osg::DrawElementsUInt(mode); - osg::DrawElementsUInt & de = *dePtr; - de.reserve(count); + osg::DrawElementsUInt * primitives = new osg::DrawElementsUInt(mode); + primitives->reserve(count); GLint end = first + count; @@ -113,9 +111,9 @@ void ReversePrimitiveFunctor::drawArrays(GLenum mode, GLint first, GLsizei count { for (GLint i=first; ipush_back(i); + primitives->push_back(i+2); + primitives->push_back(i+1); } break; } @@ -123,10 +121,10 @@ void ReversePrimitiveFunctor::drawArrays(GLenum mode, GLint first, GLsizei count { for (GLint i=first; ipush_back(i); + primitives->push_back(i+3); + primitives->push_back(i+2); + primitives->push_back(i+1); } break; } @@ -135,17 +133,17 @@ void ReversePrimitiveFunctor::drawArrays(GLenum mode, GLint first, GLsizei count { for (GLint i=first; ipush_back(i+1); + primitives->push_back(i); } break; } case (GL_TRIANGLE_FAN): { - de.push_back(first); + primitives->push_back(first); for (GLint i=end-1; i>first; i--) - de.push_back(i); + primitives->push_back(i); break; } @@ -156,7 +154,7 @@ void ReversePrimitiveFunctor::drawArrays(GLenum mode, GLint first, GLsizei count case (GL_LINE_LOOP): { for (GLint i=end-1; i>=first; i--) - de.push_back(i); + primitives->push_back(i); break; } @@ -164,7 +162,7 @@ void ReversePrimitiveFunctor::drawArrays(GLenum mode, GLint first, GLsizei count break; } - _reversedPrimitiveSet = &de; + _reversedPrimitiveSet = primitives; } void ReversePrimitiveFunctor::drawElements(GLenum mode,GLsizei count,const GLubyte* indices) From 82f0a2d84922eb962a0454653173c33bce9e32e1 Mon Sep 17 00:00:00 2001 From: Jordi Torres Date: Sat, 2 Dec 2017 16:49:47 +0000 Subject: [PATCH 291/327] same values in || so one of them not needed --- applications/osgconv/osgconv.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/applications/osgconv/osgconv.cpp b/applications/osgconv/osgconv.cpp index 8c5ba420d..a324dd0ee 100644 --- a/applications/osgconv/osgconv.cpp +++ b/applications/osgconv/osgconv.cpp @@ -740,7 +740,7 @@ int main( int argc, char **argv ) while(arguments.read("--addMissingColours") || arguments.read("--addMissingColors")) { addMissingColours = true; } bool do_overallNormal = false; - while(arguments.read("--overallNormal") || arguments.read("--overallNormal")) { do_overallNormal = true; } + while(arguments.read("--overallNormal")) { do_overallNormal = true; } bool enableObjectCache = false; while(arguments.read("--enable-object-cache")) { enableObjectCache = true; } From 302f625ec70b5b61e6c4915000736ac6fd8c78a8 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Sat, 2 Dec 2017 17:08:14 +0000 Subject: [PATCH 292/327] From Jordi Torres, removed unused local variables --- src/osg/Geometry.cpp | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/osg/Geometry.cpp b/src/osg/Geometry.cpp index 30b1bd9b9..068a9f7c0 100644 --- a/src/osg/Geometry.cpp +++ b/src/osg/Geometry.cpp @@ -570,16 +570,11 @@ void Geometry::setUseVertexBufferObjects(bool flag) DrawElementsList drawElementsList; getDrawElementsList(drawElementsList); - typedef std::vector VertexBufferObjectList; - typedef std::vector ElementBufferObjectList; - /*if (_useVertexBufferObjects)*/ { if (!arrayList.empty()) { - VertexBufferObjectList vboList; - osg::ref_ptr vbo; ArrayList::iterator vitr; @@ -604,8 +599,6 @@ void Geometry::setUseVertexBufferObjects(bool flag) if (!drawElementsList.empty()) { - ElementBufferObjectList eboList; - osg::ref_ptr ebo; DrawElementsList::iterator deitr; From 490b9b0e0e37518174fcd90a5a10f2f888bf8941 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Sat, 2 Dec 2017 17:35:36 +0000 Subject: [PATCH 293/327] Fixed string parsing and substituion bugs isn substitudeEnvVars(..) --- src/osg/State.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/osg/State.cpp b/src/osg/State.cpp index ba9e143e5..031f34872 100644 --- a/src/osg/State.cpp +++ b/src/osg/State.cpp @@ -1249,15 +1249,19 @@ namespace State_Utils if (str[pos]=='"' || str[pos]=='\'') { std::string::size_type start_quote = pos; - ++pos; + ++pos; // skip over first quote pos = str.find(str[start_quote], pos); + + if (pos!=std::string::npos) + { + ++pos; // skip over second quote + } } else { std::string::size_type start_var = pos; ++pos; pos = str.find_first_not_of("ABCDEFGHIJKLMNOPQRTSUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_", pos); - std::string var_str; if (pos != std::string::npos) { From e44fb08f6a9ccd1fe58bfefb44e0c8e44b945adc Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Sat, 2 Dec 2017 17:41:27 +0000 Subject: [PATCH 294/327] From Jordi Torres, removed unused local variable --- src/osgAnimation/StatsHandler.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/osgAnimation/StatsHandler.cpp b/src/osgAnimation/StatsHandler.cpp index 3387beb27..3c864ea2d 100644 --- a/src/osgAnimation/StatsHandler.cpp +++ b/src/osgAnimation/StatsHandler.cpp @@ -409,7 +409,6 @@ struct ValueTextDrawCallback : public virtual osg::Drawable::DrawCallback if (!visitor) return; - std::string font("fonts/arial.ttf"); float leftPos = 10.0f; float characterSize = 20.0f; From 847e472130207f1de2f9a93fe8a30ab844db17f4 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Sat, 2 Dec 2017 17:42:53 +0000 Subject: [PATCH 295/327] Commented out unused local variables --- src/osgAnimation/StatsHandler.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/osgAnimation/StatsHandler.cpp b/src/osgAnimation/StatsHandler.cpp index 3c864ea2d..161634ba2 100644 --- a/src/osgAnimation/StatsHandler.cpp +++ b/src/osgAnimation/StatsHandler.cpp @@ -426,7 +426,7 @@ struct ValueTextDrawCallback : public virtual osg::Drawable::DrawCallback } const std::vector& channels = visitor->getChannels(); - std::map size; + // std::map size; for (int i = 0; i < (int)channels.size(); i++) { std::string name = channels[i]; if (_actions.find(name) == _actions.end()) { @@ -439,14 +439,14 @@ struct ValueTextDrawCallback : public virtual osg::Drawable::DrawCallback //_actions[name].touch(); } _actions[name]._group->setNodeMask(~osg::Node::NodeMask(0x0)); - size[name] = 0; + //size[name] = 0; pos.y() -= characterSize + graphSpacing; } pos.y() -= backgroundMargin; osg::Vec3Array* array = static_cast(_background->getVertexArray()); - float y = (*array)[0][1]; - y = y - (pos.y() + backgroundMargin); //(2 * backgroundMargin + (size.size() * (characterSize + graphSpacing))); + // float y = (*array)[0][1]; + // y = y - (pos.y() + backgroundMargin); //(2 * backgroundMargin + (size.size() * (characterSize + graphSpacing))); (*array)[1][1] = pos.y(); (*array)[2][1] = pos.y(); array->dirty(); From c85e56940e030ddab30082168b7f5518e23253f5 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Sat, 2 Dec 2017 17:52:47 +0000 Subject: [PATCH 296/327] From Jordi Torres, removed unused local variables --- src/osgAnimation/StatsVisitor.cpp | 4 ---- src/osgDB/OutputStream.cpp | 1 - 2 files changed, 5 deletions(-) diff --git a/src/osgAnimation/StatsVisitor.cpp b/src/osgAnimation/StatsVisitor.cpp index 48ee26797..d99b96967 100644 --- a/src/osgAnimation/StatsVisitor.cpp +++ b/src/osgAnimation/StatsVisitor.cpp @@ -77,10 +77,6 @@ void StatsActionVisitor::apply(ActionStripAnimation& action) if (isActive(action)) { _channels.push_back(action.getName()); - double value; - std::string name = action.getName(); - if (_stats->getAttribute(_frame, name, value)) - name += "+"; _stats->setAttribute(_frame, action.getName(), action.getAnimation()->getAnimation()->getWeight()); } } diff --git a/src/osgDB/OutputStream.cpp b/src/osgDB/OutputStream.cpp index a21b74fa2..8b28092f2 100644 --- a/src/osgDB/OutputStream.cpp +++ b/src/osgDB/OutputStream.cpp @@ -860,7 +860,6 @@ void OutputStream::writeSchema( std::ostream& fout ) ObjectWrapper::TypeList types; wrapper->writeSchema( properties, types ); - std::string propertiesString; unsigned int size = osg::minimum( properties.size(), types.size() ); for ( unsigned int i=0; i Date: Sat, 2 Dec 2017 17:58:17 +0000 Subject: [PATCH 297/327] From Jordi Torres, removed unused local variables --- src/osgGA/UFOManipulator.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/osgGA/UFOManipulator.cpp b/src/osgGA/UFOManipulator.cpp index 870db8c9c..c39f73b8e 100644 --- a/src/osgGA/UFOManipulator.cpp +++ b/src/osgGA/UFOManipulator.cpp @@ -536,11 +536,6 @@ void UFOManipulator::_adjustPosition() return; // Forward line segment at 3 times our intersect distance - - - typedef std::vector Intersections; - Intersections intersections; - // Check intersects infront. osg::Vec3d ip; if (intersect(_position, From d7f535705933385fc37e84b0f15fea86e4aeff9e Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Sat, 2 Dec 2017 18:00:03 +0000 Subject: [PATCH 298/327] From Jordi Torres, Removed unused local variables --- src/osgPlugins/bsp/Q3BSPReader.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/osgPlugins/bsp/Q3BSPReader.cpp b/src/osgPlugins/bsp/Q3BSPReader.cpp index 9e90b2abc..fd8bddde6 100644 --- a/src/osgPlugins/bsp/Q3BSPReader.cpp +++ b/src/osgPlugins/bsp/Q3BSPReader.cpp @@ -36,8 +36,6 @@ Q3BSPReader::Q3BSPReader() bool Q3BSPReader::readFile(const std::string& file, const osgDB::ReaderWriter::Options* options) { - std::string ext = osgDB::getLowerCaseFileExtension(file); - Q3BSPLoad load_data; load_data.Load(file,8); @@ -513,7 +511,7 @@ bool Q3BSPReader::loadLightMaps( - // A continuación, añado el blanco + // A continuacin, aado el blanco osg::Image* image=new osg::Image; unsigned char *data=new unsigned char[3]; for(int whiteidx=0;whiteidx<3;whiteidx++) From c913c0e6f76b88f446cb605e1ac114cc09d5ef2c Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Sat, 2 Dec 2017 18:04:43 +0000 Subject: [PATCH 299/327] From Jordi Torres, removed unused local variables --- src/osgPlugins/bsp/VBSPReader.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/osgPlugins/bsp/VBSPReader.cpp b/src/osgPlugins/bsp/VBSPReader.cpp index 90fdfa022..172013581 100644 --- a/src/osgPlugins/bsp/VBSPReader.cpp +++ b/src/osgPlugins/bsp/VBSPReader.cpp @@ -653,8 +653,6 @@ ref_ptr VBSPReader::readMaterialFile(std::string materialName) bool found = false; ref_ptr stateSet; std::string shaderName; - std::string texName; - std::string tex2Name; ref_ptr texture; ref_ptr texture2; ref_ptr combiner0; @@ -992,7 +990,6 @@ void VBSPReader::createScene() Quat yaw, pitch, roll; ref_ptr propXform; std::string propModel; - std::string propFile; ref_ptr propNode; // Load the materials and create a StateSet for each one From 24c3b40b56952b8094adba221e75ee2e271699f3 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Sat, 2 Dec 2017 18:07:13 +0000 Subject: [PATCH 300/327] From Jordi Torres, removed unused local variables --- src/osgPlugins/dae/daeRMaterials.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/osgPlugins/dae/daeRMaterials.cpp b/src/osgPlugins/dae/daeRMaterials.cpp index 2aae4e366..d4c2703b2 100644 --- a/src/osgPlugins/dae/daeRMaterials.cpp +++ b/src/osgPlugins/dae/daeRMaterials.cpp @@ -589,8 +589,6 @@ bool daeReader::processColorOrTextureType(const osg::StateSet* ss, } bool retVal = false; - std::string texCoordSet; - //osg::StateAttribute *sa = NULL; //TODO: Make all channels process type of value if (channel == osg::Material::EMISSION ) From bd716b38c7fa9e2cc35356bfb9352843e6667419 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Sun, 3 Dec 2017 09:27:41 +0000 Subject: [PATCH 301/327] From Jordi Torres, added ref_ptr<> usage to quieten cppcheck false positive --- src/osgPlugins/dae/daeRSceneObjects.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/osgPlugins/dae/daeRSceneObjects.cpp b/src/osgPlugins/dae/daeRSceneObjects.cpp index 9874ed315..9096345a4 100644 --- a/src/osgPlugins/dae/daeRSceneObjects.cpp +++ b/src/osgPlugins/dae/daeRSceneObjects.cpp @@ -361,7 +361,7 @@ osg::Node* daeReader::processLight( domLight *dlight ) lightmodel->setAmbientIntensity(osg::Vec4(0.0f,0.0f,0.0f,1.0f)); _rootStateSet->setAttributeAndModes(lightmodel, osg::StateAttribute::ON); - osg::LightSource* lightsource = new osg::LightSource(); + osg::ref_ptr lightsource = new osg::LightSource(); lightsource->setLight(light); std::string name = dlight->getId() ? dlight->getId() : ""; if (dlight->getName()) @@ -520,7 +520,7 @@ osg::Node* daeReader::processLight( domLight *dlight ) light->setDirection(osg::Vec3(0, 0, -1)); } - return lightsource; + return lightsource.release(); } // From 24d32e89a17da989a84d571731d0f5a8a02b8840 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Sun, 3 Dec 2017 09:30:35 +0000 Subject: [PATCH 302/327] From Jordi Torres, fix indentation and removed redundent break; --- src/osgPlugins/jpeg/ReaderWriterJPEG.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/osgPlugins/jpeg/ReaderWriterJPEG.cpp b/src/osgPlugins/jpeg/ReaderWriterJPEG.cpp index 115203322..f49a7a18d 100644 --- a/src/osgPlugins/jpeg/ReaderWriterJPEG.cpp +++ b/src/osgPlugins/jpeg/ReaderWriterJPEG.cpp @@ -689,7 +689,7 @@ class ReaderWriterJPEG : public osgDB::ReaderWriter default: { OSG_DEBUG << "ReaderWriterJPEG::write_JPEG_file - Error pixel format non supported" << std::endl; - return WriteResult::ERROR_IN_WRITING_FILE; break; + return WriteResult::ERROR_IN_WRITING_FILE; } } From 6ca3cab0d5c92587d5fb002774b4ac8cfae314c8 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Sun, 3 Dec 2017 09:32:50 +0000 Subject: [PATCH 303/327] From Jordi Torres, removed unused local variable --- src/osgPlugins/obj/obj.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/osgPlugins/obj/obj.cpp b/src/osgPlugins/obj/obj.cpp index e2038f60a..c041a8437 100644 --- a/src/osgPlugins/obj/obj.cpp +++ b/src/osgPlugins/obj/obj.cpp @@ -231,7 +231,6 @@ bool Model::readMTL(std::istream& fin) bool usingDissolve = false; Material* material = 0;// &(materialMap[""]); - std::string filename; while (fin) { From ef5410aaf0916c9427a53ea5fa0c9c0749dbd8ac Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Sun, 3 Dec 2017 09:34:43 +0000 Subject: [PATCH 304/327] From Jordi Torres, fixed leak and inappropriate read bug --- src/osgPlugins/ogr/ReaderWriterOGR.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/osgPlugins/ogr/ReaderWriterOGR.cpp b/src/osgPlugins/ogr/ReaderWriterOGR.cpp index 5fed4aaea..6e27aa652 100644 --- a/src/osgPlugins/ogr/ReaderWriterOGR.cpp +++ b/src/osgPlugins/ogr/ReaderWriterOGR.cpp @@ -262,8 +262,6 @@ public: osg::Geometry* multiPointToDrawable(OGRMultiPoint* mpoint) const { - osg::Geometry* geom = new osg::Geometry; - osg::Geometry* pointGeom = new osg::Geometry(); osg::Vec3Array* vertices = new osg::Vec3Array(); @@ -286,7 +284,7 @@ public: if (pointGeom->getVertexArray()) { - OSG_INFO << "osgOgrFeature::multiPointToDrawable " << geom->getVertexArray()->getNumElements() << " vertexes"<< std::endl; + OSG_INFO << "osgOgrFeature::multiPointToDrawable " << pointGeom->getVertexArray()->getNumElements() << " vertexes"<< std::endl; } return pointGeom; From 3870edf376a1b4a7fa1c9d38f8952038a21cb55d Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Sun, 3 Dec 2017 09:38:32 +0000 Subject: [PATCH 305/327] Fixed leak and clean up formatting. --- src/osgPlugins/tga/ReaderWriterTGA.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/osgPlugins/tga/ReaderWriterTGA.cpp b/src/osgPlugins/tga/ReaderWriterTGA.cpp index 256beb603..861c61b70 100644 --- a/src/osgPlugins/tga/ReaderWriterTGA.cpp +++ b/src/osgPlugins/tga/ReaderWriterTGA.cpp @@ -405,6 +405,7 @@ int *numComponents_ret) break; default: tgaerror = ERR_UNSUPPORTED; + delete [] formattedMap; return NULL; /* unreachable code - (depth < 1 || depth > 4) rejected by "check for reasonable values in case this is not a tga file" near the start of this function*/ } @@ -415,8 +416,7 @@ int *numComponents_ret) dest += lineoffset; } - if (formattedMap) - delete[] formattedMap; + delete [] formattedMap; } break; case 2: /* RGB, uncompressed */ From 9a96e211f99f9eea076b0178ac3f64ffcaf8801c Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Sun, 3 Dec 2017 09:45:37 +0000 Subject: [PATCH 306/327] Quietened down cppcheck false positive. --- src/osgUtil/SceneView.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/osgUtil/SceneView.cpp b/src/osgUtil/SceneView.cpp index b4fd18a89..c788cf8ff 100644 --- a/src/osgUtil/SceneView.cpp +++ b/src/osgUtil/SceneView.cpp @@ -743,7 +743,7 @@ void SceneView::cull() _cullVisitorRight->setClampProjectionMatrixCallback(_cullVisitor->getClampProjectionMatrixCallback()); _cullVisitorRight->setTraversalMask(_cullMaskRight); computeRightEyeViewport(getViewport()); - computeNearFar = cullStage(computeRightEyeProjection(getProjectionMatrix()),computeRightEyeView(getViewMatrix()),_cullVisitorRight.get(),_stateGraphRight.get(),_renderStageRight.get(),_viewportRight.get()); + computeNearFar = cullStage(computeRightEyeProjection(getProjectionMatrix()),computeRightEyeView(getViewMatrix()),_cullVisitorRight.get(),_stateGraphRight.get(),_renderStageRight.get(),_viewportRight.get()) | computeNearFar; if (computeNearFar) { From 5ff16798a354c9e7ce6776dfa22162fd0e83efff Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Sun, 3 Dec 2017 09:49:09 +0000 Subject: [PATCH 307/327] Removed unused local variable and associated typedef --- src/osgUtil/Simplifier.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/osgUtil/Simplifier.cpp b/src/osgUtil/Simplifier.cpp index cb3f2ad61..9d54a2d16 100644 --- a/src/osgUtil/Simplifier.cpp +++ b/src/osgUtil/Simplifier.cpp @@ -267,7 +267,6 @@ public: typedef std::vector< osg::ref_ptr > PointList; typedef std::list< osg::ref_ptr > TriangleList; typedef std::set< osg::ref_ptr > TriangleSet; - typedef std::map< osg::ref_ptr, unsigned int, dereference_less > TriangleMap; struct Point : public osg::Referenced { @@ -813,7 +812,6 @@ public: osg::ref_ptr edge_p1 = edge->_p1; osg::ref_ptr edge_p2 = edge->_p2; - TriangleMap triangleMap; TriangleList triangles_p1; TriangleList triangles_p2; LocalEdgeList oldEdges; From 200537ed6fdadc6cdfe1ec90a6ff16fe197232bf Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Sun, 3 Dec 2017 10:49:39 +0000 Subject: [PATCH 308/327] Removed redundent !ps --- src/osgUtil/TriStripVisitor.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/osgUtil/TriStripVisitor.cpp b/src/osgUtil/TriStripVisitor.cpp index 074bfb890..605aa6c8a 100644 --- a/src/osgUtil/TriStripVisitor.cpp +++ b/src/osgUtil/TriStripVisitor.cpp @@ -607,7 +607,7 @@ void TriStripVisitor::mergeTriangleStrips(osg::Geometry::PrimitiveSetList& primi osg::PrimitiveSet* ps = primitives[i].get(); // remove null primitive sets and all primitives that have been merged // (i.e. all TRIANGLE_STRIP DrawElements) - if (!ps || (ps && ps->getMode() == osg::PrimitiveSet::TRIANGLE_STRIP)) + if (ps && ps->getMode() == osg::PrimitiveSet::TRIANGLE_STRIP) { primitives.erase(primitives.begin() + i); } From 9ef79c2f44577222f35d929543d39caa339f869a Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Sun, 3 Dec 2017 11:17:34 +0000 Subject: [PATCH 309/327] Renamed chanels to array to be consistent with the rest of the usage --- src/osgUtil/MeshOptimizers.cpp | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/osgUtil/MeshOptimizers.cpp b/src/osgUtil/MeshOptimizers.cpp index 7f95113bc..4eee09a89 100644 --- a/src/osgUtil/MeshOptimizers.cpp +++ b/src/osgUtil/MeshOptimizers.cpp @@ -1183,21 +1183,21 @@ void SharedArrayOptimizer::findDuplicatedUVs(const osg::Geometry& geometry) { _deduplicateUvs.clear(); - // look for all channels that are shared only *within* the geometry + // look for all arrays that are shared only *within* the geometry std::map arrayPointerCounter; for(unsigned int id = 0 ; id < geometry.getNumTexCoordArrays() ; ++ id) { - const osg::Array* channel = geometry.getTexCoordArray(id); - if(channel && channel->getNumElements()) + const osg::Array* array = geometry.getTexCoordArray(id); + if(array && array->getNumElements()) { - if(arrayPointerCounter.find(channel) == arrayPointerCounter.end()) + if(arrayPointerCounter.find(array) == arrayPointerCounter.end()) { - arrayPointerCounter[channel] = 1; + arrayPointerCounter[array] = 1; } else { - arrayPointerCounter[channel] += 1; + arrayPointerCounter[array] += 1; } } } @@ -1206,14 +1206,14 @@ void SharedArrayOptimizer::findDuplicatedUVs(const osg::Geometry& geometry) for(unsigned int id = 0 ; id != geometry.getNumTexCoordArrays() ; ++ id) { - const osg::Array* channel = geometry.getTexCoordArray(id); + const osg::Array* array = geometry.getTexCoordArray(id); // test if array is shared inside the geometry - if(channel && arrayPointerCounter[channel] > 1) + if(array && arrayPointerCounter[array] > 1) { - std::map::const_iterator reference = references.find(channel); + std::map::const_iterator reference = references.find(array); if(reference == references.end()) { - references[channel] = id; + references[array] = id; } else { From aa26f9936736262752babf7b282777420ca63eb8 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Sun, 3 Dec 2017 14:14:34 +0000 Subject: [PATCH 310/327] Updated ChangeLog --- ChangeLog | 149 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 149 insertions(+) diff --git a/ChangeLog b/ChangeLog index 7d75e6a5d..0564cefef 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,152 @@ +Sun, 3 Dec 2017 11:17:34 +0000 +Author : Robert Osfield +Renamed chanels to array to be consistent with the rest of the usage + +Sun, 3 Dec 2017 11:12:20 +0000 +Author : OpenSceneGraph git repository +Merge pull request #398 from marchelbling/sharedarrayoptimizer-fixImprove SharedArrayOptimizer + +Sun, 3 Dec 2017 10:49:39 +0000 +Author : Robert Osfield +Removed redundent !ps + +Sun, 3 Dec 2017 09:49:09 +0000 +Author : Robert Osfield +Removed unused local variable and associated typedef + +Sun, 3 Dec 2017 09:45:37 +0000 +Author : Robert Osfield +Quietened down cppcheck false positive. + +Sun, 3 Dec 2017 09:38:32 +0000 +Author : Robert Osfield +Fixed leak and clean up formatting. + +Sun, 3 Dec 2017 09:34:43 +0000 +Author : Robert Osfield +From Jordi Torres, fixed leak and inappropriate read bug + +Sun, 3 Dec 2017 09:32:50 +0000 +Author : Robert Osfield +From Jordi Torres, removed unused local variable + +Sun, 3 Dec 2017 09:30:35 +0000 +Author : Robert Osfield +From Jordi Torres, fix indentation and removed redundent break; + +Sun, 3 Dec 2017 09:27:41 +0000 +Author : Robert Osfield +From Jordi Torres, added ref_ptr<> usage to quieten cppcheck false positive + +Sat, 2 Dec 2017 18:07:13 +0000 +Author : Robert Osfield +From Jordi Torres, removed unused local variables + +Sat, 2 Dec 2017 18:04:43 +0000 +Author : Robert Osfield +From Jordi Torres, removed unused local variables + +Sat, 2 Dec 2017 18:00:03 +0000 +Author : Robert Osfield +From Jordi Torres, Removed unused local variables + +Sat, 2 Dec 2017 17:58:17 +0000 +Author : Robert Osfield +From Jordi Torres, removed unused local variables + +Sat, 2 Dec 2017 17:52:47 +0000 +Author : Robert Osfield +From Jordi Torres, removed unused local variables + +Sat, 2 Dec 2017 17:42:53 +0000 +Author : Robert Osfield +Commented out unused local variables + +Sat, 2 Dec 2017 17:41:27 +0000 +Author : Robert Osfield +From Jordi Torres, removed unused local variable + +Sat, 2 Dec 2017 17:35:36 +0000 +Author : Robert Osfield +Fixed string parsing and substituion bugs isn substitudeEnvVars(..) + +Sat, 2 Dec 2017 17:08:14 +0000 +Author : Robert Osfield +From Jordi Torres, removed unused local variables + +Sat, 2 Dec 2017 16:49:47 +0000 +Author : Jordi Torres +same values in || so one of them not needed + +Sat, 2 Dec 2017 16:35:16 +0000 +Author : Robert Osfield +Improved readaibility of text by removing redundent indirection. + +Sat, 2 Dec 2017 16:20:34 +0000 +Author : Robert Osfield +Fixes for cppcheck reported issues + +Fri, 1 Dec 2017 12:26:00 +0100 +Author : Marc Helbling +Improve SharedArrayOptimizerWhen an array is shared within and outside a geometry, it's still worth it and safe +to recreate the reference within each individual geometry. + + +Thu, 30 Nov 2017 14:13:21 +0000 +Author : OpenSceneGraph git repository +Merge pull request #396 from bjornblissing/feature/DPIAwareScalingApplications declared as DPI-aware in the Windows environment + +Thu, 30 Nov 2017 14:12:05 +0000 +Author : OpenSceneGraph git repository +Added return to last line + +Thu, 30 Nov 2017 12:48:47 +0000 +Author : Robert Osfield +Quieted down dubug output + +Thu, 30 Nov 2017 13:00:54 +0100 +Author : Björn Blissing +Applications declared DPI-aware in the Windows environmentApplications that run on a Windows computer with desktop scaling enabled +gets scaled incorrectly since windows assumes that applications are +DPI-unaware unless declared otherwise. + +This change declares the application DPI-aware, thus not automatically +scaled by the operating system. + +The corresponding library call requires Windows 8.1 or later. + + +Thu, 30 Nov 2017 12:53:24 +0100 +Author : Björn Blissing +Added script to identify Windows versionAdded script to identify the Windows version used to compile the source. +Currently the windows version for Windows NT is hard coded into the +source. By running this CMake script the _WIN32_WINNT preprocessor +variable gets set to the corresponding windows version. + + +Thu, 30 Nov 2017 12:47:57 +0100 +Author : Björn Blissing +Removed unnecessary define in FileUtilsThe define of _WIN32_WINNT was added to handle an error case from MinGW +,as described in commit 712ca432196cd797cc3c265adb2847465551461f + +This was later giving warnings and thus undefined for MinGW by commit +3bf6fb1778687c45d389b91675b55f709ef1f67b + +Since the two operations cancel each other out, they should be removed. + + +Wed, 29 Nov 2017 21:20:10 +0000 +Author : Robert Osfield +Typo fix + +Wed, 29 Nov 2017 15:06:53 +0000 +Author : Robert Osfield +Update version to 3.5.10 + +Wed, 29 Nov 2017 14:49:00 +0000 +Author : Robert Osfield +Updated ChangeLog and AUTHORS for 3.5.9 dev release + Wed, 29 Nov 2017 14:44:00 +0000 Author : Robert Osfield Fixed build with OSG_USE_REF_PTR_IMPLICIT_OUTPUT_CONVERSION set to OFF From 1810c9e7e3d20e33ec0585f70fc0ea352bd71116 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Sun, 3 Dec 2017 14:27:10 +0000 Subject: [PATCH 311/327] Updated ChangeLog and AUTHORS file --- AUTHORS.txt | 42 ++++++++++++------------ applications/osgversion/Contributors.cpp | 3 +- 2 files changed, 23 insertions(+), 22 deletions(-) diff --git a/AUTHORS.txt b/AUTHORS.txt index 36d546850..f7b2a94ec 100644 --- a/AUTHORS.txt +++ b/AUTHORS.txt @@ -1,4 +1,4 @@ -OpenSceneGraph Library 3.5.9 +OpenSceneGraph Library 3.5.10 568 Contributors: @@ -8,11 +8,11 @@ Robert Osfield Stephan Huber Paul Martz Farshid Lashkari -Mathias Fröhlich +Mathias Frhlich Laurens Voerman Marco Jez Wang Rui -Jean-Sébastien Guay +Jean-Sbastien Guay Ulrich Hertlein Mike Weiblen Sukender @@ -48,6 +48,7 @@ Magnus Kessler David Fries Tom Jolley Paul Melis +Jordi Torres Luc Frauciel Aurelien Albert Torben Dannhauer @@ -65,11 +66,11 @@ Norman Vine Chris Denham Sherman Wilcox Serge Lages -Romano José Magacho da Silva +Romano Jos Magacho da Silva Mourad Boufarguine Alberto Farre Glenn Waldron -André Garneau +Andr Garneau Adrian Egli Sebastian Messerschmidt Randall Hopper @@ -84,7 +85,7 @@ Michael Gronager Martin Naylor Joakim Simonsson David Spilling -Daniel Sjölie +Daniel Sjlie Bryan Thrall Andreas Ekstrand Rafa Gaitan @@ -94,7 +95,6 @@ Fabien Lavignotte Thomas Hogarth Riccardo Corsi Melchior Franz -Jordi Torres Johannes Baeuerle Neil Hughes Martin Beckett @@ -122,7 +122,7 @@ Gordon Tomlinson Frederic Marmond Frederic Bouvier Carlo Camporesi -Björn Blissing +Bjrn Blissing Alexander Sinditskiy Vladimir Chebaev Thibault Genessay @@ -141,7 +141,7 @@ Uwe Woessner Tony Horrobin Thom DeCarlo Tatsuhiro Nishioka -Tanguy Fautré +Tanguy Fautr Sean Spicer Ryan Kawicki Richard Schmidt @@ -202,7 +202,7 @@ Phil Atkin Pawel Ksiezopolski Patrick Neary Nathan Monteleone -Miha Rav¨elj +Miha Ravelj Miguel Escriva Mattias Linde Mark Sciabica @@ -234,8 +234,8 @@ Christian Ruzicka Christian Buchner Charles Cole Blake Williams -Björn Hein -Aurélien Chatelain +Bjrn Hein +Aurlien Chatelain Antoine Hue Andrew Bettison Andreas Henne @@ -264,7 +264,7 @@ Paul Obermeier Nguyen Van Truong Nathan Cournia Morten Haukness -Morné Pistorius +Morn Pistorius Michael Mc Donnell Michael Henheffer Michael Guerrero @@ -297,7 +297,7 @@ Guillaume Taze Guillaume Chouvenc Giuseppe Donvito Gill Peacegood -Giampaolo Viganò +Giampaolo Vigan Gerrick Bivins George Tarantilis Ferdi Smit @@ -305,7 +305,7 @@ Eduardo Poyart Edgar Ellis Dmitry Marakasov Dimi Christopoulos -Diane Delallée +Diane Delalle David Longest David Ergo Daniel Trstenjak @@ -337,7 +337,7 @@ Vasily Radostev Valery Bickov Valeriy Dubov Vaclav Bilek -Tyge Løvset +Tyge Lvset Troy Yee Torben Dannahauer Tony Vasile @@ -387,7 +387,7 @@ Piotr Rak Pierre Bourdin Philipp Svehla Philipp Siemoleit -Philipp Mächler +Philipp Mchler Philip Lamb Petr Salinger Peter Bear @@ -412,7 +412,7 @@ Nick Thu Nick Black Mojtaba Fathi Mirko Viviani -Mikkel Gjøl +Mikkel Gjl Mike Krus Mike Garrity Mick Thu @@ -465,7 +465,7 @@ Juan Hernando Josh Portway Jonathan Greig John Tan -John Hedström +John Hedstrm John Grant John Farrier John Donovan @@ -524,11 +524,11 @@ David Jung Danny Valente Daniel Stien Dan Minor -César L. B. Silveira +Csar L. B. Silveira Cyril Brulebois Curtis Rubel Cory Slep -Clément B½sch +Clment Bsch Clay Fowler Claus Steuer Chuck Sembroski diff --git a/applications/osgversion/Contributors.cpp b/applications/osgversion/Contributors.cpp index 5948a45d0..9d42686cc 100644 --- a/applications/osgversion/Contributors.cpp +++ b/applications/osgversion/Contributors.cpp @@ -279,7 +279,8 @@ const char* invalidNames[] = "StreamOperator", "SceneLoader", "OpenGL", - "FindLIBLAS" + "FindLIBLAS", + "MinGW" }; From 279df6d57ec2d4fd263e8a9360f960ac9ffcaed2 Mon Sep 17 00:00:00 2001 From: Anna Sokol Date: Mon, 4 Dec 2017 13:01:52 +0000 Subject: [PATCH 312/327] From Anna Sokol, "There is no need to specify WINVER of 0x0603 in order to check for the SetProcessDPIAwareness function existence. If your current OS where the application is running is Windows 8.1 or above it the function will exist in the dll or if its below it wont. I checked the attached code with both a Windows 7 desktop (where the function doesn't exist) and a Windows 10 tablet (where it does and had my screen scaled to 150%) and in both cases the code worked as intended." --- src/osgViewer/GraphicsWindowWin32.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/osgViewer/GraphicsWindowWin32.cpp b/src/osgViewer/GraphicsWindowWin32.cpp index 6905a8856..c96189518 100644 --- a/src/osgViewer/GraphicsWindowWin32.cpp +++ b/src/osgViewer/GraphicsWindowWin32.cpp @@ -96,9 +96,9 @@ enum tagPOINTER_INPUT_TYPE { PT_TOUCH = 0x00000002, // Touch PT_PEN = 0x00000003, // Pen PT_MOUSE = 0x00000004, // Mouse -#if(WINVER >= 0x0603) +//#if(WINVER >= 0x0603) PT_TOUCHPAD = 0x00000005, // Touchpad -#endif /* WINVER >= 0x0603 */ +//#endif /* WINVER >= 0x0603 */ }; typedef DWORD POINTER_INPUT_TYPE; @@ -145,7 +145,7 @@ static GetTouchInputInfoFunc *getTouchInputInfoFunc = NULL; static GetPointerTypeFunc *getPointerTypeFunc = NULL; // DPI Awareness -#if(WINVER >= 0x0603) +// #if(WINVER >= 0x0603) #ifndef DPI_ENUMS_DECLARED @@ -163,7 +163,7 @@ BOOL PROCESS_DPI_AWARENESS dpi_awareness)); static SetProcessDpiAwarenessFunc *setProcessDpiAwareness = NULL; -#endif +// #endif @@ -787,10 +787,10 @@ Win32WindowingSystem::Win32WindowingSystem() } -#if(WINVER >= 0x0603) - // For Windows 8.1 and higher +// #if(WINVER >= 0x0603) + // For Windows 8.1 and higher // - // Per monitor DPI aware.This app checks for the DPI when it is created and adjusts the scale factor + // Per monitor DPI aware.This app checks for the DPI when it is created and adjusts the scale factor // whenever the DPI changes.These applications are not automatically scaled by the system. HMODULE hModuleShore = LoadLibrary("Shcore"); if (hModuleShore) { @@ -799,7 +799,7 @@ Win32WindowingSystem::Win32WindowingSystem() (*setProcessDpiAwareness)(PROCESS_DPI_AWARENESS::PROCESS_PER_MONITOR_DPI_AWARE); } } -#endif +// #endif } Win32WindowingSystem::~Win32WindowingSystem() From 56681c89cd166541be6d3028a2f35594ebb797b4 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Mon, 4 Dec 2017 14:50:12 +0000 Subject: [PATCH 313/327] Changed the reload presentaiton key to 'R' to better match the 'E' for editor --- src/osgPresentation/SlideEventHandler.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/osgPresentation/SlideEventHandler.cpp b/src/osgPresentation/SlideEventHandler.cpp index 8e2ff0b8c..3d56918aa 100644 --- a/src/osgPresentation/SlideEventHandler.cpp +++ b/src/osgPresentation/SlideEventHandler.cpp @@ -1240,7 +1240,7 @@ bool SlideEventHandler::handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIAction _hold = false; return true; } - else if (ea.getKey()=='e') + else if (ea.getKey()=='R') { // reload presentation to reflect changes from editor setRequestReload(true); From 7f0baaab616d01078c0f1f5fac4e352f993202a0 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Mon, 4 Dec 2017 16:43:08 +0000 Subject: [PATCH 314/327] Added passing of the osgDB::Options to the remove from cache to make sure the cache model for the presentation is found and removed. --- applications/present3D/ReadShowFile.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/applications/present3D/ReadShowFile.cpp b/applications/present3D/ReadShowFile.cpp index 147a54bda..474660cb5 100644 --- a/applications/present3D/ReadShowFile.cpp +++ b/applications/present3D/ReadShowFile.cpp @@ -256,7 +256,7 @@ osg::ref_ptr p3d::readShowFiles(osg::ArgumentParser& arguments,const nodeList.push_back(node); // make sure that this presentation isn't cached - osgDB::Registry::instance()->removeFromObjectCache( arguments[pos] ); + osgDB::Registry::instance()->removeFromObjectCache( arguments[pos], local_options.get()); } } } From 551e9ba17c07129f78fbddb7468fdf32994be582 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Mon, 4 Dec 2017 17:51:21 +0000 Subject: [PATCH 315/327] Fixed AUTHORS --- AUTHORS.txt | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/AUTHORS.txt b/AUTHORS.txt index f7b2a94ec..6bd66ef68 100644 --- a/AUTHORS.txt +++ b/AUTHORS.txt @@ -8,11 +8,11 @@ Robert Osfield Stephan Huber Paul Martz Farshid Lashkari -Mathias Frhlich +Mathias Fröhlich Laurens Voerman Marco Jez Wang Rui -Jean-Sbastien Guay +Jean-Sébastien Guay Ulrich Hertlein Mike Weiblen Sukender @@ -66,11 +66,11 @@ Norman Vine Chris Denham Sherman Wilcox Serge Lages -Romano Jos Magacho da Silva +Romano José Magacho da Silva Mourad Boufarguine Alberto Farre Glenn Waldron -Andr Garneau +André Garneau Adrian Egli Sebastian Messerschmidt Randall Hopper @@ -85,7 +85,7 @@ Michael Gronager Martin Naylor Joakim Simonsson David Spilling -Daniel Sjlie +Daniel Sjölie Bryan Thrall Andreas Ekstrand Rafa Gaitan @@ -122,7 +122,7 @@ Gordon Tomlinson Frederic Marmond Frederic Bouvier Carlo Camporesi -Bjrn Blissing +Björn Blissing Alexander Sinditskiy Vladimir Chebaev Thibault Genessay @@ -141,7 +141,7 @@ Uwe Woessner Tony Horrobin Thom DeCarlo Tatsuhiro Nishioka -Tanguy Fautr +Tanguy Fautré Sean Spicer Ryan Kawicki Richard Schmidt @@ -202,7 +202,7 @@ Phil Atkin Pawel Ksiezopolski Patrick Neary Nathan Monteleone -Miha Ravelj +Miha Rav¨elj Miguel Escriva Mattias Linde Mark Sciabica @@ -234,8 +234,8 @@ Christian Ruzicka Christian Buchner Charles Cole Blake Williams -Bjrn Hein -Aurlien Chatelain +Björn Hein +Aurélien Chatelain Antoine Hue Andrew Bettison Andreas Henne @@ -264,7 +264,7 @@ Paul Obermeier Nguyen Van Truong Nathan Cournia Morten Haukness -Morn Pistorius +Morné Pistorius Michael Mc Donnell Michael Henheffer Michael Guerrero @@ -297,7 +297,7 @@ Guillaume Taze Guillaume Chouvenc Giuseppe Donvito Gill Peacegood -Giampaolo Vigan +Giampaolo Viganò Gerrick Bivins George Tarantilis Ferdi Smit @@ -305,7 +305,7 @@ Eduardo Poyart Edgar Ellis Dmitry Marakasov Dimi Christopoulos -Diane Delalle +Diane Delallée David Longest David Ergo Daniel Trstenjak @@ -337,7 +337,7 @@ Vasily Radostev Valery Bickov Valeriy Dubov Vaclav Bilek -Tyge Lvset +Tyge Løvset Troy Yee Torben Dannahauer Tony Vasile @@ -387,7 +387,7 @@ Piotr Rak Pierre Bourdin Philipp Svehla Philipp Siemoleit -Philipp Mchler +Philipp Mächler Philip Lamb Petr Salinger Peter Bear @@ -412,7 +412,7 @@ Nick Thu Nick Black Mojtaba Fathi Mirko Viviani -Mikkel Gjl +Mikkel Gjøl Mike Krus Mike Garrity Mick Thu @@ -465,7 +465,7 @@ Juan Hernando Josh Portway Jonathan Greig John Tan -John Hedstrm +John Hedström John Grant John Farrier John Donovan @@ -524,11 +524,11 @@ David Jung Danny Valente Daniel Stien Dan Minor -Csar L. B. Silveira +César L. B. Silveira Cyril Brulebois Curtis Rubel Cory Slep -Clment Bsch +Clément B½sch Clay Fowler Claus Steuer Chuck Sembroski From a8924a7b362e02f8f38e3120cb6d6f275fe094d2 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Tue, 5 Dec 2017 16:33:01 +0000 Subject: [PATCH 316/327] Added "rs=value" Options support to SVG plugin --- src/osgPlugins/dot/ReaderWriterDOT.cpp | 1 + src/osgPlugins/svg/ReaderWriterSVG.cpp | 45 ++++++++++++++++++-------- 2 files changed, 33 insertions(+), 13 deletions(-) diff --git a/src/osgPlugins/dot/ReaderWriterDOT.cpp b/src/osgPlugins/dot/ReaderWriterDOT.cpp index 575ee481e..c03079738 100644 --- a/src/osgPlugins/dot/ReaderWriterDOT.cpp +++ b/src/osgPlugins/dot/ReaderWriterDOT.cpp @@ -17,6 +17,7 @@ class ReaderWriterDOT : public osgDB::ReaderWriter { public: + virtual const char* className() const { return "DOT Writer"; } virtual bool acceptsExtension(const std::string& extension) const { return osgDB::equalCaseInsensitive(extension,"dot"); } diff --git a/src/osgPlugins/svg/ReaderWriterSVG.cpp b/src/osgPlugins/svg/ReaderWriterSVG.cpp index 21e45f442..5bc63514f 100644 --- a/src/osgPlugins/svg/ReaderWriterSVG.cpp +++ b/src/osgPlugins/svg/ReaderWriterSVG.cpp @@ -36,6 +36,8 @@ class ReaderWriterSVG : public osgDB::ReaderWriter ReaderWriterSVG() { supportsExtension("svg","Scalar Vector Graphics format"); + supportsOption("1024x512","Set resolution of the image generated by SVG"); + supportsOption("rs=2.0","Scale the resolution of the image generated by SVG"); } virtual const char* className() const { return "SVG Image Reader"; } @@ -60,24 +62,41 @@ class ReaderWriterSVG : public osgDB::ReaderWriter osg::Image *image; if (options) { - unsigned int w=0, h=0; std::string op = options->getOptionString(); - size_t i = op.find("x"); - std::stringstream ss1(op.substr(0, i)); - std::stringstream ss2(op.substr(i+1, op.size())); - ss1 >> w; - ss2 >> h; - if (w==0 || h==0){ - image = createImage(handle, dimensionData.width, dimensionData.height); + size_t i = op.find("x"); + if (i!=std::string::npos) + { + + std::stringstream ss1(op.substr(0, i)); + std::stringstream ss2(op.substr(i+1, op.size())); + unsigned int w=0, h=0; + ss1 >> w; + ss2 >> h; + if (w!=0 && h!=0) + { + dimensionData.width = w; + dimensionData.height = h; + } } - else{ - image = createImage(handle, w, h); + + i = op.find("rs="); + if (i!=std::string::npos) + { + + std::stringstream ss(op.substr(i+3, op.size())); + double scale; + ss >> scale; + if (scale!=0.0) + { + dimensionData.width = dimensionData.width * scale; + dimensionData.height = dimensionData.height * scale; + } } } - else{ - image = createImage(handle, dimensionData.width, dimensionData.height); - } + + image = createImage(handle, dimensionData.width, dimensionData.height); + g_object_unref(handle); image->setFileName(file); return image; From d82a7e7c0bbffb683fd18d084da483d8f0a03c90 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Tue, 5 Dec 2017 17:16:17 +0000 Subject: [PATCH 317/327] Removed the unncessary rescale to power of two, and added clear of image to prevent previous image data corrupting the rendered image --- src/osgPlugins/svg/ReaderWriterSVG.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/osgPlugins/svg/ReaderWriterSVG.cpp b/src/osgPlugins/svg/ReaderWriterSVG.cpp index 5bc63514f..f69284f79 100644 --- a/src/osgPlugins/svg/ReaderWriterSVG.cpp +++ b/src/osgPlugins/svg/ReaderWriterSVG.cpp @@ -110,12 +110,15 @@ class ReaderWriterSVG : public osgDB::ReaderWriter // I don't know why, but we check the size... if (width < 128) width = 128; if (height < 128) height = 128; - width = osg::Image::computeNearestPowerOfTwo(width); - height = osg::Image::computeNearestPowerOfTwo(height); + //width = osg::Image::computeNearestPowerOfTwo(width); + //height = osg::Image::computeNearestPowerOfTwo(height); osg::Image *image = new osg::Image(); image->allocateImage(width, height, 1, GL_RGBA, GL_UNSIGNED_BYTE); image->setPixelFormat(GL_BGRA); + // make sure the image data is cleared before we write to it. + memset(image->data(), 0, image->getTotalSizeInBytesIncludingMipmaps()); + cairo_surface_t *cairo_surface = cairo_image_surface_create_for_data(image->data(), CAIRO_FORMAT_ARGB32, width, height, image->getRowSizeInBytes()); cairo_t *cr = cairo_create(cairo_surface); From d313184cd029542fd984f9e4f117a27861c5aab1 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 6 Dec 2017 09:50:42 +0000 Subject: [PATCH 318/327] Added fine grained checking for GL errors in the GLObjectVisitor so that the OSG's default pre compile stage provides better feesback on any GL errors. --- include/osgUtil/GLObjectsVisitor | 18 +++++++++++++----- src/osgUtil/GLObjectsVisitor.cpp | 29 +++++++++++++++++++++++------ 2 files changed, 36 insertions(+), 11 deletions(-) diff --git a/include/osgUtil/GLObjectsVisitor b/include/osgUtil/GLObjectsVisitor index c52d6cce6..353bc3023 100644 --- a/include/osgUtil/GLObjectsVisitor +++ b/include/osgUtil/GLObjectsVisitor @@ -91,6 +91,12 @@ class OSGUTIL_EXPORT GLObjectsVisitor : public osg::NodeVisitor return _renderInfo; } + /** Set whether and how often OpenGL errors should be checked for, defaults to osg::State::ONCE_PER_ATTRIBUTE. */ + void setCheckForGLErrors(osg::State::CheckForGLErrors check) { _checkGLErrors = check; } + + /** Get whether and how often OpenGL errors should be checked for.*/ + osg::State::CheckForGLErrors getCheckForGLErrors() const { return _checkGLErrors; } + /** Simply traverse using standard NodeVisitor traverse method.*/ virtual void apply(osg::Node& node); @@ -105,11 +111,13 @@ class OSGUTIL_EXPORT GLObjectsVisitor : public osg::NodeVisitor typedef std::set DrawableAppliedSet; typedef std::set StatesSetAppliedSet; - Mode _mode; - osg::RenderInfo _renderInfo; - DrawableAppliedSet _drawablesAppliedSet; - StatesSetAppliedSet _stateSetAppliedSet; - osg::ref_ptr _lastCompiledProgram; + Mode _mode; + osg::RenderInfo _renderInfo; + osg::State::CheckForGLErrors _checkGLErrors; + + DrawableAppliedSet _drawablesAppliedSet; + StatesSetAppliedSet _stateSetAppliedSet; + osg::ref_ptr _lastCompiledProgram; }; diff --git a/src/osgUtil/GLObjectsVisitor.cpp b/src/osgUtil/GLObjectsVisitor.cpp index 25aa8c896..32acc58fa 100644 --- a/src/osgUtil/GLObjectsVisitor.cpp +++ b/src/osgUtil/GLObjectsVisitor.cpp @@ -28,7 +28,7 @@ GLObjectsVisitor::GLObjectsVisitor(Mode mode) setTraversalMode(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN); _mode = mode; - + _checkGLErrors = osg::State::ONCE_PER_ATTRIBUTE; } void GLObjectsVisitor::apply(osg::Node& node) @@ -57,8 +57,15 @@ void GLObjectsVisitor::apply(osg::Drawable& drawable) { if (_drawablesAppliedSet.count(&drawable)!=0) return; + if (_checkGLErrors==osg::State::ONCE_PER_ATTRIBUTE) _renderInfo.getState()->checkGLErrors("start of Drawable::apply(osg::Drawable& drawable)"); + _drawablesAppliedSet.insert(&drawable); + if (drawable.getStateSet()) + { + apply(*(drawable.getStateSet())); + } + if (_mode&SWITCH_OFF_DISPLAY_LISTS) { drawable.setUseDisplayList(false); @@ -82,30 +89,34 @@ void GLObjectsVisitor::apply(osg::Drawable& drawable) if (_mode&COMPILE_DISPLAY_LISTS && _renderInfo.getState() && (drawable.getUseDisplayList() || drawable.getUseVertexBufferObjects())) { + drawable.compileGLObjects(_renderInfo); + + if (_checkGLErrors==osg::State::ONCE_PER_ATTRIBUTE) _renderInfo.getState()->checkGLErrors("after drawable.compileGLObjects() call in Drawable::apply(osg::Drawable& drawable) "); } + if (_mode&RELEASE_DISPLAY_LISTS) { drawable.releaseGLObjects(_renderInfo.getState()); } - - if (drawable.getStateSet()) - { - apply(*(drawable.getStateSet())); - } } void GLObjectsVisitor::apply(osg::StateSet& stateset) { if (_stateSetAppliedSet.count(&stateset)!=0) return; + if (_checkGLErrors==osg::State::ONCE_PER_ATTRIBUTE) _renderInfo.getState()->checkGLErrors("start of GLObjectsVisitor::apply(osg::StateSet& stateset)"); + _stateSetAppliedSet.insert(&stateset); if (_mode & COMPILE_STATE_ATTRIBUTES && _renderInfo.getState()) { + stateset.compileGLObjects(*_renderInfo.getState()); + if (_checkGLErrors==osg::State::ONCE_PER_ATTRIBUTE) _renderInfo.getState()->checkGLErrors("after stateset.compileGLObjects in GLObjectsVisitor::apply(osg::StateSet& stateset)"); + osg::Program* program = dynamic_cast(stateset.getAttribute(osg::StateAttribute::PROGRAM)); if (program) { if( program->isFixedFunction() ) @@ -129,6 +140,8 @@ void GLObjectsVisitor::apply(osg::StateSet& stateset) ++itr) { pcp->apply(*(itr->second.first)); + + if (_checkGLErrors==osg::State::ONCE_PER_ATTRIBUTE) _renderInfo.getState()->checkGLErrors(std::string("after pcp->apply(Unfiorm&) in GLObjectsVisitor::apply(osg::StateSet& stateset), unifrom name: ")+(itr->second.first)->getName()); } } } @@ -151,6 +164,8 @@ void GLObjectsVisitor::apply(osg::StateSet& stateset) { stateset.checkValidityOfAssociatedModes(*_renderInfo.getState()); } + + if (_checkGLErrors==osg::State::ONCE_PER_ATTRIBUTE) _renderInfo.getState()->checkGLErrors("after GLObjectsVisitor::apply(osg::StateSet& stateset)"); } void GLObjectsVisitor::compile(osg::Node& node) @@ -166,6 +181,8 @@ void GLObjectsVisitor::compile(osg::Node& node) extensions->glUseProgram(0); _renderInfo.getState()->setLastAppliedProgramObject(0); } + + if (_checkGLErrors!=osg::State::NEVER_CHECK_GL_ERRORS) _renderInfo.getState()->checkGLErrors("after GLObjectsVisitor::compile(osg::Node& node)"); } } From 37dbb04608aa08fbf994f218f2676326333ac21a Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Mon, 14 Nov 2016 11:59:47 +0000 Subject: [PATCH 319/327] Added more flexibility into the State::checkGLErrors() method, allowing calling code to pass in two strings. Improved the StateSet::compileGLObjects() usage of checkGLErrors() to make the warning reports more meaningful. --- src/osgUtil/GLObjectsVisitor.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/osgUtil/GLObjectsVisitor.cpp b/src/osgUtil/GLObjectsVisitor.cpp index 32acc58fa..8784366b8 100644 --- a/src/osgUtil/GLObjectsVisitor.cpp +++ b/src/osgUtil/GLObjectsVisitor.cpp @@ -141,7 +141,7 @@ void GLObjectsVisitor::apply(osg::StateSet& stateset) { pcp->apply(*(itr->second.first)); - if (_checkGLErrors==osg::State::ONCE_PER_ATTRIBUTE) _renderInfo.getState()->checkGLErrors(std::string("after pcp->apply(Unfiorm&) in GLObjectsVisitor::apply(osg::StateSet& stateset), unifrom name: ")+(itr->second.first)->getName()); + if (_checkGLErrors==osg::State::ONCE_PER_ATTRIBUTE) _renderInfo.getState()->checkGLErrors("after pcp->apply(Unfiorm&) in GLObjectsVisitor::apply(osg::StateSet& stateset), unifrom name: ", (itr->second.first->getName()).c_str()); } } } From 7f2481e976327efe79f34c4248f33c727910c119 Mon Sep 17 00:00:00 2001 From: Julien Valentin Date: Wed, 6 Dec 2017 22:57:03 +0100 Subject: [PATCH 320/327] add a fix in order setArray work with an user managed interleaved array --- src/osg/VertexArrayState.cpp | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/src/osg/VertexArrayState.cpp b/src/osg/VertexArrayState.cpp index 7af9bec4a..f0bc391d1 100644 --- a/src/osg/VertexArrayState.cpp +++ b/src/osg/VertexArrayState.cpp @@ -483,6 +483,14 @@ struct VertexAttribArrayDispatch : public VertexArrayState::ArrayDispatch callVertexAttribPointer(ext, new_array, (const GLvoid *)(vbo->getOffset(new_array->getBufferIndex()))); } + virtual void enable_and_dispatch(osg::State& state, GLint size, GLenum type, GLsizei stride, const GLvoid *ptr, GLboolean normalized) + { + GLExtensions* ext = state.get(); + + ext->glEnableVertexAttribArray( unit ); + ext->glVertexAttribPointer(static_cast(unit), size, type, normalized, stride, ptr); + } + virtual void dispatch(osg::State& state, const osg::Array* new_array) { GLExtensions* ext = state.get(); @@ -713,30 +721,20 @@ void VertexArrayState::setArray(ArrayDispatch* vad, osg::State& state, const osg void VertexArrayState::setArray(ArrayDispatch* vad, osg::State& state, GLint size, GLenum type, GLsizei stride, const GLvoid *ptr, GLboolean normalized) { - if (ptr) - { + if(!vad->array){ + if (!vad->active) { vad->active = true; _activeDispatchers.push_back(vad); } - if (vad->array==0) - { - unbindVertexBufferObject(); - vad->enable_and_dispatch(state, size, type, stride, ptr, normalized); - } - else - { - unbindVertexBufferObject(); - vad->dispatch(state, size, type, stride, ptr, normalized); - } + vad->enable_and_dispatch(state, size, type, stride, ptr, normalized); - vad->array = 0; vad->modifiedCount = 0xffffffff; } - else if (vad->array) + else { disable(vad, state); } From 25f5605ad8d78e51e5000e7fb6d7f65ffc4137ee Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Thu, 7 Dec 2017 17:52:24 +0000 Subject: [PATCH 321/327] Improvements to dot visitors --- src/osgPlugins/dot/BaseDotVisitor.cpp | 198 ++++++++++++------------ src/osgPlugins/dot/BaseDotVisitor.h | 60 ++++--- src/osgPlugins/dot/SimpleDotVisitor.cpp | 121 ++++++++------- src/osgPlugins/dot/SimpleDotVisitor.h | 33 ++-- 4 files changed, 201 insertions(+), 211 deletions(-) diff --git a/src/osgPlugins/dot/BaseDotVisitor.cpp b/src/osgPlugins/dot/BaseDotVisitor.cpp index 3aec31ac2..0a4804495 100644 --- a/src/osgPlugins/dot/BaseDotVisitor.cpp +++ b/src/osgPlugins/dot/BaseDotVisitor.cpp @@ -24,8 +24,11 @@ using namespace osg; namespace osgDot { - BaseDotVisitor::BaseDotVisitor() - { +BaseDotVisitor::BaseDotVisitor(): + osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN) +{ + // setNodeMaskOverride(0xffffff); + _rankdir = "rankdir = LR;"; // Set the locale used by the _nodes and _edges streams to the // classic or "C" locale. This is needed because most of the @@ -33,156 +36,145 @@ namespace osgDot { // by id numbers containing commas or periods. _nodes.imbue(std::locale("C")); _edges.imbue(std::locale("C")); - } +} - BaseDotVisitor::~BaseDotVisitor() { - } +BaseDotVisitor::~BaseDotVisitor() +{ +} - void BaseDotVisitor::setOptions(const osgDB::Options* options) +void BaseDotVisitor::setOptions(const osgDB::Options* options) +{ + _options = const_cast(options); + OSG_INFO<<"BaseDotVisitor::setOptions("<getOptionString().empty())) { - _options = const_cast(options); - OSG_INFO<<"BaseDotVisitor::setOptions("<getOptionString().empty())) + + std::string optionString = _options->getOptionString(); + + OSG_INFO<<" BaseDotVisitor::optionString ("<getOptionString(); - - OSG_INFO<<" BaseDotVisitor::optionString ("<getStateSet(); - if ( s ) { - int id3; - if ( getOrCreateId( s, id3 ) ) { - handle( *s, id3 ); - } - handle( *drawable, *s, id2, id3 ); - } - } - handle( node, *drawable, id, id2 ); - } - + if ( getOrCreateId( &drawable, id ) ) + { + handle( drawable, id ); + handleNodeAndTraverse( drawable, id ); } +} - } - - void BaseDotVisitor::apply(Group& node) { +void BaseDotVisitor::apply(Group& node) +{ int id; - if ( getOrCreateId( &node, id ) ) { - handle( node, id ); - handleNodeAndTraverse( node, id ); + if ( getOrCreateId( &node, id ) ) + { + handle( node, id ); + handleNodeAndTraverse( node, id ); - unsigned int i; - for ( i = 0; i < node.getNumChildren(); i++ ) { - osg::Node* child = node.getChild( i ); - //handleNodeAndTraverse( *child ); - int id2; - if (getOrCreateId( child, id2 )) + unsigned int i; + for ( i = 0; i < node.getNumChildren(); i++ ) { + osg::Node* child = node.getChild( i ); + //handleNodeAndTraverse( *child ); + int id2; + getOrCreateId( child, id2 ); handle( node, *child, id, id2 ); } - } } +} - } +void BaseDotVisitor::handle(osg::Node&, int) {} - void BaseDotVisitor::handle(osg::Node&, int) {} +void BaseDotVisitor::handle(osg::Group&, int) {} - void BaseDotVisitor::handle(osg::Geode&, int) {} +void BaseDotVisitor::handle(osg::Group&, osg::Node&, int, int) {} - void BaseDotVisitor::handle(osg::Group&, int) {} - - void BaseDotVisitor::handle(osg::Group&, osg::Node&, int, int) {} - - void BaseDotVisitor::handleNodeAndTraverse(osg::Node& node, int id) { +void BaseDotVisitor::handleNodeAndTraverse(osg::Node& node, int id) +{ osg::StateSet* ss = node.getStateSet(); - if ( ss ) { - int id2; - if ( getOrCreateId( ss, id2 ) ) { - handle( *ss, id2 ); - } - handle( node, *ss, id, id2 ); + if ( ss ) + { + int id2; + if ( getOrCreateId( ss, id2 ) ) + { + handle( *ss, id2 ); + } + handle( node, *ss, id, id2 ); } traverse(node); - } +} - void BaseDotVisitor::handle(osg::StateSet&, int) {} +void BaseDotVisitor::handle(osg::StateSet&, int) {} - void BaseDotVisitor::handle(osg::Node&, osg::StateSet&, int, int) {} +void BaseDotVisitor::handle(osg::Node&, osg::StateSet&, int, int) {} - void BaseDotVisitor::handle(osg::Drawable&, int) {} +void BaseDotVisitor::handle(osg::Drawable&, int) {} - void BaseDotVisitor::handle(osg::Drawable&, osg::StateSet&, int, int) {} +void BaseDotVisitor::handle(osg::Drawable&, osg::StateSet&, int, int) {} - void BaseDotVisitor::handle(osg::Geode&, osg::Drawable&, int, int) {} - - bool BaseDotVisitor::getOrCreateId( osg::Object* object, int &id ) { - assert( object ); +bool BaseDotVisitor::getOrCreateId( osg::Object* object, int &id ) +{ ObjectMap::iterator it = _objectMap.find( object ); - if ( it != _objectMap.end() ) { - id = it->second; - return false; + if ( it != _objectMap.end() ) + { + id = it->second; + return false; } id = _objectMap.size(); _objectMap[ object ] = id; return true; - } +} } // namespace osgDot diff --git a/src/osgPlugins/dot/BaseDotVisitor.h b/src/osgPlugins/dot/BaseDotVisitor.h index 87b06662a..d0e2b2737 100644 --- a/src/osgPlugins/dot/BaseDotVisitor.h +++ b/src/osgPlugins/dot/BaseDotVisitor.h @@ -30,54 +30,52 @@ namespace osgDot { - class BaseDotVisitor : public osg::NodeVisitor { - public: - typedef std::map< osg::Object*, int > ObjectMap; +class BaseDotVisitor : public osg::NodeVisitor +{ + public: + typedef std::map< osg::Object*, int > ObjectMap; - public: - BaseDotVisitor(); + public: + BaseDotVisitor(); - virtual ~BaseDotVisitor(); + virtual ~BaseDotVisitor(); - void setOptions(const osgDB::Options* options); + void setOptions(const osgDB::Options* options); - bool run( osg::Node& root, std::ostream* ostream ); + bool run( osg::Node& root, std::ostream* ostream ); - virtual void apply(osg::Node& node); + virtual void apply(osg::Node& node); - virtual void apply(osg::Geode& node); + virtual void apply(osg::Drawable& node); - virtual void apply(osg::Group& node); + virtual void apply(osg::Group& node); + protected: - protected: + void handleNodeAndTraverse(osg::Node& node, int id); - void handleNodeAndTraverse(osg::Node& node, int id); + virtual void handle(osg::StateSet& stateset, int id); + virtual void handle(osg::Drawable& drawable, int id); + virtual void handle(osg::Node& node, int id); + virtual void handle(osg::Group& node, int id); - virtual void handle(osg::Node& node, int id); - virtual void handle(osg::Geode& node, int id); - virtual void handle(osg::Group& node, int id); - virtual void handle(osg::StateSet& stateset, int id); - virtual void handle(osg::Drawable& drawable, int id); + virtual void handle(osg::Node& node, osg::StateSet& stateset, int parentID, int childID); + virtual void handle(osg::Drawable& drawable, osg::StateSet& stateset, int parentID, int childID ); + virtual void handle(osg::Group& parent, osg::Node& child, int parentID, int childID); - virtual void handle(osg::Node& node, osg::StateSet& stateset, int parentID, int childID); - virtual void handle(osg::Group& parent, osg::Node& child, int parentID, int childID); - virtual void handle(osg::Geode& geode, osg::Drawable& drawable, int parentID, int childID); - virtual void handle(osg::Drawable& drawable, osg::StateSet& stateset, int parentID, int childID ); + osg::ref_ptr _options; - osg::ref_ptr _options; + std::string _rankdir; - std::string _rankdir; + std::stringstream _nodes; + std::stringstream _edges; - std::stringstream _nodes; - std::stringstream _edges; + private: + bool getOrCreateId( osg::Object* object, int& id ); - private: - bool getOrCreateId( osg::Object* object, int& id ); + ObjectMap _objectMap; - ObjectMap _objectMap; - - }; +}; } // namespace osgDot diff --git a/src/osgPlugins/dot/SimpleDotVisitor.cpp b/src/osgPlugins/dot/SimpleDotVisitor.cpp index 60fad98d0..075a6445a 100644 --- a/src/osgPlugins/dot/SimpleDotVisitor.cpp +++ b/src/osgPlugins/dot/SimpleDotVisitor.cpp @@ -15,79 +15,80 @@ namespace osgDot { - SimpleDotVisitor::SimpleDotVisitor() { - } +SimpleDotVisitor::SimpleDotVisitor() +{ +} - SimpleDotVisitor::~SimpleDotVisitor() { - } +SimpleDotVisitor::~SimpleDotVisitor() +{ +} - void SimpleDotVisitor::handle(osg::Node& node, int id) { - std::stringstream label; - label << " Node"; - if ( !node.getName().empty() ) { label << "| " << node.getName(); } - drawNode( id, "record", "solid", label.str(), "black", "white" ); - } - void SimpleDotVisitor::handle(osg::Geode& node, int id) { - std::stringstream label; - label << " " << node.className(); - if ( !node.getName().empty() ) { label << "| " << node.getName(); } - drawNode( id, "record", "solid", label.str(), "brown", "white" ); - } - - void SimpleDotVisitor::handle(osg::Group& node, int id) { - std::stringstream label; - label << " " << node.className(); - if ( !node.getName().empty() ) { label << "| " << node.getName(); } - drawNode( id, "record", "solid", label.str(), "black", "white" ); - } - - void SimpleDotVisitor::handle(osg::Group&, osg::Node&, int parentID, int childID ) { - drawEdge( parentID, childID, "setlinewidth(2)" ); - } - - void SimpleDotVisitor::handle(osg::StateSet& stateset, int id) { +void SimpleDotVisitor::handle(osg::StateSet& stateset, int id) +{ std::stringstream label; label << " " << stateset.className(); - if ( !stateset.getName().empty() ) { label << "| " << stateset.getName(); } - drawNode( id, "Mrecord", "solid", label.str(), "green", "white" ); - } + if ( !stateset.getName().empty() ) { label << " | " << stateset.getName(); } + drawNode( id, "Mrecord", "solid, filled", label.str(), "green", "black" ); +} - void SimpleDotVisitor::handle(osg::Node&, osg::StateSet&, int parentID, int childID ) { - drawEdge( parentID, childID, "dashed" ); - } - - void SimpleDotVisitor::handle(osg::Drawable& drawable, int id) { +void SimpleDotVisitor::handle(osg::Drawable& drawable, int id) +{ std::stringstream label; label << " " << drawable.className(); - if ( !drawable.getName().empty() ) { label << "| " << drawable.getName(); } - drawNode( id, "record", "solid", label.str(), "blue", "white" ); - } + if ( !drawable.getName().empty() ) { label << " | " << drawable.getName(); } + drawNode( id, "record", "solid, filled", label.str(), "lightblue", "black" ); +} - void SimpleDotVisitor::handle(osg::Geode&, osg::Drawable&, int parentID, int childID ) { - drawEdge( parentID, childID, "dashed" ); - } +void SimpleDotVisitor::handle(osg::Node& node, int id) +{ + std::stringstream label; + label << " "< " << node.className(); + if ( !node.getName().empty() ) { label << " | " << node.getName(); } + drawNode( id, "record", "solid, filled", label.str(), "yellow", "black" ); +} - void SimpleDotVisitor::drawNode( int id, const std::string& shape, const std::string& style, const std::string& label, const std::string& color, const std::string& fillColor ) { +void SimpleDotVisitor::handle(osg::Node&, osg::StateSet&, int parentID, int childID ) +{ + drawEdge( parentID, childID, "" ); +} + +void SimpleDotVisitor::handle(osg::Drawable&, osg::StateSet&, int parentID, int childID ) +{ + drawEdge( parentID, childID, "" ); +} + +void SimpleDotVisitor::handle(osg::Group&, osg::Node&, int parentID, int childID ) +{ + drawEdge( parentID, childID, "" ); +} + +void SimpleDotVisitor::drawNode( int id, const std::string& shape, const std::string& style, const std::string& label, const std::string& color, const std::string& fillColor ) +{ _nodes << id << - "[shape=\"" << shape << - "\" ,label=\"" << label << - "\" ,style=\"" << style << - "\" ,color=\"" << color << - "\" ,fillColor=\"" << fillColor << - "\"]" << std::endl; - } + "[shape=\"" << shape << + "\" ,label=\"" << label << + "\" ,style=\"" << style << + "\" ,color=\"" << color << + "\" ,fillColor=\"" << fillColor << + "\"]" << std::endl; +} - void SimpleDotVisitor::drawEdge( int sourceId, int sinkId, const std::string& style ) { +void SimpleDotVisitor::drawEdge( int sourceId, int sinkId, const std::string& style ) +{ _edges - << sourceId << ":top -> " - << sinkId << ":top [style=\"" - << style << "\"];" - << std::endl; - } + << sourceId << ":top -> " + << sinkId << ":top [style=\"" + << style << "\"];" + << std::endl; +} } // namespace osgDot diff --git a/src/osgPlugins/dot/SimpleDotVisitor.h b/src/osgPlugins/dot/SimpleDotVisitor.h index e5e986ebc..94ad8ec69 100644 --- a/src/osgPlugins/dot/SimpleDotVisitor.h +++ b/src/osgPlugins/dot/SimpleDotVisitor.h @@ -23,30 +23,29 @@ namespace osgDot { - class SimpleDotVisitor : public BaseDotVisitor { - public: - SimpleDotVisitor(); +class SimpleDotVisitor : public BaseDotVisitor +{ + public: + SimpleDotVisitor(); - virtual ~SimpleDotVisitor(); + virtual ~SimpleDotVisitor(); - protected: - virtual void handle(osg::Node& node, int id); - virtual void handle(osg::Geode& geode, int id); - virtual void handle(osg::Group& node, int id); + protected: - virtual void handle(osg::StateSet& stateset, int id); - virtual void handle(osg::Drawable& drawable, int id); + virtual void handle(osg::StateSet& stateset, int id); + virtual void handle(osg::Drawable& drawable, int id); + virtual void handle(osg::Node& node, int id); + virtual void handle(osg::Group& node, int id); - virtual void handle(osg::Node& node, osg::StateSet& stateset, int parentID, int childID ); - virtual void handle(osg::Geode& geometry, osg::Drawable& drawable, int parentID, int childID ); - virtual void handle(osg::Group& parent, osg::Node& child, int parentID, int childID ); - virtual void handle(osg::Drawable& drawable, osg::StateSet& stateset, int parentID, int childID ); + virtual void handle(osg::Node& node, osg::StateSet& stateset, int parentID, int childID ); + virtual void handle(osg::Drawable& drawable, osg::StateSet& stateset, int parentID, int childID ); + virtual void handle(osg::Group& parent, osg::Node& child, int parentID, int childID ); - virtual void drawNode( int id, const std::string& shape, const std::string& style, const std::string& label, const std::string& color, const std::string& fillColor ); + virtual void drawNode( int id, const std::string& shape, const std::string& style, const std::string& label, const std::string& color, const std::string& fillColor ); - virtual void drawEdge( int sourceId, int sinkId, const std::string& style ); + virtual void drawEdge( int sourceId, int sinkId, const std::string& style ); - }; +}; } // namespace osgDot From 53d8032656e12011ee7b2d51242980451fd5e7d1 Mon Sep 17 00:00:00 2001 From: Julien Valentin Date: Thu, 7 Dec 2017 20:13:57 +0100 Subject: [PATCH 322/327] fix logo reader plugin TODO upgrade to a more modern gl (remove glDrawpixel usage) --- src/osgPlugins/logo/ReaderWriterLOGO.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/osgPlugins/logo/ReaderWriterLOGO.cpp b/src/osgPlugins/logo/ReaderWriterLOGO.cpp index 2ca9fd318..e5ce86a97 100644 --- a/src/osgPlugins/logo/ReaderWriterLOGO.cpp +++ b/src/osgPlugins/logo/ReaderWriterLOGO.cpp @@ -259,7 +259,7 @@ class LOGOReaderWriter : public osgDB::ReaderWriter Logos::RelativePosition pos = Logos::LowerRight; - std::ifstream fin(filePath.c_str()); + std::ifstream fin(fileName.c_str()); if (!fin) return NULL; while(fin) From 6ef0e667d219fff9b257f8b57f7c64c532371002 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Fri, 8 Dec 2017 16:10:57 +0000 Subject: [PATCH 323/327] Added support for OSG_BORDERLESS_WINDOW="x y width heigh" and --bordless-window x y width height to make it easier to manage custom placement of viewers without window decoration --- src/osgViewer/Viewer.cpp | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/src/osgViewer/Viewer.cpp b/src/osgViewer/Viewer.cpp index 7908e7460..0eb63c586 100644 --- a/src/osgViewer/Viewer.cpp +++ b/src/osgViewer/Viewer.cpp @@ -33,6 +33,7 @@ #include #include #include +#include #include @@ -63,6 +64,7 @@ Viewer::Viewer(osg::ArgumentParser& arguments) arguments.getApplicationUsage()->addCommandLineOption("--clear-color ","Set the background color of the viewer in the form \"r,g,b[,a]\"."); arguments.getApplicationUsage()->addCommandLineOption("--screen ","Set the screen to use when multiple screens are present."); arguments.getApplicationUsage()->addCommandLineOption("--window ","Set the position (x,y) and size (w,h) of the viewer window."); + arguments.getApplicationUsage()->addCommandLineOption("--borderless-window ","Set the position (x,y) and size (w,h) of a borderless viewer window."); arguments.getApplicationUsage()->addCommandLineOption("--run-on-demand","Set the run methods frame rate management to only rendering frames when required."); arguments.getApplicationUsage()->addCommandLineOption("--run-continuous","Set the run methods frame rate management to rendering frames continuously."); @@ -136,7 +138,14 @@ Viewer::Viewer(osg::ArgumentParser& arguments) bool ss3d = false; bool wowvx20 = false; bool wowvx42 = false; - if ((wowvx20=arguments.read("--wowvx-20")) || (wowvx42=arguments.read("--wowvx-42")) || arguments.read("--wowvx")) + + if (arguments.read("--borderless-window",x,y,width,height)) + { + osg::ref_ptr sw = new osgViewer::SingleWindow(x, y, width, height, screenNum); + sw->setWindowDecoration(false); + apply(sw.get()); + } + else if ((wowvx20=arguments.read("--wowvx-20")) || (wowvx42=arguments.read("--wowvx-42")) || arguments.read("--wowvx")) { osg::ref_ptr wow = new WoWVxDisplay; @@ -510,7 +519,13 @@ void Viewer::realize() int x = -1, y = -1, width = -1, height = -1; osg::getEnvVar("OSG_WINDOW", x, y, width, height); - if (width>0 && height>0) + if (osg::getEnvVar("OSG_BORDERLESS_WINDOW", x, y, width, height)) + { + osg::ref_ptr sw = new osgViewer::SingleWindow(x, y, width, height, screenNum); + sw->setWindowDecoration(false); + apply(sw.get()); + } + else if (width>0 && height>0) { if (screenNum>=0) setUpViewInWindow(x, y, width, height, screenNum); else setUpViewInWindow(x,y,width,height); From 9bf3d2b7cee83952d53d7b5778394a69b7fad208 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Sat, 9 Dec 2017 11:12:35 +0000 Subject: [PATCH 324/327] Pushed background image away from eye point a small amount to prevent z fighting with text on the image plane. --- src/osgPresentation/SlideShowConstructor.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/osgPresentation/SlideShowConstructor.cpp b/src/osgPresentation/SlideShowConstructor.cpp index 2ab07cedd..450c67b1a 100644 --- a/src/osgPresentation/SlideShowConstructor.cpp +++ b/src/osgPresentation/SlideShowConstructor.cpp @@ -484,7 +484,8 @@ void SlideShowConstructor::addLayer(bool inheritPreviousLayers, bool defineAsBas bool useTextureRectangle = true; float s = useTextureRectangle ? image->s() : 1.0; float t = useTextureRectangle ? image->t() : 1.0; - osg::Geometry* backgroundQuad = osg::createTexturedQuadGeometry(_slideOrigin, + osg::Vec3 backgroundShift(0.0f, _slideWidth*0.0001f, 0.0f); + osg::Geometry* backgroundQuad = osg::createTexturedQuadGeometry(_slideOrigin+backgroundShift, osg::Vec3(_slideWidth,0.0f,0.0f), osg::Vec3(0.0f,0.0f,_slideHeight), s, t); From 588cad24e2cfa6577c43c4ef57bda07db0aca31e Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Sat, 9 Dec 2017 18:29:19 +0000 Subject: [PATCH 325/327] Quietened down debug messages --- src/osgPlugins/p3d/ReaderWriterP3D.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/osgPlugins/p3d/ReaderWriterP3D.cpp b/src/osgPlugins/p3d/ReaderWriterP3D.cpp index 0ac468c4b..774a2d1bc 100644 --- a/src/osgPlugins/p3d/ReaderWriterP3D.cpp +++ b/src/osgPlugins/p3d/ReaderWriterP3D.cpp @@ -2195,11 +2195,11 @@ void ReaderWriterP3DXML::parseLayer(osgPresentation::SlideShowConstructor& const if (constructor.getCurrentLayer()) { constructor.getCurrentLayer()->setUserValue("name",name); - OSG_NOTICE<<"Setting current layers name "<setUserValue("name",name); - OSG_NOTICE<<"Setting current slide name "< Date: Sat, 9 Dec 2017 18:42:40 +0000 Subject: [PATCH 326/327] Quited now deboug output --- src/osg/DisplaySettings.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/osg/DisplaySettings.cpp b/src/osg/DisplaySettings.cpp index 7add41792..52d0efd80 100644 --- a/src/osg/DisplaySettings.cpp +++ b/src/osg/DisplaySettings.cpp @@ -658,17 +658,17 @@ void DisplaySettings::readEnvironmentalVariables() { if (value=="VERTEX_BUFFER_OBJECT" || value=="VBO") { - OSG_NOTICE<<"OSG_VERTEX_BUFFER_HINT set to VERTEX_BUFFER_OBJECT"< Date: Sat, 9 Dec 2017 19:18:43 +0000 Subject: [PATCH 327/327] Quitened down debug output --- src/osgPresentation/KeyEventHandler.cpp | 2 +- src/osgPresentation/PickEventHandler.cpp | 2 +- src/osgPresentation/SlideEventHandler.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/osgPresentation/KeyEventHandler.cpp b/src/osgPresentation/KeyEventHandler.cpp index ad0373a57..f08fdc003 100644 --- a/src/osgPresentation/KeyEventHandler.cpp +++ b/src/osgPresentation/KeyEventHandler.cpp @@ -146,7 +146,7 @@ void KeyEventHandler::doOperation() } case(osgPresentation::JUMP): { - OSG_NOTICE<<"Requires jump "<dispatchEvent(_keyPos); break; } diff --git a/src/osgPresentation/SlideEventHandler.cpp b/src/osgPresentation/SlideEventHandler.cpp index 3d56918aa..4c3d22a04 100644 --- a/src/osgPresentation/SlideEventHandler.cpp +++ b/src/osgPresentation/SlideEventHandler.cpp @@ -40,7 +40,7 @@ SlideEventHandler* SlideEventHandler::instance() { return s_seh.get(); } bool JumpData::jump(SlideEventHandler* seh) const { - OSG_NOTICE<<"Requires jump"<