H3D API  2.4.1
Scene.h
Go to the documentation of this file.
1 // Copyright 2004-2019, SenseGraphics AB
3 //
4 // This file is part of H3D API.
5 //
6 // H3D API is free software; you can redistribute it and/or modify
7 // it under the terms of the GNU General Public License as published by
8 // the Free Software Foundation; either version 2 of the License, or
9 // (at your option) any later version.
10 //
11 // H3D API is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
15 //
16 // You should have received a copy of the GNU General Public License
17 // along with H3D API; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 //
20 // A commercial license is also available. Please contact us at
21 // www.sensegraphics.com for more information.
22 //
23 //
27 //
29 #ifndef __SCENE_H__
30 #define __SCENE_H__
31 
32 #include <H3D/X3DChildNode.h>
33 #include <H3D/H3DWindowNode.h>
34 #include <H3D/SAIFunctions.h>
35 #include <H3D/ShadowCaster.h>
37 #include <string>
38 
39 
40 // HAPI includes
41 #include <H3DUtil/Threads.h>
42 #include <vector>
43 
44 
45 
46 namespace H3D {
47 
56  class H3DAPI_API Scene : public Node {
57  public:
58 
59  #ifdef HAVE_PROFILER
60  // profiledResult structure
61  class profiledResultData
62  {
63  private:
64  pthread_t thread_id;
65  std::string profiled_result_string;
66  std::string thread_debug_string;
67  public:
68  void setResult(pthread_t id,std::string result_profile)
69  {
70  if(!result_profile.empty())
71  {this->thread_id=id;this->profiled_result_string=result_profile;}
72  }
73  void setResult(pthread_t id,std::string result_profile, std::string result_thread_debug)
74  {
75  if(!result_profile.empty())
76  {
77  this->thread_id=id;
78  this->profiled_result_string=result_profile;
79  this->thread_debug_string=result_thread_debug;
80  }
81  }
82  void setThread_debug(std::string result){this->thread_debug_string=result;}
83  bool isEmpty(){return this->profiled_result_string.empty()&&this->thread_debug_string.empty();}
84  pthread_t getId(){return thread_id;}
85  std::string getResult();
86  //std::string getString(){return profiled_result_string;}
87  };
88  #endif
89 #ifdef HAVE_NVAPI
91  static string nvidia_graphics_options_file_url;
92 #endif // HAVE_NVAPI
93 
96 
98  Scene( Inst< SFChildNode > _sceneRoot = 0,
99  Inst< MFWindow > _window = 0,
100  Inst< SFFloat > _frameRate = 0
101 #ifdef HAVE_PROFILER
102  ,
103  Inst< MFString > _profiledResult = 0
104 #endif
105  ,Inst< SFFloat > _maxFrameRate= 0
106 #ifdef HAVE_NVAPI
107  ,
108  Inst< SFNvidiaGraphicsOptions > _nvidiaGraphicsOptions = 0
109 #endif // HAVE_NVAPI
110  );
111 
113  ~Scene();
114 
117  return last_traverseinfo;
118  }
119 
122  void setActive( bool _active ) {
123  active = _active;
124  }
125 
127  inline bool isActive() {
128  return active;
129  }
130 
133  virtual void idle();
134 
138  void loadSceneRoot( const string &url );
139 
141  void setSceneRoot( SAI::SAIScene *scene_info );
142 
144  inline SAI::Browser *getSAIBrowser() {
145  return &SAI_browser;
146  }
147 
148  ShadowCaster *getDefaultShadowCaster() {
149  return shadow_caster.get();
150  }
151 
152 #ifdef HAVE_GLUT
156  static void mainLoop();
157 #endif
158 
162  H3DUniquePtr< SFChildNode > sceneRoot;
163 
167  H3DUniquePtr< MFWindow > window;
168 
172  H3DUniquePtr< SFFloat > frameRate;
173 
182  H3DUniquePtr< SFFloat > maxFrameRate;
183 #ifdef HAVE_PROFILER
184  H3DUniquePtr< MFString > profiledResult;
185 
186  Scene::profiledResultData H3D_scene_result;
187  Scene::profiledResultData haptic_result;
188  Scene::profiledResultData H3D_sofa_result;
189 
190  bool outputonce ;
191  std::string generateProfileResult();
192 
193  struct ProfileNodeResult {
194  Node* node;
195  H3DTime render_time;
196  H3DTime traverse_time;
197 
198  H3DTime render_time_last;
199  H3DTime traverse_time_last;
200  };
201  static bool compareRenderTime ( const ProfileNodeResult& lhs, const ProfileNodeResult& rhs ) { return lhs.render_time > rhs.render_time; }
202  static bool compareTraverseTime( const ProfileNodeResult& lhs, const ProfileNodeResult& rhs ) { return lhs.traverse_time > rhs.traverse_time; }
203 
204  typedef std::vector < ProfileNodeResult > ProfileNodeResultVec;
205  std::string exclusive_times_string;
206  H3DTime exclusive_times_update_time;
207 
208  void computeExclusiveTimes( Node& _node, ProfileNodeResultVec& _result );
209 #endif
214  static H3DUniquePtr< SFTime > time;
215  //static SFTime *time;
216 
218  static set< Scene* > scenes;
219 
220 #ifdef HAVE_NVAPI
221  H3DUniquePtr<SFNvidiaGraphicsOptions> nvidiaGraphicsOptions;
222 #endif // HAVE_NVAPI
223 
226 
228  typedef enum {
233  CALLBACK_CONTINUE
234  } CallbackCode;
235 
237  typedef CallbackCode (*CallbackFunc)(void *data);
238 
241  static void addCallback( CallbackFunc func, void *data ) {
242  callback_lock.lock();
243  callbacks.push_back( make_pair( func, data ) );
244  callback_lock.unlock();
245  }
246 
247 
248  struct ProgramSetting {
250  ProgramSetting( Field *_field,
251  const string &_name = "",
252  const string &_section = ""):
253  field( _field ),
254  name( _name ),
255  section( _section ) {}
256 
257 
258  Field *field;
259  string name;
260  string section;
261 
262  };
263 
264  typedef std::list< ProgramSetting > ProgramSettings;
265 
277  static void addProgramSetting( Field *field,
278  const string &name = "",
279  const string &section = "Main settings");
280 
287  static bool removeProgramSetting( const string &name,
288  const string &section = "Main settings" );
289 
294  static bool removeProgramSetting( Field *field );
295 
301  static Field *getProgramSetting( const string &name,
302  const string &section = "Main settings" );
303 
304  typedef ProgramSettings::iterator SettingsIterator;
305 
308  static SettingsIterator programSettingsBegin();
309 
311  static SettingsIterator programSettingsEnd();
312 
313  typedef enum {
314  ADD_SETTING,
315  REMOVE_SETTING
316  } ProgramSettingsEvent;
317 
319  typedef void (*ProgramSettingsCallbackFunc)( ProgramSettingsEvent event,
320  const ProgramSetting &settings,
321  void *data);
322 
323  typedef std::pair< ProgramSettingsCallbackFunc, void * > ProgramSettingsCallbackId;
324 
327  static ProgramSettingsCallbackId addProgramSettingsCallback( ProgramSettingsCallbackFunc func,
328  void *data );
329 
331  static bool removeProgramSettingsCallback( ProgramSettingsCallbackId id );
332 
334  static void clearProgramSettingsCallbacks();
335 
337  static H3D::Node* findChildNode(H3D::X3DGroupingNode *group, const std::string &nodeType, const std::string &nodeName="");
338 
340  static H3D::Node* findNodeType(H3D::Node *node, const std::string &nodeType, const std::string &nodeName="" );
341 
342  typedef std::map < Node*, AutoRefVector<Node> > NodeParentsMap;
343  typedef std::map < std::string,std::vector < std::string > > SearchFieldNameMap;
344  typedef std::vector < std::string > StringVec;
345 
402  template < typename NodeType >
403  static void findNodes (
404  Node& _node,
405  AutoRefVector<NodeType>& _result,
406  const std::string& _nodeName= "",
407  NodeParentsMap* _parentMap= NULL,
408  SearchFieldNameMap* _searchFieldNames= NULL,
409  StringVec* _typeNames= NULL,
410  bool _exactNodeName= true,
411  bool _verbose= false,
412  Node* _parent= NULL,
413  StringVec* _ignoreTraverseNodeTypeNames= NULL ) {
414 
415  // if the node type name is in the ignore list we have nothing to do with this node
416  if ( _ignoreTraverseNodeTypeNames &&
417  find ( _ignoreTraverseNodeTypeNames->begin(), _ignoreTraverseNodeTypeNames->end(), _node.getTypeName() ) != _ignoreTraverseNodeTypeNames->end() ) {
418  // We should not search this node type at all
419  return;
420  }
421 
422  if ( _typeNames == NULL ||
423  find ( _typeNames->begin(), _typeNames->end(), _node.getTypeName() ) != _typeNames->end() ) {
424  if ( NodeType* n= dynamic_cast < NodeType* > ( &_node ) ) {
425  const std::string& node_name= n->getName();
426  if ( _nodeName.empty() ||
427  ( ( _exactNodeName && _nodeName == node_name) ||
428  (!_exactNodeName && node_name.find ( _nodeName ) != std::string::npos ) ) ) {
429  _result.push_back ( n );
430  if ( _parentMap && _parent ) {
431  (*_parentMap)[n].push_back ( _parent );
432  }
433  }
434  }
435  }
436 
437  // get field names to search, if empty search all
438  std::vector<std::string> field_names;
439  if ( _searchFieldNames ) {
440  SearchFieldNameMap::iterator i= _searchFieldNames->find ( _node.getTypeName() );
441  if ( i != _searchFieldNames->end() ) {
442  field_names= (*i).second;
443  } else {
444  // We should not search this node type at all
445  return;
446  }
447  }
448 
449  // Iterate over all fields and recurse into children
451 
453  db->fieldDBEnd() != i; ++i ) {
454  Field *f = i.getField( &_node );
455 
456  if( f ) {
457  if ( f->getAccessType() != Field::INPUT_ONLY ) {
458  if ( _searchFieldNames ) {
459  if ( find ( field_names.begin(), field_names.end(), f->getName() ) == field_names.end() ) {
460  // This field should be skipped
461  continue;
462  }
463  }
464 
465  if ( SFNode* sf_node= dynamic_cast< SFNode * >( f ) ) {
466  Node* c= sf_node->getValue();
467  if ( c ) {
468  if ( _verbose ) {
469  Console(LogLevel::Error) << "Node::findNodes(): " << _node.getName() << " -> " << f->getName() << endl;
470  }
471  findNodes ( *c, _result, _nodeName, _parentMap, _searchFieldNames, _typeNames, _exactNodeName, _verbose, &_node, _ignoreTraverseNodeTypeNames );
472  }
473  } else if ( MFNode* mf_node= dynamic_cast< MFNode * >( f ) ) {
474  const NodeVector& children= mf_node->getValue();
475  for ( NodeVector::const_iterator j = children.begin(); j != children.end(); ++j ) {
476  Node* c= *j;
477  if ( c ) {
478  if ( _verbose ) {
479  Console(LogLevel::Error) << "Node::findNodes(): " << _node.getName() << " -> " << f->getName() << endl;
480  }
481  findNodes ( *c, _result, _nodeName, _parentMap, _searchFieldNames, _typeNames, _exactNodeName, _verbose, &_node, _ignoreTraverseNodeTypeNames );
482  }
483  }
484  }
485  }
486  }
487  }
488  }
489 
490  protected:
491  SAI::Browser SAI_browser;
492 
493  static H3DUtil::MutexLock callback_lock;
494 
495  static ProgramSettings program_settings;
496 
497  typedef std::list< std::pair< CallbackFunc, void * > > CallbackList;
498  typedef std::list< std::pair< ProgramSettingsCallbackFunc, void * > > ProgramSettingsCallbackList;
499  // A list of the callback functions to run.
500  static CallbackList callbacks;
501  static ProgramSettingsCallbackList program_settings_callbacks;
502 
506  class EventSink: public Field {
507  public:
510  setName( "Scene::eventSink" );
511  }
512  ~EventSink(){
513  }
514  protected:
515  virtual void update();
516  };
517 
518  public:
520  static H3DUniquePtr<EventSink> eventSink;
521 
522  private:
523  bool active;
524  // the time of the start of the last loop.
525  TimeStamp last_time;
526  // the TraverseInfo instance from the previous scenegraph loop.
527  TraverseInfo *last_traverseinfo;
528  // Reference to shadow caster used to cast shadows for shapes
529  // in scene graph.
530  AutoRef< ShadowCaster > shadow_caster;
531 
532 #ifdef HAVE_NVAPI
533  static bool NVOptions_applied;
534 #endif // HAVE_NVAPI
535 
537  H3DTime last_unused_texture_check;
538  public:
540  static void removeCallback(void *data ) {
541  callback_lock.lock();
542  for( CallbackList::iterator i = callbacks.begin(); i != callbacks.end(); ++i ) {
543  if( (*i).second == data ) {
544  callbacks.erase( i );
545  break;
546  }
547  }
548  callback_lock.unlock();
549  }
550  };
551 }
552 
553 #endif
Header file for H3DWindowNode.
Header file for NvidiaGraphicsOptions.
Header file for common SAI interface classes and functions for use by script engine implementations s...
Header file for ShadowCaster.
Header file for X3DChildNode, X3D scene-graph node.
const_iterator end() const
std::vector< RefCountedClassType * >::const_iterator const_iterator
void push_back(const value_type &x)
const_iterator begin() const
std::string getTypeName() const
std::string getName() const
The Field class.
Definition: Field.h:46
string getName()
Gets the name of the field.
Definition: Field.cpp:417
@ INPUT_ONLY
The value of the field can only set, not read.
Definition: Field.h:67
AccessType getAccessType()
Get the access type of the field.
Definition: Field.h:215
The FieldDBConstIterator is an iterator class used for iterating over the field instances in an H3DNo...
Definition: H3DNodeDatabase.h:217
MFNode is almost like any MField but it encapsulates a vector of Node pointers.
Definition: MFNode.h:44
Node is the base class for all classes that can be part of the H3D scene-graph.
Definition: Node.h:46
SFNode is almost like any SField but it encapsulates a pointer to a Node.
Definition: SFNode.h:45
The EventSink class makes all fields up-to-date what are routed to it, with the exception of Periodic...
Definition: Scene.h:506
EventSink()
Constructor.
Definition: Scene.h:509
The Scene node is topmost node that takes care of the rendering of the scene graph both haptically an...
Definition: Scene.h:56
static void addCallback(CallbackFunc func, void *data)
Add a callback function to be called after scene traversal and rendering.
Definition: Scene.h:241
static set< Scene * > scenes
All instances of Scene that has been created.
Definition: Scene.h:218
H3DUniquePtr< SFFloat > frameRate
The instantaneous frame rate of the scene.
Definition: Scene.h:172
bool isActive()
Returns if the Scene instance is active or not.
Definition: Scene.h:127
TraverseInfo * getLastTraverseInfo()
Returns the TraverseInfo from the previous sceneRoot traversal.
Definition: Scene.h:116
static void findNodes(Node &_node, AutoRefVector< NodeType > &_result, const std::string &_nodeName="", NodeParentsMap *_parentMap=NULL, SearchFieldNameMap *_searchFieldNames=NULL, StringVec *_typeNames=NULL, bool _exactNodeName=true, bool _verbose=false, Node *_parent=NULL, StringVec *_ignoreTraverseNodeTypeNames=NULL)
Finds all the nodes of a given type (and optional name) by searching downwards from _node through all...
Definition: Scene.h:403
H3DUniquePtr< SFChildNode > sceneRoot
The scene graph to render in this scene.
Definition: Scene.h:162
CallbackCode
Return code for callback functions.
Definition: Scene.h:228
@ CALLBACK_DONE
The callback is done and should not be called any more.
Definition: Scene.h:230
static H3DUniquePtr< EventSink > eventSink
Any field routed to this field will be updated once per frame.
Definition: Scene.h:520
H3DUniquePtr< SFFloat > maxFrameRate
A desired maximum frame rate (Hz).
Definition: Scene.h:182
SAI::Browser * getSAIBrowser()
Returns the SAI::Browser object for this Scene.
Definition: Scene.h:144
static void removeCallback(void *data)
Remove a callback function by finding a callback with the same data adress.
Definition: Scene.h:540
static H3DNodeDatabase database
The H3DNodeDatabase for this node.
Definition: Scene.h:225
static H3DUniquePtr< SFTime > time
Current time within the simulation, updated during each graphic loop.
Definition: Scene.h:214
void setActive(bool _active)
Set whether this Scene instance should be active or not.
Definition: Scene.h:122
H3DUniquePtr< MFWindow > window
The windows to render into this scene.
Definition: Scene.h:167
The ShadowCaster node uses shadow volumes using stencil buffer to cast shadows from objects in a scen...
Definition: ShadowCaster.h:99
TraverseInfo is a structure that is passed along when traversing the scene graph.
Definition: TraverseInfo.h:57
Template to make sure that the Nodes that are added to a MFNode are of a specified Node type.
Definition: MFNode.h:221
Template to make sure that the Node that is set in a SFNode is of a specified Node type.
Definition: SFNode.h:97
This abstract node type indicates that concrete node types derived from it contain children nodes and...
Definition: X3DGroupingNode.h:53
double H3DTime
H3D API namespace.
Definition: Anchor.h:38
The H3DNodeDatabase contains a mapping between a name of a Node and the constructor for the Node with...
Definition: H3DNodeDatabase.h:194
FieldDBConstIterator fieldDBEnd()
Returns an iterator pointing at the end of fields in the H3DNodeDatabase.
Definition: H3DNodeDatabase.h:435
FieldDBConstIterator fieldDBBegin()
Gets an iterator to the beginning first field in the H3DNodeDatabase.
Definition: H3DNodeDatabase.h:430
static H3DNodeDatabase * lookupNodeInstance(const Node *n)
Get the database for a specific node instance.
Definition: H3DNodeDatabase.cpp:386