Umasoft
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Groups Pages
NodeOSG.h
1 //
2 // NodeOSG.h
3 //
4 // Extend the behavior of OSG scene graph nodes.
5 //
6 // Copyright (c) 2001-2011 Virtual Terrain Project
7 // Free for all uses, see license.txt for details.
8 //
9 
10 #ifndef VTOSG_NODEH
11 #define VTOSG_NODEH
12 
13 #include <osg/Fog>
14 #include <osg/Geode>
15 #include <osg/LightSource>
16 #include <osg/LOD>
17 #include <osg/MatrixTransform>
18 #include <osg/Projection>
19 #include <osg/Version>
20 #include <osgShadow/ShadowedScene>
21 
22 
23 #include <osg/PositionAttitudeTransform> //ADDED by NcB
24 #include <osg/ImageStream>
25 #include <osgDB/ReadFile>
26 #include <osgGA/StateSetManipulator>
27 #include <osgViewer/ViewerEventHandlers>
28 #include <osgViewer/Viewer>
29 #include <vlc/vlc.h>
30 #include <osg/ShapeDrawable>
31 
32 #define VLC_PLUGIN_PATH "G://umasoft//vtp-src//vlc//plugins//"
33 
34 #define VTLISPSM 0
35 
36 class vtCamera;
37 
40 
41 
43 // vtlib's Extension class provide some additional functionality to OSG's
44 // Node, Group, and MatrixTransform classes.
45 //
46 
52 {
53  NodeExtension();
54 
55  void SetEnabled(bool bOn);
56  bool GetEnabled() const;
57 
59  void SetCastShadow(bool b);
60 
62  bool GetCastShadow();
63 
65  void GetBoundSphere(FSphere &sphere, bool bGlobal = false);
66 
67  // Implementation
68  void SetOsgNode(osg::Node *n);
69  osg::Node *m_pNode;
70  bool m_bCastShadow;
71 };
72 
77 {
78  void SetOsgTransform(osg::MatrixTransform *xform) { m_pNode = m_pTransform = xform; }
79 
81  void Identity();
82 
84  void SetTrans(const FPoint3 &pos);
85 
87  FPoint3 GetTrans() const;
88 
91  void Translate1(const FPoint3 &pos);
92 
95  void TranslateLocal(const FPoint3 &pos);
96 
98  void Rotate2(const FPoint3 &axis, double angle);
99 
101  void RotateLocal(const FPoint3 &axis, double angle);
102 
105  void RotateParent(const FPoint3 &axis, double angle);
106 
108  FQuat GetOrient() const;
109 
113  FPoint3 GetDirection() const;
114 
118  void SetDirection(const FPoint3 &point, bool bPitch = true);
119 
121  void Scale(float factor);
123  void Scale3(float x, float y, float z);
124 
126  void SetTransform1(const FMatrix4 &mat);
128  void GetTransform1(FMatrix4 &mat) const;
129 
133  void PointTowards(const FPoint3 &point, bool bPitch = true);
134 
135  osg::MatrixTransform *m_pTransform;
136 };
137 
139 {
140 public:
141  int m_iTextureUnit;
142 #if VTLISPSM
143  int m_iMode;
144 #endif
145  osg::Node *m_pNode;
146  osg::ref_ptr<osg::Texture2D> m_pTexture;
147 };
148 
149 
151 // Standalone methods which operate on a node
152 //
153 
154 bool FindAncestor(osg::Node *node, osg::Node *parent);
155 osg::Node *FindDescendent(osg::Group *node, const char *pName);
156 
157 void InsertNodeAbove(osg::Node *node, osg::Group *newnode);
158 void InsertNodeBelow(osg::Group *group, osg::Group *newnode);
159 
160 vtMultiTexture *AddMultiTexture(osg::Node *onode, int iTextureUnit, vtImage *pImage,
161  int iTextureMode, const FPoint2 &scale, const FPoint2 &offset);
162 void EnableMultiTexture(osg::Node *node, vtMultiTexture *mt, bool bEnable);
163 bool MultiTextureIsEnabled(osg::Node *node, vtMultiTexture *mt);
164 
165 void LocalToWorld(osg::Node *node, FPoint3 &point);
166 void GetBoundSphere(osg::Node *node, FSphere &sphere, bool bGlobal = false);
167 FSphere GetGlobalBoundSphere(osg::Node *node);
168 bool ContainsParticleSystem(osg::Node *node);
169 
170 void SetEnabled(osg::Node *node, bool bOn);
171 bool GetEnabled(osg::Node *node);
172 bool NodeIsEnabled(osg::Node *node);
173 
174 void ApplyVertexRotation(osg::Node *node, const FPoint3 &axis, float angle);
175 void ApplyVertexTransform(osg::Node *node, const FMatrix4 &mat);
176 
177 void vtLogGraph(osg::Node *node, bool bExtents = false, bool bRefCounts = false, int indent=0);
178 void WriteDotFile(osg::Group *node, const char *filename);
179 
180 
182 // File I/O
183 //
184 
186 osg::Node *vtLoadModel(const char *filename, bool bAllowCache = true,
187  bool bDisableMipmaps = false);
188 bool vtSaveModel(osg::Node *node, const char *filename);
189 void SetLoadModelCallback(osg::Node *callback(osg::Transform *input));
190 extern bool g_bDisableMipmaps; // set to disable ALL mipmaps
191 
192 
194 // Node classes
195 //
196 
197 typedef osg::ref_ptr<osg::Node> NodePtr;
198 
202 class vtGroup : public osg::Group, public NodeExtension
203 {
204 public:
205  vtGroup();
206 };
207 typedef osg::ref_ptr<vtGroup> vtGroupPtr;
208 typedef osg::ref_ptr<osg::Group> GroupPtr;
209 
214 class vtTransform : public osg::MatrixTransform, public TransformExtension
215 {
216 public:
217  vtTransform();
218 };
219 typedef osg::ref_ptr<vtTransform> vtTransformPtr;
220 
224 class vtFog : public osg::Group, public NodeExtension
225 {
226 public:
227  vtFog();
228 
229  static RGBf s_white;
230  void SetFog(bool bOn, float start = 0, float end = 10000, const RGBf &color = s_white, osg::Fog::Mode eType = osg::Fog::LINEAR);
231 
232 protected:
233  osg::ref_ptr<osg::StateSet> m_pFogStateSet;
234  osg::ref_ptr<osg::Fog> m_pFog;
235 };
236 typedef osg::ref_ptr<vtFog> vtFogPtr;
237 
238 
239 class vtHeightField3d;
240 class vtLodGrid;
241 
248 class vtShadow : public osgShadow::ShadowedScene, public NodeExtension
249 {
250 public:
251  vtShadow(const int ShadowTextureUnit, int LightNumber);
252 
254  void SetDarkness(float bias);
256  float GetDarkness();
257 
258  void AddAdditionalTerrainTextureUnit(const uint Unit, const uint Mode);
259  void RemoveAdditionalTerrainTextureUnit(const uint Unit);
260  void RemoveAllAdditionalTerrainTextureUnits();
261 
263  void SetShadowTextureResolution(const uint ShadowTextureResolution);
264 
266  void SetRecalculateEveryFrame(const bool RecalculateEveryFrame);
267  bool GetRecalculateEveryFrame() const;
268 
269  void SetShadowSphereRadius(const float ShadowSphereRadius);
270  void SetHeightField3d(vtHeightField3d *pHeightField3d);
271  void AddLodGridToIgnore(vtLodGrid* pLodGrid);
272  void ForceShadowUpdate();
273 
274  void SetDebugHUD(vtGroup *pGroup);
275 
276 protected:
277  const int m_ShadowTextureUnit;
278  const int m_LightNumber;
279 };
280 typedef osg::ref_ptr<vtShadow> vtShadowPtr;
281 
290 class vtLightSource : public osg::LightSource, public NodeExtension
291 {
292 public:
293  vtLightSource(int LightNumber);
294 
295  void SetDiffuse(const RGBf &color);
296  RGBf GetDiffuse() const;
297  void SetAmbient(const RGBf &color);
298  RGBf GetAmbient() const;
299  void SetSpecular(const RGBf &color);
300  RGBf GetSpecular() const;
301 
302 protected:
303  // to ensure that reference counting is respected.
304  virtual ~vtLightSource() {}
305 };
306 
318 class vtGeode : public osg::Geode, public NodeExtension
319 {
320 public:
321  vtGeode();
322 
323  vtGeode *CloneGeode();
324  void CloneFromGeode(const vtGeode *rhs);
325 
330  void AddMesh(vtMesh *pMesh, int iMatIdx);
331 
334  void RemoveMesh(vtMesh *pMesh);
335 
340  void AddTextMesh(vtTextMesh *pMesh, int iMatIdx);
341 
343  uint GetNumMeshes() const;
344 
346  vtMesh *GetMesh(int i) const;
347 
349  vtTextMesh *GetTextMesh(int i) const;
350 
351  virtual void SetMaterials(const class vtMaterialArray *mats);
352  const vtMaterialArray *GetMaterials() const;
353 
354  vtMaterial *GetMaterial(int idx);
355 
356  void SetMeshMatIndex(vtMesh *pMesh, int iMatIdx);
357 
358  // OSG implementation
359  osg::ref_ptr<const vtMaterialArray> m_pMaterialArray;
360 
361 protected:
362  // Destructor is protected so that people will use Release() instead,
363  // to ensure that reference counting is respected.
364  virtual ~vtGeode() {}
365 };
366 typedef osg::ref_ptr<vtGeode> vtGeodePtr;
367 
372 class vtMovGeode : public vtTransform
373 {
374 public:
375  vtMovGeode(vtGeode *pContained) : vtTransform()
376  {
377  m_pGeode = pContained;
378  addChild(m_pGeode);
379  }
380  vtGeode *m_pGeode;
381 };
382 typedef osg::ref_ptr<vtMovGeode> vtMovGeodePtr;
383 
390 class vtLOD : public osg::LOD, public NodeExtension
391 {
392 public:
393  vtLOD();
394 
396  void SetCenter(const FPoint3 &center) { setCenter(v2s(center)); }
397 
399  void GetCenter(FPoint3 &center) { s2v(getCenter(), center); }
400 
401 protected:
402  virtual ~vtLOD() {}
403 };
404 
416 class vtCamera : public vtTransform
417 {
418 public:
419  vtCamera();
420 
421  void SetHither(float f);
422  float GetHither() const;
423  void SetYon(float f);
424  float GetYon() const;
425  void SetFOV(float f);
426  float GetFOV() const;
427  float GetVertFOV() const;
428 
429  void SetOrtho(bool bOrtho);
430  bool IsOrtho() const;
431  void SetWidth(float f);
432  float GetWidth() const;
433 
434  void ZoomToSphere(const FSphere &sphere, float fPitch = 0.0f);
435 
436 protected:
437  float m_fFOV;
438  float m_fHither;
439  float m_fYon;
440 
441  bool m_bOrtho;
442  float m_fWidth;
443 
444  virtual ~vtCamera() {}
445 };
446 typedef osg::ref_ptr<vtCamera> vtCameraPtr;
447 
464 
465 
466 
467 
469 // callback for animating various Uniforms (currently only the SIN uniform)
470 
471 class AnimateCallback: public osg::Uniform::Callback
472 {
473  public:
474  enum Operation { SIN };
475  AnimateCallback(Operation op) : _operation(op) {}
476  virtual void operator() ( osg::Uniform* uniform, osg::NodeVisitor* nv )
477  {
478  float angle = 2.0 * nv->getFrameStamp()->getSimulationTime();
479  float sine = sinf( angle ); // -1 -> 1
480  switch(_operation) {
481  case SIN : uniform->set( sine ); break;
482  }
483  }
484  private:
485  Operation _operation;
486 };
487 
488 
489 osg::Drawable* viewing_frustum(double near_val,double far_val,double fov_val);
490 
491 
492 
493 
494 
495 // VLC PLAYER ////////////////////////////////////////////ADDED BY NcB
496 
497 class VLCImageStream : public osg::ImageStream // ADDED BY NcB
498 {
499 public:
500  static void* lockFunc( void* data, void** p_pixels )
501  {
502  VLCImageStream* stream = (VLCImageStream*)data;
503  *p_pixels = (void*)stream->data();
504  return NULL;
505  }
506 
507  static void unlockFunc( void* data, void* id, void* const* p_pixels )
508  {
509  VLCImageStream* stream = (VLCImageStream*)data;
510  stream->dirty();
511  }
512 
513  static void displayFunc( void* data, void* id )
514  {
515  }
516 
517  static void videoEndFunc( const libvlc_event_t*, void* data )
518  {
519  VLCImageStream* stream = (VLCImageStream*)data;
520  stream->_status = INVALID;
521  }
522 
523  VLCImageStream( const char* const* vlc_argv=0 )
524  : osg::ImageStream(), _vlcMedia(0)
525  {
526  if ( !vlc_argv )
527  {
528  const char* vlc_args[] = {
529  "--ignore-config", // don't use VLC's config
530  "--data-path="VLC_PLUGIN_PATH
531  };
532  _vlc = libvlc_new( sizeof(vlc_args)/sizeof(vlc_args[0]), vlc_args );
533  }
534  else
535  _vlc = libvlc_new( sizeof(vlc_argv)/sizeof(vlc_argv[0]), vlc_argv );
536  _vlcPlayer = libvlc_media_player_new( _vlc );
537 
538  libvlc_event_attach( libvlc_media_player_event_manager(_vlcPlayer), libvlc_MediaPlayerStopped,
539  &VLCImageStream::videoEndFunc, this );
540  _status = INVALID;
541  }
542 
543  VLCImageStream( const VLCImageStream& copy, const osg::CopyOp& op=osg::CopyOp::SHALLOW_COPY )
544  : osg::ImageStream(copy, op), _vlc(copy._vlc), _vlcMedia(copy._vlcMedia),
545  _vlcPlayer(copy._vlcPlayer) {}
546 
548 
549 
560  void open( const std::string& file, bool needPlay=true )
561  {
562  _vlcMedia = libvlc_media_new_path( _vlc, file.c_str() );
563  libvlc_media_player_set_media( _vlcPlayer, _vlcMedia );
564  libvlc_video_set_callbacks( _vlcPlayer, &VLCImageStream::lockFunc, &VLCImageStream::unlockFunc,
565  &VLCImageStream::displayFunc, this );
566 
567  unsigned int width = 512, height = 512;
568  libvlc_media_track_info_t* info = NULL;
569  int numTracks = libvlc_media_get_tracks_info( _vlcMedia, &info );
570  for ( int i=0; i<numTracks; ++i )
571  {
572  if(info[i].i_type == libvlc_track_video)
573  {
574  width = info[i].u.video.i_width;
575  height = info[i].u.video.i_height;
576  }
577  }
578  libvlc_video_set_format( _vlcPlayer, "RV32", width, height, width*4 );
579 
580  allocateImage( width, height, 1, GL_RGBA, GL_UNSIGNED_BYTE );
581  if ( needPlay ) play();
582  }
583 
584  virtual void play()
585  {
586  if ( _status==PAUSED )
587  {
588  libvlc_media_player_set_pause( _vlcPlayer, false );
589  }
590  else if ( _status!=PLAYING )
591  {
592  libvlc_media_player_play( _vlcPlayer );
593  }
594  _status = PLAYING;
595  }
596 
597  virtual void pause()
598  {
599  libvlc_media_player_set_pause( _vlcPlayer, true );
600  _status = PAUSED;
601  }
602 
603  virtual void rewind()
604  {
605  libvlc_media_player_stop( _vlcPlayer );
606  libvlc_media_player_set_time( _vlcPlayer, 0 );
607  libvlc_media_player_next_frame( _vlcPlayer );
608  _status = INVALID;
609  }
610 
611  virtual void quit( bool waitForThreadToExit=true )
612  {
613  libvlc_media_player_stop( _vlcPlayer );
614  libvlc_media_player_release( _vlcPlayer );
615  _status = INVALID;
616  }
617 
618  virtual void setReferenceTime( double time ) { libvlc_media_player_set_time(_vlcPlayer, (int)time); }
619  virtual double getReferenceTime() const { return (int)libvlc_media_player_get_time(_vlcPlayer); }
620 
621  virtual void setTimeMultiplier( double m ) { libvlc_video_set_scale(_vlcPlayer, m); }
622  virtual double getTimeMultiplier() const { return libvlc_video_get_scale(_vlcPlayer); }
623 
624  virtual void setVolume( float vol ) { libvlc_audio_set_volume(_vlcPlayer, (int)vol); }
625  virtual float getVolume() const { return (int)libvlc_audio_get_volume(_vlcPlayer); }
626 
627 protected:
628  virtual ~VLCImageStream()
629  {
630  if ( _status!=INVALID )
631  {
632  libvlc_media_player_stop( _vlcPlayer );
633  libvlc_media_player_release( _vlcPlayer );
634  }
635  libvlc_release( _vlc );
636  }
637 
638  libvlc_instance_t* _vlc;
639  libvlc_media_t* _vlcMedia;
640  libvlc_media_player_t* _vlcPlayer;
641 };
642 
643 osg::Node* createVideoQuad( const osg::Vec3& corner, const std::string& file,double near,double far,double fov );
644 void AddCylinderBetweenPoints(osg::Vec3 StartPoint, osg::Vec3 EndPoint, float radius, osg::Vec4 CylinderColor,osg::PositionAttitudeTransform *pAddToThisGroup);
645 
646 
647 
648 //camera instance
649 class Camera3kb : public vtCamera // ADDED by NcB
650 {
651 public:
652  bool updated;
653  bool selected;
654  bool rotateright;
655  bool rotateleft;
656  bool rotateup;
657  bool rotatedown;
658  bool positionchanged;
659  bool heightup;
660  bool heightdown;
661  int cameraNo;
662  double rotatex,rotatey;
663  double height_val;
664  std::string ipAdres;
665  osg::ref_ptr<osg::PositionAttitudeTransform> frustum;
666  osg::ref_ptr<osg::PositionAttitudeTransform> model;
667  osg::PositionAttitudeTransform *video_data;
668  vtGroup *root_cam;
669  FPoint3 coordinate;
670 
671  std::vector< osg::ref_ptr<osg::PositionAttitudeTransform> > camline;
672 
673  Camera3kb()
674  { updated = false;
675  selected=false;
676  rotateright=false;
677  rotateleft=false;
678  rotateup=false;
679  rotatedown=false;
680  positionchanged=false;
681  heightup=false;
682  heightdown=false;
683  cameraNo=0;
684  height_val=0;
685  root_cam=NULL;
686  rotatex=0;
687  rotatey=0;
688  };
689 
690  void calculate_viewfrustum();
691  void setRoot(vtGroup *pGeomGroup);
692  void play_video();
693 
694 };
695 //camera node callback for rotate and translate
696 class cam3kbNodeCallback : public osg::NodeCallback //ADDED by NcB
697 {
698  public:
699 
701  {
702  camupdate=cam;
703  _angle=cam->rotatey;
704  _anglex=cam->rotatex;
705  _height=cam->height_val;
706  };
707 
708  virtual void operator()(osg::Node* node, osg::NodeVisitor* nv);
709 
710 
711  protected:
712  double _angle;
713  double _anglex;
714  double _height;
715  Camera3kb *camupdate;
716 
717 };
718 //3d model class for building
719 class models3d //ADDED by NcB
720 {
721 public:
722 
723  bool selected;
724  bool rotateright;
725  bool rotateleft;
726  bool rotateup;
727  bool rotatedown;
728  bool positionchanged;
729  bool scaleup;
730  bool scaledown;
731 
732  osg::PositionAttitudeTransform *model;
733  FPoint3 coordinate;
734 
735 
736  models3d()
737  {
738  selected=false;
739  rotateright=false;
740  rotateleft=false;
741  rotateup=false;
742  rotatedown=false;
743  positionchanged=false;
744  scaleup=false;
745  scaledown=false;
746  };
747 
748 };
749 
750 class models3dNodeCallback: public osg::NodeCallback //ADDED by NcB
751 {
752 public:
753  models3dNodeCallback(models3d *model) : _angle( 0. ),_anglex(0.),scale_val(1.)
754  {
755  models3dupdate=model;
756  };
757 
758  virtual void operator()(osg::Node* node, osg::NodeVisitor* nv);
759 
760 
761  protected:
762  double _angle;
763  double _anglex;
764  double scale_val;
765  models3d *models3dupdate;
766 
767 };
768 
769 
770 
771 
776 class vtHUD : public osg::Projection, public NodeExtension
777 {
778 public:
779  vtHUD(bool bPixelCoords = true);
780 
781  void SetWindowSize(int w, int h);
782  osg::Group *GetContainer() { return modelview_abs.get(); }
783 
784 protected:
785  osg::ref_ptr<osg::MatrixTransform> modelview_abs;
786  bool m_bPixelCoords;
787 };
788 
789 
791 // Dynamic geometry
792 
793 /*
794  * We create our own OSG drawable in order to override the draw method.
795  */
796 class OsgDynMesh : public osg::Drawable
797 {
798 public:
799  OsgDynMesh();
800 
801  // overrides
802  virtual osg::Object* cloneType() const { return new OsgDynMesh; }
803  virtual osg::Object* clone(const osg::CopyOp &foo) const { return new OsgDynMesh; }
804  virtual bool isSameKindAs(const osg::Object* obj) const { return dynamic_cast<const OsgDynMesh*>(obj)!=NULL; }
805  virtual const char* className() const { return "OsgDynMesh"; }
806 
807  // As of OSG 0.9.9, computeBound returns a BoundingBox
808  virtual osg::BoundingBox computeBound() const;
809  virtual void drawImplementation(osg::RenderInfo& renderInfo) const;
810 
811  class vtDynGeom *m_pDynGeom;
812  osg::State *m_pDrawState;
813 
814 protected:
815  virtual ~OsgDynMesh() {}
816 };
817 
818 
819 // Visibility return codes from vtDynGeom::IsVisible
820 #define VT_Visible 1
821 #define VT_AllVisible 2
822 
841 class vtDynGeom : public vtGeode
842 {
843 public:
844  vtDynGeom();
845 
846  // Tests a sphere or triangle, and return one of:
847  // 0 - not in view
848  // VT_Visible - partly in view
849  // VT_AllVisible - entirely in view
850  //
851  int IsVisible(const FSphere &sphere) const;
852  int IsVisible(const FPoint3 &point0,
853  const FPoint3 &point1,
854  const FPoint3 &point2,
855  const float fTolerance = 0.0f) const;
856  int IsVisible(const FPoint3 &point, float radius);
857 
858  // Tests a single point, returns true if in view
859  bool IsVisible(const FPoint3 &point) const;
860 
861  void ApplyMaterial(vtMaterial *mat);
862 
863  // vt methods (must be overriden)
864  virtual void DoRender() = 0;
865  virtual void DoCalcBoundBox(FBox3 &box) = 0;
866  virtual void DoCull(const vtCamera *pCam) = 0;
867 
868  // The current clipping planes
869  FPlane m_cullPlanes[6];
870 
871 protected:
872  OsgDynMesh *m_pDynMesh;
873 };
874 typedef osg::ref_ptr<vtDynGeom> vtDynGeomPtr;
875 
876 
878 // Intersection testing
879 
886 struct vtHit
887 {
888  bool operator < (const vtHit &i) const { return distance < i.distance; }
889  osg::Geode *geode;
890  FPoint3 point;
891  float distance;
892 };
893 
894 typedef std::vector<vtHit> vtHitList;
895 int vtIntersect(osg::Node *pTop, const FPoint3 &start, const FPoint3 &end,
896  vtHitList &hitlist, bool bLocalCoords = false, bool bNativeNodes = true);
897 
898 
900 // Statistics: exact bounds and primitive counts
901 
904 {
906  int Vertices;
911 
913  int Points;
917  int TriFans;
921  int Quads;
925  int Polygons;
930 };
931 
932 void GetNodeBoundBox(osg::Node *node, FBox3 &box);
933 void GetNodePrimCounts(osg::Node *node, vtPrimInfo &info);
934  // Group sg
936 
937 #endif // VTOSG_NODEH
938