K3dCamera.cpp

Go to the documentation of this file.
00001 
00011 /***************************************************************************
00012  *   Copyright (C) 2007 by Jan Koci   *
00013  *   honza.koci@email.cz   *
00014  *   http://kengine.sourceforge.net/tutorial/
00015  *                                                                         *
00016  *   This program is free software; you can redistribute it and/or modify  *
00017  *   it under the terms of the GNU General Public License as published by  *
00018  *   the Free Software Foundation; either version 2 of the License, or     *
00019  *   (at your option) any later version.                                   *
00020  *                                                                         *
00021  *   This program is distributed in the hope that it will be useful,       *
00022  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00023  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00024  *   GNU General Public License for more details.                          *
00025  *                                                                         *
00026  *   You should have received a copy of the GNU General Public License     *
00027  *   along with this program; if not, write to the                         *
00028  *   Free Software Foundation, Inc.,                                       *
00029  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
00030  ***************************************************************************/
00031 
00032 #include "K3dCamera.h"
00033 #include <SDL/SDL.h>
00034 
00035 K3dCamera::K3dCamera(K3dGameData *_pGameData)
00036 {
00037         m_pGameData = _pGameData;
00038         m_pVector3Work = m_pGameData->GetVector3Work();
00039         Init();
00040 }
00041 
00042 K3dCamera::~K3dCamera()         
00043 {
00044 }
00045 
00046 
00048 void K3dCamera::Init()
00049 {
00050         // Default camera speed
00051         m_fSpeed = 10;
00052         // Default camera acceleration
00053         m_fSpeedAccel = 150;
00054         
00055         // Set alternation anle and position
00056         K3dVector3 angleAlter(0,0,0);
00057         K3dVector3 posAlter(0,0,0);
00058         // Set up vector
00059         m_kUp.Set(0,1,0);       
00060         m_bIsMouseMove = false;
00061         // Set view vector
00062         m_kView.Set(0,0,-1);
00063 
00064         // Get gloabl graphics options
00065         TGraphicOption *pOptions = m_pGameData->GetGraphicOption();
00066         // Set middle of screen
00067         int aiMiddle[2];
00068         aiMiddle[0] = pOptions->iWidth  >> 1;
00069         aiMiddle[1] = pOptions->iHeight >> 1;
00070         // Move mouse cursor to the middle of screen
00071         SDL_WarpMouse(aiMiddle[0], aiMiddle[1]);
00072 }
00073 
00075 void K3dCamera::UpdateCamera()
00076 {
00077         // Get global timer
00078         K3dTimer *pTimer = m_pGameData->GetTimer();
00079         // Synchronize camera speed
00080         m_fSpeed = m_fSpeedAccel;
00081         pTimer->SynchronizeSpeed(m_fSpeed);
00082         // Move with camera by mouse
00083         if(m_bIsMouseMove)
00084         {
00085                 MouseRotate();
00086         }
00087 
00088         // Get global keyboard map pointer
00089         K3dKeyMap *pKeyMap = m_pGameData->GetKeyMap();  
00090 
00091         if(pKeyMap->IsKeyPressed(K_GO_FORWARD))
00092         {
00093                 GoForward();
00094         }
00095         if(pKeyMap->IsKeyPressed(K_GO_BACKWARD))
00096         {
00097                 GoBackward();
00098         }
00099         if(pKeyMap->IsKeyPressed(K_TURN_LEFT))
00100         {
00101                 TurnLeft();
00102         }
00103         if(pKeyMap->IsKeyPressed(K_TURN_RIGHT))
00104         {
00105                 TurnRight();
00106         }
00107         if(pKeyMap->IsKeyPressed(K_STRAFE_RIGHT))
00108         {
00109                 StrafeRight();
00110         }
00111         if(pKeyMap->IsKeyPressed(K_STRAFE_LEFT))
00112         {
00113                 StrafeLeft();
00114         }
00115         if(pKeyMap->IsKeyPressed(K_GO_UP))
00116         {
00117                 GoUp();
00118         }
00119         if(pKeyMap->IsKeyPressed(K_GO_DOWN))
00120         {
00121                 GoDown();
00122         }
00123         if(pKeyMap->IsKeyPressed(K_LURCH_LEFT))
00124         {
00125                 LurchLeft();
00126         }
00127         if(pKeyMap->IsKeyPressed(K_LURCH_RIGHT))
00128         {
00129                 LurchRight();
00130         }
00131         if(pKeyMap->IsKeyPressed(K_TURN_UP))
00132         {
00133                 TurnUp();
00134         }
00135         if(pKeyMap->IsKeyPressed(K_TURN_DOWN))
00136         {
00137                 TurnDown();
00138         }
00139 
00140         ChangeMatrix(); 
00141 }
00142 
00144 K3dVector3Obj& K3dCamera::GetPosition()
00145 {
00146     return m_kPosition;
00147 }
00148 const K3dVector3Obj& K3dCamera::GetPosition() const
00149 {
00150     return m_kPosition;
00151 }
00152 
00154 K3dVector3Obj& K3dCamera::GetForward()
00155 {
00156     return m_kForward;
00157 }
00158 
00159 const K3dVector3Obj& K3dCamera::GetForward() const
00160 {
00161     return m_kForward;
00162 }
00163 
00165 K3dVector3Obj& K3dCamera::GetUp()
00166 {
00167         return m_kUp;
00168 }
00169 const K3dVector3Obj& K3dCamera::GetUp() const
00170 {
00171         return m_kUp;
00172 }
00173 
00175 K3dVector3Obj& K3dCamera::GetRight()
00176 {
00177         return m_kRight;
00178 }
00179 const K3dVector3Obj& K3dCamera::GetRight() const
00180 {
00181         return m_kRight;
00182 }
00183 
00185 K3dMatrix& K3dCamera::GetRotMatrix()
00186 {
00187         return m_kRotMatrix;
00188 }
00189 const K3dMatrix& K3dCamera::GetRotMatrix() const
00190 {
00191         return m_kRotMatrix;
00192 }
00193 
00195 K3dMatrix& K3dCamera::GetMatrix()
00196 {
00197         return m_kMatrix;
00198 }
00199 const K3dMatrix& K3dCamera::GetMatrix() const
00200 {
00201         return m_kMatrix;
00202 }
00203 
00205 K3dMatrix& K3dCamera::GetPrevMatrix()
00206 {
00207         return m_kPrevMatrix;
00208 }
00209 const K3dMatrix& K3dCamera::GetPrevMatrix() const
00210 {
00211         return m_kPrevMatrix;
00212 }
00213 
00216 void K3dCamera::Move(const float _fSpeed )
00217 {       
00218         // If spectator view
00219         if(m_eCamView == K_CAM_SPECTATE) 
00220         {
00221                 m_pVector3Work->SubtractScalar(m_kPosition, _fSpeed * m_kForward.GetScalar(0) ,0);
00222                 m_pVector3Work->SubtractScalar(m_kPosition, _fSpeed * m_kForward.GetScalar(1) ,1);
00223                 m_pVector3Work->AddScalar(m_kPosition, _fSpeed * m_kForward.GetScalar(2) ,2);
00224                 return;
00225         }
00226         // If first person view
00227         if(m_eCamView == K_CAM_FIRST_PERSON)
00228         {
00229                 m_pVector3Work->SubtractScalar(m_kPosition, _fSpeed * m_kForward.GetScalar(0) ,0);
00230                 m_pVector3Work->AddScalar(m_kPosition, _fSpeed * m_kForward.GetScalar(2) ,2);
00231                 return;
00232         }
00233 }
00234 
00236 void K3dCamera::RestrictCamView()
00237 {
00238         if ( m_kAngle[0] >= K3dMath::K_FI )
00239         {
00240                 m_kAngle[0] = K3dMath::K_FI;
00241         }
00242         
00243         if ( m_kAngle[0] <= -K3dMath::K_FI )
00244         {
00245                 m_kAngle[0] = -K3dMath::K_FI;
00246         }
00247 }
00248 
00250 void K3dCamera::MouseRotate()
00251 {       
00252         // Get global graphics options
00253         TGraphicOption *pOptions = m_pGameData->GetGraphicOption();
00254         
00255         // Set middle of screen
00256         int aiMiddle[2];
00257         aiMiddle[0] = pOptions->iWidth  >> 1;
00258         aiMiddle[1] = pOptions->iHeight >> 1;
00259         
00260         // Get current mouse cursor position
00261         int aiPos[2];
00262         aiPos[0] = m_pGameData->GetMouse()->MousePosition()[0];
00263         aiPos[1] = m_pGameData->GetMouse()->MousePosition()[1];
00264         
00265         // Calculate mouse step
00266         int aiStep[2];
00267         aiStep[0] = (aiPos[0] - aiMiddle[0]);
00268         aiStep[1] = (aiPos[1] - aiMiddle[1]);
00269 
00270         // Change rotation angles by mouse step
00271         m_pVector3Work->AddScalar(m_kAngle, (float)aiStep[0]*0.01 ,1);
00272         m_pVector3Work->AddScalar(m_kAngle, (float)aiStep[1]*0.01 ,0);
00273         
00274         // Move mouse cursor to the middle of screen
00275         SDL_WarpMouse(aiMiddle[0], aiMiddle[1]);
00276 
00277         // If spectator or first person view than restric camera view
00278         if((m_eCamView == K_CAM_FIRST_PERSON) || (m_eCamView == K_CAM_SPECTATE))
00279         {
00280                 RestrictCamView();
00281         }
00282 }
00283 
00285 void K3dCamera::GoForward()
00286 {
00287         // If descent camera
00288         if(m_eCamView == K_CAM_DESCENT)
00289         {       
00290                 // Change currect position by forward vector
00291                 m_kPosition += (m_kForward * m_fSpeed);
00292                 return;
00293         }
00294         // If first person camera
00295         if(m_eCamView == K_CAM_FIRST_PERSON)
00296         {
00297                 m_pVector3Work->SubtractScalar(m_kPosition, m_fSpeed * m_kForward.GetScalar(0) ,0);
00298                 m_pVector3Work->AddScalar(m_kPosition, m_fSpeed * m_kForward.GetScalar(2) ,2);
00299                 return;
00300         }
00301         // If spectate camera
00302         if(m_eCamView == K_CAM_SPECTATE)
00303         {
00304                 m_pVector3Work->SubtractScalar(m_kPosition, m_fSpeed * m_kForward.GetScalar(0) ,0);
00305                 m_pVector3Work->SubtractScalar(m_kPosition, m_fSpeed * m_kForward.GetScalar(1) ,1);
00306                 m_pVector3Work->AddScalar(m_kPosition, m_fSpeed * m_kForward.GetScalar(2) ,2);
00307                 return;
00308         }
00309 }
00310 
00312 void K3dCamera::GoBackward()
00313 {
00314         // If descent camera
00315         if(m_eCamView == K_CAM_DESCENT)
00316         {       
00317                 // Change currect position by right vector
00318                 m_kPosition -= (m_kForward * m_fSpeed);
00319                 return;
00320         }
00321         // If first person camera
00322         if(m_eCamView == K_CAM_FIRST_PERSON)
00323         {
00324                 m_pVector3Work->SubtractScalar(m_kPosition, -m_fSpeed * m_kForward.GetScalar(0) ,0);
00325                 m_pVector3Work->AddScalar(m_kPosition, -m_fSpeed * m_kForward.GetScalar(2) ,2);
00326                 return;
00327         }
00328         // If spectate camera
00329         if(m_eCamView == K_CAM_SPECTATE)
00330         {
00331                 m_pVector3Work->SubtractScalar(m_kPosition, -m_fSpeed * m_kForward.GetScalar(0) ,0);
00332                 m_pVector3Work->SubtractScalar(m_kPosition, -m_fSpeed * m_kForward.GetScalar(1) ,1);
00333                 m_pVector3Work->AddScalar(m_kPosition, -m_fSpeed * m_kForward.GetScalar(2) ,2);
00334                 return;
00335         }
00336 }
00337 
00339 void K3dCamera::GoUp()
00340 {
00341         // If descent camera
00342         if(m_eCamView == K_CAM_DESCENT)
00343         {
00344                 // Change currect position by up vector
00345                 m_kPosition += m_kUp * m_fSpeed;
00346         }
00347         else
00348         {
00349                 m_pVector3Work->AddScalar(m_kPosition, m_fSpeed ,1);
00350         }
00351 }
00352 
00354 void K3dCamera::GoDown()
00355 {
00356         if(m_eCamView == K_CAM_DESCENT)
00357         {
00358                 // Change currect position by up vector
00359                 m_kPosition -= m_kUp * m_fSpeed;
00360         }
00361         else
00362         {
00363                 m_pVector3Work->SubtractScalar(m_kPosition, m_fSpeed ,1);
00364         }
00365 }
00366 
00368 void K3dCamera::SetStrafeDirection()
00369 {
00370                 K3dVector3 kDirection;
00371                         
00372                 // Slave matrixes (reset)
00373                 K3dMatrix kM;
00374                 K3dMatrix kMX;
00375                 K3dMatrix kMY;
00376                 
00377                 // Set X rotation matrix 
00378                 kMX.RotationXGL(m_kAngle[0]);
00379                 // Set Y rotation matrix
00380                 kMY.RotationYGL(m_kAngle[1]);
00381                 
00383                 // Set X direction
00385                 // Hold mX matrix
00386                 kM = kMX;
00387                 // Multiply by matrix mY
00388                 kM.MultiplyTranspose(kMY);
00389                 // Reset direction vector
00390                 kDirection.Set(1,0,0);
00391                 // Change coordination X in direction vector
00392                 kM.ChangeVectorXGL(kDirection);
00393                 // Set X coord to my direction
00394                 m_kForward.SetX(kDirection[0]);
00395                 
00397                 // Set Y direction
00399                 m_kForward.SetY(0);
00400                 
00402                 // Set Z direction
00404                 // Reset direction vector
00405                 kDirection.Set(1,0,0);
00406                 // Change coordination X in direction vector
00407                 kM.ChangeVectorZGL(kDirection);
00408                 // Set Z coord to my direction
00409                 m_kForward.SetZ(kDirection[2]);
00410 }
00411 
00413 void K3dCamera::StrafeLeft()
00414 {
00415         // If descent camera
00416         if(m_eCamView == K_CAM_DESCENT)
00417         {       
00418                 // Change currect position by right vector
00419                 m_kPosition -= (m_kRight * m_fSpeed);
00420         }
00421         else
00422         {
00423                 SetStrafeDirection();
00424                 // Move by new direction
00425                 Move(m_fSpeed);
00426         }
00427 }
00428 
00430 void K3dCamera::StrafeRight()
00431 {
00432         // If descent camera
00433         if(m_eCamView == K_CAM_DESCENT)
00434         {
00435                 // Change currect position by right vector
00436                 m_kPosition += m_kRight * m_fSpeed;
00437         }
00438         else
00439         {
00440                 SetStrafeDirection();
00441                 // Move by new direction
00442                 Move(-m_fSpeed);
00443         }
00444 }
00445 
00447 void K3dCamera::TurnLeft()
00448 {
00449         m_pVector3Work->SubtractScalar(m_kAngle, m_fSpeed* 0.01f ,1);
00450 }
00451 
00453 void K3dCamera::TurnRight()
00454 {
00455         m_pVector3Work->AddScalar(m_kAngle, m_fSpeed* 0.01f ,1);
00456 }
00457 
00458 
00460 void K3dCamera::TurnUp()                
00461 {
00462         if(m_eCamView == K_CAM_DESCENT)
00463         {
00464                 // Set angles
00465                 m_pVector3Work->AddScalar(m_kAngle, m_fSpeed * 0.01f ,0);
00466         }
00467         else
00468         {
00469                 m_pVector3Work->AddScalar(m_kAngle, m_fSpeed * 0.01f ,0);
00470                 // If spectator or first person view than restric camera view
00471                 RestrictCamView();
00472         }
00473 }
00474 
00476 void K3dCamera::TurnDown()              
00477 {
00478         if(m_eCamView == K_CAM_DESCENT)
00479         {
00480                 // Set angles
00481                 m_pVector3Work->SubtractScalar(m_kAngle, m_fSpeed  * 0.01f ,0);
00482         }
00483         else
00484         {       
00485                 m_pVector3Work->SubtractScalar(m_kAngle, m_fSpeed  * 0.01f ,0);
00486                 // If spectator or first person view than restric camera view
00487                 RestrictCamView();
00488         }
00489 }
00490 
00492 void K3dCamera::LurchLeft()
00493 {
00494         if(m_eCamView == K_CAM_DESCENT)
00495         {
00496                 // Set angles
00497                 m_pVector3Work->SubtractScalar(m_kAngle, m_fSpeed * 0.01f ,2);
00498         }
00499 }
00500 
00502 void K3dCamera::LurchRight()
00503 {
00504         if(m_eCamView == K_CAM_DESCENT)
00505         {
00506                 // Set angle
00507                 m_pVector3Work->AddScalar(m_kAngle, m_fSpeed * 0.01f ,2);
00508         }
00509 }
00510 
00512 void K3dCamera::Look()
00513 {
00514         // Load OpenGL model matrix from camera matrix
00515         glLoadMatrixf(m_kMatrix.GetMatrix());
00516 }
00517 
00519 void K3dCamera::ChangeMatrix()
00520 {
00521         // If descent view
00522         if(m_eCamView == K_CAM_DESCENT)
00523         {
00524                 // Slave matrices (reset)
00525                 K3dMatrix kT;
00526                 K3dMatrix kR;
00527                 // Set quaternion from angle
00528                 K3dQuaternion kQuat;
00529                 kQuat.FromAxisAngle(m_kAngle);
00530                 // Set rotation matrix from quaternion
00531                 kQuat.ToRotationMatrix(kR);
00532                 // Copy rotation to camera matrix
00533                 m_kMatrix = kR;
00534                 // Multiply previous matrix by new matrix
00535                 m_kMatrix.Multiply(m_kPrevMatrix);
00536                 // Set rotation matrix from current matrix
00537                 m_kRotMatrix = m_kMatrix;
00538                 // Inverse rotation matrix
00539                 m_kRotMatrix.Inverse();
00540                 // Set direction vector
00541                 m_kForward.Set(0,0,-1);
00542                 // Change direction vector by rotation matrix
00543                 m_kRotMatrix.ChangeVectorGL(m_kForward);
00544                 // Set up vector
00545                 m_kUp.Set(0,1,0);
00546                 // Change up vector by rotation matrix
00547                 m_kRotMatrix.ChangeVectorGL(m_kUp);
00548                 // Set right vector
00549                 m_kRight.Set(1,0,0);
00550                 // Change right vector by rotation matrix
00551                 m_kRotMatrix.ChangeVectorGL(m_kRight);
00552                 // Store current matrix to previous matrix
00553                 m_kPrevMatrix = m_kMatrix;
00554                 // Set inverse matrix from current position 
00555                 kT.InverseTranslation(m_kPosition);
00556                 // Multiply inverse matrix and current position matrix
00557                 m_kMatrix.Multiply(kT);
00558                 // Reset angles
00559                 m_kAngle.Reset();
00560                 
00562                 // Set view vector
00564                 m_kView.Set(0,0,-1);
00565                 m_kMatrix.ChangeVector(m_kView);
00566                 return;
00567         }
00568 
00569         // If spectator or first person view
00570         if((m_eCamView == K_CAM_SPECTATE)||(m_eCamView == K_CAM_FIRST_PERSON))
00571         {
00572                 // Slave direction vector
00573                 K3dVector3 kDirection;
00574                 // Right vector
00575                 K3dVector3 kRight;
00576                 // Slave matrices (reset)
00577                 K3dMatrix kMX;
00578                 K3dMatrix kMY;
00579                 K3dMatrix kMT;
00580 
00581                 // Set X rotation matrix 
00582                 kMX.RotationXGL(m_kAngle[0]);
00583                 // Set Y rotation matrix
00584                 kMY.RotationYGL(m_kAngle[1]);
00585                 // Set inverse translation matrix
00586                 kMT.InverseTranslation(m_kPosition);
00587 
00589                 // Set Z direction
00591                 // Reset direction vector
00592                 kDirection.Set(0,0,-1);
00593                 kMY.ChangeVectorZGL(kDirection);
00594                 // Set Z coord to my direction
00595                 m_kForward.SetZ(kDirection[2]);
00596         
00597                 // Only if spectate view
00598                 if(m_eCamView == K_CAM_SPECTATE)
00599                 {
00601                         // Set Y direction
00603                         // Reset direction vector
00604                         kDirection.Set(0,0,-1);
00605                         kMX.ChangeVectorYGL(kDirection);
00606                         // Set Z coord to my direction
00607                         m_kForward.SetY(kDirection[1]);
00608                 }
00610                 // Calculate camera matrix
00612                 // Copy slave matrix Y to camera matrix
00613                 m_kMatrix = kMY;
00614                 // Multiply by slave matrix X
00615                 m_kMatrix.MultiplyTranspose(kMX);
00616                 // Multiply by slave transform matrix Y
00617                 m_kMatrix.Multiply(kMT);
00618 
00620                 // Set X direction
00622                 // Reset direction vector
00623                 kDirection.Set(0,0,-1);
00624                 // Change coordination X in direction vector
00625                 m_kMatrix.ChangeVectorXGL(kDirection);
00626                 // Set X coord to my direction
00627                 m_kForward.SetX(kDirection[0]);
00628 
00630                 // Set view vector
00632                 m_kView.Set(0,0,-1);
00633                 m_kMatrix.ChangeVector(m_kView);
00635                 // Set right vector
00637                 m_kRight.Set(1,0,0);
00638                 // Change right vector by rotation matrix
00639                 m_kMatrix.ChangeVector(m_kRight);
00641                 // Set up vector
00643                 m_kUp.Set(0,1,0);
00644                 // Change up vector by rotation matrix
00645                 m_kMatrix.ChangeVector(m_kUp);
00646 
00647                 return;
00648         }
00649 }

Generated on Thu Aug 16 23:53:26 2007 for K3dEngine by  doxygen 1.5.0