camera.cc
Go to the documentation of this file.
00001 /*
00002  *  camera.cc
00003  *  Stage
00004  *
00005  *  Created by Alex Couture-Beil on 06/06/08.
00006  *
00007  */
00008 
00009 
00010 #include "stage.hh"
00011 #include "worldfile.hh"
00012 using namespace Stg;
00013 
00014 #include <iostream>
00015 
00016 // Perspective Camera
00017 PerspectiveCamera::PerspectiveCamera( void ) : 
00018         Camera(),
00019         _z_near( 0.2 ), _z_far( 40.0 ),
00020         _vert_fov( 70 ), _horiz_fov( 70 ),
00021         _aspect( 1.0 )
00022 {
00023         setPitch( 70.0 );
00024 }
00025 
00026 void PerspectiveCamera::move( double x, double y, double z )
00027 {
00028   (void)z; // avoid warning about unused var
00029 
00030         //scale relative to zoom level
00031         x *= _z / 100.0;
00032         y *= _z / 100.0;
00033         
00034         //adjust for yaw angle
00035         _x += cos( dtor( _yaw ) ) * x;
00036         _x += -sin( dtor( _yaw ) ) * y;
00037         
00038         _y += sin( dtor( _yaw ) ) * x;
00039         _y += cos( dtor( _yaw ) ) * y;
00040         }
00041 
00042 void PerspectiveCamera::Draw( void ) const
00043 {       
00044         glMatrixMode (GL_MODELVIEW);
00045         glLoadIdentity ();
00046         
00047         glRotatef( - _pitch, 1.0, 0.0, 0.0 );
00048         glRotatef( - _yaw, 0.0, 0.0, 1.0 );
00049 
00050         glTranslatef( - _x, - _y, - _z );
00051         //zooming needs to happen in the Projection code (don't use glScale for zoom)
00052 }
00053 
00054 void PerspectiveCamera::SetProjection( void ) const
00055 {
00056 //      SetProjection( pixels_width/pixels_height );
00057         
00058         glMatrixMode (GL_PROJECTION);
00059         glLoadIdentity ();
00060         
00061         double top = tan( dtor( _vert_fov ) / 2.0 ) * _z_near;
00062         double bottom = -top;
00063         double right = tan( dtor( _horiz_fov ) / 2.0 ) * _z_near;
00064         double left = -right;
00065         
00066         right *= _aspect;
00067         left *= _aspect;
00068 
00069         glFrustum( left, right, bottom, top, _z_near, _z_far );
00070         
00071         glMatrixMode (GL_MODELVIEW);
00072         
00073 }
00074 
00075 void PerspectiveCamera::update( void )
00076 {       
00077 }
00078 
00079 
00080 void PerspectiveCamera::strafe( double amount )
00081 {
00082         _x += cos( dtor( _yaw ) ) * amount;
00083         _y += sin( dtor( _yaw ) ) * amount;
00084 }
00085 
00086 void PerspectiveCamera::forward( double amount )
00087 {
00088         _x += -sin( dtor( _yaw ) ) * amount;
00089         _y += cos( dtor( _yaw ) ) * amount;
00090 }
00091 
00092 void PerspectiveCamera::Load( Worldfile* wf, int sec )
00093 {
00094   wf->ReadTuple( sec, "pcam_loc", 0, 3, "lll", &_x, &_y, &_z );  
00095   wf->ReadTuple( sec, "pcam_angle", 0, 2, "aa", &_pitch, &_yaw );  
00096 }
00097 
00098 void PerspectiveCamera::Save( Worldfile* wf, int sec ) 
00099 {
00100   wf->WriteTuple( sec, "pcam_loc", 0, 3, "lll", _x, _y, _z );  
00101   wf->WriteTuple( sec, "pcam_angle", 0, 2, "aa", _pitch, _yaw );  
00102 }
00103 
00104 
00105 
00106 
00108 //Ortho camera
00110 void OrthoCamera::Draw( void ) const
00111 {       
00112         glMatrixMode (GL_MODELVIEW);
00113         glLoadIdentity ();
00114 
00115         glRotatef( - _pitch, 1.0, 0.0, 0.0 );
00116         glRotatef( - _yaw, 0.0, 0.0, 1.0 );
00117 
00118         glTranslatef( - _x, - _y, 0.0 );
00119         //zooming needs to happen in the Projection code (don't use glScale for zoom)
00120 
00121 }
00122 
00123 void OrthoCamera::SetProjection( void ) const
00124 {
00125         glMatrixMode (GL_PROJECTION);
00126         glLoadIdentity ();
00127         
00128         glOrtho( -_pixels_width/2.0 / _scale, _pixels_width/2.0 / _scale,
00129                         -_pixels_height/2.0 / _scale, _pixels_height/2.0 / _scale,
00130                         _y_min * _scale * 2, _y_max * _scale * 2 );     
00131         
00132         glMatrixMode (GL_MODELVIEW);
00133 }
00134 
00135 void OrthoCamera::SetProjection( double pixels_width, double pixels_height, double y_min, double y_max )
00136 {
00137         _pixels_width = pixels_width;
00138         _pixels_height = pixels_height;
00139         _y_min = y_min; 
00140         _y_max = y_max;
00141         SetProjection();
00142 }
00143 
00144 void OrthoCamera::move( double x, double y ) {
00145         //convert screen points into world points
00146         x = x / ( _scale );
00147         y = y / ( _scale );
00148         
00149         //adjust for pitch angle
00150         y = y / cos( dtor( _pitch ) );
00151         
00152         //don't allow huge values
00153         if( y > 100 ) 
00154                 y = 100;
00155         else if( y < -100 ) 
00156                 y = -100;
00157         
00158         //adjust for yaw angle
00159         double yaw = -dtor( _yaw );
00160         _x += cos( yaw ) * x;
00161         _y += -sin( yaw ) * x;
00162         
00163         _x += sin( yaw ) * y;
00164         _y += cos( yaw ) * y;
00165 }
00166 
00167 //TODO re-evaluate the way the camera is shifted when the mouse zooms - it might be possible to simplify
00168 void OrthoCamera::scale( double scale, double shift_x, double w, double shift_y, double h )
00169 {
00170         double to_scale = -scale;
00171         const double old_scale = _scale;
00172 
00173         //TODO setting up the factor can use some work
00174         double factor = 1.0 + fabs( to_scale ) / 25;
00175         if( factor < 1.1 )
00176                 factor = 1.1; //this must be greater than 1.
00177         else if( factor > 2.5 )
00178                 factor = 2.5;
00179 
00180         //convert the shift distance to the range [-0.5, 0.5]
00181         shift_x = shift_x / w - 0.5;
00182         shift_y = shift_y / h - 0.5;
00183 
00184         //adjust the shift values based on the factor (this represents how much the positions grows/shrinks)
00185         shift_x *= factor - 1.0;
00186         shift_y *= factor - 1.0;
00187 
00188         if( to_scale > 0 ) {
00189                 //zoom in
00190                 _scale *= factor;
00191                 move( shift_x * w, - shift_y * h );
00192         }
00193         else {
00194                 //zoom out
00195                 _scale /= factor;
00196                 if( _scale < 1 ) {
00197                         _scale = 1;
00198                 } else {
00199                         //shift camera to follow where mouse zoomed out
00200                         move( - shift_x * w / old_scale * _scale, 
00201                                         shift_y * h / old_scale * _scale );
00202                 }
00203         }
00204 }
00205 
00206 void OrthoCamera::Load( Worldfile* wf, int sec ) 
00207 {
00208   wf->ReadTuple( sec, "center", 0, 2, "ff", &_x, &_y );
00209   wf->ReadTuple( sec, "rotate", 0, 2, "ff", &_pitch, &_yaw );  
00210   setScale( wf->ReadFloat(sec, "scale", scale() ) );
00211 }
00212 
00213 void OrthoCamera::Save( Worldfile* wf, int sec ) 
00214 {
00215   wf->WriteTuple( sec, "center", 0, 2, "ff", _x, _y );
00216   wf->WriteTuple( sec, "rotate", 0, 2, "ff", _pitch, _yaw );  
00217 
00218   // wf->WriteTupleFloat( sec, "center", 0, x() );
00219   // wf->WriteTupleFloat( sec, "center", 1, y() );
00220   // wf->WriteTupleFloat( sec, "rotate", 0, pitch() );
00221   // wf->WriteTupleFloat( sec, "rotate", 1, yaw() );
00222   
00223   wf->WriteFloat(sec, "scale", scale() );
00224 }
00225 


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 Thu Aug 27 2015 15:20:57