Basic Image AlgorithmS Library  2.8.0
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
SceneOpenSceneGraph.cpp
1 #include <bias_config.h>
2 #include <Gui/biasgl.h>
3 
4 #include "SceneOpenSceneGraph.hh"
5 #include <GLviewer/OpenSceneGraphHelper.hh>
6 
7 #include <GLviewer/GLProjectionParametersInterface.hh>
8 #include <Base/Common/FileHandling.hh>
9 #include <Base/Debug/Debug.hh>
10 #include <osg/CameraNode>
11 #include <osg/Depth>
12 #include <osg/Geometry>
13 #include <osg/BlendEquation>
14 #include <osg/CullFace>
15 #include <osg/FrontFace>
16 #include <osg/LightSource>
17 #include <osg/Switch>
18 #include <osg/Stencil>
19 #include <osg/MatrixTransform>
20 #include <osg/BlendFunc>
21 #include <osgShadow/ShadowedScene>
22 #include <osgShadow/ShadowMap>
23 #include <osg/Version>
24 
25 //------ for osg animation ----
26 //#include <osgAnimation/>
27 
28 // ----- for mirror --------
29 #include <osg/AlphaFunc>
30 #include <osg/Node>
31 #include <osg/Geometry>
32 #include <osg/Geode>
33 #include <osg/Notify>
34 #include <osg/ClipNode>
35 #include <osg/AnimationPath>
36 #include <osgDB/ReadFile>
37 #include <osgDB/WriteFile>
38 #include <osgUtil/Optimizer>
39 #include <osgViewer/Viewer>
40 #include <iostream>
41 // ------- for particles -------
42 #include <osgParticle/Particle>
43 #include <osgParticle/ParticleSystem>
44 #include <osgParticle/ParticleSystemUpdater>
45 #include <osgParticle/ModularEmitter>
46 #include <osgParticle/MultiSegmentPlacer>
47 #include <osgParticle/ModularProgram>
48 #include <osgParticle/AccelOperator>
49 #include <osgParticle/FluidFrictionOperator>
50 
51 // ------- for fx -------------
52 #include <osgFX/Registry>
53 #include <osgFX/Effect>
54 #include <osgFX/BumpMapping>
55 
56 #include <GLviewer/Scenes/NodeInfoOpenSGVisitor.hh>
57 #include <osgDB/WriteFile>
58 #include <cctype>
59 
60 #ifdef WIN32
61 # include <direct.h> // for _getcwd
62 #endif
63 
64 using namespace std;
65 using namespace BIAS;
66 using namespace BIAS;
67 
68 
69 //////////////////////////////////////////////////////////////////////////
70 //////////////////////////////////////////////////////////////////////////
71 
72 
73 SceneOpenSceneGraph::
74 SceneOpenSceneGraph(bool redirect) : SceneBase(), timer_(), startTick_()
75 {
76  NewDebugLevel("D_SCENEOSG");
77  NewDebugLevel("D_SCENEOSG_MatrixTransform");
78  AddDebugLevel("D_SCENEOSG");
79  AddDebugLevel("D_SCENEOSG_MatrixTransform");
80  Reset();
81 }
82 
83 
86 {
87  if(initialized_) Reset();
88 }
89 
90 
93 {
94  animate_= false;
95  clearMask_ =GL_COLOR_BUFFER_BIT| GL_DEPTH_BUFFER_BIT;
96  initialized_ = false;
97  sceneView_ = NULL;
98  rootTree_ = NULL;
99  lightTransform_ = NULL;
102  frameStamp_ = NULL;
103  frameNumber_ = 0;
104  headlight_ = true;
105  timeOffset_ =0;
106  lastPauseTime_ =0;
108 }
109 
110 
113 {
114  if (initialized_)
115  {
116  BIASERR("Init on SceneOpenSceneGraph should only be called "
117  "once: skipping\n");
118  return 1;
119  }
120 
122  initialized_ = true;
123  animTime_ = 0.0;
124  osg::setNotifyLevel(osg::ALWAYS);//disable osg debugspam
125  return 0;
126 }
127 
128 
131 {
132  // From the FAQ:
133  // NOTE: The call to setComputeNearFarMode is very important. If you don't
134  // do this, then OSG will use a different near and far plane when rendering
135  // its objects, and they will have different values in the depth-buffer than
136  // the rest of your scene. This can lead to very odd effects.
137 
138  sceneView_ = new osgViewer::Viewer;
139  // params of window are overwritten in draw.
140  embedWindow_ = sceneView_->setUpViewerAsEmbeddedInWindow(0, 0, 800, 600);
141  // clear to black
142  sceneView_->getCamera()->setClearColor(osg::Vec4(255.0f, 255.0f, 255.0f, 1.0f));
143  sceneView_->getCamera()->setClearMask(clearMask_);
144  sceneView_->getCamera()->setComputeNearFarMode(osg::CullSettings::DO_NOT_COMPUTE_NEAR_FAR);
145  sceneView_->setLightingMode(osg::View::HEADLIGHT); //NO_LIGHT,HEADLIGHT
146 
147  // the Light
148  light_= new osg::Light;
149 
150  light_->setLightNum( 0 );
151  light_->setAmbient( osg::Vec4( .3f, .3f, .3f, 1.0f ));
152  // light_->setAmbient( osg::Vec4(1.0f,1.0f,1.0f,1.0f ));
153  light_->setDiffuse( osg::Vec4( 1.0f, 1.0f, 1.0f, 1.0f ));
154  light_->setSpecular( osg::Vec4( 1.0f, 1.0f, 1.0f, 1.0f ));
155 
156  sceneView_->setLight(light_.get());
157 
158  sceneView_->realize();
159 
160  rootTree_ = new osg::Group();
161  rootTree_ ->setName(SOSG_ROOT_NODE_NAME);
162  SetNodeVisible(rootTree_.get(), true);
163  sceneView_->setSceneData(rootTree_.get());
164 
165  // enable lighting
166  osg::StateSet* state = rootTree_->getOrCreateStateSet();
167  state->setMode(GL_LIGHTING, osg::StateAttribute::ON);
168  state->setMode(GL_LIGHT0, osg::StateAttribute::ON);
169  //state->setMode(GL_LIGHTING,osg::StateAttribute::OVERRIDE|osg::StateAttribute::OFF);
170  state->setMode(GL_NORMALIZE, osg::StateAttribute::ON);
171 
172  //enable culling
173  //state->setMode(GL_CULL_FACE,osg::StateAttribute::ON);
174  // ich geb dir gleich "disable culling" !!!
175  //state->setMode(GL_CULL_FACE,osg::StateAttribute::OVERRIDE|osg::StateAttribute::OFF);
176 
177  // MatrixTransform
178  lightTransform_ = new osg::MatrixTransform;
179  osg::Matrix m;
180  m.makeTranslate(osg::Vec3(0., 0., 0.));
181  lightTransform_->setMatrix(m);
182  lightTransform_->setName(SOSG_LIGHT_TRANSFORM_NAME);
183  SetNodeVisible(lightTransform_.get(), false);
184  rootTree_->addChild(lightTransform_.get());
185 
186  // LightSource
187  osg::ref_ptr<osg::LightSource> lightSource = new osg::LightSource;
188  lightSource->setReferenceFrame(osg::LightSource::ABSOLUTE_RF);
189  lightSource->setLight(light_.get());
190  lightSource->setName(SOSG_LIGHT_SOURCE_NAME);
191 
192  SetNodeVisible(lightSource.get(), false);
193  lightTransform_->addChild(lightSource.get());
194 
195  // Switch
196  lightRepresentationSwitch_ = new osg::Switch;
197  lightSource->addChild(lightRepresentationSwitch_.get());
199  lightRepresentationSwitch_->setName(SOSG_LIGHT_REPRESENTATION_SWITCH_NAME);
200  // Geode(Sphere)
201  osg::ShapeDrawable *lightRepresentation = new osg::ShapeDrawable(
202  new osg::Sphere(osg::Vec3(0., 0., 0.), 20.0));
203  lightRepresentation->setColor(osg::Vec4(1., 1., 0., 1.)); // yellow
204  lightRepresentationGeode_ = new osg::Geode;
205  lightRepresentationGeode_->addDrawable(lightRepresentation);
206  lightRepresentationGeode_->setName(SOSG_LIGHT_REPRESENTATION_GEODE_NAME);
207 
211 
212  // enable animations using the frameStamp
213  frameStamp_ = new osg::FrameStamp();
214  sceneView_->setFrameStamp(frameStamp_.get());
215  startTick_ = osg::Timer::instance()->tick();
216 
217  //MakeRootShadowNode(lightSource);
218  SetFixedPointLight(true,Vector3<double> (10, 10, 10));
219 }
220 
221 class disableZwriteNodeVisitor : public osg::NodeVisitor
222 {
223 public:
224  // Default constructor - initialize searchForName to "" and
225  // set the traversal mode to TRAVERSE_ALL_CHILDREN
226  disableZwriteNodeVisitor()
227  : osg::NodeVisitor(TRAVERSE_ALL_CHILDREN)
228  {}
229 
230  virtual void apply(osg::Geode &node)
231  {
232  unsigned num_drawables = node.getNumDrawables();
233  for (unsigned int i=0; i<num_drawables; i++)
234  {
235  osg::Drawable* dr = node.getDrawable(i);
236  if (dr)
237  {
238  osg::StateSet* sts = dr->getStateSet();
239  if(sts)
240  {
241  if(sts->getMode(GL_BLEND)==osg::StateAttribute::ON)
242  {
243  osg::Depth* pDepth = new osg::Depth();
244  pDepth->setWriteMask(false);
245  sts->setAttributeAndModes(pDepth, osg::StateAttribute::OVERRIDE |
246  osg::StateAttribute::ON);
247  sts->setMode(GL_CULL_FACE, osg::StateAttribute::ON |
248  osg::StateAttribute::OVERRIDE );
249  osg::CullFace *cullFace = new osg::CullFace(osg::CullFace::BACK);
250  sts->setAttribute(cullFace);
251  osg::BlendFunc* pBlendFunc = new osg::BlendFunc(osg::BlendFunc::SRC_ALPHA,
252  osg::BlendFunc::ONE_MINUS_SRC_ALPHA);
253  sts->setAttributeAndModes(pBlendFunc, osg::StateAttribute::OVERRIDE |
254  osg::StateAttribute::ON);
255  sts->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
256  }
257  }
258  }
259  }
260  }
261  virtual void apply(osg::ClearNode &node)
262  {
263  //cout << "c"<<flush;
264  node.setClearMask(0);
265  }
266 };
267 
268 
271 {
272  //rootTree_
273  disableZwriteNodeVisitor vis;
274  rootTree_->accept(vis);
275 }
276 
277 
280 {
283  //cout << "lightRepresentationVisible: "<<boolalpha<<lightRepresentationVisible_<<endl;
284 }
285 
286 
289 {
290  SetNodeOccluder(node.get(),false);
291  rootTree_->addChild(node.get());
292  rootTree_->dirtyBound();
293 
294 }
295 
296 
299 {
300  SetNodeOccluder(node.get(),false);
301  osg::ref_ptr<osg::Switch> sw = new osg::Switch;
302  if ((node->getName()).empty()) {
303  sw->setName(SOSG_SWITCH_PREFIX+(string) "Whatever");
304  } else {
305  sw->setName(SOSG_SWITCH_PREFIX+node->getName());
306  }
307  SetNodeVisible(sw.get(), false);
308  sw->addChild(node.get());
309  NodeInfoMap_[node.get()].NodeType = NodeType;
310  OpenSceneGraphHelper::AddOrSetInfo(node, SOSG_KEY_NODE_TYPE,
311  NodeType2String(NodeType));
312  sw->setAllChildrenOn(); //enable rendering of all osg:switch children
313  // assigning RenderBin 10 for occluding possibilities
314  osg::StateSet *stateset = (node.get())->getOrCreateStateSet();
315  stateset->setRenderBinDetails( 10, "RenderBin");
316  rootTree_->addChild(sw.get());
317  NodeInfoMap_[sw.get()].NodeType = NodeType;
318  OpenSceneGraphHelper::AddOrSetInfo(sw, SOSG_KEY_IS_MODEL_SWITCH,
319  "TRUE");
320  rootTree_->dirtyBound();
321  node = sw.get(); // HACK, not very well tested, friso 2009-04
322  SetNodeOccluder(node.get(), false);
323  return 0;
324 }
325 
326 
328 AppendSubTreeFromFile(const std::string& fileName,
330  bool optimize)
331 {
332  string path, base, suffix;
333  FileHandling::SplitName(fileName, path, base, suffix);
334  // hack to work with openvrml 0.14.3 and drive letters c:, d:, ...
335 #ifdef WIN32
336  char currentdir[255];
337  if (path!="") {
338  _getcwd(currentdir,255);
339  int res = _chdir(path.c_str());
340  if (res<0) return -1;
341  }
342  node = osgDB::readNodeFile((base+suffix).c_str());
343 #else
344  node = osgDB::readNodeFile(fileName.c_str());
345 #endif
346 
347 #ifdef WIN32
348  if (path!="")
349  _chdir(currentdir);
350 #endif
351 
352  if (!node)
353  {
354  BIASWARN("Could not read 3d-model-file "<<fileName<<endl);
355  return -1;
356  }
357 
358  string name = ((node->getName()).empty()) ? (base) : (node->getName());
359 
360  // add a switch node
361  osg::ref_ptr<osg::Switch> sw = new osg::Switch;
362  sw->setName(SOSG_SWITCH_PREFIX+name);
363  OpenSceneGraphHelper::AddOrSetInfo(sw, SOSG_KEY_IS_MODEL_SWITCH,
364  "TRUE");
365  SetNodeVisible(sw.get(), false);
366 
367  std::transform(suffix.begin(), suffix.end(), suffix.begin(), (int
368  (*)(int)) std::tolower);
369  BCDOUT(D_SCENEOSG_MatrixTransform, "suffix: "<<suffix<< endl);
370  if (suffix == ".wrl"){
371  BCDOUT(D_SCENEOSG_MatrixTransform, "found wrl file\n");
372  // osg wrl import automatically adds a transform node (rotation around
373  // x-axis). This needs to be dropped
374  osg::MatrixTransform *mt =
375  dynamic_cast<osg::MatrixTransform *> (node.get());
376  if (mt && mt->getNumChildren() == 1){
377  osg::Node *child = mt->getChild(0);
378  BCDOUT(D_SCENEOSG_MatrixTransform, "dropping matrix transform node\n");
379  node = child;
380  }
381  }
382 
383  // try to compensate the rotation of the model...
384 // osg::ref_ptr<osg::MatrixTransform> mt;
385 // if(suffix == ".osg"){
386 // BCDOUT(D_SCENEOSG_MatrixTransform, "found wrl file, adding matrix "
387 // <<"transform for compensation\n");
388 // // osg wrl export automatically adds a transform node (rotation around
389 // // x-axis). This needs to be compensated
390 // mt = new osg::MatrixTransform(osg::Matrix(1, 0, 0, 0, 0, 0, 1, 0, 0, 1,
391 // 0, 0, 0, 0, 0, 1));
392 // mt->addChild(node);
393 // mt->setName(node->getName());
394 // node = mt.get();
395 // }
396 
397  //what if no transform node is there? e.g. when loading a 3ds file?
398  if(!dynamic_cast<osg::MatrixTransform *>(node.get())){
399  osg::MatrixTransform *mt = new osg::MatrixTransform();
400  mt->addChild(node.get());
401  node = mt;
402  }
403  node->setName(name);
404  sw->addChild(node.get());
405 
406  // assigning RenderBin 10 for occlusion
407  osg::StateSet *stateset = (node.get())->getOrCreateStateSet();
408  stateset->setMode( GL_RESCALE_NORMAL, osg::StateAttribute::ON );
409  stateset->setRenderBinDetails( 10, "RenderBin");
410  NodeInfoMap_[node.get()].NodeType = eNT_FromDisk;
411  NodeInfoMap_[node.get()].FileName = fileName;
412  NodeInfoMap_[node.get()].Name = FileHandling::Basename(fileName);
413  NodeInfoMap_[node.get()].IsEditable = true;
414  OpenSceneGraphHelper::AddOrSetInfo(node, SOSG_KEY_NODE_TYPE,
416  OpenSceneGraphHelper::AddOrSetInfo(node, SOSG_KEY_FILE_NAME,
417  fileName);
418  OpenSceneGraphHelper::AddOrSetInfo(node, SOSG_KEY_NAME,
419  FileHandling::Basename(fileName) +
420  FileHandling::Suffix(fileName));
421  OpenSceneGraphHelper::AddOrSetInfo(node, SOSG_KEY_IS_EDITABLE, "TRUE");
422 
423  // swap childeNode with Switch node
424  node = sw.get();
425 
426  AppendSubTree(node);
427 
428  // find animation in subtree
429  AnimationManagerFinder finder;
430  node->accept(finder);
431  if (finder._am.valid()) {
433 
434  osgAnimation::AnimationList animlst = finder._am->getAnimationList();
435  osg::ref_ptr<osgAnimation::Animation> animation = animlst[0];
436  std::cout << "Animation Duration: " << animation->getDuration() << ", Starttime: " << animation->getStartTime() << std::endl;
437 
438  animationManager_.registerAnimation(animation);
439 #ifdef WIN32
440  animation->setPlaymode(osgAnimation::Animation::ONCE);
441 #else
442  animation->setPlayMode(osgAnimation::Animation::ONCE);
443 #endif
444  node->setUpdateCallback(&animationManager_);
445 
446  std::cout << "found animation" << std::endl;
447  }
448 
449 
450  sw->setAllChildrenOn();
451 
452  NodeInfoMap_[sw.get()].NodeType = eNT_FromDisk;
453  NodeInfoMap_[sw.get()].FileName = fileName;
454  OpenSceneGraphHelper::AddOrSetInfo(sw, SOSG_KEY_IS_MODEL_SWITCH,
455  "TRUE");
456 
457  rootTree_->dirtyBound();
458  //fix transparent nodes
459  // disabled fkellner
460  //DisableZWriteForTransparentNodes_();
461  return 0;
462 }
463 
464 
466 AppendSubTreeFromImageFile(const string& fileName,
467  const double& width_mm,
468  osg::ref_ptr<osg::Node>& imageNode)
469 {
470  if ( !imageNode.valid() ) return -1;
471  osg::ref_ptr<osg::MatrixTransform> mt = new osg::MatrixTransform();
472  SetNodeVisible(mt.get(), true);
473  SetNodeOccluder(mt.get(), false);
474  mt->addChild(imageNode);
475 
476  osg::ref_ptr<osg::Switch> sw = new osg::Switch;
477  SetNodeVisible(sw.get(), false);
478  if (fileName.empty()) {
479  sw->setName(SOSG_SWITCH_PREFIX+(string)"Image");
480  mt->setName((string)"Image");
481  } else {
482  sw->setName(SOSG_SWITCH_PREFIX+FileHandling::Basename(fileName));
483  mt->setName(FileHandling::Basename(fileName));
484  }
485  sw->addChild(mt);
486 
487  NodeInfoMap_[mt.get()].FileName = fileName;
488  NodeInfoMap_[mt.get()].Name = FileHandling::Basename(fileName);
489  NodeInfoMap_[mt.get()].NodeType = eNT_FromImageFile;
490  NodeInfoMap_[mt.get()].SizeMM = width_mm;
491  NodeInfoMap_[mt.get()].IsEditable = true;
492  OpenSceneGraphHelper::AddOrSetInfo(mt, SOSG_KEY_NODE_TYPE,
494  OpenSceneGraphHelper::AddOrSetInfo(mt, SOSG_KEY_FILE_NAME,
495  fileName);
496  OpenSceneGraphHelper::AddOrSetInfo(mt, SOSG_KEY_NAME,
497  FileHandling::Basename(fileName) +
498  FileHandling::Suffix(fileName));
499  OpenSceneGraphHelper::AddOrSetInfo(mt, SOSG_KEY_IS_EDITABLE, "TRUE");
500  ostringstream oss;
501  oss << setprecision(7) << width_mm ;
502  OpenSceneGraphHelper::AddOrSetInfo(mt, SOSG_KEY_SIZE_MM, oss.str());
503 
504  // enable rendering of all osg:switch children
505  sw->setAllChildrenOn();
506  // assigning RenderBin 10 for occluding possibilities
507  osg::StateSet *stateset = (mt.get())->getOrCreateStateSet();
508  stateset->setRenderBinDetails( 10, "RenderBin");
509  rootTree_->addChild(sw.get());
510  rootTree_->dirtyBound();
511 
512  imageNode = sw.get(); // HACK, not very well tested, friso 2009-04
513  NodeInfoMap_[imageNode.get()].FileName = fileName;
514  NodeInfoMap_[imageNode.get()].Name = FileHandling::Basename(fileName);
515  NodeInfoMap_[imageNode.get()].NodeType = eNT_FromImageFile;
516  NodeInfoMap_[imageNode.get()].SizeMM = width_mm;
517  NodeInfoMap_[imageNode.get()].IsEditable = true;
518  //SetNodeOccluder(imageNode.get(), false);
519  OpenSceneGraphHelper::AddOrSetInfo(sw, SOSG_KEY_IS_MODEL_SWITCH,
520  "TRUE");
521  return 0;
522 }
523 
524 
527 {
528  NodeInfoMap_.clear();
530 }
531 
532 
534 RemoveSubTreeAndParents(osg::Node* Node)
535 {
536  if (!Node)
537  return;
538  //find top parent below global root
539  osg::Node::ParentList parlist = Node->getParents();
540  osg::Node* actnode = Node;
541  if (parlist.size() != 0)
542  {
543  osg::Group* pargoup = parlist[0];
544  while (pargoup != rootTree_.get())
545  {
546  actnode = pargoup;
547  parlist = actnode->getParents();BIASASSERT(parlist.size()!=0);//this happens if node isn't in rootree
548  pargoup = parlist[0];
549  }
550  }
551  //remove sub tree
552  RemoveSubTree(actnode);
553  rootTree_->dirtyBound();
554 }
555 
556 
559 {
560  //delete entries of subtreenodes from nodeinfomap:
561  NodeInfoEraseOp erasor;
562  NodeInfoOpenSGVisitor erasevisitor(&NodeInfoMap_, &erasor);
563  childNode->accept(erasevisitor);
564  //delete osg nodes
565  if (!rootTree_->removeChild(childNode.get())){
566  BIASERR("not a valid child node "<<childNode.get());
567  }
568  rootTree_->dirtyBound();
569 }
570 
571 
573 SaveSubTree(osg::Node *node, const std::string &fileName)
574 {
575  if (!node)
576  {
577  return false;
578  }
579  osg::Node *myNode = node;
580 
581  string path, base, suffix;
582  FileHandling::SplitName(fileName, path, base, suffix);
583 
584  std::transform(suffix.begin(), suffix.end(), suffix.begin(), (int
585  (*)(int)) std::tolower);
586  BCDOUT(D_SCENEOSG_MatrixTransform, "saving suffix: "<<suffix<< endl);
588  if (suffix == ".wrl")
589  {
590  BCDOUT(D_SCENEOSG_MatrixTransform, "found wrl file, adding matrix "
591  <<"transform for compensation\n");
592  // osg wrl export automatically adds a transform node (rotation around
593  // x-axis). This needs to be compensated
594  mt = new osg::MatrixTransform(osg::Matrix(1, 0, 0, 0, 0, 0, 1, 0, 0, -1,
595  0, 0, 0, 0, 0, 1));
596  mt->addChild(node);
597  mt->setName(node->getName());
598  myNode = mt.get();
599  }
600 
601  osgDB::writeNodeFile(*myNode, fileName);
602 
603  return true;
604 }
605 
606 
607 /*
608 void SceneOpenSceneGraph::
609 MergeTransforms_(osg::Node *node)
610  {
611  if(!node) {
612  BCDOUT(D_SCENEOSG_IdentifyMatrixTransform, "zero node\n");
613  return;
614  }
615 
616  // check if parent is also a matrix transform
617  if (node->getNumParents()!=0){
618  osg::Node *parent = node->getParent(0);
619  osg::Transform* t = parent->asTransform();
620  osg::MatrixTransform* tm = 0;
621  if(t) {
622  tm = t->asMatrixTransform();
623  }
624  if(tm && t) {
625  // parent is matrix transfrom, Merge must be called from topmost node
626  return MergeTransforms_(parent);
627  }
628  }
629 
630  // check for child amd grandchild
631 
632 
633 
634  // check if node is matrix transform
635  osg::Transform* t = node->asTransform();
636  if(!t) {
637  BCDOUT(D_SCENEOSG_IdentifyMatrixTransform, "not a transform node\n");
638  return;
639  }
640  osg::MatrixTransform* tm = t->asMatrixTransform();
641  if(!tm) {
642  BCDOUT(D_SCENEOSG_IdentifyMatrixTransform, "not a matrix transform node\n");
643  return;
644  }
645  osg::Matrix m = tm->getMatrix();
646 
647  // check if child is also a matrix transform
648  t = child->asTransform();
649  if(!t) {
650  BCDOUT(D_SCENEOSG_IdentifyMatrixTransform, "not a transform node\n");
651  return;
652  }
653  tm = t->asMatrixTransform();
654  if(!tm) {
655  BCDOUT(D_SCENEOSG_IdentifyMatrixTransform, "not a matrix transform node\n");
656  return;
657  }
658  osg::Matrix cm = tm->getMatrix();
659 
660  // check
661 
662 }
663 */
664 
665 
667 RemoveSubTree(osg::Node* childNode)
668 {
669  if (!childNode)
670  return;
671  //delete entries of subtreenodes from nodeinfomap:
672  NodeInfoEraseOp erasor;
673  NodeInfoOpenSGVisitor erasevisitor(&NodeInfoMap_, &erasor);
674  childNode->accept(erasevisitor);
675  //delete osg nodes
676  if (!rootTree_->removeChild(childNode))
677  {
678  BIASERR("not a valid child node "<<childNode);
679  }
680 }
681 
682 
684 Save(std::string filename)
685 {
686  //iterate through all nodeinfoentries
687  std::map<osg::Node*, NodeInfo>::iterator it;
688  for (it = NodeInfoMap_.begin(); it != NodeInfoMap_.end(); it++)
689  {
690  osg::Node* node = (*it).first;
691  if (!node)
692  {
693  BIASWARN("Null pointer in nodeinfo list");
694  continue;
695  }
696  //get node ptr and generate id string from it
697  (*it).second.Id = NodePtr2IDString_(node);
698  //save name of node
699  (*it).second.Name = node->getName();
700  node->setName((*it).second.Id);
701  }
702  std::string dir;
703  std::string base;
704  std::string suffix;
705  //export nodeinfomap as xmlfile
706  FileHandling::SplitName(filename, dir, base, suffix);
707 
708  if (NodeInfoMap_.XMLWrite(dir + base + ".xml") != 0)
709  return false;
710 
711  //export complete scene graph
712  string ivename = dir + base + ".ive";
713  //why do we write only ive, there os a seg fault in attempting to write 3ds
714  //string ivename = dir + base + suffix;
715  if (!osgDB::writeNodeFile(*rootTree_, ivename))
716  {
717  return false;
718  }
719  //restore node names
720  for (it = NodeInfoMap_.begin(); it != NodeInfoMap_.end(); it++)
721  {
722  osg::Node* node = (*it).first;
723  if (!node)
724  {
725  BIASWARN("Null pointer in nodeinfo list");
726  continue;
727  }
728  node->setName((*it).second.Name);
729  }
730  return true;
731 }
732 
733 
735 Load(std::string filename)
736 {
737  std::string dir;
738  std::string base;
739  std::string suffix;
740  //export nodeinfomap as xmlfile
741  FileHandling::SplitName(filename, dir, base, suffix);
742 
743  osg::ref_ptr<osg::Node> tempNode;
744  string modelfilename = dir + base + ".ive";
745 
746  tempNode = osgDB::readNodeFile(modelfilename);
747  if (!tempNode)
748  return false;
749  osg::ref_ptr<osg::Group> tempGroup;
750  tempGroup = tempNode->asGroup();
751  if (!tempGroup)
752  {
753  BIASWARN("not a valid scene tree file");
754  return false;
755  }
756 
757  //load nodeinfos
758  NodeInfoMap tempMap; //contains invalid pointers as key
759  string xmlpath = dir + base + ".xml";
760  if (tempMap.XMLRead(xmlpath) != 0)
761  {
762  BIASWARN(xmlpath<<" not found");
763  return false;
764  }
765  NodeInfoMap_.clear(); //clear map and rebuild it from tempmap
766  //visit all treenodes check for nodeinfo in tempmap and correct
767  //node name and add new node info with corrected pointer to NodeInfoMap_
769  op.targetMap = &NodeInfoMap_;
770  NodeInfoOpenSGVisitor namerestorevisitor(&tempMap, &op);
771  tempGroup->accept(namerestorevisitor); //here we go...
772 
773  //copy new root ptr to rootnode
774  rootTree_ = tempGroup;
775  sceneView_->setSceneData(rootTree_.get());
776  return true;
777 }
778 
779 
780 std::string SceneOpenSceneGraph::
781 NodePtr2IDString_(osg::Node* node)
782 {
783  stringstream ss;
784  ss.fill('0');
785  ss << node; //stream the pointer to string
786  return (ss.str());
787 }
788 
789 
791 SetFixedPointLight(bool on, Vector3<double> posPointLight)
792 {
793  if(!on){
794  light_->setAmbient( osg::Vec4( .0f, .0f, .0f, .0f ));
795  light_->setDiffuse( osg::Vec4( .0f, .0f, .0f, .0f ));
796  light_->setSpecular( osg::Vec4( .0f, .0f, .0f, .0f ));
797  }
798  else{
799  light_->setAmbient( osg::Vec4( .3f, .3f, .3f, 1.0f ));
800  // light_->setAmbient( osg::Vec4(1.0f,1.0f,1.0f,1.0f ));
801  light_->setDiffuse( osg::Vec4( 1.0f, 1.0f, 1.0f, 1.0f ));
802  light_->setSpecular( osg::Vec4( 1.0f, 1.0f, 1.0f, 1.0f ));
803 
804 
805  headlight_ = false;
806  osg::Matrix m;
807  m.makeTranslate(osg::Vec3(posPointLight[0], posPointLight[1],
808  posPointLight[2]));
809  lightTransform_->setMatrix(m);
810  }
811 }
812 
813 
815 SetFixedDirectionalLight(bool on, Vector3<double> dirDirectionalLight)
816 {
817  // BIASERR("unfinished");
818 }
819 
820 
823 {
824  headlight_ = on;
825 }
826 
827 
829 SetAnimate(const bool animate)
830 {
831  animate_ = animate;
832  osg::Timer_t t1 = osg::Timer::instance()->tick();
833  double time = osg::Timer::instance()->delta_s(startTick_, t1);
834  if (animate_)
835  {
836  timeOffset_ += time - lastPauseTime_;
837  }
838  else
839  {
840  lastPauseTime_ = time;
841  }
842 }
843 
844 
845 
846 class transparentColourValueVisitor : public osg::ValueVisitor
847 {
848 public:
849  transparentColourValueVisitor() :
850  osg::ValueVisitor(), transparency_(0.5)
851  {
852  }
853 
854  transparentColourValueVisitor(const double transparency) :
855  osg::ValueVisitor(), transparency_(transparency)
856  {
857  }
858 
859  virtual void
860  apply(osg::Vec4 &v)
861  {
862  v[3] = 1.0 - transparency_;
863  }
864 
865  virtual void apply(osg::Vec4ub &v)
866  { v[3] = (unsigned char)(255.0*(1.0-transparency_)); }
867 
868 private:
869  double transparency_;
870 };
871 
872 class transparentColourArrayVisitor : public osg::ArrayVisitor
873 {
874 public:
875  transparentColourArrayVisitor() :
876  osg::ArrayVisitor(), transparency_(0.5)
877  {
878  }
879 
880  transparentColourArrayVisitor(const double transparency) :
881  osg::ArrayVisitor(), transparency_(transparency)
882  {
883  }
884 
885  virtual void
886  apply(osg::Vec4Array &va)
887  { //cout << "a" << flush;
888  transparentColourValueVisitor tcvv(transparency_);
889  const unsigned num = va.getNumElements();
890  for (unsigned i = 0; i < num; i++)
891  {
892  va.accept(i, tcvv);
893  }
894  }
895 
896  virtual void apply(osg::Vec4ubArray &va)
897  {
898  transparentColourValueVisitor tcvv(transparency_);
899  const unsigned num = va.getNumElements();
900  for (unsigned i=0; i<num; i++){
901  va.accept(i,tcvv);
902  }
903  }
904 
905 private:
906  double transparency_;
907 };
908 
909 class makeTransparentNodeVisitor : public osg::NodeVisitor
910 {
911 public:
912 
913  // Default constructor - initialize searchForName to "" and
914  // set the traversal mode to TRAVERSE_ALL_CHILDREN
915  makeTransparentNodeVisitor() :
916  osg::NodeVisitor(TRAVERSE_ALL_CHILDREN), transparency_(0.5)
917  {
918  }
919 
920  // Constructor that accepts string argument
921  // Initializes searchForName to user string
922  // set the traversal mode to TRAVERSE_ALL_CHILDREN
923  makeTransparentNodeVisitor(const double transparency) :
924  osg::NodeVisitor(TRAVERSE_ALL_CHILDREN), transparency_(transparency)
925  {
926  BIASASSERT(transparency>=0.0 && transparency<=1.0);
927  }
928 
929  virtual void
930  apply(osg::Geode &node)
931  {
932  unsigned num_drawables = node.getNumDrawables();
933  for (unsigned int i = 0; i < num_drawables; i++)
934  {
935  osg::Geometry *geom = node.getDrawable(i)->asGeometry();
936  if (geom)
937  {
938  //cout << "g"<<flush;
939  osg::Array *col = geom->getColorArray();
940  //cout << col->getNumElements() << flush;
941  if (!col)
942  return;
943  transparentColourArrayVisitor tcav(transparency_);
944  col->accept(tcav);
945  }
946  else
947  {
948  //cout << "x"<<flush;
949  }
950  //cout << endl;
951  }
952  }
953 
954  virtual void
955  apply(osg::ClearNode &node)
956  {
957  //cout << "c"<<flush;
958  node.setClearMask(0);
959  }
960 
961  // Set the searchForName to user-defined string
962  inline void
963  setTransparency(const double transparency)
964  {
965  BIASASSERT(transparency>=0.0 && transparency<=1.0);
966  transparency_ = transparency;
967  }
968 
969 private:
970  double transparency_;
971 
972 };
973 
975 MakeTransparent(const double transparency)
976 {
977  BIASASSERT(transparency>=0.0 && transparency<=1.0);
978 
979  osg::StateSet *stateset = rootTree_->getOrCreateStateSet();
980 
981  stateset->setMode(GL_BLEND, osg::StateAttribute::ON
982  | osg::StateAttribute::OVERRIDE);
983 
984  osg::BlendEquation* blendEquation = new osg::BlendEquation(
985  osg::BlendEquation::FUNC_ADD);
986  osg::BlendFunc* pBlendFunc = new osg::BlendFunc(osg::BlendFunc::SRC_ALPHA,
987  osg::BlendFunc::ONE_MINUS_SRC_ALPHA);
988  stateset->setAttributeAndModes(pBlendFunc, osg::StateAttribute::OVERRIDE |
989  osg::StateAttribute::ON);
990 
991  stateset->setAttributeAndModes(blendEquation, osg::StateAttribute::OVERRIDE
992  | osg::StateAttribute::ON);
993 
994  stateset->setMode(GL_CULL_FACE, osg::StateAttribute::ON
995  | osg::StateAttribute::OVERRIDE);
996 
997  // TODO VN culls BACK, CAU culls FRONT
998  osg::CullFace *cullFace = new osg::CullFace(osg::CullFace::BACK);
999  //osg::CullFace *cullFace = new osg::CullFace(osg::CullFace::FRONT);
1000  //osg::CullFace *cullFace = new osg::CullFace(osg::CullFace::FRONT_AND_BACK );
1001  stateset->setAttribute(cullFace);
1002 
1003  // stateset->setMode(GL_DEPTH_TEST, osg::StateAttribute::OFF |
1004  // osg::StateAttribute::OVERRIDE );
1005 
1006  // the object in the opaque bin are rendered before the object in the
1007  // transparent bin, to allow propper blending
1008  stateset->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
1009 
1010  makeTransparentNodeVisitor tnv(transparency);
1011  rootTree_->accept(tnv);
1012  sceneView_->init();
1013 }
1014 
1015 
1017 SetAnimationTime(const double current_time, bool CallDraw)
1018 {
1019  if (animate_)
1020  {
1021  BEXCEPTION("you can't animate automatically and set time manually");
1022  }
1023  frameStamp_->setFrameNumber(frameStamp_->getFrameNumber() + 1);
1024  frameStamp_->setReferenceTime(current_time);
1025  frameStamp_->setSimulationTime(current_time);
1026  if(CallDraw)
1027  {
1028  Draw(); //WTF?
1029  }
1030 }
1031 
1034 {
1035  if (animate_) {
1036  osg::Timer_t t1 = osg::Timer::instance()->tick();
1037  double time = osg::Timer::instance()->delta_s(startTick_, t1);
1038  frameStamp_->setFrameNumber(frameStamp_->getFrameNumber()+1);
1039  frameStamp_->setReferenceTime(time);
1040  frameStamp_->setSimulationTime(time - timeOffset_);
1041  }
1042 
1043  // OpenSceneGraph is managing this
1044  // glPushAttrib( GL_ALL_ATTRIB_BITS );
1045  glPushAttrib( GL_VIEWPORT_BIT );
1046  glMatrixMode(GL_PROJECTION);
1047  glPushMatrix();
1048  glMatrixMode(GL_TEXTURE);
1049  glPushMatrix();
1050  glMatrixMode(GL_MODELVIEW);
1051  glPushMatrix();
1052 
1053  GLint viewParams[4];
1054  glGetIntegerv( GL_VIEWPORT, viewParams );
1055  sceneView_->getCamera()->setViewport(viewParams[0], viewParams[1],
1056  viewParams[2], viewParams[3]);
1057 
1058  GLfloat glMat[16];
1059  osg::Matrixf osgMat;
1060 
1061  glGetFloatv( GL_PROJECTION_MATRIX, glMat );
1062  osgMat.set( glMat );
1063  sceneView_->getCamera()->setProjectionMatrix( osgMat );
1064 
1065  // cout <<"Projection (in SceneOpenSceneGraph):"<<endl;
1066  // for (unsigned int j=0;j<4;j++){
1067  // for (unsigned int i=0;i<4;i++)
1068  // cout <<glMat[j*4+i]<<" ";
1069  // cout <<endl;
1070  // }
1071  glGetFloatv( GL_MODELVIEW_MATRIX, glMat );
1072 
1073  // cout <<"ModelView (in SceneOpenSceneGraph):"<<endl;
1074  // for (unsigned int j=0;j<4;j++){
1075  // for (unsigned int i=0;i<4;i++)
1076  // cout <<glMat[j*4+i]<<" ";
1077  // cout <<endl;
1078  // }
1079  osgMat.set( glMat );
1080  if (headlight_){
1081  //cout<<"Headlight!"<<endl;
1082  osg::Vec3d eye, center, up;
1083  float lookDistance=1.0;
1084  osgMat.getLookAt (eye, center, up, lookDistance);
1085  osg::Matrix m;
1086  m.makeTranslate(eye);
1087  lightTransform_->setMatrix(m);
1088  }
1089  sceneView_->getCamera()->getViewMatrix().set( osgMat );
1090 
1091  GLbitfield mask = sceneView_->getCamera()->getClearMask();
1092  sceneView_->getCamera()->setClearMask(0);
1093 
1094  //(sceneView_->getCamera())->setRenderTargetImplementation(osg::Camera::FRAME_BUFFER_OBJECT);
1095  // do the update traversal the scene graph - such as updating animations
1096  sceneView_->updateTraversal();
1097  sceneView_->renderingTraversals();
1098  if (sceneView_.valid()) sceneView_->frame();
1099 
1100 
1101  GLint drawenum;
1102  glGetIntegerv(GL_DRAW_BUFFER,&drawenum);
1103 
1104  // sceneView_->setDrawBufferValue(drawenum);
1105  //workaround for osgview when using framebuffer objects in glprojection**
1106 
1107  // TODO the following ghas been disabled by CAU, was enabled at VN
1108  //(sceneView_->getState())->setCheckForGLErrors(osg::State::ONCE_PER_ATTRIBUTE);
1109 
1110  sceneView_->getCamera()->setClearMask(mask);
1111 
1112  glMatrixMode(GL_MODELVIEW);
1113  glPopMatrix();
1114  glMatrixMode(GL_TEXTURE);
1115  glPopMatrix();
1116  glMatrixMode(GL_PROJECTION);
1117  glPopMatrix();
1118  glPopAttrib();
1119 
1120 }
1121 
1122 
1125 {
1126  const osg::BoundingSphere& bs = rootTree_->getBound();
1127 
1128  return BIAS::Vector3<double>((double) bs.center()[0],
1129  (double) bs.center()[1], (double) bs.center()[2]);
1130 }
1131 
1132 
1135  double> &max)
1136 {
1137  const osg::BoundingSphere& bs = rootTree_->getBound();
1138 
1139  Vector3<double> center((double) bs.center()[0], (double) bs.center()[1],
1140  (double) bs.center()[2]);
1141 
1142  double radius = (double) bs.radius();
1143 
1144  Vector3<double> diag(radius, radius, radius);
1145  min = center - diag;
1146  max = center + diag;
1147 }
1148 
1149 
1152 {
1153 
1155  double depth = camera->GetDepth(x, y);
1156  if (depth <= 0.0)
1157  return false;
1158  HomgPoint2D thepoint(x, y);
1159  HomgPoint3D intersection = camera->GetMyselfAsProjectionParametersBase()->
1160  UnProjectToPoint(thepoint, depth);
1161  cout << "viewing ray intersects scene at " << intersection << endl;
1162  return true;
1163 }
1164 
1165 
1168 {
1169  return (osg::dynamic_pointer_cast<osg::Node>(rootTree_));
1170 }
1171 
1172 
1175 {
1176  TreeDescr res;
1177  res.RootNode = GetSceneRoot();
1178  res.pNodeInfoMap = &NodeInfoMap_;
1179  return res;
1180 }
1181 
1182 
1184 SetNodeVisible(osg::Node* node, const bool visible)
1185 {
1186  //affects only the display in graph visualization guis
1187  //e.g. the tree control. this has no effect on
1188  //the visibility of the node during rendering!!
1189  NodeInfoMap_[node].IsVisible = visible;
1190  const string vis = (visible)?("TRUE"):("FALSE");
1191  OpenSceneGraphHelper::AddOrSetInfo(node, SOSG_KEY_IS_VISIBLE, vis);
1192 }
1193 
1194 
1196 SetNodeMarkerID(osg::Node* node, const unsigned long long &id)
1197 {
1198  NodeInfoMap_[node].MarkerID = id;
1199  ostringstream oss;
1200  oss << id;
1201  OpenSceneGraphHelper::AddOrSetInfo(node, SOSG_KEY_MARKER_ID, oss.str());
1202 }
1203 
1204 
1206 SetNodeOccluder(osg::Node* node, const bool state)
1207 {
1208  NodeInfoMap_[node].IsOccluder = state;
1209  const string occ = (state)?("TRUE"):("FALSE");
1210  OpenSceneGraphHelper::AddOrSetInfo(node, SOSG_KEY_IS_OCCLUDER, occ);
1211 
1212  osg::StateSet *stateset = node->getOrCreateStateSet();
1213  BIASASSERT(stateset);
1214  osg::ColorMask *colmask = new osg::ColorMask(!state, !state, !state, !state);
1215  stateset->setAttribute(colmask);
1216  osg::Stencil *stencil = new osg::Stencil();
1217 
1218  if(state)
1219  {
1220  stateset->setRenderBinDetails( 1, "RenderBin"/* ,osg::StateSet::OVERRIDE_RENDERBIN_DETAILS*/);
1221  //stencil->setFunction( osg::Stencil::ALWAYS, 2, ~(unsigned int)0);
1222  //if buffer >1 do nothing because 2 is overlay geometry
1223  stencil->setFunction( osg::Stencil::GREATER, 1, ~(unsigned int)0); //is stencil 2 ?
1224  //if stencilbuffer <=1 (stencil test fails) -> keep stencil buffer 1 or 2
1225  //if sp >1 (passes) and ztest fails -> keep stencil at 1
1226  //if sp >1 and ztest passes
1227  stencil->setOperation(osg::Stencil::KEEP,osg::Stencil::KEEP,
1228  osg::Stencil::REPLACE);
1229 
1230  }
1231  else
1232  {
1233  stateset->setRenderBinDetails( 10, "RenderBin"/*, osg::StateSet::OVERRIDE_RENDERBIN_DETAILS*/);
1234  //stencil->setFunction( osg::Stencil::ALWAYS, 0, ~(unsigned int)0);
1235  //stencil test passes if reference value is not equal to stencil buffer
1236  stencil->setFunction( osg::Stencil::NOTEQUAL, 2, ~(unsigned int)0);
1237  //operation stencil fail, stencilpass und zfail, zpass
1238  //if stencilbuffer == 2 (stenciltest fails) -> keep stencilbuffer 2 (btw: 2 means overlay geometry)
1239  //if stencilbuffer != 2 (passes) and ztest fails -> also keep stencilbuffer (most likely 1)
1240  //if stencilbuffer != 2 and ztest passes. set stencil to 0
1241  stencil->setOperation(osg::Stencil::KEEP,osg::Stencil::KEEP,
1242  osg::Stencil::ZERO); //set to zero if passes this changes occluder's 1 to 0
1243  }
1244 
1245  #if (OPENSCENEGRAPH_MAJOR_VERSION>=2) && (OPENSCENEGRAPH_MINOR_VERSION>=8)
1246  stateset->setNestRenderBins(false);
1247  #endif
1248  stateset->setAttributeAndModes(stencil); //default is on!
1249 }
1250 
1251 
1253 IsEditableNode(osg::Node* node)
1254 {
1255  if (!node)
1256  return false;
1257  osg::Transform * t;
1258  t = node->asTransform();
1259  if (!t)
1260  return false;
1261  osg::MatrixTransform * tm;
1262  tm = t->asMatrixTransform();
1263  if (!tm)
1264  return false;
1265  //check editable flag from nodeinfo map
1266 
1267  string val;
1268  if (OpenSceneGraphHelper::HasInfo(node, SOSG_KEY_IS_EDITABLE, val)){
1269  BIASASSERT(NodeInfoMap_.NodeHasNodeInfo(node));
1270  BIASASSERT( (NodeInfoMap_[node].IsEditable && (val=="TRUE") ) ||
1271  (!NodeInfoMap_[node].IsEditable && (val!="TRUE") ) );
1272  return (val=="TRUE");
1273  }
1274  // if (NodeInfoMap_.NodeHasNodeInfo(node)){
1275  // return ((NodeInfoMap_[node]).IsEditable);
1276  //}
1277  return true;
1278 }
1279 
1280 
1283 {
1284  //TODO test if shadow node is already inserted:
1285 
1286  // const int ReceivesShadowTraversalMask = 0x1;
1287  // const int CastsShadowTraversalMask = 0x2;
1288 
1290 
1291  //create new shadow technique
1292  osg::ref_ptr<osgShadow::ShadowMap> st = new osgShadow::ShadowMap;
1293  //create shadownode and add technique
1294  //osg::ref_ptr<osgShadow::ShadowedScene> shadowedScene =
1295  rootTree_ = new osgShadow::ShadowedScene(st.get());
1296  rootTree_->setName("_sceneRootShadowed");
1297  //add old root's children to shadow node
1298  for (unsigned int n = 0; n < (temproot->getNumChildren()); n++)
1299  {
1300  rootTree_->addChild(temproot->getChild(n));
1301  }
1302 
1304  osg::dynamic_pointer_cast<osgShadow::ShadowedScene>(rootTree_);
1305  dynamic_cast<osgShadow::ShadowMap*> (shadowedScene->getShadowTechnique()) ->setLight(
1306  lightSource.get());
1307  //shadowedScene->addChild(rootTree_.get());
1308  // shadowedScene->setReceivesShadowTraversalMask(ReceivesShadowTraversalMask);
1309  // shadowedScene->setCastsShadowTraversalMask(CastsShadowTraversalMask);
1310  // //set shadownode as new root
1311  // rootTree_ = shadowedScene->asGroup();
1312 }
1313 
1314 
1315 /** @brief helper function for mirror effects, called for all subscenes */
1316 osg::Node* SceneOpenSceneGraph::
1317 createMirroredScene(osg::Node* model, const BIAS::Vector3<
1318  double>& ul, const BIAS::Vector3<double>& ur,
1319  const BIAS::Vector3<double>& ll, const BIAS::Vector3<double>& lr,
1320  const string &mirrortexture, bool cutUpperHalf)
1321 {
1322 
1323  osg::Geometry* geom = new osg::Geometry;
1324 
1325  osg::Vec3Array* coords = new osg::Vec3Array(4);
1326  (*coords)[0].set(ll[0], ll[1], ll[2]); //(xMin,yMax,z);
1327  (*coords)[1].set(ul[0], ul[1], ul[2]);
1328  (*coords)[2].set(ur[0], ur[1], ur[2]);
1329  (*coords)[3].set(lr[0], lr[1], lr[2]);
1330 
1331  //cout<<" "<<ll[0]<<" "<<ll[1]<<" "<<ll[2]<<endl;
1332  //cout<<" "<<ul[0]<<" "<<ul[1]<<" "<<ul[2]<<endl;
1333  //cout<<" "<<ur[0]<<" "<<ur[1]<<" "<<ur[2]<<endl;
1334  //cout<<" "<<lr[0]<<" "<<lr[1]<<" "<<lr[2]<<endl;
1335 
1336  geom->setVertexArray(coords);
1337 
1338  osg::Vec3Array* norms = new osg::Vec3Array(1);
1339  Vector3<double> norm((ul - ur).CrossProduct(ul - ll));
1340  norm.Normalize();
1341  // (*norms)[0].set(0.0f,0.0f,1.0f);
1342 
1343  Vector3<double> center2(ul + ur + ll + lr);
1344  center2 *= 0.25;
1345  center2.Normalize();
1346 
1347  // (*norms)[0].set(norm[0], norm[1], norm[2]);
1348  (*norms)[0].set(-center2[0], -center2[1], -center2[2]);
1349  geom->setNormalArray(norms);
1350  geom->setNormalBinding(osg::Geometry::BIND_OVERALL);
1351 
1352  osg::Vec2Array* tcoords = new osg::Vec2Array(4);
1353  // (*tcoords)[0].set(0.0f,1.0f);
1354  // (*tcoords)[1].set(0.0f,0.0f);
1355  // (*tcoords)[2].set(1.0f,0.0f);
1356  // (*tcoords)[3].set(1.0f,1.0f);
1357  (*tcoords)[0].set(0.0f, 1.0f);
1358  (*tcoords)[1].set(0.0f, 0.0f);
1359  (*tcoords)[2].set(1.0f, 0.0f);
1360  (*tcoords)[3].set(1.0f, 1.0f);
1361  geom->setTexCoordArray(0, tcoords);
1362  geom->setTexCoordArray(1, tcoords);
1363 
1364  osg::Vec4Array* colours = new osg::Vec4Array(1);
1365  // (*colours)[0].set(0.5f,.5f,.5,0.6f);
1366  (*colours)[0].set(1.0f, 1.0f, 1.0f, 1.0f);
1367  geom->setColorArray(colours);
1368  geom->setColorBinding(osg::Geometry::BIND_OVERALL);
1369 
1370  geom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUADS, 0, 4));
1371 
1372  // create a textured, transparent node at the appropriate place.
1373  osg::Drawable* mirror = geom;
1374 
1375  osg::MatrixTransform* rootNode = new osg::MatrixTransform;
1376  //rootNode->setMatrix(osg::Matrix::rotate(osg::inDegrees(45.0f),1.0f,0.0f,0.0f));
1377 
1378  // make sure that the global color mask exists.
1379  osg::ColorMask* rootColorMask = new osg::ColorMask;
1380  rootColorMask->setMask(true, true, true, true);
1381 
1382  // set up depth to be inherited by the rest of the scene unless
1383  // overrideen. this is overridden in bin 3.
1384  osg::Depth* rootDepth = new osg::Depth;
1385  rootDepth->setFunction(osg::Depth::LESS);
1386  rootDepth->setRange(0.0, 1.0);
1387 
1388  osg::StateSet* rootStateSet = new osg::StateSet();
1389  rootStateSet->setAttribute(rootColorMask);
1390  rootStateSet->setAttribute(rootDepth);
1391 
1392  rootNode->setStateSet(rootStateSet);
1393 
1394  // bin1 - set up the stencil values and depth for mirror.
1395  {
1396 
1397  // set up the stencil ops so that the stencil buffer get set at
1398  // the mirror plane
1399  osg::Stencil* stencil = new osg::Stencil;
1400  stencil->setFunction(osg::Stencil::ALWAYS, 1, ~0u);
1401  stencil->setOperation(osg::Stencil::KEEP, osg::Stencil::KEEP,
1402  osg::Stencil::REPLACE);
1403 
1404  // switch off the writing to the color bit planes.
1405  osg::ColorMask* colorMask = new osg::ColorMask;
1406  colorMask->setMask(false, false, false, false);
1407 
1408  osg::StateSet* statesetBin1 = new osg::StateSet();
1409  statesetBin1->setRenderBinDetails(1, "RenderBin");
1410  statesetBin1->setMode(GL_CULL_FACE,osg::StateAttribute::OFF);
1411  statesetBin1->setAttributeAndModes(stencil, osg::StateAttribute::ON);
1412  statesetBin1->setAttribute(colorMask);
1413 
1414  // set up the mirror geode.
1415  osg::Geode* geode = new osg::Geode;
1416  geode->addDrawable(mirror);
1417  geode->setStateSet(statesetBin1);
1418  rootNode->addChild(geode);
1419 
1420  }
1421 
1422  // bin one - draw scene without mirror or reflection, unset
1423  // stencil values where scene is infront of mirror and hence
1424  // occludes the mirror.
1425  {
1426  osg::Stencil* stencil = new osg::Stencil;
1427  stencil->setFunction(osg::Stencil::ALWAYS, 0, ~0u);
1428  stencil->setOperation(osg::Stencil::KEEP, osg::Stencil::KEEP,
1429  osg::Stencil::REPLACE);
1430 
1431  osg::StateSet* statesetBin2 = new osg::StateSet();
1432  statesetBin2->setRenderBinDetails(2, "RenderBin");
1433  statesetBin2->setAttributeAndModes(stencil, osg::StateAttribute::ON);
1434 
1435  osg::Group* groupBin2 = new osg::Group();
1436  groupBin2->setStateSet(statesetBin2);
1437  groupBin2->addChild(model);
1438 
1439  // comment out
1440  if (!cutUpperHalf)
1441  rootNode->addChild(groupBin2);
1442  }
1443 
1444  // bin3 - set up the depth to the furthest depth value
1445  {
1446 
1447  // set up the stencil ops so that only operator on this mirrors stencil value.
1448  osg::Stencil* stencil = new osg::Stencil;
1449  stencil->setFunction(osg::Stencil::EQUAL, 1, ~0u);
1450  stencil->setOperation(osg::Stencil::KEEP, osg::Stencil::KEEP,
1451  osg::Stencil::KEEP);
1452 
1453  // switch off the writing to the color bit planes.
1454  osg::ColorMask* colorMask = new osg::ColorMask;
1455  colorMask->setMask(false, false, false, false);
1456 
1457  // set up depth so all writing to depth goes to maximum depth.
1458  osg::Depth* depth = new osg::Depth;
1459  depth->setFunction(osg::Depth::ALWAYS);
1460  depth->setRange(1.0, 1.0);
1461 
1462  osg::StateSet* statesetBin3 = new osg::StateSet();
1463  statesetBin3->setRenderBinDetails(3, "RenderBin");
1464  statesetBin3->setMode(GL_CULL_FACE,osg::StateAttribute::OFF);
1465  statesetBin3->setAttributeAndModes(stencil, osg::StateAttribute::ON);
1466  statesetBin3->setAttribute(colorMask);
1467  statesetBin3->setAttribute(depth);
1468 
1469  // set up the mirror geode.
1470  osg::Geode* geode = new osg::Geode;
1471  geode->addDrawable(mirror);
1472  geode->setStateSet(statesetBin3);
1473 
1474  rootNode->addChild(geode);
1475 
1476  }
1477 
1478  // bin4 - draw the reflection.
1479  {
1480 
1481  // now create the 'reflection' of the loaded model by applying
1482  // create a Transform which flips the loaded model about the z axis
1483  // relative to the mirror node, the loadedModel is added to the
1484  // Transform so now appears twice in the scene, but is shared so there
1485  // is negligable memory overhead. Also use an osg::StateSet
1486  // attached to the Transform to override the face culling on the subgraph
1487  // to prevert an 'inside' out view of the reflected model.
1488  // set up the stencil ops so that only operator on this mirrors stencil value.
1489 
1490 
1491  // this clip plane removes any of the scene which when mirror would
1492  // poke through the mirror. However, this clip plane should really
1493  // flip sides once the eye point goes to the back of the mirror...
1494  osg::ClipPlane* clipplane = new osg::ClipPlane;
1495 
1496  Vector3<double> normal((ul - ur).CrossProduct(ul - ll));
1497  normal.Normalize();
1498  osg::Vec3 onormal(-normal[0], -normal[1], -normal[2]);
1499  Vector3<double> center(ul + ur + ll + lr);
1500  center *= 0.25;
1501  osg::Plane theclipplane(onormal, osg::Vec3(center[0], center[1],
1502  center[2]));
1503  cout << "clipplane is " << theclipplane[0] << " " << theclipplane[1]
1504  << " " << theclipplane[2] << " " << theclipplane[3] << " " << endl;
1505  clipplane->setClipPlane(theclipplane);
1506  clipplane->setClipPlaneNum(0);
1507 
1508  osg::ClipNode* clipNode = new osg::ClipNode;
1509  clipNode->addClipPlane(clipplane);
1510 
1511  osg::StateSet* dstate = clipNode->getOrCreateStateSet();
1512  dstate->setRenderBinDetails(4, "RenderBin");
1513  dstate->setMode(GL_CULL_FACE,osg::StateAttribute::OVERRIDE
1514  | osg::StateAttribute::OFF);
1515 
1516  osg::Stencil* stencil = new osg::Stencil;
1517  stencil->setFunction(osg::Stencil::EQUAL, 1, ~0u);
1518  stencil->setOperation(osg::Stencil::KEEP, osg::Stencil::KEEP,
1519  osg::Stencil::KEEP);
1520  dstate->setAttributeAndModes(stencil, osg::StateAttribute::ON);
1521 
1522  osg::MatrixTransform* reverseMatrix = new osg::MatrixTransform;
1523  reverseMatrix->setStateSet(dstate);
1524 
1525  osg::Matrix rot, rott;
1526  rot.makeRotate(osg::Vec3(0, 0, 1), onormal);
1527  rott.invert(rot);
1528 
1529  reverseMatrix->preMult(osg::Matrix::translate(-center[0], -center[1],
1530  -center[2]) * rott * osg::Matrix::scale(1.0f, 1.0f, -1.0f) * rot
1531  * osg::Matrix::translate(center[0], center[1], center[2]));
1532 
1533  reverseMatrix->addChild(model);
1534  clipNode->addChild(reverseMatrix);
1535  rootNode->addChild(clipNode);
1536  }
1537 
1538  // bin5 - draw the textured mirror and blend it with the reflection.
1539  {
1540 
1541  // set up depth so all writing to depth goes to maximum depth.
1542  osg::Depth* depth = new osg::Depth;
1543  depth->setFunction(osg::Depth::ALWAYS);
1544 
1545  osg::Stencil* stencil = new osg::Stencil;
1546  stencil->setFunction(osg::Stencil::EQUAL, 1, ~0u);
1547  //stencil->setOperation(osg::Stencil::KEEP, osg::Stencil::KEEP, osg::Stencil::ZERO);
1548  stencil->setOperation(osg::Stencil::KEEP, osg::Stencil::KEEP,
1549  osg::Stencil::ZERO);
1550 
1551  // set up additive blending.
1552  osg::BlendFunc* trans = new osg::BlendFunc;
1553  // Blending function, the higher the alpha in texture image, the more texture will be seen
1554  trans->setFunction(osg::BlendFunc::SRC_ALPHA,
1555  osg::BlendFunc::ONE_MINUS_SRC_ALPHA);
1556 
1557  osg::AlphaFunc* alpha = new osg::AlphaFunc;
1558  alpha->setFunction(osg::AlphaFunc::ALWAYS);
1559 
1560  osg::StateSet* statesetBin5 = new osg::StateSet;
1561 
1562  statesetBin5->setMode(GL_CULL_FACE,osg::StateAttribute::OFF
1563  | osg::StateAttribute::PROTECTED);
1564 
1565  // set up the texture.
1566  osg::Image* image = osgDB::readImageFile(mirrortexture.c_str());
1567  if (image)
1568  {
1569  osg::Texture2D* texture = new osg::Texture2D;
1570  texture->setImage(image);
1571  // texture->setWrap(osg::Texture2D::WRAP_S, osg::Texture2D::REPEAT);
1572  // texture->setWrap(osg::Texture2D::WRAP_T, osg::Texture2D::REPEAT);
1573  statesetBin5->setTextureAttributeAndModes(0, texture,
1574  osg::StateAttribute::ON | osg::StateAttribute::PROTECTED);
1575  }
1576  else
1577  {
1578  BIASERR("could not load texture "<<mirrortexture);
1579  }
1580 
1581  statesetBin5->setRenderBinDetails(5, "RenderBin");
1582  statesetBin5->setMode(GL_CULL_FACE,osg::StateAttribute::OFF);
1583  statesetBin5->setAttributeAndModes(stencil, osg::StateAttribute::ON);
1584  statesetBin5->setAttributeAndModes(trans, osg::StateAttribute::ON);
1585  statesetBin5->setAttributeAndModes(alpha, osg::StateAttribute::ON);
1586  statesetBin5->setAttribute(depth);
1587 
1588  // set up the mirror geode.
1589  osg::Geode* geode = new osg::Geode;
1590  geode->addDrawable(mirror);
1591  geode->setStateSet(statesetBin5);
1592 
1593  // // Add Bump Map to the Mirror - BROKEN! todo
1594  // osg::Group *root = new osg::Group();
1595  // osgFX::BumpMapping *bump = new osgFX::BumpMapping();
1596  // bump->addChild(geode);
1597  // /////////////////////////
1598  // // assign textures
1599  //
1600  // osg::Texture2D *normal = new osg::Texture2D();
1601  // osg::Texture2D *diffuse = new osg::Texture2D();
1602  //
1603  // const char* normal_texture = "/home/fkellner/216-bump.jpg";
1604  // const char* diffuse_texture = "/home/fkellner/teich.png";
1605  //
1606  // osg::Image *normal_image = osgDB::readImageFile( normal_texture );
1607  // osg::Image *diffuse_image = osgDB::readImageFile( diffuse_texture );
1608  //
1609  // normal->setImage( normal_image );
1610  // normal->setFilter( osg::Texture::MIN_FILTER, osg::Texture::LINEAR_MIPMAP_LINEAR );
1611  // normal->setFilter( osg::Texture::MAG_FILTER, osg::Texture::LINEAR );
1612  // normal->setWrap( osg::Texture::WRAP_S, osg::Texture::REPEAT );
1613  // normal->setWrap( osg::Texture::WRAP_T, osg::Texture::REPEAT );
1614  // normal->setMaxAnisotropy(8);
1615  //
1616  // diffuse->setImage( diffuse_image );
1617  // diffuse->setFilter( osg::Texture::MIN_FILTER, osg::Texture::LINEAR_MIPMAP_LINEAR );
1618  // diffuse->setFilter( osg::Texture::MAG_FILTER, osg::Texture::LINEAR );
1619  // diffuse->setWrap( osg::Texture::WRAP_S, osg::Texture::REPEAT );
1620  // diffuse->setWrap( osg::Texture::WRAP_T, osg::Texture::REPEAT );
1621  // diffuse->setMaxAnisotropy(8);
1622  //
1623  // /////////////////////////////
1624  // // create the state set
1625  // osg::StateSet *state = new osg::StateSet();
1626  // state->setTextureAttributeAndModes( 0, diffuse, osg::StateAttribute::ON );
1627  // state->setTextureAttributeAndModes( 1, normal, osg::StateAttribute::ON );
1628  // state->setGlobalDefaults();
1629  // state->setMode( GL_LIGHTING, osg::StateAttribute::ON );
1630  // state->setMode( GL_BLEND, osg::StateAttribute::ON );
1631  // state->setRenderingHint( osg::StateSet::TRANSPARENT_BIN );
1632  //
1633  // bump->setStateSet( state );
1634  //
1635  // //////////////////////////////////////////
1636  // // create the bump mapping effect
1637  //
1638  // bump->setEnabled( true );
1639  // bump->setLightNumber( 0 );
1640  // bump->setOverrideNormalMapTexture( normal );
1641  // bump->setOverrideDiffuseTexture( diffuse );
1642  // bump->prepareChildren();
1643  //
1644  // ///////////////////////////
1645  // // add to the scene
1646  //
1647  // osg::MatrixTransform *MT = new osg::MatrixTransform();
1648  // MT->addChild( bump );
1649  //
1650  // root->addChild( MT );
1651  // rootNode->addChild(root);
1652  //
1653  // //rootNode->addChild(loadedModel);
1654 
1655 
1656  rootNode->addChild(geode);
1657 
1658  }
1659  // static int n=0;
1660  // osgDB::writeNodeFile(*rootNode, "mirror"+LeadingZeroString(n,2)+".osg");
1661  rootNode->setName(model->getName() + "_mirrored");
1662  return rootNode;
1663 }
1664 
1665 
1668  const BIAS::Vector3<double>& ll, const BIAS::Vector3<double>& lr,
1669  const string& mirrortexture, bool cutUpperHalf)
1670 {
1671 
1672  cout << "SceneOpenSceneGraph has " << rootTree_->getNumChildren()
1673  << " children..." << endl;
1674  for (unsigned int i = 0; i < rootTree_->getNumChildren(); i++)
1675  {
1676  osg::Node *node = rootTree_->getChild(i);
1677  cout << "creating reflection for subtree " << i << " with name "
1678  << node->getName() << endl;
1679  // if (node->getName().compare("/_lightTransform")==0) {
1680  // cout <<"skip" << endl;
1681  // continue;
1682  // }
1683  osg::Node* newnode = createMirroredScene(node, ul, ur, ll, lr,
1684  mirrortexture, cutUpperHalf);
1685 
1686  rootTree_->replaceChild(node, newnode);
1687  }
1688 
1689  return;
1690 }
1691 
1692 
1695 {
1696  osgParticle::ParticleSystem *dustParticleSystem =
1697  new osgParticle::ParticleSystem;
1698 
1699  // Set the attributes 'texture', 'emmisive' and 'lighting'
1700  dustParticleSystem->setDefaultAttributes("/home/koeser/test.png", false,
1701  false);
1702 
1703  // Since the particle system is derived from the class Drawable, we can create
1704  // add it to the scene as a child of a geode
1705  osg::Geode *geode = new osg::Geode;
1706  osg::Group* rootNode = new osg::Group;
1707  rootNode->addChild(geode);
1708  geode->addDrawable(dustParticleSystem);
1709 
1710  // Add an 'updater' to help per-frame management
1711  osgParticle::ParticleSystemUpdater *dustSystemUpdater =
1712  new osgParticle::ParticleSystemUpdater;
1713  // Associate this updater with our particle system
1714  dustSystemUpdater->addParticleSystem(dustParticleSystem);
1715  // add the updater node to the scene graph
1716  rootNode->addChild(dustSystemUpdater);
1717 
1718  // Create a partical to be used by our particle system and define a few
1719  // of its properties
1720  osgParticle::Particle smokeParticle;
1721  smokeParticle.setSizeRange(osgParticle::rangef(0.01, 20.0)); // meters
1722  smokeParticle.setLifeTime(4); // seconds
1723  smokeParticle.setMass(0.01); // in kilograms
1724  // Make this our particle system's default particle
1725  dustParticleSystem->setDefaultParticleTemplate(smokeParticle);
1726 
1727  // Create a modular emitter (this contains default counter, placer and shooter.)
1728  osgParticle::ModularEmitter *emitter = new osgParticle::ModularEmitter;
1729  // Associate this emitter with the particle system
1730  emitter->setParticleSystem(dustParticleSystem);
1731 
1732  // Get a handle to the emitter's counter and adjust the number of new particles
1733  // that will be added each frame
1734  osgParticle::RandomRateCounter *dustRate =
1735  static_cast<osgParticle::RandomRateCounter *> (emitter->getCounter());
1736  dustRate->setRateRange(5, 10); // generate 5 to 10 particles per second
1737 
1738  // To customize the placer, create and initialize a multi-segment placer
1739  osgParticle::MultiSegmentPlacer* lineSegment =
1740  new osgParticle::MultiSegmentPlacer();
1741  // Add vertices to our placer. This defines line seqments along which our particles will
1742  // originate. (If we co-locate a tank and this emitter, this will result in dust particles
1743  // originating from a line extending below and behind the tank model.)
1744  lineSegment->addVertex(0, 0, -2);
1745  lineSegment->addVertex(0, -2, -2);
1746  lineSegment->addVertex(0, -16, 0);
1747  // Use this placer for our emitter
1748  emitter->setPlacer(lineSegment);
1749 
1750  // To customize the shooter, create and initialize a radial shooter
1751  osgParticle::RadialShooter* smokeShooter = new osgParticle::RadialShooter();
1752  // Set properties of this shooter
1753  smokeShooter->setThetaRange(0.0, 3.14159 / 2); // radians, relative to Z axis.
1754  smokeShooter->setInitialSpeedRange(50, 100); // meters/second
1755  // Use this shooter for our emitter
1756  emitter->setShooter(smokeShooter);
1757 
1758  //This section of code creates a modular program instance to control how particles are updated during their lifespan. The modular program applies operators to particles in the order the operators are added to the program.
1759 
1760  // Create a modular program and attach it to our particle system
1761  osgParticle::ModularProgram *moveDustInAir = new osgParticle::ModularProgram;
1762  moveDustInAir->setParticleSystem(dustParticleSystem);
1763 
1764  // Create an operator that simulates gravity, adjust it and add it to our program
1765  osgParticle::AccelOperator *accelUp = new osgParticle::AccelOperator;
1766  accelUp->setToGravity(-1); // scale factor for normal acceleration due to gravity.
1767  moveDustInAir->addOperator(accelUp);
1768 
1769  // Add an operator to our program to calculate the friction of air.
1770  osgParticle::FluidFrictionOperator *airFriction =
1771  new osgParticle::FluidFrictionOperator;
1772  airFriction->setFluidToAir();
1773  //airFriction->setFluidDensity(1.2929/*air*/*5.0f);
1774  moveDustInAir->addOperator(airFriction);
1775 
1776  // Finally, add the program to the scene
1777  rootNode->addChild(moveDustInAir);
1778  rootTree_->addChild(rootNode);
1779 }
osg::ref_ptr< osg::Group > rootTree_
NodeInfoMap * pNodeInfoMap
Definition: NodeInfo.hh:227
class HomgPoint2D describes a point with 2 degrees of freedom in projective coordinates.
Definition: HomgPoint2D.hh:67
void AddDebugLevel(const long int lv)
Definition: Debug.hh:355
int XMLRead(const std::string &Filename)
derived classes must implement the function XMLIn which is called by this function XMLRead to read ev...
Definition: XMLBase.cpp:78
osg::Node * createMirroredScene(osg::Node *model, const BIAS::Vector3< double > &ul, const BIAS::Vector3< double > &ur, const BIAS::Vector3< double > &ll, const BIAS::Vector3< double > &lr, const std::string &mirrortexture, bool cutUpperHalf)
helper function for mirror effects, called for all subscenes
double lastPauseTime_
Time when the animation was paused for the last time.
bool NodeHasNodeInfo(osg::Node *node) const
Definition: NodeInfo.hh:206
container for scene root and ptr to nodeinfomap
Definition: NodeInfo.hh:224
void SetAnimate(const bool animate)
virtual BIAS::ProjectionParametersBase * GetMyselfAsProjectionParametersBase() const =0
void AppendSubTree(osg::ref_ptr< osg::Node > &childNode)
Append an OSG subtree to the constructed root tree.
void RemoveSubTree(osg::ref_ptr< osg::Node > &childNode)
BIAS::Vector3< double > GetBoundingBoxCenter()
Returns center of bounding box around the whole scene.
int AppendSubTreeFromImageFile(const std::string &fileName, const double &width_mm, osg::ref_ptr< osg::Node > &imageNode)
Loads contents from 2D image file into scene graph.
bool IsEditableNode(osg::Node *node)
osg::ref_ptr< osgViewer::Viewer > sceneView_
void AddMirror(const BIAS::Vector3< double > &ul, const BIAS::Vector3< double > &ur, const BIAS::Vector3< double > &ll, const BIAS::Vector3< double > &lr, const std::string &mirrortexture, bool cutUpperHalf=false)
adds a rectangular mirror surface into the scene
bool Save(std::string filename)
Abstract interface class to handle changes in rendering parameters by controllers and in rendering co...
visitor for traversing the scene graph and applying some operation to the related nodeinfomap ...
void MakeTransparent(const double transparency)
static std::string Basename(const std::string &fullname)
Get file base name without path from given path and filename.
class Vec3f Vec3
void Reset()
deletes internal pointers
int XMLWrite(const std::string &Filename, int CompressionLevel=0, bool AutoAddCompressionSuffix=true, std::string encoding="UTF-8") const
call this to add the class to a new xml tree and write it to the file Filename.
Definition: XMLBase.cpp:40
double timeOffset_
Time offset because of time &quot;pauses&quot;.
static void SplitName(const std::string &fullname, std::string &dir, std::string &base, std::string &suffix)
Split full path into:
class Matrixd Matrix
void SetAnimationTime(const double current_time, bool CallDraw=true)
setanimationtime() calls draw.
void SetNodeOccluder(osg::Node *node, const bool state)
long int NewDebugLevel(const std::string &name)
creates a new debuglevel
Definition: Debug.hh:474
MyBasicAnimationManager animationManager_
osg::ref_ptr< osg::Node > RootNode
Definition: NodeInfo.hh:226
virtual GLProjectionParametersInterface * GetGLProjectionParametersInterface()
Get the camera as projectionparametersinterface, can be of type GLProjection of of any from GLProject...
Definition: SceneBase.hh:85
class HomgPoint3D describes a point with 3 degrees of freedom in projective coordinates.
Definition: HomgPoint3D.hh:61
bool Load(std::string filename)
int Init()
Initializes OpenSG tree for scene appendance.
int AppendSubTreeSwitch(osg::ref_ptr< osg::Node > &switchNode, eNodeType NodeType=eNT_Default)
Append an OSG subtree to the constructed root tree with switch node.
osg::ref_ptr< osg::Node > GetSceneRoot()
returns ref_ptr to root of tree
virtual void Draw()
To do anything usefull, overload this method, assume context is ready and draw.
osg::ref_ptr< osgAnimation::BasicAnimationManager > _am
osg::ref_ptr< osg::Light > light_
static bool AddOrSetInfo(osg::ref_ptr< osg::Node > node, const std::string &key, const std::string &value)
Adds or sets information to the node.
void SetNodeMarkerID(osg::Node *node, const unsigned long long &id)
bool RightMouseDoubleClicked(int x, int y)
static std::string Suffix(const std::string &fullname)
Get file suffix (including dot!) from given path and filename.
Base class for all scenes.
Definition: SceneBase.hh:68
int AppendSubTreeFromFile(const std::string &fileName, osg::ref_ptr< osg::Node > &childNode, bool optimize=false)
Loads contents from file into scene graph.
void HeadlightSwitch(bool on=true)
Toggles the headlight.
osg::ref_ptr< osg::MatrixTransform > lightTransform_
void SetFixedPointLight(bool on, BIAS::Vector3< double > posPointLight)
Removes the camera as a beacon for the lights and sets a fixed position for Point Light or fixed dire...
void MakeRootShadowNode(osg::ref_ptr< osg::LightSource > lightSource)
osg::observer_ptr< osgViewer::GraphicsWindow > embedWindow_
bool SaveSubTree(osg::Node *node, const std::string &fileName)
Saves contents beginning at node into a file.
virtual double GetDepth(const unsigned int x, const unsigned int y)=0
osg::ref_ptr< osg::Switch > lightRepresentationSwitch_
void SetFixedDirectionalLight(bool on, BIAS::Vector3< double > dirDirectionalLight)
std::string NodePtr2IDString_(osg::Node *node)
void SetNodeVisible(osg::Node *node, const bool visible)
sets node visbility in guis like treectrlopensgwx this changes only the nodeinfomap and has no effec...
virtual void GetBoundingBox(BIAS::Vector3< double > &min, BIAS::Vector3< double > &max)
Returns bounding box around the whole scene.
osg::ref_ptr< osg::FrameStamp > frameStamp_
osg::ref_ptr< osg::Geode > lightRepresentationGeode_
std::string NodeType2String(const enum eNodeType &t)
Definition: NodeInfo.hh:45
Vector3< T > & Normalize()
normalize this vector to length 1
Definition: Vector3.hh:663
void RemoveSubTreeAndParents(osg::Node *Node)
removes the subtree and the parents except the globalroot of a given node
static bool HasInfo(const osg::ref_ptr< osg::Node > node, const std::string &key, std::string &value)
Checks if the node contains additional information in form of a key value pair.
eNodeType
Definition: NodeInfo.hh:16