tgCamera.cpp
Go to the documentation of this file.
00001 //CPP:
00002 //                      Title:                  class tgCamera
00003 //                      File:                           tgCamera.cpp
00004 //
00005 //                      Function:               Viewing tgCamera for free movement in space
00006 //                                                                      Forward, Backward, Strafe, Rotate
00007 //
00008 //                      Author:                 Thomas Mörwald
00009 //                      Date:                           09.01.2007
00010 // ----------------------------------------------------------------------------
00011 #include <blort/TomGine/tgCamera.h>
00012 
00013 using namespace TomGine;
00014 
00015 tgCamera::Parameter::Parameter(){
00016     width = 640;
00017     height = 480;
00018     fx = 520.0f;
00019     fy = 520.0f;
00020     cx = 320.0f;
00021     cy = 240.0f;
00022     k1 = 0.0f;
00023     k2 = 0.0f;
00024     k3 = 0.0f;
00025     p1 = 0.0f;
00026     p2 = 0.0f;
00027     rot.fromRotVector(vec3(-2.0f,-1.0f,0.5f));
00028     pos = vec3(0.6f, -0.2f, 0.5f);
00029     zNear = 0.01f;
00030     zFar = 4.0f;
00031 }
00032 
00033 tgCamera::Parameter::Parameter(const sensor_msgs::CameraInfo& cam_info)
00034 {
00035     width = cam_info.width;
00036     height = cam_info.height;
00037     fx =cam_info.K.at(0);
00038     cx = cam_info.K.at(2);
00039     fy = cam_info.K.at(4);
00040     cy = cam_info.K.at(5);
00041     k1 = cam_info.D.at(0);
00042     k2 = cam_info.D.at(1);
00043     k3 = cam_info.D.at(4);
00044     p1 = cam_info.D.at(2);
00045     p2 = cam_info.D.at(3);
00046     zNear = 0.1f;
00047     zFar = 5.0f;
00048     rot.fromRotVector(vec3(-2.0f,-1.0f,0.5f));
00049     pos = vec3(0.6f, -0.2f, 0.5f);
00050 }
00051 
00052 void tgCamera::Parameter::setPose(const TomGine::tgPose& camPose)
00053 {
00054 //    pos = camPose.t;
00055 //    rot = camPose.q;
00056 }
00057 
00058 tgCamera::tgCamera(){
00059     f = tgVector3(0.0f,0.0f,-1.0f);
00060     s = tgVector3(1.0f,0.0f,0.0f);
00061     u = tgVector3(0.0f,1.0f,0.0f);
00062 }
00063 
00064 void tgCamera::Load(tgCamera::Parameter camPars){
00065 
00066     // intrinsic parameters
00067     // transform the coordinate system of computer vision to OpenGL
00068     //   Vision: origin is in the up left corner, x-axis pointing right, y-axis pointing down
00069     //   OpenGL: origin is in the middle, x-axis pointing right, y-axis pointing up
00070     float fx = 2.0f*camPars.fx / camPars.width;                                 // scale range from [0 ... 640] to [0 ... 2]
00071     float fy = 2.0f*camPars.fy / camPars.height;                                        // scale range from [0 ... 480] to [0 ... 2]
00072     float cx = 1.0f-(2.0f*camPars.cx / camPars.width);          // move coordinates from left to middle of image: [0 ... 2] -> [-1 ... 1] (not negative z value at w-division)
00073     float cy = (2.0f*camPars.cy / camPars.height)-1.0f;         // flip and move coordinates from top to middle of image: [0 ... 2] -> [-1 ... 1] (not negative z value at w-division)
00074     float z1 = (camPars.zFar+camPars.zNear)/(camPars.zNear-camPars.zFar);                                                               // entries for clipping planes
00075     float z2 = 2.0f*camPars.zFar*camPars.zNear/(camPars.zNear-camPars.zFar);                                                            // look up for gluPerspective
00076 
00077     // intrinsic matrix
00078     mat4 intrinsic;
00079     intrinsic[0]=fx;    intrinsic[4]=0; intrinsic[8]=cx;        intrinsic[12]=0;
00080     intrinsic[1]=0;     intrinsic[5]=fy;        intrinsic[9]=cy;        intrinsic[13]=0;
00081     intrinsic[2]=0;     intrinsic[6]=0;         intrinsic[10]=z1;       intrinsic[14]=z2;
00082     intrinsic[3]=0;     intrinsic[7]=0;         intrinsic[11]=-1;       intrinsic[15]=0;        // last row assigns w=-z which inverts cx and cy at w-division
00083 
00084     // computer vision camera coordinates to OpenGL camera coordinates transform
00085     // rotate 180� about x-axis
00086     mat4 cv2gl;
00087     cv2gl[0]=1.0; cv2gl[4]=0.0;         cv2gl[8]=0.0;   cv2gl[12]=0.0;
00088     cv2gl[1]=0.0; cv2gl[5]=-1.0;        cv2gl[9]=0.0;   cv2gl[13]=0.0;
00089     cv2gl[2]=0.0; cv2gl[6]=0.0;         cv2gl[10]=-1.0; cv2gl[14]=0.0;
00090     cv2gl[3]=0.0; cv2gl[7]=0.0;         cv2gl[11]=0.0;  cv2gl[15]=1.0;
00091 
00092     // extrinsic parameters
00093     // look up comments in tools/hardware/video/src/slice/Video.ice
00094     // p = R^T*(w - t) = (R^T, -R^T*t) * (w,1)
00095     mat3 R = camPars.rot;
00096     vec3 t = camPars.pos;
00097     mat4 extrinsic;
00098     extrinsic[0]=R[0];  extrinsic[4]=R[3];      extrinsic[8]=R[6];              extrinsic[12]=0.0;
00099     extrinsic[1]=R[1];  extrinsic[5]=R[4];      extrinsic[9]=R[7];              extrinsic[13]=0.0;
00100     extrinsic[2]=R[2];  extrinsic[6]=R[5];      extrinsic[10]=R[8];             extrinsic[14]=0.0;
00101     extrinsic[3]=0.0;   extrinsic[7]=0.0;       extrinsic[11]=0.0;              extrinsic[15]=1.0;
00102     //  extrinsic = extrinsic.transpose();                                                      // R^T
00103     vec4 tp = -(extrinsic * vec4(t.x, t.y, t.z, 1.0));                  // -R^T*t
00104     extrinsic[12]=tp.x; extrinsic[13]=tp.y; extrinsic[14]=tp.z;
00105     extrinsic = cv2gl * extrinsic;
00106 
00107     // set camera parameters
00108     SetViewport(camPars.width,camPars.height);
00109     SetZRange(camPars.zNear, camPars.zFar);
00110     SetIntrinsic(intrinsic);
00111     SetExtrinsic(extrinsic);
00112     SetPos(camPars.pos.x, camPars.pos.y, camPars.pos.z);
00113 }
00114 
00115 void tgCamera::Set(     float posx,  float posy,  float posz,
00116                         float viewx, float viewy, float viewz,
00117                         float upx,   float upy,   float upz,
00118                         float fovy, unsigned width, unsigned height,
00119                         float zNear, float zFar,
00120                         unsigned short projection){
00121     m_vPos      = tgVector3(posx,  posy,  posz ); // set position
00122     m_vView     = tgVector3(viewx, viewy, viewz); // set view point
00123     m_vUp       = tgVector3(upx,   upy,   upz  ); // set the up vector
00124     pvu2fsu();
00125 
00126     m_fovy = fovy;
00127     m_width = width;
00128     m_height = height;
00129     m_zNear = zNear;
00130     m_zFar = zFar;
00131     m_projection = projection;
00132 
00133     fwh2intrinsic();
00134     fsu2extrinsic();
00135 }
00136 
00137 void tgCamera::SetExtrinsic(float* M){  
00138     m_extrinsic = mat4(M);
00139 
00140     extrinsic2fsu();
00141     fsu2pvu();
00142 
00143     Activate();
00144 }
00145 
00146 void tgCamera::SetIntrinsic(float* M){
00147     m_intrinsic = mat4(M);
00148 
00149     Activate();
00150 }
00151 
00152 void tgCamera::SetIntrinsic(    float fovy, unsigned width, unsigned height,
00153                                 float zNear, float zFar,
00154                                 unsigned short projection)
00155 {
00156     m_fovy = fovy;
00157     m_width = width;
00158     m_height = height;
00159     m_zNear = zNear;
00160     m_zFar = zFar;
00161     m_projection = projection;
00162 
00163     float m[16];
00164     glMatrixMode(GL_PROJECTION);
00165     glLoadIdentity();
00166 
00167     if(m_projection == GL_ORTHO){
00168         glOrtho(0, m_width, 0, m_height, m_zNear, m_zFar);
00169     }
00170     else if(m_projection == GL_PERSPECTIVE){
00171         gluPerspective( m_fovy, float(m_width)/float(m_height), m_zNear, m_zFar);
00172     }
00173     glGetFloatv(GL_PROJECTION_MATRIX, m);
00174     m_intrinsic = mat4(m);
00175 
00176     Activate();
00177 }
00178 
00179 void tgCamera::SetViewport(unsigned w, unsigned h){
00180     m_width = w;
00181     m_height = h;
00182 }
00183 
00184 void tgCamera::SetZRange(float _near, float _far){
00185     m_zNear = _near;
00186     m_zFar = _far;
00187 }
00188 
00189 vec2 tgCamera::ToImageSpace(const vec3 &world_space){
00190     vec2 ret;
00191     vec4 tmp = m_intrinsic * m_extrinsic * vec4(world_space.x,world_space.y,world_space.z,1.0f);
00192 
00193     tmp.x = tmp.x / tmp.w;
00194     tmp.y = tmp.y / tmp.w;
00195 
00196     ret.x = (tmp.x + 1.0f) * 0.5f * m_width;
00197     ret.y = (tmp.y + 1.0f) * 0.5f * m_height;
00198 
00199     return ret;
00200 }
00201 
00202 void tgCamera::Activate(){
00203     // Apply intrinsic parameters
00204     glMatrixMode(GL_PROJECTION);
00205     glLoadMatrixf(m_intrinsic);
00206 
00207     // Apply extrinsic parameters
00208     glMatrixMode(GL_MODELVIEW);
00209     glLoadMatrixf(m_extrinsic);
00210 
00211     glViewport(0,0,m_width,m_height);
00212     glDepthRange(m_zNear,m_zFar);
00213 
00214     // Extract frustum planes
00215     m_frustum.ExtractFrustum();
00216 }
00217 
00218 void tgCamera::Print(){
00219     //  float m[16];
00220     //  float p[16];
00221     //
00222     //  glGetFloatv(GL_MODELVIEW_MATRIX, m);
00223     //  glGetFloatv(GL_PROJECTION_MATRIX, p);
00224 
00225     mat4 m = m_extrinsic;
00226     mat4 p = m_intrinsic;
00227 
00228     printf("Modelview matrix:\n");
00229     printf("%f %f %f %f\n", m[0], m[4], m[8],  m[12]);
00230     printf("%f %f %f %f\n", m[1], m[5], m[9],  m[13]);
00231     printf("%f %f %f %f\n", m[2], m[6], m[10], m[14]);
00232     printf("%f %f %f %f\n", m[3], m[7], m[11], m[15]);
00233     printf("Projection matrix:\n");
00234     printf("%f %f %f %f\n", p[0], p[4], p[8],  p[12]);
00235     printf("%f %f %f %f\n", p[1], p[5], p[9],  p[13]);
00236     printf("%f %f %f %f\n", p[2], p[6], p[10], p[14]);
00237     printf("%f %f %f %f\n", p[3], p[7], p[11], p[15]);
00238 }
00239 
00240 void tgCamera::pvu2fsu(){
00241     f = m_vView - m_vPos; f.normalize();
00242     s = f.cross(m_vUp); s.normalize();
00243     u = s.cross(f); u.normalize();
00244 }
00245 
00246 void tgCamera::fsu2pvu(){
00247     m_vView = m_vPos + f;
00248     m_vUp = u;
00249 }
00250 
00251 void tgCamera::fsu2extrinsic(){
00252     float fR[16] = {    s.x,  u.x, -f.x,  0.0,
00253                         s.y,  u.y, -f.y,  0.0,
00254                         s.z,  u.z, -f.z,  0.0,
00255                         0.0,    0.0,    0.0,  1.0};
00256 
00257     float ft[16] = {    1.0,  0.0, 0.0, 0.0,
00258                         0.0,  1.0, 0.0, 0.0,
00259                         0.0,  0.0, 1.0, 0.0,
00260                         -m_vPos.x,      -m_vPos.y, -m_vPos.z, 1.0};
00261     mat4 R(fR);
00262     mat4 t(ft);
00263 
00264     m_extrinsic = R * t;
00265 }
00266 
00267 
00268 void tgCamera::extrinsic2fsu(){
00269     s.x=m_extrinsic[0]; u.x=m_extrinsic[1]; f.x=-m_extrinsic[2];
00270     s.y=m_extrinsic[4]; u.y=m_extrinsic[5]; f.y=-m_extrinsic[6];
00271     s.z=m_extrinsic[8]; u.z=m_extrinsic[9]; f.z=-m_extrinsic[10];
00272 
00273     float fR[16] = {    s.x,  u.x, -f.x,  0.0,
00274                         s.y,  u.y, -f.y,  0.0,
00275                         s.z,  u.z, -f.z,  0.0,
00276                         0.0,    0.0,    0.0,  1.0};
00277     mat4 R(fR);
00278     mat4 t;
00279 
00280     t = R.inverse() * m_extrinsic;
00281 
00282     m_vPos.x=-t[12]; m_vPos.x=-t[13]; m_vPos.x=-t[14];
00283 }
00284 
00285 void tgCamera::fwh2intrinsic(){
00286     float m[16];
00287     glMatrixMode(GL_PROJECTION);
00288     glLoadIdentity();
00289 
00290     if(m_projection == GL_ORTHO){
00291         glOrtho(0, m_width, 0, m_height, m_zNear, m_zFar);
00292     }
00293     else if(m_projection == GL_PERSPECTIVE){
00294         gluPerspective( m_fovy, float(m_width)/float(m_height), m_zNear, m_zFar);
00295     }
00296     glGetFloatv(GL_PROJECTION_MATRIX, m);
00297     m_intrinsic = mat4(m);
00298 }
00299 
00300 tgPose tgCamera::GetPose(){
00301     printf("[tgCamera::GetPose()] Not implemented yet\n");
00302     return tgPose();
00303 }
00304 //****************************************************************************
00305 // Translations
00306 void tgCamera::Translate(tgVector3 v){
00307     m_vPos = m_vPos + v;
00308     m_vView = m_vPos + f;
00309 }
00310 
00311 void tgCamera::Translate(float x, float y, float z, float fWay){
00312     tgVector3 v = tgVector3(x,y,z);
00313     v.normalize();
00314     m_vPos = m_vPos + v * fWay;
00315     m_vView = m_vPos + f;
00316 }
00317 
00318 void tgCamera::TranslateF(float fWay){
00319     m_vPos = m_vPos + f * fWay;
00320     m_vView = m_vPos + f;
00321 }
00322 
00323 void tgCamera::TranslateS(float fWay){
00324     m_vPos = m_vPos + s * fWay;
00325     m_vView = m_vPos + f;
00326 }
00327 
00328 void tgCamera::TranslateU(float fWay){
00329     m_vPos = m_vPos + u * fWay;
00330     m_vView = m_vPos + f;
00331 }
00332 
00333 //****************************************************************************
00334 // Rotations
00335 void tgCamera::Rotate(float x, float y, float z, float fAngle){
00336     tgVector3 v = tgVector3(x,y,z);
00337     f.rotate(fAngle, v);
00338     s.rotate(fAngle, v);
00339     u.rotate(fAngle, v);
00340     fsu2pvu();
00341 }
00342 
00343 void tgCamera::RotateF(float fAngle){
00344     s.rotate(fAngle, f);
00345     u = s.cross(f); u.normalize();
00346     fsu2pvu();
00347 }
00348 
00349 void tgCamera::RotateS(float fAngle){
00350     f.rotate(fAngle, s);
00351     u = s.cross(f); u.normalize();
00352     fsu2pvu();
00353 }
00354 
00355 void tgCamera::RotateU(float fAngle){
00356     f.rotate(fAngle, u);
00357     s = f.cross(u); s.normalize();
00358     fsu2pvu();
00359 }
00360 
00361 void tgCamera::RotateX(float fAngle){
00362     printf("tgCamera.RotateX not implemented! \n");
00363 }
00364 
00365 void tgCamera::RotateY(float fAngle){
00366     tgVector3 y = tgVector3(0.0f,1.0f,0.0f);
00367     f.rotate(fAngle, y);
00368     s = f.cross(y); s.normalize();
00369     u = s.cross(f); u.normalize();
00370     fsu2pvu();
00371 }
00372 
00373 void tgCamera::RotateZ(float fAngle){
00374     printf("tgCamera.RotateZ not implemented! \n");
00375 }
00376 
00377 void tgCamera::Orbit(tgVector3 vPoint, tgVector3 vAxis, float fAngle){
00378     tgVector3 d = m_vPos - vPoint;
00379 
00380     d.rotate(fAngle, vAxis);
00381     m_vPos = vPoint + d;
00382 
00383     f.rotate(fAngle, vAxis);
00384     s.rotate(fAngle, vAxis);
00385     u.rotate(fAngle, vAxis);
00386 }
00387 
00388 //****************************************************************************
00389 // Movement
00390 void tgCamera::ApplyTransform(){
00391     fsu2extrinsic();
00392 }
00393 
00394 
00395 


blort
Author(s): Michael Zillich, Thomas Mörwald, Johann Prankl, Andreas Richtsfeld, Bence Magyar (ROS version)
autogenerated on Thu Jan 2 2014 11:38:26