Show
Ignore:
Timestamp:
10/29/10 11:35:54 (4 years ago)
Author:
robert
Message:
 
Files:
1 modified

Legend:

Unmodified
Added
Removed
  • OpenSceneGraph/trunk/examples/osganalysis/osganalysis.cpp

    r11854 r11864  
    7373}; 
    7474 
     75class SwapArrayVisitor : public osg::ArrayVisitor 
     76{ 
     77public: 
     78    SwapArrayVisitor(osg::Array* array): 
     79        _array(array) {} 
     80 
     81    template <class ARRAY> 
     82    void apply_imp(ARRAY& array) 
     83    { 
     84        if (array.getType()!=_array->getType()) 
     85        { 
     86            OSG_NOTICE<<"Arrays incompatible"<<std::endl; 
     87            return; 
     88        } 
     89        OSG_NOTICE<<"Swapping Array"<<std::endl; 
     90        array.swap(*static_cast<ARRAY*>(_array)); 
     91    } 
     92 
     93    virtual void apply(osg::ByteArray& ba) { apply_imp(ba); } 
     94    virtual void apply(osg::ShortArray& ba) { apply_imp(ba); } 
     95    virtual void apply(osg::IntArray& ba) { apply_imp(ba); } 
     96    virtual void apply(osg::UByteArray& ba) { apply_imp(ba); } 
     97    virtual void apply(osg::UShortArray& ba) { apply_imp(ba); } 
     98    virtual void apply(osg::UIntArray& ba) { apply_imp(ba); } 
     99    virtual void apply(osg::Vec4ubArray& ba) { apply_imp(ba); } 
     100    virtual void apply(osg::FloatArray& ba) { apply_imp(ba); } 
     101    virtual void apply(osg::Vec2Array& ba) { apply_imp(ba); } 
     102    virtual void apply(osg::Vec3Array& ba) { apply_imp(ba); } 
     103    virtual void apply(osg::Vec4Array& ba) { apply_imp(ba); } 
     104 
     105    osg::Array* _array; 
     106}; 
     107 
     108class MemoryVisitor : public osg::NodeVisitor 
     109{ 
     110public: 
     111     MemoryVisitor(): 
     112         osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN) {} 
     113 
     114 
     115    void reset() 
     116    { 
     117         _nodes.clear(); 
     118         _geometryMap.clear(); 
     119         _arrayMap.clear(); 
     120         _primitiveSetMap.clear(); 
     121    } 
     122 
     123    void apply(osg::Node& node) 
     124    { 
     125        _nodes.insert(&node); 
     126        traverse(node); 
     127    } 
     128 
     129    void apply(osg::Geode& geode) 
     130    { 
     131        _nodes.insert(&geode); 
     132        for(unsigned int i=0; i<geode.getNumDrawables(); ++i) 
     133        { 
     134            apply(&geode, geode.getDrawable(i)); 
     135        } 
     136    } 
     137 
     138    void apply(osg::Geode* geode, osg::Drawable* drawable) 
     139    { 
     140        if (!drawable) return; 
     141 
     142        osg::Geometry* geometry = drawable->asGeometry(); 
     143        if (geometry) 
     144        { 
     145            _geometryMap[geometry].insert(geode); 
     146 
     147            apply(geometry, geometry->getVertexArray()); 
     148            apply(geometry, geometry->getNormalArray()); 
     149            apply(geometry, geometry->getColorArray()); 
     150            apply(geometry, geometry->getSecondaryColorArray()); 
     151            apply(geometry, geometry->getFogCoordArray()); 
     152 
     153            for(unsigned int i=0; i<geometry->getNumTexCoordArrays(); ++i) 
     154            { 
     155                apply(geometry, geometry->getTexCoordArray(i)); 
     156            } 
     157            for(unsigned int i=0; i<geometry->getNumVertexAttribArrays(); ++i) 
     158            { 
     159                apply(geometry, geometry->getVertexAttribArray(i)); 
     160            } 
     161 
     162            for(unsigned int i=0; i<geometry->getNumPrimitiveSets(); ++i) 
     163            { 
     164                apply(geometry, geometry->getPrimitiveSet(i)); 
     165            } 
     166        } 
     167    } 
     168 
     169    void apply(osg::Geometry* geometry, osg::Array* array) 
     170    { 
     171        if (!array) return; 
     172        _arrayMap[array].insert(geometry); 
     173    } 
     174 
     175    void apply(osg::Geometry* geometry, osg::PrimitiveSet* primitiveSet) 
     176    { 
     177        if (!primitiveSet) return; 
     178        _primitiveSetMap[primitiveSet].insert(geometry); 
     179    } 
     180 
     181    void report(std::ostream& out) 
     182    { 
     183        OSG_NOTICE<<"Nodes "<<_nodes.size()<<std::endl; 
     184        OSG_NOTICE<<"Geometries "<<_geometryMap.size()<<std::endl; 
     185        OSG_NOTICE<<"Arrays "<<_arrayMap.size()<<std::endl; 
     186        OSG_NOTICE<<"PrimitiveSets "<<_primitiveSetMap.size()<<std::endl; 
     187    } 
     188 
     189    void reallocate() 
     190    { 
     191        OSG_NOTICE<<"Reallocating Arrays"<<std::endl; 
     192 
     193        typedef std::vector< osg::ref_ptr<osg::Array> > ArrayVector; 
     194        typedef std::vector< osg::ref_ptr<osg::Geometry> > GeometryVector; 
     195        ArrayVector newArrays; 
     196        GeometryVector newGeometries; 
     197        for(GeometryMap::iterator itr = _geometryMap.begin(); 
     198            itr != _geometryMap.end(); 
     199            ++itr) 
     200        { 
     201            osg::Geometry* geometry = itr->first; 
     202            bool useVBO = geometry->getUseVertexBufferObjects(); 
     203            osg::Geometry* newGeometry = osg::clone(geometry, osg::CopyOp(osg::CopyOp::DEEP_COPY_ALL)); 
     204            newGeometry->setUseVertexBufferObjects(false); 
     205            newGeometry->setUseVertexBufferObjects(useVBO); 
     206            newGeometries.push_back(newGeometry); 
     207        } 
     208 
     209        GeometryVector::iterator geom_itr = newGeometries.begin(); 
     210        for(GeometryMap::iterator itr = _geometryMap.begin(); 
     211            itr != _geometryMap.end(); 
     212            ++itr, ++geom_itr) 
     213        { 
     214            osg::Geometry* geometry = itr->first; 
     215            Geodes& geodes = itr->second; 
     216            for(Geodes::iterator gitr = geodes.begin(); 
     217                gitr != geodes.end(); 
     218                ++gitr) 
     219            { 
     220                osg::Geode* geode = const_cast<osg::Geode*>(*gitr); 
     221                geode->replaceDrawable(geometry, geom_itr->get()); 
     222            } 
     223        } 
     224    } 
     225 
     226    typedef std::vector< osg::ref_ptr<osg::Geometry> > GeometryVector; 
     227    typedef std::pair<osg::Array*, osg::Array*> ArrayPair; 
     228    typedef std::vector< ArrayPair > ArrayVector; 
     229    typedef std::pair<osg::PrimitiveSet*, osg::PrimitiveSet*> PrimitiveSetPair; 
     230    typedef std::vector< PrimitiveSetPair > PrimitiveSetVector; 
     231 
     232    osg::Array* cloneArray(ArrayVector& arrayVector, osg::Array* array) 
     233    { 
     234        if (!array) return 0; 
     235        osg::Array* newArray = static_cast<osg::Array*>(array->cloneType()); 
     236        arrayVector.push_back(ArrayPair(array,newArray)); 
     237        return newArray; 
     238    } 
     239 
     240    osg::PrimitiveSet* clonePrimitiveSet(PrimitiveSetVector& psVector, osg::PrimitiveSet* ps) 
     241    { 
     242        if (!ps) return 0; 
     243        osg::PrimitiveSet* newPS = static_cast<osg::PrimitiveSet*>(ps->cloneType()); 
     244        psVector.push_back(PrimitiveSetPair(ps,newPS)); 
     245        return newPS; 
     246    } 
     247 
     248    void reallocate2() 
     249    { 
     250        OSG_NOTICE<<"Reallocating Arrays"<<std::endl; 
     251 
     252        ArrayVector arrayVector; 
     253        PrimitiveSetVector primitiveSetVector; 
     254        GeometryVector newGeometries; 
     255 
     256        for(GeometryMap::iterator itr = _geometryMap.begin(); 
     257            itr != _geometryMap.end(); 
     258            ++itr) 
     259        { 
     260            osg::Geometry* geometry = itr->first; 
     261            osg::ref_ptr<osg::Geometry> newGeometry = osg::clone(geometry, osg::CopyOp::SHALLOW_COPY); 
     262            newGeometries.push_back(newGeometry.get()); 
     263 
     264            newGeometry->setVertexArray(cloneArray(arrayVector, geometry->getVertexArray())); 
     265            newGeometry->setNormalArray(cloneArray(arrayVector, geometry->getNormalArray())); 
     266            newGeometry->setColorArray(cloneArray(arrayVector, geometry->getColorArray())); 
     267            newGeometry->setSecondaryColorArray(cloneArray(arrayVector, geometry->getSecondaryColorArray())); 
     268            newGeometry->setFogCoordArray(cloneArray(arrayVector, geometry->getFogCoordArray())); 
     269            for(unsigned int i=0; i<geometry->getNumTexCoordArrays(); ++i) 
     270            { 
     271                newGeometry->setTexCoordArray(i, cloneArray(arrayVector, geometry->getTexCoordArray(i))); 
     272            } 
     273            for(unsigned int i=0; i<geometry->getNumVertexAttribArrays(); ++i) 
     274            { 
     275                newGeometry->setVertexAttribArray(i, cloneArray(arrayVector, geometry->getVertexAttribArray(i))); 
     276            } 
     277 
     278            for(unsigned int i=0; i<geometry->getNumPrimitiveSets(); ++i) 
     279            { 
     280                newGeometry->setPrimitiveSet(i,clonePrimitiveSet(primitiveSetVector, geometry->getPrimitiveSet(i))); 
     281            } 
     282        } 
     283 
     284        GeometryVector::iterator geom_itr = newGeometries.begin(); 
     285        for(GeometryMap::iterator itr = _geometryMap.begin(); 
     286            itr != _geometryMap.end(); 
     287            ++itr, ++geom_itr) 
     288        { 
     289            osg::Geometry* geometry = itr->first; 
     290            Geodes& geodes = itr->second; 
     291            for(Geodes::iterator gitr = geodes.begin(); 
     292                gitr != geodes.end(); 
     293                ++gitr) 
     294            { 
     295                osg::Geode* geode = const_cast<osg::Geode*>(*gitr); 
     296                geode->replaceDrawable(geometry, geom_itr->get()); 
     297            } 
     298        } 
     299    } 
     300 
     301protected: 
     302 
     303     typedef std::set<osg::Node*>  Nodes; 
     304     typedef std::set<osg::Geode*>  Geodes; 
     305     typedef std::set<osg::Geometry*>  Geometries; 
     306     typedef std::map<osg::Geometry*, Geodes> GeometryMap; 
     307     typedef std::map<osg::Array*, Geometries> ArrayMap; 
     308     typedef std::map<osg::PrimitiveSet*, Geometries> PrimitiveSetMap; 
     309 
     310     Nodes              _nodes; 
     311     GeometryMap        _geometryMap; 
     312     ArrayMap           _arrayMap; 
     313     PrimitiveSetMap    _primitiveSetMap; 
     314}; 
     315 
    75316class SceneGraphProcessor : public osg::Referenced 
    76317{ 
     
    101342        while (arguments.read("--compress")) { modifyTextureSettings = true; compressImages = true; } 
    102343        while (arguments.read("--disable-mipmaps")) { modifyTextureSettings = true; disableMipmaps = true; } 
     344 
     345        while (arguments.read("--reallocate") || arguments.read("--ra") ) { reallocateMemory = true; } 
     346 
    103347 
    104348        OSG_NOTICE<<"simplificatioRatio="<<simplificatioRatio<<std::endl; 
     
    156400        } 
    157401 
     402        MemoryVisitor mv; 
     403        node->accept(mv); 
     404        mv.report(osg::notify(osg::NOTICE)); 
     405 
     406        if (reallocateMemory) 
     407        { 
     408            OSG_NOTICE<<"Running Reallocation of scene graph memory"<<std::endl; 
     409            mv.reallocate(); 
     410        } 
     411 
     412        mv.reset(); 
     413        node->accept(mv); 
     414        mv.report(osg::notify(osg::NOTICE)); 
     415 
    158416        return node; 
    159417    } 
     
    175433        optimizeVertexOrder = false; 
    176434 
     435        reallocateMemory = false; 
     436         
    177437        modifyTextureSettings = false; 
    178438        buildImageMipmaps = false; 
     
    193453    bool optimizeVertexOrder; 
    194454 
     455    bool reallocateMemory; 
     456     
    195457    bool modifyTextureSettings; 
    196458    bool buildImageMipmaps;