Visitor.h

00001 /***************************************************************************
00002  *   Copyright (c) 2008   Art Tevs                                         *
00003  *                                                                         *
00004  *   This library is free software; you can redistribute it and/or modify  *
00005  *   it under the terms of the GNU Lesser General Public License as        *
00006  *   published by the Free Software Foundation; either version 3 of        *
00007  *   the License, or (at your option) any later version.                   *
00008  *                                                                         *
00009  *   This library is distributed in the hope that it will be useful,       *
00010  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00011  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00012  *   GNU Lesse General Public License for more details.                    *
00013  *                                                                         *
00014  *   The full license is in LICENSE file included with this distribution.  *
00015  ***************************************************************************/
00016 #ifndef _C_VISITOR__H_
00017 #define _C_VISITOR__H_
00018 
00019 //-------------------------------------------------------------------------
00020 // Includes
00021 //-------------------------------------------------------------------------
00022 #include <osgPPU/Export.h>
00023 #include <osgPPU/Processor.h>
00024 #include <osgPPU/Unit.h>
00025 #include <osg/NodeVisitor>
00026 #include <osg/Group>
00027 #include <osgUtil/CullVisitor>
00028 #include <queue>
00029 #include <list>
00030 
00031 namespace osgPPU
00032 {
00033 
00034 //------------------------------------------------------------------------------
00035 // Base class for all unit visitors
00036 //------------------------------------------------------------------------------
00037 class OSGPPU_EXPORT UnitVisitor : public osg::NodeVisitor
00038 {
00039     public:
00040         virtual void run(osg::Group* root) { root->traverse(*this); }
00041         inline  void run(osg::Group& root) { run(&root); }
00042 
00043         virtual const char* getVisitorName() { return ""; }
00044 
00045         static OpenThreads::Mutex s_mutex_changeUnitSubgraph;
00046 };
00047 
00048 //------------------------------------------------------------------------------
00049 // Visitor to set update traversed flag to false
00050 //------------------------------------------------------------------------------
00051 class OSGPPU_EXPORT CleanUpdateTraversedVisitor : public UnitVisitor
00052 {
00053 public:
00054 
00055     CleanUpdateTraversedVisitor() : UnitVisitor()
00056     {
00057     }
00058 
00059     void apply (osg::Group &node)
00060     {
00061         Unit* unit = dynamic_cast<Unit*>(&node);
00062         if (unit) unit->mbUpdateTraversed = false;
00063         node.traverse(*this);
00064     }
00065 
00066     void run (osg::Group* root);
00067 
00068     const char* getVisitorName() { return "CleanUpdateTraversedVisitor"; }
00069     static osg::ref_ptr<CleanUpdateTraversedVisitor> sVisitor;
00070 
00071 private:
00072     OpenThreads::Mutex _mutex;
00073 };
00074 
00075 //------------------------------------------------------------------------------
00076 // Visitor to set update traversed flag to false
00077 //------------------------------------------------------------------------------
00078 class OSGPPU_EXPORT CleanCullTraversedVisitor : public UnitVisitor
00079 {
00080 public:
00081 
00082     CleanCullTraversedVisitor() : UnitVisitor()
00083     {
00084     }
00085 
00086     void apply (osg::Group &node);
00087 
00088     void run (osg::Group* root);
00089 
00090     const char* getVisitorName() { return "CleanCullTraversedVisitor"; }
00091     static osg::ref_ptr<CleanCullTraversedVisitor> sVisitor;
00092 
00093 private:
00094     OpenThreads::Mutex _mutex;
00095 };
00096 
00097 
00098 //------------------------------------------------------------------------------
00099 // Helper visitor to setup maximum number of input attachments
00100 //------------------------------------------------------------------------------
00101 class OSGPPU_EXPORT SetMaximumInputsVisitor : public UnitVisitor
00102 {
00103 public:
00104 
00105     SetMaximumInputsVisitor(unsigned int max) : UnitVisitor()
00106     {
00107         mMaxUnitInputIndex = max;
00108     }
00109 
00110     void apply (osg::Group &node);
00111     void run (osg::Group* root);
00112 
00113     const char* getVisitorName() { return "SetMaximumInputsVisitor"; }
00114 
00115 private:
00116     unsigned int mMaxUnitInputIndex;
00117 };
00118 
00119 
00120 //------------------------------------------------------------------------------
00121 // Visitor to find a certain unit in the unit graph
00122 //------------------------------------------------------------------------------
00123 class OSGPPU_EXPORT FindUnitVisitor : public UnitVisitor
00124 {
00125 public:
00126 
00127     FindUnitVisitor(const std::string& name) : UnitVisitor(),
00128         _name(name), _result(NULL)
00129     {
00130     }
00131 
00132     void apply (osg::Group &node)
00133     {
00134         // first check if we have already visited that node, if yes, it might be a loop in the graph, so don't go further
00135         if (std::find(_visitedNodes.begin(), _visitedNodes.end(), &node) != _visitedNodes.end()) return;
00136         
00137         Unit* unit = dynamic_cast<Unit*>(&node);
00138         if (unit && unit->getName() == _name)
00139             _result = unit;
00140         else
00141         {
00142             _visitedNodes.push_back(&node);
00143             node.traverse(*this);
00144         }
00145     }
00146 
00147     Unit* getResult() { return _result; }
00148 
00149     const char* getVisitorName() { return "FindUnitVisitor"; }
00150 private:
00151     std::string _name;
00152     Unit* _result;
00153     std::vector<osg::Group*> _visitedNodes;
00154 };
00155 
00156 //------------------------------------------------------------------------------
00157 // Visitor to find and remove certain unit from the unit graph
00158 // all inputs of the unit are placed as inputs to children units
00159 //------------------------------------------------------------------------------
00160 class OSGPPU_EXPORT RemoveUnitVisitor : public UnitVisitor
00161 {
00162 public:
00163 
00164     RemoveUnitVisitor() : UnitVisitor()
00165     {
00166     }
00167 
00168     void run (osg::Group* root);
00169 
00170     const char* getVisitorName() { return "RemoveUnitVisitor"; }
00171 };
00172 
00173 
00174 //------------------------------------------------------------------------------
00175 // Visitor to optimize unit subgraph
00176 //------------------------------------------------------------------------------
00177 class OSGPPU_EXPORT OptimizeUnitsVisitor : public UnitVisitor
00178 {
00179 public:
00180 
00181     OptimizeUnitsVisitor() : UnitVisitor(),
00182         _maxUnitInputIndex(0)
00183     {
00184     }
00185 
00186     void apply (osg::Group &node);
00187     void run (osg::Group* root);
00188 
00189     const char* getVisitorName() { return "OptimizeUnitsVisitor"; }
00190 private:
00191     unsigned _maxUnitInputIndex;
00192 };
00193 
00194 //------------------------------------------------------------------------------
00195 // Visitor to resolve all cycles in the unit graph
00196 // This will add BarrierNodes where they are needed
00197 //------------------------------------------------------------------------------
00198 class OSGPPU_EXPORT ResolveUnitsCyclesVisitor : public UnitVisitor
00199 {
00200 public:
00201 
00202     ResolveUnitsCyclesVisitor() : UnitVisitor()
00203     {
00204     }
00205 
00206     void apply (osg::Group &node);
00207     void run (osg::Group* root);
00208 
00209     const char* getVisitorName() { return "ResolveUnitsCyclesVisitor"; }
00210 };
00211 
00212 //------------------------------------------------------------------------------
00213 // Visitor used to setup all units in a correct order in an appropriate rendering bin
00214 // every unit will also be initialized
00215 //------------------------------------------------------------------------------
00216 class OSGPPU_EXPORT SetupUnitRenderingVisitor : public UnitVisitor
00217 {
00218 public:
00219 
00220     SetupUnitRenderingVisitor(Processor* proc) : UnitVisitor(), _proc(proc)
00221     {
00222     }
00223 
00224     void apply (osg::Group &node);
00225     void run (osg::Group* root);
00226 
00227     const char* getVisitorName() { return "SetupUnitRenderingVisitor"; }
00228 private:
00229     typedef std::list<Unit*> UnitSet;
00230     Processor* _proc;
00231     UnitSet mUnitSet;
00232 };
00233 
00234 
00235 //--------------------------------------------------------------------------
00236 // Helper class to find the processor
00237 //--------------------------------------------------------------------------
00238 class OSGPPU_EXPORT FindProcessorVisitor: public UnitVisitor
00239 {
00240 public:
00241     FindProcessorVisitor() : UnitVisitor(), _processor(NULL)
00242     {
00243         setTraversalMode(osg::NodeVisitor::TRAVERSE_PARENTS);
00244     }
00245 
00246     void apply(osg::Group& node)
00247     {
00248         _processor = dynamic_cast<osgPPU::Processor*>(&node);
00249         if (_processor == NULL) traverse(node);
00250     }
00251 
00252     osgPPU::Processor* _processor;
00253 
00254     const char* getVisitorName() { return "FindProcessorVisitor"; }
00255 };
00256 
00257 //------------------------------------------------------------------------------
00258 // Mark every unit in the graph as dirty
00259 //------------------------------------------------------------------------------
00260 class OSGPPU_EXPORT MarkUnitsDirtyVisitor : public UnitVisitor
00261 {
00262 public:
00263 
00264     MarkUnitsDirtyVisitor() : UnitVisitor()
00265     {
00266     }
00267 
00268     void apply (osg::Group &node);
00269     void run (osg::Group* root);
00270 
00271     const char* className() { return "MarkUnitsDirtyVisitor"; }
00272 private:
00273     OpenThreads::Mutex _mutex;
00274 };
00275 
00276 //------------------------------------------------------------------------------
00277 // Remove viewports on units which has -1 as index for viewport reference
00278 //------------------------------------------------------------------------------
00279 class OSGPPU_EXPORT RemoveUnitsViewportsVisitor : public UnitVisitor
00280 {
00281 public:
00282 
00283     RemoveUnitsViewportsVisitor(int index = -1) : UnitVisitor(), _index(index)
00284     {
00285     }
00286 
00287     void apply (osg::Group &node);
00288     void run (osg::Group* root);
00289 
00290     const char* className() { return "RemoveUnitsViewportsVisitor"; }
00291 private:
00292     OpenThreads::Mutex _mutex;
00293     int _index;
00294 };
00295 
00296 }; // end namespace
00297 
00298 #endif

Back to Homepage of osgPPU

Copyright (C) 2008 by Art Tevs (LGPL)