00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052 #ifndef ACG_SCENEGRAPH_HH
00053 #define ACG_SCENEGRAPH_HH
00054
00055
00056
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
00067
00068 namespace ACG {
00069 namespace SceneGraph {
00070
00071
00072
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
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
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
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
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
00141 if (status != BaseNode::HideSubtree)
00142 {
00143
00144
00145 if (_node->status() != BaseNode::HideNode)
00146 {
00147
00148 if_has_enter (_action, _node);
00149
00150
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
00161 for (cIt = _node->childrenBegin(); cIt != cEnd; ++cIt)
00162 if (~(*cIt)->traverseMode() & BaseNode::SecondPass)
00163 traverse(*cIt, _action);
00164
00165
00166 for (cIt = _node->childrenBegin(); cIt != cEnd; ++cIt)
00167 if ((*cIt)->traverseMode() & BaseNode::SecondPass)
00168 traverse(*cIt, _action);
00169
00170 }
00171
00172
00173 if (_node->status() != BaseNode::HideNode)
00174 {
00175
00176
00177 if (_node->traverseMode() & BaseNode::ChildrenFirst)
00178 _action(_node);
00179
00180
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
00202 if (_node) {
00203 BaseNode::StatusMode status(_node->status());
00204 bool process_children(status != BaseNode::HideChildren);
00205
00206
00207 if (status != BaseNode::HideSubtree) {
00208
00209
00210 if ( _node->multipassStatusActive(_pass) )
00211 if_has_enter(_action, _node);
00212
00213
00214
00215
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
00224 for (cIt = _node->childrenBegin(); cIt != cEnd; ++cIt)
00225 if (~(*cIt)->traverseMode() & BaseNode::SecondPass)
00226 traverse_multipass(*cIt, _action, _pass);
00227
00228
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
00237
00238
00239 if ( (_node->traverseMode() & BaseNode::ChildrenFirst ) && (_node->status() != BaseNode::HideNode) && _node->multipassNodeActive(_pass) )
00240 _action(_node);
00241
00242
00243 if ( _node->multipassStatusActive(_pass) )
00244 if_has_leave(_action, _node);
00245
00246 }
00247 }
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
00345 _state.reset_render_pass();
00346
00347
00348 unsigned int max_passes = _state.max_render_passes();
00349
00350
00351 for(unsigned int pass = BaseNode::PASS_1; pass <= (BaseNode::PASS_1 + max_passes); ++pass) {
00352
00353
00354 traverse_multipass (_node, action, pass);
00355
00356 _state.next_render_pass();
00357 }
00358
00359
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
00448 BaseNode::MultipassBitMask statusPass = _node->multipassStatus();
00449
00450
00451 if ( statusPass != BaseNode::ALLPASSES) {
00452
00453
00454
00455 unsigned int c = 0;
00456
00457
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
00469 BaseNode::MultipassBitMask nodePass = _node->multipassNode();
00470
00471
00472 if ( nodePass != BaseNode::ALLPASSES) {
00473
00474
00475
00476 unsigned int c = 0;
00477
00478
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
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
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
00812 return !dirty_;
00813 }
00814
00815 bool isDirty() const { return dirty_; };
00816
00817 private:
00818
00819 bool dirty_;
00820 };
00821
00822
00823
00824 }
00825 }
00826
00827 #endif // ACG_SCENEGRAPH_HH defined
00828
00829