PeriDyno 1.0.0
Loading...
Searching...
No Matches
SceneGraph.cpp
Go to the documentation of this file.
1#include "SceneGraph.h"
2//#include "Action/ActDraw.h"
3#include "Action/ActReset.h"
6
8
11
13
14#include "SceneLoaderFactory.h"
15
16#include "Timer.h"
17
18#include <sstream>
19#include <iomanip>
20
21namespace dyno
22{
24 {
25 public:
27 mFrameNumber = num;
28 };
29
30 void process(Node* node) override {
31 if (node == NULL)
32 return;
33
34 node->stateFrameNumber()->setValue(mFrameNumber);
35 }
36
38 };
39
41 {
42 static SceneGraph m_instance;
43 return m_instance;
44 }
45
50
52 {
53 mAdvativeInterval = adaptive;
54 }
55
60
62 {
63 mGravity = g;
64 }
65
67 {
68 return mGravity;
69 }
70
72 {
73 mNodeMap.clear();
74 mNodeQueue.clear();
75 }
76
77 void SceneGraph::advance(float dt)
78 {
79 class AdvanceAct : public Action
80 {
81 public:
82 AdvanceAct(float dt, float t, bool bTiming = false) {
83 mDt = dt;
84 mElapsedTime = t;
85 mTiming = bTiming;
86 };
87
88 void start(Node* node) override {
89 if (node == NULL)
90 return;
91
92 node->stateTimeStep()->setValue(mDt);
93 node->stateElapsedTime()->setValue(mElapsedTime);
94 }
95
96 void process(Node* node) override {
97 if (node == NULL)
98 {
99 Log::sendMessage(Log::Error, "Node is invalid!");
100 return;
101 }
102
103 CTimer timer;
104
105 if (mTiming) {
106 timer.start();
107 }
108
109 node->update();
110
111 if (mTiming) {
112 timer.stop();
113
114 std::stringstream name;
115 std::stringstream ss;
116 name << std::setw(40) << node->getClassInfo()->getClassName();
117 ss << std::setprecision(10) << timer.getElapsedTime();
118
119 std::string info = "Node: \t" + name.str() + ": \t " + ss.str() + "ms \n";
121 }
122 }
123
124 float mDt;
125 float mElapsedTime;
126
127 bool mTiming = false;
128 };
129
131
132 mElapsedTime += dt;
133 }
134
136 {
137 class AsyncAdvanceAct : public Action
138 {
139 public:
140 AsyncAdvanceAct(bool bTiming = false) {
141 mTiming = bTiming;
142 };
143
144 void start(Node* node) override {
145 if (node == NULL)
146 return;
147
148 auto dt = node->getDt();
149 node->stateTimeStep()->setValue(dt);
150 }
151
152 void process(Node* node) override {
153 if (node == NULL)
154 {
155 Log::sendMessage(Log::Error, "Node is invalid!");
156 return;
157 }
158
159 CTimer timer;
160
161 if (mTiming) {
162 timer.start();
163 }
164
165 node->update();
166
167 if (mTiming) {
168 timer.stop();
169
170 std::stringstream name;
171 std::stringstream ss;
172 name << std::setw(40) << node->getClassInfo()->getClassName();
173 ss << std::setprecision(10) << timer.getElapsedTime();
174
175 std::string info = "Node: \t" + name.str() + ": \t " + ss.str() + "ms \n";
177 }
178 }
179
180 void end(Node* node) override {
181 if (node == NULL)
182 return;
183
184 auto dt = node->stateTimeStep()->getValue();
185 auto time = node->stateElapsedTime()->getValue();
186 node->stateElapsedTime()->setValue(time + dt);
187 }
188
189 bool mTiming = false;
190 };
191
193 }
194
196 {
197 std::cout << "**************** Frame " << mFrameNumber << " Started ****************" << std::endl;
198
199 CTimer timer;
200 timer.start();
201
203 {
204 this->advanceInAsync();
205 }
206 else
207 {
208 float t = 0.0f;
209 float dt = 0.0f;
210
211 class QueryTimeStep : public Action
212 {
213 public:
214 void process(Node* node) override {
215 if (node != nullptr && node->isActive())
216 dt = node->getDt() < dt ? node->getDt() : dt;
217 }
218
219 float dt;
220 } timeStep;
221
222 timeStep.dt = 1.0f / mFrameRate;
223
224 this->traverseForward(&timeStep);
225 dt = timeStep.dt;
226
228 {
229 this->advance(dt);
230 }
231 else
232 {
233 float interval = 1.0f / mFrameRate;
234 while (t + dt < interval)
235 {
236 this->advance(dt);
237
238 t += dt;
239 timeStep.dt = 1.0f / mFrameRate;
240 this->traverseForward(&timeStep);
241 dt = timeStep.dt;
242 }
243
244 this->advance(interval - t);
245 }
246 }
247
249
251
252 timer.stop();
253
254 std::cout << "---------------- Frame " << mFrameNumber << " Ended! ( " << timer.getElapsedTime() << " ms in Total) ----------------" << std::endl << std::endl;
255
256 mFrameNumber++;
257
259 }
260
262 {
263 class UpdateGrpahicsContextAct : public Action
264 {
265 public:
266 void process(Node* node) override {
267 if (node->isVisible())
268 {
269 node->graphicsPipeline()->update();
270 }
271 }
272 };
273
275 }
276
277
279 {
280
281 }
282
284 {
285 NBoundingBox box;
286 for (auto it = this->begin(); it != this->end(); it++)
287 {
288 box.join(it->boundingBox());
289 }
290
291 return box;
292 }
293
295 {
296 class ResetNodeAct : public Action
297 {
298 public:
299 void process(Node* node) override {
300 if (node == NULL) {
301 Log::sendMessage(Log::Error, "Node is invalid!");
302 return;
303 }
304
305 node->reset();
306 }
307 };
308
310
311 mElapsedTime = 0.0f;
312 mFrameNumber = 0;
313
315 }
316
317 void SceneGraph::reset(std::shared_ptr<Node> node)
318 {
319 this->traverseForward<ResetAct>(node);
320 }
321
322 void SceneGraph::printNodeInfo(bool enabled)
323 {
324 mNodeTiming = enabled;
325 }
326
328 {
329 mSimulationTiming = enabled;
330 }
331
333 {
334 mRenderingTiming = enabled;
335 }
336
338 {
339 mValidationInfo = enabled;
340 }
341
342 bool SceneGraph::load(std::string name)
343 {
345 if (loader)
346 {
347 //mRoot = loader->load(name);
348 return true;
349 }
350
351 return false;
352 }
353
355 {
356 return mLowerBound;
357 }
358
360 {
361 return mUpperBound;
362 }
363
365 {
366 mLowerBound = lowerBound;
367 }
368
370 {
371 mUpperBound = upperBound;
372 }
373
378
380 {
381 class MouseEventAct : public Action
382 {
383 public:
384 MouseEventAct(PMouseEvent event) { mMouseEvent = event; }
385 ~MouseEventAct() override {}
386
387 private:
388 void process(Node* node) override
389 {
390 if (!node->isVisible())
391 return;
392
393 for (auto iter : node->animationPipeline()->activeModules())
394 {
395 auto m = dynamic_cast<MouseInputModule*>(iter.get());
396 if (m)
397 {
398 m->enqueueEvent(mMouseEvent);
399 }
400 }
401
402 for (auto iter : node->graphicsPipeline()->activeModules())
403 {
404 auto m = dynamic_cast<MouseInputModule*>(iter.get());
405 if (m)
406 {
407 m->enqueueEvent(mMouseEvent);
408 }
409 }
410 }
411
412 PMouseEvent mMouseEvent;
413 };
414
415 MouseEventAct eventAct(event);
416
417 this->traverseForward(&eventAct);
418 }
419
420 void SceneGraph::onMouseEvent(PMouseEvent event, std::shared_ptr<Node> node)
421 {
422 if (node == nullptr || !node->isVisible())
423 return;
424
425 for (auto iter : node->animationPipeline()->activeModules())
426 {
427 auto m = dynamic_cast<MouseInputModule*>(iter.get());
428 if (m)
429 {
430 m->enqueueEvent(event);
431 }
432 }
433
434 for (auto iter : node->graphicsPipeline()->activeModules())
435 {
436 auto m = dynamic_cast<MouseInputModule*>(iter.get());
437 if (m)
438 {
439 m->enqueueEvent(event);
440 }
441 }
442 }
443
445 {
446 class KeyboardEventAct : public Action
447 {
448 public:
449 KeyboardEventAct(PKeyboardEvent event) { mKeyboardEvent = event; }
450 ~KeyboardEventAct() override {}
451
452 private:
453 void process(Node* node) override
454 {
455 if (!node->isVisible())
456 return;
457
458 for (auto iter : node->animationPipeline()->activeModules())
459 {
460 auto m = dynamic_cast<KeyboardInputModule*>(iter.get());
461 if (m)
462 {
463 m->enqueueEvent(mKeyboardEvent);
464 }
465 }
466
467 for (auto iter : node->graphicsPipeline()->activeModules())
468 {
469 auto m = dynamic_cast<KeyboardInputModule*>(iter.get());
470 if (m)
471 {
472 m->enqueueEvent(mKeyboardEvent);
473 }
474 }
475 }
476
477 PKeyboardEvent mKeyboardEvent;
478 };
479
480 KeyboardEventAct eventAct(event);
481
482 this->traverseForward(&eventAct);
483 }
484
485// //Used to traverse the whole scene graph
486// void DFS(Node* node, NodeList& nodeQueue, std::map<ObjectId, bool>& visited) {
487//
488// visited[node->objectId()] = true;
489//
490// auto imports = node->getImportNodes();
491// for (auto port : imports) {
492// auto& inNodes = port->getNodes();
493// for (auto inNode : inNodes) {
494// if (inNode != nullptr && !visited[inNode->objectId()]) {
495// DFS(inNode, nodeQueue, visited);
496// }
497// }
498// }
499//
500// auto inFields = node->getInputFields();
501// for (auto f : inFields) {
502// auto* src = f->getSource();
503// if (src != nullptr) {
504// auto* inNode = dynamic_cast<Node*>(src->parent());
505// if (inNode != nullptr && !visited[inNode->objectId()]) {
506// DFS(inNode, nodeQueue, visited);
507// }
508// }
509// }
510//
511// nodeQueue.push_back(node);
512//
513// auto exports = node->getExportNodes();
514// for (auto port : exports) {
515// auto exNode = port->getParent();
516// if (exNode != nullptr && !visited[exNode->objectId()]) {
517// DFS(exNode, nodeQueue, visited);
518// }
519// }
520//
521// auto outFields = node->getOutputFields();
522// for (auto f : outFields) {
523// auto& sinks = f->getSinks();
524// for (auto sink : sinks) {
525// if (sink != nullptr) {
526// auto exNode = dynamic_cast<Node*>(sink->parent());
527// if (exNode != nullptr && !visited[exNode->objectId()]) {
528// DFS(exNode, nodeQueue, visited);
529// }
530// }
531// }
532// }
533// };
534
535 //Used to traverse the scene graph from a specific node
536 void BFS(Node* node, NodeList& list, std::map<ObjectId, bool>& visited) {
537
538 visited[node->objectId()] = true;
539
540 std::queue<Node*> queue;
541 queue.push(node);
542
543 while (!queue.empty())
544 {
545 auto fn = queue.front();
546 queue.pop();
547
548 list.push_back(fn);
549
550 auto exports = fn->getExportNodes();
551 for (auto port : exports) {
552 auto next = port->getParent();
553 if (next != nullptr && !visited[next->objectId()]) {
554 queue.push(next);
555 }
556 }
557
558 auto outFields = fn->getOutputFields();
559 for (auto f : outFields) {
560 auto& sinks = f->getSinks();
561 for (auto sink : sinks) {
562 if (sink != nullptr) {
563 auto next = dynamic_cast<Node*>(sink->parent());
564 if (next != nullptr && !visited[next->objectId()]) {
565 queue.push(next);
566 }
567 }
568 }
569 }
570 }
571 };
572
573 // void SceneGraph::retriveExecutionQueue(std::list<Node*>& nQueue)
574 // {
575 // nQueue.clear();
576 //
577 // std::map<ObjectId, bool> visited;
578 // for (auto& nm : mNodeMap) {
579 // visited[nm.first] = false;
580 // }
581 //
582 // for (auto& n : mNodeMap) {
583 // if (!visited[n.first]) {
584 //
585 // Node* node = n.second.get();
586 //
587 // DFS(node, nQueue, visited);
588 // }
589 // }
590 //
591 // visited.clear();
592 // }
593
595 {
597 return;
598
599 mNodeQueue.clear();
600
602
603 auto dummyId = Object::baseId();
604
605 for (auto& n : mNodeMap) {
606 Node* node = n.second.get();
607
608 auto outId = node->objectId();
609
610 bool hasAncestor = false;
611
612 //Input nodes
613 auto imports = node->getImportNodes();
614 for (auto port : imports) {
615 auto& inNodes = port->getNodes();
616 for (auto inNode : inNodes) {
617 if (inNode != nullptr) {
618 dag.addEdge(inNode->objectId(), outId);
619
620 hasAncestor = true;
621 }
622 }
623 }
624
625 //Input fields
626 auto inFields = node->getInputFields();
627 for (auto f : inFields) {
628 auto* src = f->getSource();
629 if (src != nullptr) {
630 auto* inNode = dynamic_cast<Node*>(src->parent());
631 if (inNode != nullptr) {
632 dag.addEdge(inNode->objectId(), outId);
633
634 hasAncestor = true;
635 }
636 }
637 }
638
639 //In case of an isolated node, add an virtual edge to connect a dummy node and the node
640 if (!hasAncestor)
641 {
642 dag.addEdge(dummyId, outId);
643 }
644 }
645
646 auto& sortedIds = dag.topologicalSort();
647
648 for (auto id : sortedIds)
649 {
650 if (id != dummyId)
651 mNodeQueue.push_back(mNodeMap[id].get());
652 }
653
654 mQueueUpdateRequired = false;
655 }
656
658 {
660
661 for (auto rit = mNodeQueue.rbegin(); rit != mNodeQueue.rend(); ++rit)
662 {
663 Node* node = *rit;
664
665 act->start(node);
666 act->process(node);
667 act->end(node);
668 }
669 }
670
672 {
674
675 for (auto it = mNodeQueue.begin(); it != mNodeQueue.end(); ++it)
676 {
677 Node* node = *it;
678
679 act->start(node);
680 act->process(node);
681 act->end(node);
682 }
683 }
684
685 void SceneGraph::traverseForward(std::shared_ptr<Node> node, Action* act)
686 {
687 std::map<ObjectId, bool> visited;
688 for (auto& nm : mNodeMap) {
689 visited[nm.first] = false;
690 }
691
692 NodeList list;
693 BFS(node.get(), list, visited);
694
695 for (auto it = list.begin(); it != list.end(); ++it)
696 {
697 Node* node = *it;
698
699 act->start(node);
700 act->process(node);
701 act->end(node);
702 }
703
704 list.clear();
705 visited.clear();
706 }
707
708 //Used to traverse the scene graph from a specific node
709 void BFSWithAutoSync(Node* node, NodeList& list, std::map<ObjectId, bool>& visited) {
710
711 visited[node->objectId()] = true;
712
713 std::queue<Node*> queue;
714 queue.push(node);
715
716 while (!queue.empty())
717 {
718 auto fn = queue.front();
719 queue.pop();
720
721 list.push_back(fn);
722
723 auto exports = fn->getExportNodes();
724 for (auto port : exports) {
725 auto next = port->getParent();
726 if (next != nullptr && next->isAutoSync() && !visited[next->objectId()]) {
727 queue.push(next);
728 }
729 }
730
731 auto outFields = fn->getOutputFields();
732 for (auto f : outFields) {
733 auto& sinks = f->getSinks();
734 for (auto sink : sinks) {
735 if (sink != nullptr) {
736 auto next = dynamic_cast<Node*>(sink->parent());
737 if (next != nullptr && next->isAutoSync() && !visited[next->objectId()]) {
738 queue.push(next);
739 }
740 }
741 }
742 }
743 }
744 };
745
746 void SceneGraph::traverseForwardWithAutoSync(std::shared_ptr<Node> node, Action* act)
747 {
748 std::map<ObjectId, bool> visited;
749 for (auto& nm : mNodeMap) {
750 visited[nm.first] = false;
751 }
752
753 NodeList list;
754 BFSWithAutoSync(node.get(), list, visited);
755
756 for (auto it = list.begin(); it != list.end(); ++it)
757 {
758 Node* node = *it;
759
760 act->start(node);
761 act->process(node);
762 act->end(node);
763 }
764
765 list.clear();
766 visited.clear();
767 }
768
769 void SceneGraph::deleteNode(std::shared_ptr<Node> node)
770 {
771 if (node == nullptr ||
772 mNodeMap.find(node->objectId()) == mNodeMap.end())
773 return;
774
775 mNodeMap.erase(node->objectId());
777 }
778
779 void SceneGraph::propagateNode(std::shared_ptr<Node> node)
780 {
781 std::map<ObjectId, bool> visited;
782 for (auto it = mNodeQueue.begin(); it != mNodeQueue.end(); ++it)
783 {
784 visited[(*it)->objectId()] = false;
785 }
786
787 //DownwardDFS(node.get(), visited);
788
789 visited.clear();
790 }
791
792}
virtual void end(Node *node)
Definition Action.cpp:22
virtual void process(Node *node)
Definition Action.cpp:18
virtual void start(Node *node)
Definition Action.cpp:13
void process(Node *node) override
double getElapsedTime()
return the elapsed time in (ms)
Definition Timer.cpp:41
void start()
Definition Timer.cpp:17
void stop()
Definition Timer.cpp:29
Graph class represents a directed graph.
void addEdge(ObjectId v, ObjectId w)
std::vector< ObjectId > & topologicalSort(ObjectId v)
@ Info
Information to user.
Definition Log.h:48
@ Error
Error information while executing something.
Definition Log.h:50
static void sendMessage(MessageType type, const std::string &text)
Add a new message to log.
Definition Log.cpp:41
std::shared_ptr< GraphicsPipeline > graphicsPipeline()
Definition Node.cpp:320
virtual bool isActive()
Check the state of dynamics.
Definition Node.cpp:73
virtual Real getDt()
Simulation timestep.
Definition Node.cpp:93
void update()
Called every time interval.
Definition Node.cpp:146
void reset()
Definition Node.cpp:183
std::shared_ptr< AnimationPipeline > animationPipeline()
Definition Node.cpp:311
virtual bool isVisible()
Check the visibility of context.
Definition Node.cpp:83
std::vector< NodePort * > & getImportNodes()
Definition Node.h:115
std::vector< FBase * > & getInputFields()
Definition OBase.h:171
static ObjectId baseId()
Base Id.
Definition Object.cpp:46
ObjectId objectId()
Definition Object.h:129
bool mAsynchronousSimulation
Definition SceneGraph.h:261
NodeList mNodeQueue
Definition SceneGraph.h:265
void deleteNode(std::shared_ptr< Node > node)
void markQueueUpdateRequired()
An interface to tell SceneGraph to update the execuation queue.
void setLowerBound(Vec3f lowerBound)
virtual void takeOneFrame()
bool isIntervalAdaptive()
void updateExecutionQueue()
NBoundingBox boundingBox()
void onMouseEvent(PMouseEvent event)
void printValidationInfo(bool enabled)
EWorkMode mWorkMode
Definition SceneGraph.h:273
virtual void advanceInAsync()
void traverseBackward(Action *act)
Depth-first tree traversal.
void setGravity(Vec3f g)
void traverseForward(Action *act)
Breadth-first tree traversal.
void propagateNode(std::shared_ptr< Node > node)
void printNodeInfo(bool enabled)
void setAsynchronousSimulation(bool b)
void onKeyboardEvent(PKeyboardEvent event)
Iterator end()
Definition SceneGraph.h:149
void setAdaptiveInterval(bool adaptive)
void traverseForwardWithAutoSync(std::shared_ptr< Node > node, Action *act)
Breadth-first tree traversal starting from a specific node, only those whose mAutoSync turned-on will...
void printRenderingInfo(bool enabled)
virtual void run()
void setUpperBound(Vec3f upperBound)
virtual bool load(std::string name)
void printSimulationInfo(bool enabled)
Iterator begin()
Definition SceneGraph.h:142
virtual void advance(float dt)
virtual void updateGraphicsContext()
bool mQueueUpdateRequired
Definition SceneGraph.h:260
static SceneGraph & getInstance()
static SceneLoaderFactory & getInstance()
Get the ObjectFactory singleton instance.
SceneLoader * getEntryByFileName(std::string filename)
Get an entry given a file name.
This is an implementation of AdditiveCCD based on peridyno.
Definition Array.h:25
void BFS(Node *node, NodeList &list, std::map< ObjectId, bool > &visited)
void BFSWithAutoSync(Node *node, NodeList &list, std::map< ObjectId, bool > &visited)
std::list< Node * > NodeList
Definition SceneGraph.h:27
Vector< float, 3 > Vec3f
Definition Vector3D.h:93
unsigned int uint
Definition VkProgram.h:14
NBoundingBox & join(const NBoundingBox box)
Definition Node.h:48