SceneGraph.hh

00001 /*===========================================================================*\
00002  *                                                                           *
00003  *                              OpenFlipper                                  *
00004  *      Copyright (C) 2001-2009 by Computer Graphics Group, RWTH Aachen      *
00005  *                           www.openflipper.org                             *
00006  *                                                                           *
00007  *---------------------------------------------------------------------------*
00008  *  This file is part of OpenFlipper.                                        *
00009  *                                                                           *
00010  *  OpenFlipper is free software: you can redistribute it and/or modify      *
00011  *  it under the terms of the GNU Lesser General Public License as           *
00012  *  published by the Free Software Foundation, either version 3 of           *
00013  *  the License, or (at your option) any later version with the              *
00014  *  following exceptions:                                                    *
00015  *                                                                           *
00016  *  If other files instantiate templates or use macros                       *
00017  *  or inline functions from this file, or you compile this file and         *
00018  *  link it with other files to produce an executable, this file does        *
00019  *  not by itself cause the resulting executable to be covered by the        *
00020  *  GNU Lesser General Public License. This exception does not however       *
00021  *  invalidate any other reasons why the executable file might be            *
00022  *  covered by the GNU Lesser General Public License.                        *
00023  *                                                                           *
00024  *  OpenFlipper is distributed in the hope that it will be useful,           *
00025  *  but WITHOUT ANY WARRANTY; without even the implied warranty of           *
00026  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            *
00027  *  GNU Lesser General Public License for more details.                      *
00028  *                                                                           *
00029  *  You should have received a copy of the GNU LesserGeneral Public          *
00030  *  License along with OpenFlipper. If not,                                  *
00031  *  see <http://www.gnu.org/licenses/>.                                      *
00032  *                                                                           *
00033 \*===========================================================================*/
00034 
00035 /*===========================================================================*\
00036  *                                                                           *
00037  *   $Revision: 8548 $                                                       *
00038  *   $Author: moebius $                                                      *
00039  *   $Date: 2010-02-12 14:40:13 +0100 (Fr, 12. Feb 2010) $                   *
00040  *                                                                           *
00041 \*===========================================================================*/
00042 
00043 
00044 
00045 
00046 //=============================================================================
00047 //
00048 //  CLASS SceneGraph
00049 //
00050 //=============================================================================
00051 
00052 #ifndef ACG_SCENEGRAPH_HH
00053 #define ACG_SCENEGRAPH_HH
00054 
00055 
00056 //== INCLUDES =================================================================
00057 
00058 #include "BaseNode.hh"
00059 #include "DrawModes.hh"
00060 #include "../GL/gl.hh"
00061 #include "../Math/VectorT.hh"
00062 #include <float.h>
00063 
00064 #include <QMouseEvent>
00065 
00066 //== NAMESPACES ===============================================================
00067 
00068 namespace ACG {
00069 namespace SceneGraph {
00070 
00071 
00072 //== CLASS DEFINITION =========================================================
00073 
00077 template<bool C, typename T = void>
00078 struct enable_if {
00079   typedef T type;
00080 };
00081 
00082 template<typename T>
00083 struct enable_if<false, T> { };
00084 
00085 #define HAS_MEM_FUNC(func) \
00086     template<typename T, typename Sign>                                               \
00087     struct has_##func {                                                               \
00088         template <typename U, U> struct type_check;                                   \
00089         template <typename _1> static char (& chk(type_check<Sign, &_1::func> *))[1]; \
00090         template <typename   > static char (& chk(...))[2];                           \
00091         static bool const value = sizeof(chk<T>(0)) == 1;                             \
00092     };
00093 
00094 HAS_MEM_FUNC(enter)
00095 
00096 // if the enter function is implemented
00097 template<typename Action>
00098 typename enable_if<has_enter <Action, void (Action::*) (BaseNode *) >::value, void>::type
00099 if_has_enter(Action &_action, BaseNode *_node) {
00100   _action.enter (_node);
00101 }
00102 
00103 // if the enter function isn't implemented
00104 template<typename Action>
00105 typename enable_if<!has_enter <Action, void (Action::*) (BaseNode *) >::value, void>::type
00106 if_has_enter(Action &, BaseNode *) {
00107 }
00108 
00109 HAS_MEM_FUNC(leave)
00110 
00111 // if the enter function is implemented
00112 template<typename Action>
00113 typename enable_if<has_leave <Action, void (Action::*) (BaseNode *) >::value, void>::type
00114 if_has_leave(Action &_action, BaseNode *_node) {
00115   _action.leave (_node);
00116 }
00117 
00118 // if the enter function isn't implemented
00119 template<typename Action>
00120 typename enable_if<!has_enter <Action, void (Action::*) (BaseNode *) >::value, void>::type
00121 if_has_leave(Action &, BaseNode *) {
00122 }
00123 
00124 //----------------------------------------------------------------------------
00125 
00126 
00131 template <class Action>
00132 void
00133 traverse( BaseNode* _node, Action& _action )
00134 {
00135   if (_node)
00136   {
00137     BaseNode::StatusMode status(_node->status());
00138     bool process_children(status != BaseNode::HideChildren);
00139 
00140     // If the subtree is hidden, ignore this node and its children while rendering
00141     if (status != BaseNode::HideSubtree)
00142     {
00143 
00144       // If the node itself is hidden, ignore it but continue with its children
00145       if (_node->status() != BaseNode::HideNode)
00146       {
00147         // Executes this nodes enter function (if available)
00148         if_has_enter (_action, _node);
00149 
00150         // Test rendering order. If NodeFirst, execute this node and the children later.
00151         if (_node->traverseMode() & BaseNode::NodeFirst)
00152           process_children &= _action(_node);
00153       }
00154 
00155       if (process_children)
00156       {
00157 
00158         BaseNode::ChildIter cIt, cEnd(_node->childrenEnd());
00159 
00160         // Process all children which are not second pass
00161         for (cIt = _node->childrenBegin(); cIt != cEnd; ++cIt)
00162           if (~(*cIt)->traverseMode() & BaseNode::SecondPass)
00163             traverse(*cIt, _action);
00164 
00165         // Process all children which are second pass
00166         for (cIt = _node->childrenBegin(); cIt != cEnd; ++cIt)
00167           if ((*cIt)->traverseMode() & BaseNode::SecondPass)
00168             traverse(*cIt, _action);
00169 
00170       }
00171 
00172       // If the node is not hidden
00173       if (_node->status() != BaseNode::HideNode)
00174       {
00175 
00176         // If the children had to be rendered first, we now render the node afterwards
00177         if (_node->traverseMode() & BaseNode::ChildrenFirst)
00178           _action(_node);
00179 
00180         // Call the leave function of the node.
00181         if_has_leave (_action, _node);
00182       }
00183 
00184     }
00185   }
00186 }
00187 
00188 //---------------------------------------------------------------------------------
00189 
00197 template <class Action>
00198 void
00199 traverse_multipass ( BaseNode* _node, Action& _action, const unsigned int& _pass )
00200 {
00201     // Process node if it exists
00202     if (_node) {
00203         BaseNode::StatusMode status(_node->status());
00204         bool process_children(status != BaseNode::HideChildren);
00205 
00206         // If the subtree is hidden, ignore this node and its children while rendering
00207         if (status != BaseNode::HideSubtree) {
00208 
00209             // Executes this nodes enter function (if available and active in multipass)
00210             if ( _node->multipassStatusActive(_pass) )
00211               if_has_enter(_action, _node);
00212 
00213             // If the node itself is hidden, don't call the action on it.
00214             // Additionally check if rendering order is node first. otherwise, we will call it after the children.
00215             // And check if it should be called in this rendering pass.
00216             if ( (_node->status() != BaseNode::HideNode )  && ( _node->traverseMode() & BaseNode::NodeFirst ) && _node->multipassNodeActive(_pass))
00217                 process_children &= _action(_node);
00218 
00219             if (process_children) {
00220 
00221                 BaseNode::ChildIter cIt, cEnd(_node->childrenEnd());
00222 
00223                 // Process all children
00224                 for (cIt = _node->childrenBegin(); cIt != cEnd; ++cIt)
00225                     if (~(*cIt)->traverseMode() & BaseNode::SecondPass)
00226                         traverse_multipass(*cIt, _action, _pass);
00227 
00228                 // Process all children which are second pass
00229                 for (cIt = _node->childrenBegin(); cIt != cEnd; ++cIt)
00230                     if ((*cIt)->traverseMode() & BaseNode::SecondPass)
00231                         traverse_multipass(*cIt, _action, _pass);
00232 
00233             }
00234 
00235             
00236             // If we are in childrenfirst node, the children have been painted andwe now check, if we can draw this node.
00237             // If its hidden, ignore it.
00238             // If it should not be rendered in this pass, ignore it too.
00239             if ( (_node->traverseMode() & BaseNode::ChildrenFirst ) && (_node->status() != BaseNode::HideNode) && _node->multipassNodeActive(_pass) )
00240                 _action(_node);
00241 
00242             // Call the leave function of the node (if available and active in multipass).
00243             if ( _node->multipassStatusActive(_pass) )
00244               if_has_leave(_action, _node);
00245 
00246         } // if (status != BaseNode::HideSubtree)
00247     } // if(node_)
00248 }
00249 
00250 //----------------------------------------------------------------------------
00251 
00257 template <class Action>
00258 class MetaAction
00259 {
00260   public:
00261     MetaAction (Action & _action, GLState& _state, DrawModes::DrawMode _drawMode) :
00262       action_(_action),
00263       state_(_state),
00264       drawMode_(_drawMode)
00265     {
00266     }
00267 
00268     bool operator()(BaseNode* _node)
00269     {
00270       return action_(_node, state_);
00271     }
00272 
00273     void enter (BaseNode *_node)
00274     {
00275       if ( _node->drawMode() == DrawModes::DEFAULT )
00276         _node->enter(state_, drawMode_);  
00277       else
00278         _node->enter(state_,  _node->drawMode());
00279     }
00280 
00281     void leave (BaseNode *_node)
00282     {
00283       if ( _node->drawMode() == DrawModes::DEFAULT )
00284         _node->leave(state_, drawMode_);  
00285       else
00286         _node->leave(state_,  _node->drawMode());
00287     }
00288 
00289   private:
00290     Action  &action_;
00291     GLState &state_;
00292     DrawModes::DrawMode drawMode_;
00293 
00294 };
00295 
00296 //----------------------------------------------------------------------------
00297 
00307 template <class Action>
00308 void
00309 traverse( BaseNode*           _node,
00310           Action&             _action,
00311           GLState&            _state,
00312           DrawModes::DrawMode _drawmode=DrawModes::DEFAULT)
00313 {
00314     MetaAction<Action> action (_action, _state, _drawmode);
00315     traverse(_node, action);
00316 }
00317 
00318 //----------------------------------------------------------------------------
00319 
00335 template <class Action>
00336 void
00337 traverse_multipass( BaseNode*           _node,
00338                     Action&             _action,
00339                     GLState&            _state,
00340                     DrawModes::DrawMode _drawmode=DrawModes::DEFAULT)
00341 {
00342     MetaAction<Action> action (_action, _state, _drawmode);
00343 
00344     // Reset render pass counter
00345     _state.reset_render_pass();
00346 
00347     // Get max render passes
00348     unsigned int max_passes = _state.max_render_passes();
00349 
00350     // Render all passes
00351     for(unsigned int pass = BaseNode::PASS_1; pass <= (BaseNode::PASS_1 + max_passes); ++pass) {
00352 
00353         // Traverse scenegraph
00354         traverse_multipass (_node, action, pass);
00355         // Increment render pass counter by 1
00356         _state.next_render_pass();
00357     }
00358 
00359     // Reset render pass counter
00360     _state.reset_render_pass();
00361 }
00362 
00363 //--------------------------------------------------------------------------------
00364 
00372 class BoundingBoxAction
00373 {
00374 public:
00375 
00376   BoundingBoxAction() :
00377     bbMin_( FLT_MAX,  FLT_MAX,  FLT_MAX),
00378     bbMax_(-FLT_MAX, -FLT_MAX, -FLT_MAX),
00379     state_(false)
00380   { }
00381 
00382   bool operator()(BaseNode* _node)
00383   {
00384     Vec3d bbMin( FLT_MAX,  FLT_MAX,  FLT_MAX);
00385     Vec3d bbMax(-FLT_MAX, -FLT_MAX, -FLT_MAX);
00386     _node->boundingBox(bbMin, bbMax);
00387 
00388     if ((bbMin[0] > bbMax[0]) ||
00389         (bbMin[1] > bbMax[1]) ||
00390         (bbMin[2] > bbMax[2]))
00391       return true;
00392 
00393     bbMin_.minimize(state_.modelview().transform_point (bbMin));
00394     bbMin_.minimize(state_.modelview().transform_point (bbMax));
00395     bbMax_.maximize(state_.modelview().transform_point (bbMin));
00396     bbMax_.maximize(state_.modelview().transform_point (bbMax));
00397     return true;
00398   }
00399 
00400   void enter (BaseNode *_node)
00401   {
00402     _node->enter(state_, DrawModes::DEFAULT);
00403   }
00404 
00405   void leave (BaseNode *_node)
00406   {
00407     _node->leave(state_, DrawModes::DEFAULT);
00408   }
00409 
00411   const Vec3d& bbMin() const { return bbMin_; }
00413   const Vec3d& bbMax() const { return bbMax_; }
00414 
00415 private:
00416 
00417   Vec3d        bbMin_, bbMax_;
00418   GLState      state_;
00419 };
00420 
00421 
00422 //-----------------------------------------------------------------------------
00423 
00424 
00436 class MultiPassInfoAction
00437 {
00438 public:
00439 
00440   MultiPassInfoAction() :
00441     statusPasses_(BaseNode::ALLPASSES),
00442     nodePasses_(BaseNode::ALLPASSES)
00443   {}
00444 
00445   bool operator()(BaseNode* _node) {
00446 
00447       // Get status pass 
00448       BaseNode::MultipassBitMask statusPass = _node->multipassStatus();
00449 
00450       // Ignore if set to ALLPASSES as we want to get the real maximum pass number
00451       if ( statusPass != BaseNode::ALLPASSES) {
00452         // Convert render pass bit mask to
00453         // decimal value (0x001011 -> 4)
00454         // Note: Same as (int)log2(bitmask)
00455         unsigned int c = 0;
00456         
00457         // Skip the first one as this is the ALLPASSES flag
00458         statusPass = statusPass >> 1;
00459         
00460         while( statusPass != 0u ) {
00461           statusPass = statusPass >> 1;
00462           ++c;
00463         }
00464         statusPasses_ = c > statusPasses_ ? c : statusPasses_;
00465       }
00466       
00467       
00468       // Get Node pass 
00469       BaseNode::MultipassBitMask nodePass = _node->multipassNode();
00470       
00471       // Ignore if set to ALLPASSES as we want to get the real maximum pass number
00472       if ( nodePass != BaseNode::ALLPASSES) {
00473         // Convert render pass bit mask to
00474         // decimal value (0x001011 -> 4)
00475         // Note: Same as (int)log2(bitmask)
00476         unsigned int c = 0;
00477         
00478         // Skip the first one as this is the ALLPASSES flag
00479         nodePass = nodePass >> 1;
00480         
00481         while(nodePass != 0u) {
00482           nodePass = nodePass >> 1;
00483           ++c;
00484         }
00485         nodePasses_ = c > nodePasses_ ? c : nodePasses_;
00486       }
00487 
00488       return true;
00489   }
00490 
00495   unsigned int getMaxPasses() const { 
00496     unsigned int maxpasses = std::max(statusPasses_,nodePasses_);
00497     
00498     // if maxpasses is 0 we have all nodes in ALLPASSES mode so we render only once
00499     return maxpasses == 0 ? 1 : maxpasses; 
00500   }
00501 
00506   unsigned int getStatusPasses() { return statusPasses_ == 0 ? 1 : statusPasses_; };
00507   
00512   unsigned int getNodePasses() { return nodePasses_ == 0 ? 1 : nodePasses_; };
00513 
00514 private:
00515 
00516   unsigned int statusPasses_;
00517   unsigned int nodePasses_;
00518   
00519 };
00520 
00521 
00522 //----------------------------------------------------------------------------
00523 
00524 
00533 class FindNodeAction
00534 {
00535 public:
00536 
00538   FindNodeAction(unsigned int _node_id) :
00539     node_id_(_node_id), node_ptr_(0)  {}
00540 
00541   bool operator()(BaseNode* _node)
00542   {
00543     if (_node->id() == node_id_)
00544     {
00545       node_ptr_ = _node;
00546       return false;
00547     }
00548     return true;
00549   }
00550 
00552   BaseNode*  node_ptr() { return node_ptr_; }
00553 
00554 private:
00555 
00556   unsigned int  node_id_;
00557   BaseNode*     node_ptr_;
00558 };
00559 
00560 
00564 ACGDLLEXPORT
00565 BaseNode* find_node( BaseNode* _root, unsigned int _node_idx );
00566 
00567 
00568 //----------------------------------------------------------------------------
00569 
00570 
00579 class CollectDrawModesAction
00580 {
00581 public:
00582 
00583   CollectDrawModesAction() : drawModes_(DrawModes::NONE) {}
00584 
00585   bool operator()(BaseNode* _node)
00586   {
00587     drawModes_ |= _node->availableDrawModes();
00588     return true;
00589   }
00590 
00592   DrawModes::DrawMode drawModes() const { return drawModes_; }
00593 
00594 private:
00595 
00596   DrawModes::DrawMode drawModes_;
00597 };
00598 
00599 //----------------------------------------------------------------------------
00600 
00601 
00610 class CollectActiveDrawModesAction
00611 {
00612 public:
00613 
00614   CollectActiveDrawModesAction() : drawMode_(DrawModes::NONE) {}
00615 
00616   bool operator()(BaseNode* _node)
00617   {
00618     drawMode_ |= _node->drawMode();
00619     return true;
00620   }
00621 
00623   DrawModes::DrawMode drawMode() const { return drawMode_; }
00624 
00625 private:
00626 
00627   DrawModes::DrawMode drawMode_;
00628 };
00629 
00630 //----------------------------------------------------------------------------
00631 
00632 
00642 class SetDrawModesAction
00643 {
00644 public:
00645 
00646   SetDrawModesAction(DrawModes::DrawMode _mode) : newModes_(_mode) {}
00647 
00648   bool operator()(BaseNode* _node)
00649   {
00650     if ( newModes_ == DrawModes::DEFAULT )
00651       _node->drawMode( DrawModes::DEFAULT );
00652 
00653     DrawModes::DrawMode availableModes = _node->availableDrawModes();
00654 
00655     if ( availableModes & newModes_ )
00656       _node->drawMode( availableModes & newModes_ );
00657     else
00658       _node->drawMode( DrawModes::DEFAULT );
00659 
00660     return true;
00661   }
00662 
00663 private:
00664   DrawModes::DrawMode newModes_;
00665 };
00666 
00667 
00668 //----------------------------------------------------------------------------
00669 
00670 
00680 class DrawAction
00681 {
00682 public:
00683 
00685   DrawAction(DrawModes::DrawMode _drawMode, bool _blending)
00686     : drawMode_(_drawMode), blending_(_blending) {}
00687 
00688   bool operator()(BaseNode* _node, GLState& _state)
00689   {
00690     // draw only if Material status == DrawAction status
00691     if(_state.blending() == blending_)
00692     {
00693       _node->setDirty (false);
00694       if (_node->drawMode() == DrawModes::DEFAULT)
00695         _node->draw(_state, drawMode_);
00696       else
00697         _node->draw(_state, _node->drawMode());
00698     }
00699     return true;
00700   }
00701 
00702 private:
00703 
00704   DrawModes::DrawMode drawMode_;
00705   bool                blending_;
00706 };
00707 
00708 
00709 //----------------------------------------------------------------------------
00710 
00711 
00720 class ACGDLLEXPORT PickAction
00721 {
00722 public:
00723 
00725   PickAction(GLState &_state, PickTarget _target, DrawModes::DrawMode _drawmode) :
00726     state_(_state),
00727     pickTarget_(_target),
00728     drawmode_(_drawmode) {}
00729 
00732   bool operator()(BaseNode* _node);
00733   
00737   bool operator()(BaseNode* _node, GLState& _state);
00738 
00739   void enter(BaseNode* _node)
00740   {
00741     if (_node->drawMode() == DrawModes::DEFAULT)
00742         _node->enterPick(state_, pickTarget_, drawmode_);
00743       else
00744         _node->enterPick(state_, pickTarget_, _node->drawMode());
00745   }
00746 
00747   void leave(BaseNode* _node)
00748   {
00749     if (_node->drawMode() == DrawModes::DEFAULT)
00750         _node->leavePick(state_, pickTarget_, drawmode_);
00751       else
00752         _node->leavePick(state_, pickTarget_, _node->drawMode());
00753   }
00754 
00755 private:
00756 
00757   GLState             &state_;
00758   PickTarget          pickTarget_;
00759   DrawModes::DrawMode drawmode_;
00760 };
00761 
00762 
00763 //----------------------------------------------------------------------------
00764 
00765 
00773 class MouseEventAction
00774 {
00775 public:
00776 
00777 
00778   MouseEventAction(QMouseEvent* _event) : event_(_event) {}
00779 
00780   bool operator()(BaseNode* _node, GLState& _state)
00781   {
00782     _node->mouseEvent(_state, event_);
00783     return true;
00784   }
00785 
00786 private:
00787 
00788   QMouseEvent* event_;
00789 };
00790 
00791 //----------------------------------------------------------------------------
00792 
00793 
00801 class CheckDirtyAction
00802 {
00803 public:
00804 
00805 
00806   CheckDirtyAction() : dirty_(false) {}
00807 
00808   bool operator()(BaseNode* _node)
00809   {
00810     dirty_ |= _node->isDirty();
00811     // don't traverse children if current node is _dirty
00812     return !dirty_;
00813   }
00814 
00815   bool isDirty() const { return dirty_; };
00816 
00817 private:
00818 
00819   bool dirty_;
00820 };
00821 
00822 
00823 //=============================================================================
00824 } // namespace SceneGraph
00825 } // namespace ACG
00826 //=============================================================================
00827 #endif // ACG_SCENEGRAPH_HH defined
00828 //=============================================================================
00829 

acg pic Project OpenFlipper, ©  Computer Graphics Group, RWTH Aachen. Documentation generated using doxygen .