Changeset 13041 for OpenSceneGraph/trunk/include/osgUtil/Optimizer
- Timestamp:
- 03/21/12 18:36:20 (14 months ago)
- Files:
-
- 1 modified
-
OpenSceneGraph/trunk/include/osgUtil/Optimizer (modified) (43 diffs)
Legend:
- Unmodified
- Added
- Removed
-
OpenSceneGraph/trunk/include/osgUtil/Optimizer
r11987 r13041 1 /* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield 1 /* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield 2 2 * 3 * This library is open source and may be redistributed and/or modified under 4 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or 3 * This library is open source and may be redistributed and/or modified under 4 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or 5 5 * (at your option) any later version. The full license is in LICENSE file 6 6 * included with this distribution, and on the openscenegraph.org website. 7 * 7 * 8 8 * This library is distributed in the hope that it will be useful, 9 9 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 11 * OpenSceneGraph Public License for more details. 12 12 */ … … 45 45 inline bool isOperationPermissibleForObject(const osg::StateSet* object) const; 46 46 inline bool isOperationPermissibleForObject(const osg::StateAttribute* object) const; 47 inline bool isOperationPermissibleForObject(const osg::Drawable* object) const; 47 inline bool isOperationPermissibleForObject(const osg::Drawable* object) const; 48 48 inline bool isOperationPermissibleForObject(const osg::Node* object) const; 49 49 … … 57 57 * For example of usage see examples/osgimpostor or osgviewer. 58 58 */ 59 59 60 60 class OSGUTIL_EXPORT Optimizer 61 61 { … … 118 118 /** Reset internal data to initial state - the getPermissibleOptionsMap is cleared.*/ 119 119 void reset(); 120 120 121 121 /** Traverse the node and its subgraph with a series of optimization 122 122 * visitors, specified by the OptimizationOptions.*/ … … 128 128 129 129 130 /** Callback for customizing what operations are permitted on objects in the scene graph.*/ 130 /** Callback for customizing what operations are permitted on objects in the scene graph.*/ 131 131 struct IsOperationPermissibleForObjectCallback : public osg::Referenced 132 132 { … … 135 135 return optimizer->isOperationPermissibleForObjectImplementation(stateset,option); 136 136 } 137 137 138 138 virtual bool isOperationPermissibleForObjectImplementation(const Optimizer* optimizer, const osg::StateAttribute* attribute,unsigned int option) const 139 139 { 140 140 return optimizer->isOperationPermissibleForObjectImplementation(attribute,option); 141 141 } 142 142 143 143 virtual bool isOperationPermissibleForObjectImplementation(const Optimizer* optimizer, const osg::Drawable* drawable,unsigned int option) const 144 144 { 145 145 return optimizer->isOperationPermissibleForObjectImplementation(drawable,option); 146 146 } 147 147 148 148 virtual bool isOperationPermissibleForObjectImplementation(const Optimizer* optimizer, const osg::Node* node,unsigned int option) const 149 149 { 150 150 return optimizer->isOperationPermissibleForObjectImplementation(node,option); 151 151 } 152 153 }; 154 155 /** Set the callback for customizing what operations are permitted on objects in the scene graph.*/ 152 153 }; 154 155 /** Set the callback for customizing what operations are permitted on objects in the scene graph.*/ 156 156 void setIsOperationPermissibleForObjectCallback(IsOperationPermissibleForObjectCallback* callback) { _isOperationPermissibleForObjectCallback=callback; } 157 157 158 /** Get the callback for customizing what operations are permitted on objects in the scene graph.*/ 158 /** Get the callback for customizing what operations are permitted on objects in the scene graph.*/ 159 159 IsOperationPermissibleForObjectCallback* getIsOperationPermissibleForObjectCallback() { return _isOperationPermissibleForObjectCallback.get(); } 160 160 161 /** Get the callback for customizing what operations are permitted on objects in the scene graph.*/ 161 /** Get the callback for customizing what operations are permitted on objects in the scene graph.*/ 162 162 const IsOperationPermissibleForObjectCallback* getIsOperationPermissibleForObjectCallback() const { return _isOperationPermissibleForObjectCallback.get(); } 163 163 … … 167 167 _permissibleOptimizationsMap[object] = options; 168 168 } 169 169 170 170 inline unsigned int getPermissibleOptimizationsForObject(const osg::Object* object) const 171 171 { … … 180 180 if (_isOperationPermissibleForObjectCallback.valid()) 181 181 return _isOperationPermissibleForObjectCallback->isOperationPermissibleForObjectImplementation(this,object,option); 182 else 183 return isOperationPermissibleForObjectImplementation(object,option); 182 else 183 return isOperationPermissibleForObjectImplementation(object,option); 184 184 } 185 185 … … 188 188 if (_isOperationPermissibleForObjectCallback.valid()) 189 189 return _isOperationPermissibleForObjectCallback->isOperationPermissibleForObjectImplementation(this,object,option); 190 else 191 return isOperationPermissibleForObjectImplementation(object,option); 190 else 191 return isOperationPermissibleForObjectImplementation(object,option); 192 192 } 193 193 … … 196 196 if (_isOperationPermissibleForObjectCallback.valid()) 197 197 return _isOperationPermissibleForObjectCallback->isOperationPermissibleForObjectImplementation(this,object,option); 198 else 199 return isOperationPermissibleForObjectImplementation(object,option); 198 else 199 return isOperationPermissibleForObjectImplementation(object,option); 200 200 } 201 201 … … 204 204 if (_isOperationPermissibleForObjectCallback.valid()) 205 205 return _isOperationPermissibleForObjectCallback->isOperationPermissibleForObjectImplementation(this,object,option); 206 else 207 return isOperationPermissibleForObjectImplementation(object,option); 206 else 207 return isOperationPermissibleForObjectImplementation(object,option); 208 208 } 209 209 … … 212 212 return (option & getPermissibleOptimizationsForObject(stateset))!=0; 213 213 } 214 214 215 215 bool isOperationPermissibleForObjectImplementation(const osg::StateAttribute* attribute, unsigned int option) const 216 216 { … … 246 246 return (option & getPermissibleOptimizationsForObject(node))!=0; 247 247 } 248 248 249 249 protected: 250 250 … … 252 252 253 253 typedef std::map<const osg::Object*,unsigned int> PermissibleOptimizationsMap; 254 PermissibleOptimizationsMap _permissibleOptimizationsMap; 255 254 PermissibleOptimizationsMap _permissibleOptimizationsMap; 255 256 256 public: 257 257 258 258 /** Flatten Static Transform nodes by applying their transform to the 259 * geometry on the leaves of the scene graph, then removing the 259 * geometry on the leaves of the scene graph, then removing the 260 260 * now redundant transforms. Static transformed Subgraphs that have multiple 261 261 * parental paths above them are not flattened, if you require this then 262 * the subgraphs have to be duplicated - for this use the 262 * the subgraphs have to be duplicated - for this use the 263 263 * FlattenStaticTransformsDuplicatingSharedSubgraphsVisitor. */ 264 264 class OSGUTIL_EXPORT FlattenStaticTransformsVisitor : public BaseOptimizerVisitor … … 285 285 typedef std::set<osg::Node* > NodeSet; 286 286 typedef std::set<osg::Transform*> TransformSet; 287 287 288 288 TransformStack _transformStack; 289 289 NodeSet _excludedNodeSet; … … 299 299 * of duplicated and flatten individually. This results in more static transforms 300 300 * being removed, but also means that more data is generated, and as a result may 301 * not always be the most appropriate flatten visitor to use.*/ 301 * not always be the most appropriate flatten visitor to use.*/ 302 302 class OSGUTIL_EXPORT FlattenStaticTransformsDuplicatingSharedSubgraphsVisitor : public BaseOptimizerVisitor 303 303 { … … 325 325 }; 326 326 327 /** Combine Static Transform nodes that sit above one another.*/ 327 /** Combine Static Transform nodes that sit above one another.*/ 328 328 class OSGUTIL_EXPORT CombineStaticTransformsVisitor : public BaseOptimizerVisitor 329 329 { … … 357 357 virtual void apply(osg::Geode& geode); 358 358 virtual void apply(osg::Group& group); 359 359 360 360 void removeEmptyNodes(); 361 361 … … 372 372 RemoveRedundantNodesVisitor(Optimizer* optimizer=0): 373 373 BaseOptimizerVisitor(optimizer, REMOVE_REDUNDANT_NODES) {} 374 374 375 375 virtual void apply(osg::Group& group); 376 376 virtual void apply(osg::Transform& transform); 377 377 378 378 bool isOperationPermissible(osg::Node& node); 379 379 380 380 void removeRedundantNodes(); 381 381 … … 392 392 RemoveLoadedProxyNodesVisitor(Optimizer* optimizer=0): 393 393 BaseOptimizerVisitor(optimizer, REMOVE_LOADED_PROXY_NODES) {} 394 394 395 395 virtual void apply(osg::ProxyNode& group); 396 396 397 397 void removeRedundantNodes(); 398 398 … … 431 431 432 432 }; 433 433 434 434 /** Optimize State in the scene graph by removing duplicate state, 435 435 * replacing it with shared instances, both for StateAttributes, … … 451 451 } 452 452 453 /** empty visitor, make it ready for next traversal.*/ 453 /** empty visitor, make it ready for next traversal.*/ 454 454 virtual void reset(); 455 455 … … 463 463 464 464 void addStateSet(osg::StateSet* stateset,osg::Object* obj); 465 465 466 466 inline bool optimize(osg::Object::DataVariance variance) 467 467 { … … 474 474 // note, one element for DYNAMIC, STATIC and UNSPECIFIED 475 475 bool _optimize[3]; 476 476 477 477 StateSetMap _statesets; 478 478 … … 510 510 511 511 void checkGeode(osg::Geode& geode); 512 513 }; 514 512 513 }; 514 515 515 class OSGUTIL_EXPORT MakeFastGeometryVisitor : public BaseOptimizerVisitor 516 516 { … … 524 524 525 525 void checkGeode(osg::Geode& geode); 526 527 }; 528 526 527 }; 528 529 529 class OSGUTIL_EXPORT MergeGeometryVisitor : public BaseOptimizerVisitor 530 530 { … … 540 540 _targetMaximumNumberOfVertices = num; 541 541 } 542 542 543 543 unsigned int getTargetMaximumNumberOfVertices() const 544 544 { … … 574 574 SpatializeGroupsVisitor(Optimizer* optimizer=0): 575 575 BaseOptimizerVisitor(optimizer, SPATIALIZE_GROUPS) {} 576 576 577 577 virtual void apply(osg::Group& group); 578 578 virtual void apply(osg::Geode& geode); 579 579 580 580 bool divide(unsigned int maxNumTreesPerCell=8); 581 581 582 582 bool divide(osg::Group* group, unsigned int maxNumTreesPerCell); 583 583 bool divide(osg::Geode* geode, unsigned int maxNumTreesPerCell); 584 584 585 585 typedef std::set<osg::Group*> GroupsToDivideList; 586 586 GroupsToDivideList _groupsToDivideList; … … 597 597 CopySharedSubgraphsVisitor(Optimizer* optimizer=0): 598 598 BaseOptimizerVisitor(optimizer, COPY_SHARED_NODES) {} 599 599 600 600 virtual void apply(osg::Node& node); 601 601 602 602 void copySharedNodes(); 603 603 604 604 typedef std::set<osg::Node*> SharedNodeList; 605 605 SharedNodeList _sharedNodeList; 606 606 607 607 }; 608 608 … … 621 621 _changeClientImageStorage(changeClientImageStorage), _valueClientImageStorage(valueClientImageStorage), 622 622 _changeAnisotropy(changeAnisotropy), _valueAnisotropy(valueAnisotropy) {} 623 623 624 624 virtual void apply(osg::Geode& node); 625 625 virtual void apply(osg::Node& node); … … 634 634 635 635 }; 636 636 637 637 /** Flatten MatrixTransform/Billboard pairs.*/ 638 638 class OSGUTIL_EXPORT FlattenBillboardVisitor : public BaseOptimizerVisitor … … 649 649 virtual void apply(osg::Billboard& billboard); 650 650 651 void process(); 651 void process(); 652 652 653 653 BillboardNodePathMap _billboards; 654 654 655 655 }; 656 656 657 657 /** Texture Atlas Builder creates a set of textures/images which each contain multiple images. 658 658 * Texture Atlas' are used to make it possible to use much wider batching of data. */ … … 661 661 public: 662 662 TextureAtlasBuilder(); 663 663 664 664 void reset(); 665 665 666 666 void setMaximumAtlasSize(int width, int height); 667 667 668 668 int getMaximumAtlasWidth() const { return _maximumAtlasWidth; } 669 669 int getMaximumAtlasHeight() const { return _maximumAtlasHeight; } 670 670 671 671 void setMargin(int margin); 672 672 int getMargin() const { return _margin; } … … 674 674 void addSource(const osg::Image* image); 675 675 void addSource(const osg::Texture2D* texture); 676 676 677 677 unsigned int getNumSources() const { return _sourceList.size(); } 678 678 const osg::Image* getSourceImage(unsigned int i) { return _sourceList[i]->_image.get(); } 679 679 const osg::Texture2D* getSourceTexture(unsigned int i) { return _sourceList[i]->_texture.get(); } 680 680 681 681 void buildAtlas(); 682 682 osg::Image* getImageAtlas(unsigned int i); 683 683 osg::Texture2D* getTextureAtlas(unsigned int i); 684 684 osg::Matrix getTextureMatrix(unsigned int i); 685 685 686 686 osg::Image* getImageAtlas(const osg::Image* image); 687 687 osg::Texture2D* getTextureAtlas(const osg::Image* image); 688 688 osg::Matrix getTextureMatrix(const osg::Image* image); 689 689 690 690 osg::Image* getImageAtlas(const osg::Texture2D* textue); 691 691 osg::Texture2D* getTextureAtlas(const osg::Texture2D* texture); 692 692 osg::Matrix getTextureMatrix(const osg::Texture2D* texture); 693 693 694 694 protected: 695 695 696 696 int _maximumAtlasWidth; 697 697 int _maximumAtlasHeight; 698 698 int _margin; 699 699 700 700 701 701 // forward declare 702 702 class Atlas; 703 703 704 704 class Source : public osg::Referenced 705 705 { … … 713 713 Source(const osg::Texture2D* texture): 714 714 _x(0),_y(0),_atlas(0),_texture(texture) { if (texture) _image = texture->getImage(); } 715 715 716 716 int _x; 717 717 int _y; … … 720 720 osg::ref_ptr<const osg::Image> _image; 721 721 osg::ref_ptr<const osg::Texture2D> _texture; 722 722 723 723 bool suitableForAtlas(int maximumAtlasWidth, int maximumAtlasHeight, int margin); 724 724 osg::Matrix computeTextureMatrix() const; 725 726 727 protected: 728 725 726 727 protected: 728 729 729 virtual ~Source() {} 730 730 }; … … 744 744 _height(0), 745 745 _indexFirstOfRow(0){} 746 746 747 747 int _maximumAtlasWidth; 748 748 int _maximumAtlasHeight; … … 751 751 osg::ref_ptr<osg::Texture2D> _texture; 752 752 osg::ref_ptr<osg::Image> _image; 753 753 754 754 SourceList _sourceList; 755 755 756 756 int _x; 757 757 int _y; … … 769 769 void clampToNearestPowerOfTwoSize(); 770 770 void copySources(); 771 771 772 772 protected: 773 773 virtual ~Atlas() {} 774 774 }; 775 775 776 776 typedef std::vector< osg::ref_ptr<Atlas> > AtlasList; 777 777 778 778 Source* getSource(const osg::Image* image); 779 779 Source* getSource(const osg::Texture2D* texture); … … 792 792 }; 793 793 794 795 /** Optimize texture usage in the scene graph by combining textures into texture atlas 794 795 /** Optimize texture usage in the scene graph by combining textures into texture atlas 796 796 * Use of texture atlas cuts down on the number of seperate states in the scene, reducing 797 797 * state changes and improving the chances of use larger batches of geomertry.*/ … … 807 807 TextureAtlasBuilder& getTextureAtlasBuilder() { return _builder; } 808 808 809 /** empty visitor, make it ready for next traversal.*/ 809 /** empty visitor, make it ready for next traversal.*/ 810 810 virtual void reset(); 811 811 … … 851 851 852 852 void applyStateSet(osg::StateSet& stateset); 853 853 854 854 void applyDrawable(osg::Drawable& drawable); 855 855 … … 859 859 inline bool BaseOptimizerVisitor::isOperationPermissibleForObject(const osg::StateSet* object) const 860 860 { 861 return _optimizer ? _optimizer->isOperationPermissibleForObject(object,_operationType) : true; 861 return _optimizer ? _optimizer->isOperationPermissibleForObject(object,_operationType) : true; 862 862 } 863 863 864 864 inline bool BaseOptimizerVisitor::isOperationPermissibleForObject(const osg::StateAttribute* object) const 865 865 { 866 return _optimizer ? _optimizer->isOperationPermissibleForObject(object,_operationType) : true; 866 return _optimizer ? _optimizer->isOperationPermissibleForObject(object,_operationType) : true; 867 867 } 868 868 869 869 inline bool BaseOptimizerVisitor::isOperationPermissibleForObject(const osg::Drawable* object) const 870 870 { 871 return _optimizer ? _optimizer->isOperationPermissibleForObject(object,_operationType) : true; 871 return _optimizer ? _optimizer->isOperationPermissibleForObject(object,_operationType) : true; 872 872 } 873 873 874 874 inline bool BaseOptimizerVisitor::isOperationPermissibleForObject(const osg::Node* object) const 875 875 { 876 return _optimizer ? _optimizer->isOperationPermissibleForObject(object,_operationType) : true; 876 return _optimizer ? _optimizer->isOperationPermissibleForObject(object,_operationType) : true; 877 877 } 878 878
