CloudyDay
 All Classes Functions Variables Enumerations
VoxelizeMesh.h
1 #pragma once
2 #include <osg/Image>
3 #include <osg/Geometry>
4 #include <osg/Image>
5 #include <osg/Texture2D>
6 #include <osg/Texture3D>
7 #include <osgViewer/CompositeViewer>
8 #include <iostream>
9 #include <map>
10 #include <osg/BoundingBox>
11 #include <osg/MatrixTransform>
12 
13 namespace osgCloudyDay
14 {
15  class ReadBufferCallback: public osg::Camera::DrawCallback
16 {
17 public:
18  static float* m_data;
19  int m_layer;
20  osg::Texture3D* tex;
21  osg::Image* image;
22  osg::FrameBufferObject* fbo;
23  osg::FrameBufferAttachment *fba;
24 
25  int m_slicex;
26  int m_slicey;
27 
28  ReadBufferCallback(osg::Texture3D *_tex, int slicex, int slicey, int layer) : m_layer(layer), m_slicex(slicex), m_slicey(slicey)
29  {
30  tex = _tex;
31  image = new osg::Image();
32  fbo = new osg::FrameBufferObject();
33  fba = new osg::FrameBufferAttachment(tex, layer);
34  fbo->setAttachment(osg::Camera::COLOR_BUFFER, *fba);
35  }
36 
37  virtual void operator() (osg::RenderInfo& renderInfo) const
38  {
39  fbo->apply(*(renderInfo.getState()), osg::FrameBufferObject::READ_FRAMEBUFFER);
40  image->readPixels(0, 0, m_slicex, m_slicey, GL_RGBA, GL_FLOAT);
41 
42  float* height = (float*)image->data();
43 
44  osg::Vec4 sum = osg::Vec4(0.f, 0.f, 0.f, 0.f);
45  for(int i = 0; i < m_slicex*m_slicey; i++)
46  {
47  for(int j = 0; j < 4; j++)
48  m_data[m_layer*m_slicey*m_slicex*4+i*4+j] = height[i*4+j];
49 
50  sum.x() += height[i*4+0];
51  sum.y() += height[i*4+1];
52  sum.z() += height[i*4+2];
53  sum.w() += height[i*4+3];
54  // std::cout << "height: " << height[i*4] << " " <<height[i*4+1] << " " <<height[i*4+2]<< " " <<height[i*4+3]<< std::endl;
55  }
56  std::cout << "SUM: " << sum.x() << " " << sum.y() << " " << sum.z() << " " << sum.z() << std::endl;
57  //std::cout << std::endl;
58  }
59 };
60 
61  class CcalculateBoundingBox : public osg::NodeVisitor
62 {
63 public:
64  CcalculateBoundingBox() : NodeVisitor( NodeVisitor::TRAVERSE_ALL_CHILDREN )
65  {
66  // ----------------------------------------------------------------------
67  //
68  // Default Public Class Constructor
69  //
70  // ----------------------------------------------------------------------
71  m_transformMatrix.makeIdentity();
72  }
73 
74  virtual ~CcalculateBoundingBox() {}
75  virtual void apply( osg::Geode &geode )
76  {
77  // -------------------------------------------
78  //
79  // Handle nodes of the type osg::Geode
80  //
81  // -------------------------------------------
82  osg::BoundingBox bbox;
83 
84  //
85  // update bounding box for each drawable
86  //
87  for( unsigned int i = 0; i < geode.getNumDrawables(); ++i ){
88  //
89  // expand the overall bounding box
90  //
91  bbox.expandBy( geode.getDrawable( i )->getBound());
92  }
93 
94  //
95  // transform corners by current matrix
96  //
97  osg::BoundingBox bboxTrans;
98 
99  for( unsigned int i = 0; i < 8; ++i )
100  {
101  osg::Vec3 xvec = bbox.corner( i ) * m_transformMatrix;
102  bboxTrans.expandBy( xvec );
103  }
104 
105  //
106  // update the overall bounding box size
107  //
108  m_boundingBox.expandBy( bboxTrans );
109 
110  //
111  // continue traversing through the graph
112  //
113  traverse( geode );
114 
115  } // ::apply(osg::Geode &geode)
116 
117  virtual void apply( osg::MatrixTransform &node )
118  {
119  // ---------------------------------------------------------
120  //
121  // Handle nodes of the type osg::MatrixTransform
122  //
123  // ---------------------------------------------------------
124  m_transformMatrix *= node.getMatrix();
125  std::cout << "TRANSFORM" << std::endl;
126 
127  //
128  // continue traversing through the graph
129  //
130  traverse( node );
131 
132  } // ::apply(osg::MatrixTransform &node)
133 
134  virtual void apply( osg::Billboard &node ){
135 
136  // -----------------------------------------------
137  //
138  // Handle nodes of the type osg::Billboard
139  //
140  // -----------------------------------------------
141 
142  //
143  // important to handle billboard so that its size will
144  // not affect the geode size continue traversing the graph
145  //
146 
147  traverse( node );
148  } // ::apply(osg::MatrixTransform &node)
149 
150  //
151  // return teh bounding box
152  //
153  osg::BoundingBox &getBoundBox() { return m_boundingBox; }
154 
155 protected :
156  osg::BoundingBox m_boundingBox; // the overall resultant bounding box
157  osg::Matrix m_transformMatrix; // the current transform matrix
158 
159 }; // class CcalculateBoundingBox
160 
162  {
163  public:
164  typedef std::map<GLint, osg::Texture3D*> t_tex3DsByUnit;
165 
166  public:
167  VoxelizeMesh(std::string path, int slice_width, int slice_height, int slice_depth);
168  ~VoxelizeMesh(void);
169 
170  void Perform();
171  osg::Vec4 GetData(int x, int y, int z);
172 
173  osg::ref_ptr<osg::Texture3D> voxels_tex;
174 
175  osg::BoundingBox m_boundingbox;
176 
177  private:
178  void Read3DTexture();
179 
180  osg::Texture3D* setupTexture3D( const char *name, const GLenum internalFormat, const GLenum pixelFormat, const GLenum dataType, const int width, const int height, const int depth, osg::Image *image=0);
181 
182  void Render3D(osg::Vec4 color, bool clear);
183 
184  //osg::Geode *genQuad() const;
185  void cleanUp(osgViewer::CompositeViewer *viewer);
186  void dirtyTargets(t_tex3DsByUnit &targets3D);
187  osg::GraphicsContext *setupContext();
188 
189  osg::Camera *setupCamera( const int orderNum, bool clear);
190  osg::Image *getLayerFrom3DImage(osg::Image *source, const int layer);
191  osg::Group *setupGroup(osgViewer::CompositeViewer *viewer);
192 
193  osg::ref_ptr<osg::Program> m_shader;
194 
195  private:
196  float* m_data;
197 
198  int viewportWidth;
199  int viewportHeight;
200 
201  int m_slice_depth;
202 
203  t_tex3DsByUnit targets3D;
204  osgViewer::CompositeViewer *viewer;
205  osg::ref_ptr<osg::Group> group;
206  };
207 }