00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include "stage.hh"
00011 #include "worldfile.hh"
00012 using namespace Stg;
00013
00014 #include <iostream>
00015
00016
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;
00029
00030
00031 x *= _z / 100.0;
00032 y *= _z / 100.0;
00033
00034
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
00052 }
00053
00054 void PerspectiveCamera::SetProjection( void ) const
00055 {
00056
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
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
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
00146 x = x / ( _scale );
00147 y = y / ( _scale );
00148
00149
00150 y = y / cos( dtor( _pitch ) );
00151
00152
00153 if( y > 100 )
00154 y = 100;
00155 else if( y < -100 )
00156 y = -100;
00157
00158
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
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
00174 double factor = 1.0 + fabs( to_scale ) / 25;
00175 if( factor < 1.1 )
00176 factor = 1.1;
00177 else if( factor > 2.5 )
00178 factor = 2.5;
00179
00180
00181 shift_x = shift_x / w - 0.5;
00182 shift_y = shift_y / h - 0.5;
00183
00184
00185 shift_x *= factor - 1.0;
00186 shift_y *= factor - 1.0;
00187
00188 if( to_scale > 0 ) {
00189
00190 _scale *= factor;
00191 move( shift_x * w, - shift_y * h );
00192 }
00193 else {
00194
00195 _scale /= factor;
00196 if( _scale < 1 ) {
00197 _scale = 1;
00198 } else {
00199
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
00219
00220
00221
00222
00223 wf->WriteFloat(sec, "scale", scale() );
00224 }
00225