model_camera.cc
Go to the documentation of this file.
1 //
3 // File: model_camera.cc
4 // Author: Alex Couture-Beil
5 // Date: 09 June 2008
6 //
7 // CVS info:
8 //
10 
11 #define CAMERA_HEIGHT 0.5
12 #define CAMERA_NEAR_CLIP 0.2
13 #define CAMERA_FAR_CLIP 8.0
14 
15 //#define DEBUG 1
16 #include "canvas.hh"
17 #include "worldfile.hh"
18 
19 using namespace Stg;
20 
21 #include <sstream>
22 #include <iomanip>
23 
24 //TODO make instance attempt to register an option (as customvisualizations do)
25 Option ModelCamera::showCameraData( "Show Camera Data", "show_camera", "", true, NULL );
26 
27 static const Stg::Size DEFAULT_SIZE( 0.1, 0.07, 0.05 );
28 static const char DEFAULT_GEOM_COLOR[] = "black";
29 static const float DEFAULT_HFOV = 70;
30 static const float DEFAULT_VFOV = 40;
31 
72 //caclulate the corss product, and store results in the first vertex
73 void cross( float& x1, float& y1, float& z1, float x2, float y2, float z2 )
74 {
75  float x3, y3, z3;
76 
77  x3 = y1 * z2 - z1 * y2;
78  y3 = z1 * x2 - x1 * z2;
79  z3 = x1 * y2 - y1 * x2;
80 
81  x1 = x3;
82  y1 = y3;
83  z1 = z3;
84 }
85 
86 
88  Model* parent,
89  const std::string& type ) :
90  Model( world, parent, type ),
91  _canvas( NULL ),
92  _frame_data( NULL ),
93  _frame_color_data( NULL ),
94  _valid_vertexbuf_cache( false ),
95  _vertexbuf_cache( NULL ),
96  _width( 32 ),
97  _height( 32 ),
98  _camera_quads_size( 0 ),
99  _camera_quads( NULL ),
100  _camera_colors( NULL ),
101  _camera(),
102  _yaw_offset( 0.0 ),
103  _pitch_offset( 0.0 )
104 {
105  PRINT_DEBUG2( "Constructing ModelCamera %d (%s)\n",
106  id, typestr );
107 
108  WorldGui* world_gui = dynamic_cast< WorldGui* >( world );
109 
110  if( world_gui == NULL ) {
111  printf( "Unable to use Camera Model - it must be run with a GUI world\n" );
112  assert( 0 );
113  }
114  _canvas = world_gui->GetCanvas();
115 
116  _camera.setPitch( 90.0 );
117 
118  Geom geom;
119  memset( &geom, 0, sizeof(geom));
120  geom.size = DEFAULT_SIZE;
121  SetGeom( geom );
122 
123  // set default color
125 
127 
128  Startup();
129 }
130 
132 {
133  if( _frame_data != NULL ) {
134  //dont forget about GetFrame() //TODO merge these together
135  delete[] _frame_data;
136  delete[] _frame_color_data;
137  delete[] _vertexbuf_cache;
138  delete[] _camera_quads;
139  delete[] _camera_colors;
140  }
141 }
142 
143 void ModelCamera::Load( void )
144 {
145  Model::Load();
146 
147  double horizFov = DEFAULT_HFOV;
148  double vertFov = DEFAULT_VFOV;
149  wf->ReadTuple( wf_entity, "fov", 0, 2, "ff", &horizFov, &vertFov );
150  _camera.setFov( horizFov, vertFov );
151 
152  double range_min = CAMERA_NEAR_CLIP;
153  double range_max = CAMERA_FAR_CLIP;
154  wf->ReadTuple( wf_entity, "range", 0, 2, "ll", &range_min, &range_max );
155  _camera.setClip( range_min, range_max );
156 
157  // note = these are in degrees internally
158  wf->ReadTuple( wf_entity, "pantilt", 0, 2, "ff", &_yaw_offset, &_pitch_offset );
159 
160  wf->ReadTuple( wf_entity, "resolution", 0, 2, "ii", &_width, &_height );
161 }
162 
163 
165 {
166  GetFrame();
167  Model::Update();
168 }
169 
171 {
172  if( _width == 0 || _height == 0 )
173  return false;
174 
175  if( _frame_data == NULL ) {
176  if( _frame_data != NULL ) {
177  //don't forget about destructor
178  delete[] _frame_data;
179  delete[] _frame_color_data;
180  delete[] _vertexbuf_cache;
181  delete[] _camera_quads;
182  delete[] _camera_colors;
183  }
184  _frame_data = new GLfloat[ _width * _height ]; //assumes a max of depth 4
185  _frame_color_data = new GLubyte[ 4 * _width * _height ]; //for RGBA
186 
187  _vertexbuf_cache = new ColoredVertex[ _width * _height ]; //for unit vectors
188 
189  _camera_quads_size = _height * _width * 4 * 3; //one quad per pixel, 3 vertex per quad
190  _camera_quads = new GLfloat[ _camera_quads_size ];
191  _camera_colors = new GLubyte[ _camera_quads_size ];
192  }
193 
194  //TODO overcome issue when glviewport is set LARGER than the window side
195  //currently it just clips and draws outside areas black - resulting in bad glreadpixel data
196  if( _width > _canvas->w() )
197  _width = _canvas->w();
198  if( _height > _canvas->h() )
199  _height = _canvas->h();
200 
201  GLint viewport[4];
202  glGetIntegerv(GL_VIEWPORT,viewport);
203 
204  glViewport( 0, 0, _width, _height );
205  _camera.update();
207  float height = GetGlobalPose().z;
208  //TODO reposition the camera so it isn't inside the model ( or don't draw the parent when calling renderframe )
209  _camera.setPose( parent->GetGlobalPose().x, parent->GetGlobalPose().y, height ); //TODO use something smarter than a #define - make it configurable
210  _camera.setYaw( rtod( parent->GetGlobalPose().a ) - 90.0 - _yaw_offset ); //-90.0 points the camera infront of the robot instead of pointing right
211  _camera.setPitch( 90.0 - _pitch_offset );
212  _camera.Draw();
213 
214 
215  glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
216  _canvas->DrawFloor();
217  _canvas->DrawBlocks();
218 
219  //read depth buffer
220  glReadPixels(0, 0, _width, _height,
221  GL_DEPTH_COMPONENT, //GL_RGB,
222  GL_FLOAT, //GL_UNSIGNED_BYTE,
223  _frame_data );
224  //transform length into linear length
225  float* data = ( float* )( _frame_data ); //TODO use static_cast here
226  int buf_size = _width * _height;
227  for( int i = 0; i < buf_size; i++ )
228  data[ i ] = _camera.realDistance( data[ i ] );
229 
230  //read color buffer
231  glReadPixels(0, 0, _width, _height,
232  GL_RGBA,
233  GL_UNSIGNED_BYTE,
235 
236 
237  glViewport( viewport[0], viewport[1], viewport[2], viewport[3] );
238  _canvas->invalidate();
240  return true;
241 }
242 
243 //TODO create lines outlining camera frustrum, then iterate over each depth measurement and create a square
245 {
246  if( _frame_data == NULL || !showCameraData )
247  return;
248 
249  float w_fov = _camera.horizFov();
250  float h_fov = _camera.vertFov();
251 
252  float start_fov = w_fov / 2.0 + 180.0; //start at right
253  float start_vert_fov = h_fov / 2.0 + 90.0; //start at top
254 
255  int w = _width;
256  int h = _height;
257  float a_space = w_fov / w; //degrees between each sample
258  float vert_a_space = h_fov / h; //degrees between each vertical sample
259 
260  //Create unit vectors representing a sphere - and cache it
261  if( _valid_vertexbuf_cache == false ) {
262  for( int j = 0; j < h; j++ ) {
263  for( int i = 0; i < w; i++ ) {
264 
265  float a = start_fov - static_cast< float >( i ) * a_space;
266  float vert_a = start_vert_fov - static_cast< float >( h - j - 1 ) * vert_a_space;
267 
268  int index = i + j * w;
269  ColoredVertex* vertex = _vertexbuf_cache + index;
270 
271  //calculate and cache normal unit vectors of the sphere
272  float x = -sin( dtor( vert_a ) ) * cos( dtor( a ) );
273  float y = -sin( dtor( vert_a ) ) * sin( dtor( a ) );
274  float z = -cos( dtor( vert_a ) );
275 
276  //rotate them about the pitch and yaw offsets - keeping distortion of the sphere at the extremes
277  a = dtor( - _yaw_offset );
278  vertex->x = x * cos( a ) - y * sin( a );
279  vertex->y = x * sin( a ) + y * cos( a );
280  vertex->z = z;
281 
282  x = vertex->x; y = vertex->y; z = vertex->z;
283  a = dtor( _pitch_offset );
284  vertex->x = z * sin( a ) + x * cos( a );
285  vertex->y = y;
286  vertex->z = z * cos( a ) - x * sin( a );
287  }
288  }
289  _valid_vertexbuf_cache = true;
290  }
291 
292  // glDisable( GL_CULL_FACE );
293 
294 
295  //Scale cached unit vectors with depth-buffer
296  float* depth_data = ( float* )( _frame_data );
297  for( int j = 0; j < h; j++ ) {
298  for( int i = 0; i < w; i++ ) {
299  int index = i + j * w;
300  const ColoredVertex* unit_vertex = _vertexbuf_cache + index;
301  const float length = depth_data[ index ];
302 
303  //scale unitvectors with depth-buffer
304  float sx = unit_vertex->x * length;
305  float sy = unit_vertex->y * length;
306  float sz = unit_vertex->z * length;
307 
308  //create a quad based on the current camera pixel, and normal vector
309  //the quad size is porpotial to the depth distance
310  float x, y, z;
311  x = 0; y = 0; z = length * M_PI * a_space / 360.0;
312  cross( x, y, z, unit_vertex->x, unit_vertex->y, unit_vertex->z );
313 
314  z = length * M_PI * vert_a_space / 360.0;
315 
316  GLfloat* p = _camera_quads + index * 4 * 3;
317  p[ 0 ] = sx - x; p[ 1 ] = sy - y; p[ 2 ] = sz - z;
318  p[ 3 ] = sx - x; p[ 4 ] = sy - y; p[ 5 ] = sz + z;
319  p[ 6 ] = sx + x; p[ 7 ] = sy + y; p[ 8 ] = sz + z;
320  p[ 9 ] = sx + x; p[ 10 ] = sy + y; p[ 11 ] = sz - z;
321 
322  //copy color for each vertex
323  //TODO using a color index would be smarter
324  const GLubyte* color = _frame_color_data + index * 4;
325  for( int i = 0; i < 4; i++ ) {
326  GLubyte* cp = _camera_colors + index * 4 * 3 + i * 3;
327  memcpy( cp, color, sizeof( GLubyte ) * 3 );
328  }
329  }
330  }
331 
332  // vertex arrays are already enabled
333  glEnableClientState( GL_COLOR_ARRAY );
334 
335  glVertexPointer( 3, GL_FLOAT, 0, _camera_quads );
336  glColorPointer( 3, GL_UNSIGNED_BYTE, 0, _camera_colors );
337  glDrawArrays( GL_QUADS, 0, w * h * 4 );
338 
339  glDisableClientState( GL_COLOR_ARRAY );
340 }
341 
ModelCamera(World *world, Model *parent, const std::string &type)
Definition: model_camera.cc:87
Model class
Definition: stage.hh:1742
static const Stg::Size DEFAULT_SIZE(0.1, 0.07, 0.05)
Canvas * GetCanvas(void) const
Definition: stage.hh:1592
void update(void)
Definition: camera.cc:75
World class
Definition: stage.hh:814
double dtor(double d)
Definition: stage.hh:151
#define CAMERA_NEAR_CLIP
Definition: model_camera.cc:12
The Stage library uses its own namespace.
Definition: canvas.hh:8
GLfloat * _camera_quads
Definition: stage.hh:2872
GLubyte * _camera_colors
Definition: stage.hh:2873
GLubyte * _frame_color_data
Definition: stage.hh:2862
void setDirtyBuffer(void)
Definition: canvas.hh:135
int _camera_quads_size
Definition: stage.hh:2871
virtual void Update()
Capture a new frame ( calls GetFrame )
void DrawFloor()
Definition: canvas.cc:697
static const float DEFAULT_VFOV
Definition: model_camera.cc:30
Geom geom
Definition: stage.hh:1883
void cross(float &x1, float &y1, float &z1, float x2, float y2, float z2)
Definition: model_camera.cc:73
int ReadTuple(const int entity, const char *name, const unsigned int first, const unsigned int num, const char *format,...)
Definition: worldfile.cc:1506
void setYaw(double yaw)
Definition: stage.hh:1418
PerspectiveCamera _camera
Definition: stage.hh:2877
Size size
extent
Definition: stage.hh:395
virtual void DataVisualize(Camera *cam)
Draw Camera Model - TODO.
#define PRINT_DEBUG2(m, a, b)
Definition: stage.hh:668
void setPose(double x, double y, double z)
Definition: stage.hh:1412
void DrawBlocks()
Definition: canvas.cc:714
void setFov(double horiz_fov, double vert_fov)
Definition: stage.hh:1415
meters_t z
location in 3 axes
Definition: stage.hh:251
meters_t y
Definition: stage.hh:251
Worldfile * wf
Definition: stage.hh:2015
bool _valid_vertexbuf_cache
Definition: stage.hh:2864
double _yaw_offset
Definition: stage.hh:2878
static const float DEFAULT_HFOV
Definition: model_camera.cc:29
int wf_entity
Definition: stage.hh:2016
WorldGui * world_gui
Definition: stage.hh:2018
void RegisterOption(Option *opt)
Definition: model.cc:996
void setClip(double near, double far)
Definition: stage.hh:1431
Canvas * _canvas
Definition: stage.hh:2859
Pose GetGlobalPose() const
Definition: model.cc:1379
double rtod(double r)
Definition: stage.hh:148
double realDistance(double z_buf_val) const
Definition: stage.hh:1425
virtual void Load()
virtual void Startup()
Definition: model.cc:707
static Option showCameraData
Definition: stage.hh:2875
bool GetFrame()
Take a screenshot from the camera&#39;s perspective. return: true for sucess, and data is available via F...
virtual void Update()
Definition: model.cc:735
double horizFov(void) const
Definition: stage.hh:1419
virtual void SetProjection(void) const
Definition: camera.cc:54
virtual void Load()
Definition: model.cc:1422
World * world
Definition: stage.hh:2017
#define CAMERA_FAR_CLIP
Definition: model_camera.cc:13
void SetGeom(const Geom &src)
Definition: model.cc:1243
virtual void Draw(void) const
Definition: camera.cc:42
radians_t a
rotation about the z axis.
Definition: stage.hh:252
static const char DEFAULT_GEOM_COLOR[]
Definition: model_camera.cc:28
void setPitch(double pitch)
Definition: stage.hh:1422
double vertFov(void) const
Definition: stage.hh:1420
Color color
Definition: stage.hh:1859
ColoredVertex * _vertexbuf_cache
Definition: stage.hh:2865
double _pitch_offset
Definition: stage.hh:2879
void SetColor(Color col)
Definition: model.cc:1260
meters_t x
Definition: stage.hh:251
GLfloat * _frame_data
Definition: stage.hh:2861
Model * parent
Definition: stage.hh:1912


stage
Author(s): Richard Vaughan , Brian Gerkey , Reed Hedges , Andrew Howard , Toby Collett , Pooya Karimian , Jeremy Asher , Alex Couture-Beil , Geoff Biggs , Rich Mattes , Abbas Sadat
autogenerated on Mon Jun 10 2019 15:06:09