00001
00002 #ifndef _GK_CAMERA_H
00003 #define _GK_CAMERA_H
00004
00005 #include "Transform.h"
00006 #include "IOFileSystem.h"
00007
00008 namespace gk {
00009
00010
00011 class Camera
00012 {
00013 protected:
00014 Transform m_view;
00015 Transform m_projection;
00016 Transform m_viewport;
00017
00018 float m_width;
00019 float m_height;
00020
00021 public:
00022
00023 Point origin( ) const
00024 {
00025 return m_view.inverse( Point(0.f, 0.f, 0.f) );
00026 }
00027
00028
00029 Vector up( ) const
00030 {
00031 return m_view.inverse( Vector(0.f, 1.f, 0.f) );
00032 }
00033
00034
00035 Vector right( ) const
00036 {
00037 return m_view.inverse( Vector(1.f, 0.f, 0.f) );
00038 }
00039
00040
00041 Vector forward( ) const
00042 {
00043 return m_view.inverse( Vector(0.f, 0.f, 1.f) );
00044 }
00045
00046 public:
00047
00048 Camera( )
00049 :
00050 m_view(),
00051 m_projection(),
00052 m_viewport( Viewport(100.f, 100.f) ),
00053 m_width(100.f),
00054 m_height(100.f)
00055 {}
00056
00057
00058 Camera( const Transform& projection, const int width= 100, const int height= 100 )
00059 :
00060 m_view(),
00061 m_projection(projection),
00062 m_viewport( Viewport(width, height) ),
00063 m_width(width),
00064 m_height(height)
00065 {}
00066
00067
00068 ~Camera() {}
00069
00070
00071 void setViewport( const int width, const int height )
00072 {
00073 m_width= width;
00074 m_height= height;
00075 m_viewport= Viewport(width, height);
00076 }
00077
00078
00079 void setViewport( int viewport[4] )
00080 {
00081 m_width= viewport[2];
00082 m_height= viewport[3];
00083 m_viewport= Viewport(viewport[2], viewport[3]);
00084 }
00085
00086
00087 void setProjection( const Transform& projection )
00088 {
00089 m_projection= projection;
00090 }
00091
00092
00093 const Transform& projection( )
00094 {
00095 return m_projection;
00096 }
00097
00098
00099 const Transform& view( )
00100 {
00101 return m_view;
00102 }
00103
00104
00105 const Transform& viewport( )
00106 {
00107 return m_viewport;
00108 }
00109 };
00110
00111
00112 class PerspectiveCamera : public gk::Camera
00113 {
00114 public:
00115
00116 PerspectiveCamera( )
00117 :
00118 gk::Camera()
00119 {}
00120
00121
00122 PerspectiveCamera( const float fov, const float aspect, const float znear, const float zfar, const int width= 100, const int height= 100 )
00123 :
00124 Camera( Perspective(fov, aspect, znear, zfar), width, height)
00125 {}
00126
00127
00128 PerspectiveCamera( const Transform& projection, const int width= 100, const int height= 100 )
00129 :
00130 Camera(projection, width, height)
00131 {}
00132
00133
00134 ~PerspectiveCamera( ) {}
00135 };
00136
00137
00138 class FirstPersonCamera : public PerspectiveCamera
00139 {
00140 protected:
00141 Point m_position;
00142 float m_rotation_x;
00143 float m_rotation_y;
00144 float m_rotation_z;
00145 float m_speed;
00146
00147 public:
00148 FirstPersonCamera( )
00149 :
00150 PerspectiveCamera(),
00151 m_position(),
00152 m_rotation_x(0.f),
00153 m_rotation_y(0.f),
00154 m_rotation_z(0.f),
00155 m_speed(1.f)
00156 {}
00157
00158
00159 FirstPersonCamera( const float fov, const float aspect, const float znear, const float zfar, const int width= 100, const int height= 100 )
00160 :
00161 PerspectiveCamera(fov, aspect, znear, zfar, width, height),
00162 m_position(),
00163 m_rotation_x(0.f),
00164 m_rotation_y(0.f),
00165 m_rotation_z(0.f),
00166 m_speed(1.f)
00167 {}
00168
00169 FirstPersonCamera( const Transform& projection, const int width= 100, const int height= 100 )
00170 :
00171 PerspectiveCamera(projection, width, height),
00172 m_position(),
00173 m_rotation_x(0.f),
00174 m_rotation_y(0.f),
00175 m_rotation_z(0.f),
00176 m_speed(1.f)
00177 {}
00178
00179 ~FirstPersonCamera( ) {}
00180
00181
00182 void setSpeed( const float v )
00183 {
00184 m_speed= v;
00185 }
00186
00187
00188 float speed( ) const
00189 {
00190 return m_speed;
00191 }
00192
00193
00194 void moveForward( const float v )
00195 {
00196 m_position= m_position + forward() * v * m_speed;
00197 }
00198
00199
00200 void moveRight( const float v )
00201 {
00202 m_position= m_position + right() * v * m_speed;
00203 }
00204
00205
00206 void moveUp( const float v )
00207 {
00208 m_position= m_position + up() * v * m_speed;
00209 }
00210
00211
00212 void move( const Point& p )
00213 {
00214 m_position= p;
00215 }
00216
00217
00218 void rotateUp( const float v )
00219 {
00220 m_rotation_y+= v;
00221 }
00222
00223
00224 void rotateRight( const float v )
00225 {
00226 m_rotation_x+= v;
00227 }
00228
00229
00230 void rotateForward( const float v )
00231 {
00232 m_rotation_z+= v;
00233 }
00234
00235
00236 const Point& position( )
00237 {
00238 return m_position;
00239 }
00240
00241
00242 const Transform& view( )
00243 {
00244 m_view= (Translate( Vector(m_position) ) * RotateZ(m_rotation_z) * RotateX(m_rotation_x) * RotateY(m_rotation_y)).getInverse();
00245 return m_view;
00246 }
00247
00248
00249 int read( const std::string& filename )
00250 {
00251 std::string pref= gk::IOFileSystem::changeType(filename, ".gkcamera");
00252 #ifdef VERBOSE
00253 printf("loading camera prefs '%s'...\n", pref.c_str());
00254 #endif
00255
00256 FILE *in= fopen(pref.c_str(), "rt");
00257 if(in == NULL)
00258 {
00259 #ifdef VERBOSE
00260 printf("failed.\n");
00261 #endif
00262 return -1;
00263 }
00264
00265 float x, y, z;
00266 float speed;
00267 float angle1, angle2, angle3;
00268 if(fscanf(in, "x %f y %f z %f v %f a %f b %f c %f",
00269 &x, &y, &z,
00270 &speed,
00271 &angle1, &angle2, &angle3) == 7)
00272 {
00273 #ifdef VERBOSE // _DEBUG
00274 printf("camera %f %f %f, rotate %f %f %f, speed %f\n",
00275 x, y, z, angle1, angle2, angle3, speed);
00276 #endif
00277
00278 m_position= Point(x, y, z);
00279 m_rotation_y= angle1;
00280 m_rotation_x= angle2;
00281 m_rotation_z= angle3;
00282 m_speed= speed;
00283
00284 #ifdef VERBOSE
00285 printf("done.\n");
00286 #endif
00287 fclose(in);
00288 return 0;
00289 }
00290
00291 #ifdef VERBOSE
00292 printf("failed.\n");
00293 #endif
00294 fclose(in);
00295 return -1;
00296 }
00297
00298
00299 int write( const std::string& filename )
00300 {
00301 std::string pref= gk::IOFileSystem::changeType(filename, ".gkcamera");
00302 #ifdef VERBOSE
00303 printf("writing camera prefs '%s'...\n", pref.c_str());
00304 #endif
00305
00306 FILE *out= fopen(pref.c_str(), "wt");
00307 if(out == NULL)
00308 {
00309 #ifdef VERBOSE
00310 printf("failed.\n");
00311 #endif
00312 return -1;
00313 }
00314
00315 if(fprintf(out, "x %f y %f z %f v %f a %f b %f c %f",
00316 m_position.x, m_position.y, m_position.z,
00317 m_speed,
00318 m_rotation_y, m_rotation_x, m_rotation_z) < 0)
00319 {
00320 #ifdef VERBOSE
00321 printf("failed.\n");
00322 #endif
00323 fclose(out);
00324 return -1;
00325 }
00326
00327 fclose(out);
00328 return 0;
00329 }
00330 };
00331
00332
00333
00334 class OrthographicCamera : public gk::Camera
00335 {
00336 public:
00337
00338 OrthographicCamera( )
00339 :
00340 gk::Camera()
00341 {}
00342
00343
00344 OrthographicCamera( const float znear, const float zfar, const int width= 100, const int height= 100 )
00345 :
00346 Camera( Orthographic(znear, zfar), width, height )
00347 {}
00348
00349
00350 ~OrthographicCamera( ) {}
00351 };
00352
00353 }
00354
00355 #endif