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
Copyright (C) 2008 by Art Tevs (LGPL)