From 1e4a0cadf558502f9ce1187260170b9fad7cbf4e Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Sat, 13 Oct 2001 11:16:10 +0000 Subject: [PATCH] Changed the naming and calling convention of the new Drawable::AttributeFunctor and have updated GeoSet to use mutable values for the _numverts etc, allowing osg::GeoSet::computeNumVerts() to be a const operation. osg::GeoSet::getNumVerts is now a const once more, so avoiding compilation problems. Also chaned the new osgconv orientation code to use a Drawable::AttributeFunctor so it can work on other Drawables other than just GeoSets. --- TODO | 15 +- include/osg/Drawable | 24 ++- include/osg/GeoSet | 20 +-- src/Demos/osgconv/orientationconverter.cpp | 47 +++++- src/Demos/sgv/Makefile | 2 +- src/Demos/sgv/sgv.cpp | 178 ++++++++++++++++++++- src/osg/GeoSet.cpp | 17 +- 7 files changed, 265 insertions(+), 38 deletions(-) diff --git a/TODO b/TODO index 07b99165e..a97ff39a5 100644 --- a/TODO +++ b/TODO @@ -26,9 +26,7 @@ o Core OSG Library . mutli-threading/shared memory support. - Maths - . full maths support in osg::Matrix class. . double matrix class. - . osg::Plane class. - Nodes . add osg::Sequence for basic animation. @@ -39,7 +37,6 @@ o Core OSG Library . utilise stl vectors for osg::GeoSets? . add handling of memory of osg::GeoSet's attributes. . add osg::Terrain node. - . add osg::EarthSky class for rendering earth and sky backgrounds. . add proxy node for lazy loading of nodes, when needed. . implement visual proximity to assist loading of proxied data when the view frustum nears an unloaded proxy node, and deleting @@ -93,16 +90,14 @@ o Under development - add osg::Billboard for trees etc. - full maths support in osg::Matrix class. - Netscape plug-in. - - add osg::Channel/sgCamera class. - - .pfb loader for Performer binary files (functioning already.) - - .flt Open Flight format (functioning already.) - - .3ds 3D Studio format (functioning already.) - - autoconf/configure support to aid portabilty to other unix's. - CVS support for when source is made fully public. - Mac port. - tri stripping visitor. - .obj Alias wavefront's format.(functioning already.) - .lwo Light Waves's format.(functioning already.) + - .pfb loader for Performer binary files (functioning already.) + - .flt Open Flight format (functioning already.) + - .3ds 3D Studio format (functioning already.) o Work completed ============== @@ -145,3 +140,7 @@ o Work completed - create a base class to provide interface to objects which can render, derive osg::GeoSet from this. - add support for multi-pass rendering. + - full maths support in osg::Matrix class. + - osg::Plane class. + - add osg::Camera class. + - add osg::EarthSky class for rendering earth and sky backgrounds. diff --git a/include/osg/Drawable b/include/osg/Drawable index 99f5d463f..ce4180e76 100644 --- a/include/osg/Drawable +++ b/include/osg/Drawable @@ -141,22 +141,30 @@ class SG_EXPORT Drawable : public Object TEXTURE_COORDS_3 = 0x64 }; - struct AttributeUpdateFunctor + class AttributeFunctor { - inline bool apply(AttributeBitMask abm,Vec2& vec) { return apply(abm,&vec,(&vec)+1); } - inline bool apply(AttributeBitMask abm,Vec3& vec) { return apply(abm,&vec,(&vec)+1); } - inline bool apply(AttributeBitMask abm,Vec4& vec) { return apply(abm,&vec,(&vec)+1); } - + public: + + AttributeFunctor(AttributeBitMask abm):_abm(abm) {} + virtual ~AttributeFunctor() {} + + void setAttributeBitMask(AttributeBitMask abm) { _abm=abm; } + AttributeBitMask getAttributeBitMask() const { return _abm; } + virtual bool apply(AttributeBitMask,Vec2*,Vec2*) { return false; } virtual bool apply(AttributeBitMask,Vec3*,Vec3*) { return false; } virtual bool apply(AttributeBitMask,Vec4*,Vec4*) { return false; } + + protected: + + AttributeBitMask _abm; }; - /** return the attributes supported by applyAttrbuteUpdate() as an AttributeBitMask.*/ - virtual AttributeBitMask suppportsAttributeUpdate() const { return (AttributeBitMask)0; } + /** return the attributes supported by applyAttrbuteOperation() as an AttributeBitMask.*/ + virtual AttributeBitMask suppportsAttributeOperation() const { return (AttributeBitMask)0; } /** return the attributes successully applied in applyAttributeUpdate.*/ - virtual AttributeBitMask applyAttributeUpdate(AttributeBitMask,AttributeUpdateFunctor&) { return (AttributeBitMask)0; } + virtual AttributeBitMask applyAttributeOperation(AttributeFunctor&) { return 0; } protected: diff --git a/include/osg/GeoSet b/include/osg/GeoSet index 261ad686f..a354abc14 100644 --- a/include/osg/GeoSet +++ b/include/osg/GeoSet @@ -70,7 +70,7 @@ class SG_EXPORT GeoSet : public Drawable struct IndexPointer { - uint _size; + mutable uint _size; bool _is_ushort; union { @@ -160,11 +160,11 @@ class SG_EXPORT GeoSet : public Drawable inline int *getPrimLengths() { return _primLengths; } inline const int *getPrimLengths() const { return _primLengths; } - void computeNumVerts(); + void computeNumVerts() const; /** get the number of coords required by the defined primitives. */ // inline const int getNumCoords() const - inline const int getNumCoords() + inline const int getNumCoords() const { if( _numcoords == 0 ) computeNumVerts(); return _numcoords; } /** get a pointer to Vec3 coord array. */ inline Vec3* getCoords() { return _coords; } @@ -292,10 +292,10 @@ class SG_EXPORT GeoSet : public Drawable /** return the attributes supported by applyAttrbuteUpdate() as an AttributeBitMask.*/ - virtual AttributeBitMask suppportsAttributeUpdate() const; + virtual AttributeBitMask suppportsAttributeOperation() const; /** return the attributes successully applied in applyAttributeUpdate.*/ - virtual AttributeBitMask applyAttributeUpdate(AttributeBitMask abm,AttributeUpdateFunctor& auf); + virtual AttributeBitMask applyAttributeOperation(AttributeFunctor& auf); protected: @@ -312,25 +312,25 @@ class SG_EXPORT GeoSet : public Drawable int _needprimlen; unsigned int _oglprimtype; int *_primLengths; - unsigned char _primlength; + mutable unsigned char _primlength; unsigned char _flat_shaded_skip; - int _numcoords; + mutable int _numcoords; Vec3 *_coords; IndexPointer _cindex; BindingType _normal_binding; - int _numnormals; + mutable int _numnormals; Vec3 *_normals; IndexPointer _nindex; BindingType _color_binding; - int _numcolors; + mutable int _numcolors; Vec4 *_colors; IndexPointer _colindex; BindingType _texture_binding; - int _numtcoords; + mutable int _numtcoords; Vec2 *_tcoords; IndexPointer _tindex; diff --git a/src/Demos/osgconv/orientationconverter.cpp b/src/Demos/osgconv/orientationconverter.cpp index a59491435..ca1ee7ad6 100644 --- a/src/Demos/osgconv/orientationconverter.cpp +++ b/src/Demos/osgconv/orientationconverter.cpp @@ -4,6 +4,46 @@ using namespace osg; +class TransformFunctor : public osg::Drawable::AttributeFunctor +{ + + public: + + osg::Matrix _m; + + TransformFunctor(const osg::Matrix& m): + AttributeFunctor(osg::Drawable::COORDS|osg::Drawable::NORMALS), + _m(m) {} + + virtual ~TransformFunctor() {} + + virtual bool apply(osg::Drawable::AttributeBitMask abm,osg::Vec3* begin,osg::Vec3* end) + { + if (abm == osg::Drawable::COORDS) + { + for (osg::Vec3* itr=begin;itrapplyAttributeOperation(tf); + +/* GeoSet *gset = dynamic_cast(geode.getDrawable(i)); if( gset == NULL ) continue; - int numcoords = gset->getNumCoords(); Vec3 *vertex = gset->getCoords(); @@ -54,5 +98,6 @@ void OrientationConverter::ConvertVisitor::apply( Geode &geode ) Vec3 vv = normals[i]; normals[i] = vv * _mat; } +*/ } } diff --git a/src/Demos/sgv/Makefile b/src/Demos/sgv/Makefile index c5d8b0008..044670043 100644 --- a/src/Demos/sgv/Makefile +++ b/src/Demos/sgv/Makefile @@ -14,7 +14,7 @@ TARGET_BIN_FILES = sgv #note, standard library list. LIBS = -losgGLUT -losgUtil -losgDB -losg $(GLUTLIB) -lGLU -lGL -lm -lXmu -lX11 -lXi -C++FLAGS += -I../../../include +C++FLAGS += -I../../../include -g LDFLAGS += -L../../../lib include ../../../Make/makerules diff --git a/src/Demos/sgv/sgv.cpp b/src/Demos/sgv/sgv.cpp index b8b8934af..ea7a952ba 100644 --- a/src/Demos/sgv/sgv.cpp +++ b/src/Demos/sgv/sgv.cpp @@ -2,6 +2,8 @@ #include #endif +#include +#include #include #include @@ -18,6 +20,173 @@ #include + +class TransformFunctor : public osg::Drawable::AttributeFunctor +{ + + public: + + osg::Matrix _m; + + TransformFunctor(const osg::Matrix& m): + AttributeFunctor(osg::Drawable::COORDS|osg::Drawable::NORMALS), + _m(m) {} + + virtual ~TransformFunctor() {} + + virtual bool apply(osg::Drawable::AttributeBitMask abm,osg::Vec3* begin,osg::Vec3* end) + { + if (abm == osg::Drawable::COORDS) + { + for (osg::Vec3* itr=begin;itr MatrixStack; + MatrixStack _matrixStack; + + typedef std::set TransformList; + TransformList _transformList; + + FlattenStaticTransformsVisitor():NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN) {} + + virtual void apply(osg::Geode& geode) + { + if (!_matrixStack.empty()) + { + TransformFunctor tf(_matrixStack.back()); + for(int i=0;iapplyAttributeOperation(tf); + } + } + } + + + virtual void apply(osg::Transform& transform) + { + if (_matrixStack.empty()) + { + _matrixStack.push_back(transform.getMatrix()); + } + else + { + _matrixStack.push_back(transform.getMatrix()*_matrixStack.back()); + } + + traverse(transform); + + _transformList.insert(&transform); + + // reset the matrix to identity. + transform.getMatrix().makeIdent(); + + _matrixStack.pop_back(); + } + + void removeTransforms() + { + for(TransformList::iterator itr=_transformList.begin(); + itr!=_transformList.end(); + ++itr) + { + osg::ref_ptr transform = *itr; + osg::ref_ptr group = new osg::Group; + + int i; + for(i=0;igetNumChildren();++i) + { + for(int j=0;jgetNumParents();++j) + { + group->addChild(transform->getChild(i)); + } + } + + for(i=transform->getNumParents()-1;i>=0;--i) + { + transform->getParent(i)->replaceChild(transform.get(),group.get()); + } + + } + _transformList.clear(); + } + +}; + + +class RemoveRedundentNodesVisitor : public osg::NodeVisitor +{ + public: + + typedef std::set NodeList; + NodeList _redundentNodeList; + + RemoveRedundentNodesVisitor():NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN) {} + + virtual void apply(osg::Group& group) + { + if (typeid(group)==typeid(osg::Group)) + { + if (group.getNumParents()>0 && group.getNumChildren()<=1) + { + _redundentNodeList.insert(&group); + } + } + traverse(group); + } + + + void removeRedundentNodes() + { + for(NodeList::iterator itr=_redundentNodeList.begin(); + itr!=_redundentNodeList.end(); + ++itr) + { + osg::ref_ptr group = dynamic_cast(*itr); + if (group.valid()) + { + + for(int j=group->getNumParents()-1;j>=0;--j) + { + for(int i=0;igetNumChildren();++i) + { + group->getParent(j)->addChild(group->getChild(i)); + } + group->getParent(j)->removeChild(group.get()); + } + } + } + _redundentNodeList.clear(); + } + +}; + + + + /* * Function to read several files (typically one) as specified on the command * line, and return them in an osg::Node @@ -141,8 +310,15 @@ int main( int argc, char **argv ) osv.optimize(); #endif - +/* + FlattenStaticTransformsVisitor fstv; + rootnode->accept(fstv); + fstv.removeTransforms(); + RemoveRedundentNodesVisitor rrnv; + rootnode->accept(rrnv); + rrnv.removeRedundentNodes(); +*/ // initialize the viewer. osgGLUT::Viewer viewer; viewer.addViewport( rootnode ); diff --git a/src/osg/GeoSet.cpp b/src/osg/GeoSet.cpp index 846269977..7de912fe8 100644 --- a/src/osg/GeoSet.cpp +++ b/src/osg/GeoSet.cpp @@ -129,7 +129,7 @@ void GeoSet::drawImmediateMode(State&) draw_alternate_path(); } -void GeoSet::computeNumVerts() +void GeoSet::computeNumVerts() const { int i; int numverts=0; @@ -294,9 +294,7 @@ const bool GeoSet::computeBound() const if( _numcoords == 0 ) { - // a dirty hack to cast away constness of this.. - GeoSet* gset = const_cast(this); - gset->computeNumVerts(); + computeNumVerts(); } if( _numcoords == 0 ) @@ -645,16 +643,17 @@ void GeoSet::setInterleavedArray( const InterleaveArrayType format, float *ia, I set_fast_path(); } -Drawable::AttributeBitMask GeoSet::suppportsAttributeUpdate() const +Drawable::AttributeBitMask GeoSet::suppportsAttributeOperation() const { // we do support coords,normals,texcoords and colors so return true. return COORDS | NORMALS | COLORS | TEXTURE_COORDS; } -Drawable::AttributeBitMask GeoSet::applyAttributeUpdate(AttributeBitMask amb,AttributeUpdateFunctor& auf) +Drawable::AttributeBitMask GeoSet::applyAttributeOperation(AttributeFunctor& auf) { - computeNumVerts(); + if (_numcoords == 0) computeNumVerts(); + AttributeBitMask amb = auf.getAttributeBitMask(); AttributeBitMask ramb = 0; if ((amb & COORDS) && _coords && _numcoords) @@ -671,12 +670,12 @@ Drawable::AttributeBitMask GeoSet::applyAttributeUpdate(AttributeBitMask amb,Att if (auf.apply(NORMALS,_normals,_normals+_numnormals)) ramb = NORMALS; } - if ((amb & COLORS) && _colors) + if ((amb & COLORS) && _colors && _numcolors) { if (auf.apply(COLORS,_colors,_colors+_numcolors)) ramb = COLORS; } - if ((amb & TEXTURE_COORDS) && _tcoords) + if ((amb & TEXTURE_COORDS) && _tcoords && _numtcoords) { if (auf.apply(TEXTURE_COORDS,_tcoords,_tcoords+_numtcoords)) ramb = TEXTURE_COORDS; }