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 if (status != BaseNode::HideSubtree)
00141 {
00142
00143 if (_node->status() != BaseNode::HideNode)
00144 {
00145 if_has_enter (_action, _node);
00146 if (_node->traverseMode() & BaseNode::NodeFirst)
00147 process_children &= _action(_node);
00148 }
00149
00150 if (process_children)
00151 {
00152 BaseNode::ChildIter cIt, cEnd(_node->childrenEnd());
00153 for (cIt = _node->childrenBegin(); cIt != cEnd; ++cIt)
00154 if (~(*cIt)->traverseMode() & BaseNode::SecondPass)
00155 traverse(*cIt, _action);
00156 for (cIt = _node->childrenBegin(); cIt != cEnd; ++cIt)
00157 if ((*cIt)->traverseMode() & BaseNode::SecondPass)
00158 traverse(*cIt, _action);
00159 }
00160
00161 if (_node->status() != BaseNode::HideNode)
00162 {
00163 if (_node->traverseMode() & BaseNode::ChildrenFirst)
00164 _action(_node);
00165 if_has_leave (_action, _node);
00166 }
00167 }
00168 }
00169 }
00170
00171
00172
00178 template <class Action>
00179 class MetaAction
00180 {
00181 public:
00182 MetaAction (Action & _action, GLState& _state, unsigned int _drawmode) :
00183 action_(_action),
00184 state_(_state),
00185 drawmode_(_drawmode)
00186 {
00187 }
00188
00189 bool operator()(BaseNode* _node)
00190 {
00191 return action_(_node, state_);
00192 }
00193
00194 void enter (BaseNode *_node)
00195 {
00196 unsigned int drawmode = ((_node->drawMode() == DrawModes::DEFAULT) ?
00197 drawmode_ : _node->drawMode());
00198 _node->enter(state_, drawmode);
00199 }
00200
00201 void leave (BaseNode *_node)
00202 {
00203 unsigned int drawmode = ((_node->drawMode() == DrawModes::DEFAULT) ?
00204 drawmode_ : _node->drawMode());
00205 _node->leave(state_, drawmode);
00206 }
00207
00208 private:
00209 Action &action_;
00210 GLState &state_;
00211 unsigned int drawmode_;
00212
00213 };
00214
00215
00216
00226 template <class Action>
00227 void
00228 traverse( BaseNode* _node,
00229 Action& _action,
00230 GLState& _state,
00231 unsigned int _drawmode=DrawModes::DEFAULT)
00232 {
00233 MetaAction<Action> action (_action, _state, _drawmode);
00234 traverse (_node, action);
00235 }
00236
00237
00238
00239
00247 class BoundingBoxAction
00248 {
00249 public:
00250
00251 BoundingBoxAction() :
00252 bbMin_( FLT_MAX, FLT_MAX, FLT_MAX),
00253 bbMax_(-FLT_MAX, -FLT_MAX, -FLT_MAX),
00254 state_(false)
00255 { }
00256
00257 bool operator()(BaseNode* _node)
00258 {
00259 Vec3f bbMin( FLT_MAX, FLT_MAX, FLT_MAX);
00260 Vec3f bbMax(-FLT_MAX, -FLT_MAX, -FLT_MAX);
00261 _node->boundingBox(bbMin, bbMax);
00262
00263 if ((bbMin[0] > bbMax[0]) ||
00264 (bbMin[1] > bbMax[1]) ||
00265 (bbMin[2] > bbMax[2]))
00266 return true;
00267
00268 bbMin_.minimize(state_.modelview().transform_point (bbMin));
00269 bbMin_.minimize(state_.modelview().transform_point (bbMax));
00270 bbMax_.maximize(state_.modelview().transform_point (bbMin));
00271 bbMax_.maximize(state_.modelview().transform_point (bbMax));
00272 return true;
00273 }
00274
00275 void enter (BaseNode *_node)
00276 {
00277 _node->enter(state_, DrawModes::DEFAULT);
00278 }
00279
00280 void leave (BaseNode *_node)
00281 {
00282 _node->leave(state_, DrawModes::DEFAULT);
00283 }
00284
00286 const Vec3f& bbMin() const { return bbMin_; }
00288 const Vec3f& bbMax() const { return bbMax_; }
00289
00290 private:
00291
00292 Vec3f bbMin_, bbMax_;
00293 GLState state_;
00294 };
00295
00296
00297
00298
00299
00308 class FindNodeAction
00309 {
00310 public:
00311
00313 FindNodeAction(unsigned int _node_id) :
00314 node_id_(_node_id), node_ptr_(0) {}
00315
00316 bool operator()(BaseNode* _node)
00317 {
00318 if (_node->id() == node_id_)
00319 {
00320 node_ptr_ = _node;
00321 return false;
00322 }
00323 return true;
00324 }
00325
00327 BaseNode* node_ptr() { return node_ptr_; }
00328
00329 private:
00330
00331 unsigned int node_id_;
00332 BaseNode* node_ptr_;
00333 };
00334
00335
00339 ACGDLLEXPORT
00340 BaseNode* find_node( BaseNode* _root, unsigned int _node_idx );
00341
00342
00343
00344
00345
00354 class CollectDrawModesAction
00355 {
00356 public:
00357
00358 CollectDrawModesAction() : drawModes_(0) {}
00359
00360 bool operator()(BaseNode* _node)
00361 {
00362 drawModes_ |= _node->availableDrawModes();
00363 return true;
00364 }
00365
00367 unsigned int drawModes() const { return drawModes_; }
00368
00369 private:
00370
00371 unsigned int drawModes_;
00372 };
00373
00374
00375
00376
00385 class CollectActiveDrawModesAction
00386 {
00387 public:
00388
00389 CollectActiveDrawModesAction() : drawMode_(0) {}
00390
00391 bool operator()(BaseNode* _node)
00392 {
00393 drawMode_ |= _node->drawMode();
00394 return true;
00395 }
00396
00398 unsigned int drawMode() const { return drawMode_; }
00399
00400 private:
00401
00402 unsigned int drawMode_;
00403 };
00404
00405
00406
00407
00417 class SetDrawModesAction
00418 {
00419 public:
00420
00421 SetDrawModesAction(unsigned int _mode) : newModes_(_mode) {}
00422
00423 bool operator()(BaseNode* _node)
00424 {
00425 if ( newModes_ == DrawModes::DEFAULT )
00426 _node->drawMode( DrawModes::DEFAULT );
00427
00428 unsigned int availableModes = _node->availableDrawModes();
00429
00430 if ( availableModes & newModes_ )
00431 _node->drawMode( availableModes & newModes_ );
00432 else
00433 _node->drawMode( DrawModes::DEFAULT );
00434
00435 return true;
00436 }
00437
00438 private:
00439 unsigned int newModes_;
00440 };
00441
00442
00443
00444
00445
00455 class DrawAction
00456 {
00457 public:
00458
00460 DrawAction(unsigned int _drawMode, bool _blending)
00461 : drawMode_(_drawMode), blending_(_blending) {}
00462
00463 bool operator()(BaseNode* _node, GLState& _state)
00464 {
00465
00466 if(_state.blending() == blending_)
00467 {
00468 _node->setDirty (false);
00469 if (_node->drawMode() == DrawModes::DEFAULT)
00470 _node->draw(_state, drawMode_);
00471 else
00472 _node->draw(_state, _node->drawMode());
00473 }
00474 return true;
00475 }
00476
00477 private:
00478
00479 unsigned int drawMode_;
00480 bool blending_;
00481 };
00482
00483
00484
00485
00486
00495 class ACGDLLEXPORT PickAction
00496 {
00497 public:
00498
00500 PickAction(GLState &_state, PickTarget _target, unsigned int _drawmode) :
00501 state_(_state),
00502 pickTarget_(_target),
00503 drawmode_(_drawmode) {}
00504
00505 bool operator()(BaseNode* _node);
00506
00507 void enter(BaseNode* _node)
00508 {
00509 if (_node->drawMode() == DrawModes::DEFAULT)
00510 _node->enterPick(state_, pickTarget_, drawmode_);
00511 else
00512 _node->enterPick(state_, pickTarget_, _node->drawMode());
00513 }
00514
00515 void leave(BaseNode* _node)
00516 {
00517 if (_node->drawMode() == DrawModes::DEFAULT)
00518 _node->leavePick(state_, pickTarget_, drawmode_);
00519 else
00520 _node->leavePick(state_, pickTarget_, _node->drawMode());
00521 }
00522
00523 private:
00524
00525 GLState &state_;
00526 PickTarget pickTarget_;
00527 unsigned int drawmode_;
00528 };
00529
00530
00531
00532
00533
00541 class MouseEventAction
00542 {
00543 public:
00544
00545
00546 MouseEventAction(QMouseEvent* _event) : event_(_event) {}
00547
00548 bool operator()(BaseNode* _node, GLState& _state)
00549 {
00550 _node->mouseEvent(_state, event_);
00551 return true;
00552 }
00553
00554 private:
00555
00556 QMouseEvent* event_;
00557 };
00558
00559
00560
00561
00569 class CheckDirtyAction
00570 {
00571 public:
00572
00573
00574 CheckDirtyAction() : dirty_(false) {}
00575
00576 bool operator()(BaseNode* _node)
00577 {
00578 dirty_ |= _node->isDirty();
00579
00580 return !dirty_;
00581 }
00582
00583 bool isDirty() const { return dirty_; };
00584
00585 private:
00586
00587 bool dirty_;
00588 };
00589
00590
00591
00592 }
00593 }
00594
00595 #endif // ACG_SCENEGRAPH_HH defined
00596
00597