Funkce MultiplyTranspose(...) transponovaně vynásobí aktuální matici kamery maticí v parametru funkce. Výsledek uloží do aktuální modelové matice kamery.
Funkce ChangeVectorXGL(...) ChangeVectorYGL(...) ChangeVectorZGL(...) změní XYZ koordinace vstupního vektoru podle OpenGL matice.
///\briefChangeXvectorcoordinationbyOpenGLmatrix///\param_rkVec Vector to which change X coordinationvoid CMatrix::ChangeVectorXGL( CVector3& _rkVec ){float fVec = (_rkVec[0] * m_afMatrix[0]) + (_rkVec[1] * m_afMatrix[4]) + (_rkVec[2] * m_afMatrix[8]); _rkVec[0] = fVec;}///\briefChangeYvectorcoordinationbyOpenGLmatrix///\param_rkVec Vector to which change Y coordinationvoid CMatrix::ChangeVectorYGL( CVector3& _rkVec ){float fVec = _rkVec[0] * m_afMatrix[1] + _rkVec[1] * m_afMatrix[5] + _rkVec[2] * m_afMatrix[9]; _rkVec[1] = fVec;}///\briefChangeXvectorcoordinationbyOpenGLmatrix///\param_rkVec Vector to which change X coordinationinlinevoid CMatrix::ChangeVectorZGL( CVector3& _rkVec ){float fVec = _rkVec[0] * m_afMatrix[2] + _rkVec[1] * m_afMatrix[6] + _rkVec[2] * m_afMatrix[10]; _rkVec[2] = fVec;}
Změna modelové matice pro descent, first person a spectate kameru.
Změnu modelové matice provádí funkce ChangeMatrix()
///\briefChangecameramatrixvoid CCamera::ChangeMatrix(){// If descent viewif(m_eCamView == K_CAM_DESCENT) {// Slave matrices (reset) CMatrix kT; CMatrix kR;// Set quaternion from angle CQuaternion kQuat; kQuat.FromAxisAngle(m_kAngle);// Set rotation matrix from quaternion kQuat.ToRotationMatrix(kR);// Copy rotation to camera matrix m_kMatrix = kR;// Multiply previous matrix by new matrix m_kMatrix.Multiply(m_kPrevMatrix);// Set rotation matrix from current matrix m_kRotMatrix = m_kMatrix;// Inverse rotation matrix m_kRotMatrix.Inverse();// Set direction vector m_kForward.Set(0,0,-1);// Change direction vector by rotation matrix m_kRotMatrix.ChangeVectorGL(m_kForward);// Set up vector m_kUp.Set(0,1,0);// Change up vector by rotation matrix m_kRotMatrix.ChangeVectorGL(m_kUp);// Set right vector m_kRight.Set(1,0,0);// Change right vector by rotation matrix m_kRotMatrix.ChangeVectorGL(m_kRight);// Store current matrix to previous matrix m_kPrevMatrix = m_kMatrix;// Set inverse matrix from current position kT.InverseTranslation(m_kPosition);// Multiply inverse matrix and current position matrix m_kMatrix.Multiply(kT);// Reset angles m_kAngle.Reset();return; }// If spectator or first person viewif((m_eCamView == K_CAM_SPECTATE)||(m_eCamView == K_CAM_FIRST_PERSON)) {// Slave direction vector CVector3 kDirection;// Slave matrices (reset) CMatrix kMX; CMatrix kMY; CMatrix kMT;// Set X rotation matrix kMX.RotationXGL(m_kAngle[0]);// Set Y rotation matrix kMY.RotationYGL(m_kAngle[1]);// Set inverse translation matrix kMT.InverseTranslation(m_kPosition);/////////////////////// Set Z direction//////////////////////// Reset direction vector kDirection.Set(0,0,-1); kMY.ChangeVectorZGL(kDirection);// Set Z coord to my direction m_kForward.SetZ(kDirection[2]);// Only if spectate viewif(m_eCamView == K_CAM_SPECTATE) {/////////////////////// Set Y direction//////////////////////// Reset direction vector kDirection.Set(0,0,-1); kMX.ChangeVectorYGL(kDirection);// Set Z coord to my direction m_kForward.SetY(kDirection[1]); }////////////////////////////// Calculate camera matrix/////////////////////////////// Copy slave matrix Y to camera matrix m_kMatrix = kMY;// Multiply by slave matrix X m_kMatrix.MultiplyTranspose(kMX);// Multiply by slave transform matrix Y m_kMatrix.Multiply(kMT);///////////////////// Set X direction///////////////////// Reset direction vector kDirection.Set(0,0,-1);// Change coordination X in direction vector m_kMatrix.ChangeVectorXGL(kDirection);// Set X coord to my direction m_kForward.SetX(kDirection[0]);return; }}
Změna modelové matice pro descent kameru
Vytvoříme transformační a rotační matici
CMatrix kT;
CMatrix kR;
Získáme quaternion z rotačního vektoru.
CQuaternion kQuat;
kQuat.FromAxisAngle(m_kAngle);
Získáme rotační matici z quaternionu
kQuat.ToRotationMatrix(kR);
Zkopírujeme rotační matici do modelové matice kamery
Změna pozičního m_kPosition a rotačního m_kAngle vektoru.
Změnu pozičního a rotačního vektoru provádí funkce:
GoForward()
GoBackward()
TurnLeft()
TurnRight()
StrafeRight()
StrafeLeft()
GoUp()
GoDown()
LurchLeft()
LurchRight()
TurnUp()
TurnDown()
které jsou volány po zmáčknutí určité klávesy definované v keymapě.
///\briefGoforwardbycameravoid CCamera::GoForward(){// If descent cameraif(m_eCamView == K_CAM_DESCENT) { // Change currect position by forward vector m_kPosition += (m_kForward * m_fSpeed);return; }// If first person cameraif(m_eCamView == K_CAM_FIRST_PERSON) { m_kPosition.SubtractScalar(m_fSpeed * m_kForward.GetScalar(0) ,0); m_kPosition.AddScalar(m_fSpeed * m_kForward.GetScalar(2) ,2);return; }// If spectate cameraif(m_eCamView == K_CAM_SPECTATE) { m_kPosition.SubtractScalar(m_fSpeed * m_kForward.GetScalar(0) ,0); m_kPosition.SubtractScalar(m_fSpeed * m_kForward.GetScalar(1) ,1); m_kPosition.AddScalar(m_fSpeed * m_kForward.GetScalar(2) ,2);return; }}///\briefGobackwardbycameravoid CCamera::GoBackward(){// If descent cameraif(m_eCamView == K_CAM_DESCENT) { // Change currect position by right vector m_kPosition -= (m_kForward * m_fSpeed);return; }// If first person cameraif(m_eCamView == K_CAM_FIRST_PERSON) { m_kPosition.SubtractScalar(-m_fSpeed * m_kForward.GetScalar(0) ,0); m_kPosition.AddScalar(-m_fSpeed * m_kForward.GetScalar(2) ,2);return; }// If spectate cameraif(m_eCamView == K_CAM_SPECTATE) { m_kPosition.SubtractScalar(-m_fSpeed * m_kForward.GetScalar(0) ,0); m_kPosition.SubtractScalar(-m_fSpeed * m_kForward.GetScalar(1) ,1); m_kPosition.AddScalar(-m_fSpeed * m_kForward.GetScalar(2) ,2);return; }}///\briefTurnleftbycameravoid CCamera::TurnLeft(){ m_kAngle.SubtractScalar(m_fSpeed* 0.01f ,1);}///\briefTurnrightbycameravoid CCamera::TurnRight(){ m_kAngle.AddScalar(m_fSpeed* 0.01f ,1);}///\briefStrafeleftbycameravoid CCamera::StrafeLeft(){// If descent cameraif(m_eCamView == K_CAM_DESCENT) { // Change currect position by right vector m_kPosition -= (m_kRight * m_fSpeed); }else { SetStrafeDirection();// Move by new direction Move(m_fSpeed); }}///\briefStraferightbycameravoid CCamera::StrafeRight(){// If descent cameraif(m_eCamView == K_CAM_DESCENT) {// Change currect position by right vector m_kPosition += m_kRight * m_fSpeed; }else { SetStrafeDirection();// Move by new direction Move(-m_fSpeed); }}///\briefGoupbycameravoid CCamera::GoUp(){// If descent cameraif(m_eCamView == K_CAM_DESCENT) {// Change currect position by up vector m_kPosition += m_kUp * m_fSpeed; }else { m_kPosition.AddScalar(m_fSpeed ,1); }}///\briefGodownbycameravoid CCamera::GoDown(){if(m_eCamView == K_CAM_DESCENT) {// Change currect position by up vector m_kPosition -= m_kUp * m_fSpeed; }else { m_kPosition.SubtractScalar(m_fSpeed ,1); }}///\briefCamerarotateleftbyZaxisvoid CCamera::LurchLeft(){if(m_eCamView == K_CAM_DESCENT) {// Set angles m_kAngle.SubtractScalar(m_fSpeed * 0.01f ,2); }}///\briefCamerarotaterightbyZaxisvoid CCamera::LurchRight(){if(m_eCamView == K_CAM_DESCENT) {// Set angle m_kAngle.AddScalar(m_fSpeed * 0.01f ,2); }}///\briefRotateupbycameravoid CCamera::TurnUp() {if(m_eCamView == K_CAM_DESCENT) {// Set angles m_kAngle.AddScalar(m_fSpeed * 0.01f ,0); }else { m_kAngle.AddScalar(m_fSpeed * 0.01f ,0);// If spectator or first person view than restric camera view RestrictCamView(); }}///\briefRotatedownbycameravoid CCamera::TurnDown() {if(m_eCamView == K_CAM_DESCENT) {// Set angles m_kAngle.SubtractScalar(m_fSpeed * 0.01f ,0); }else { m_kAngle.SubtractScalar(m_fSpeed * 0.01f ,0);// If spectator or first person view than restric camera view RestrictCamView(); }}
Funkce TurnUp() a TurnDown() volá funkci RestrictCamView() , která omezuje rotaci kamery. Kamera se díky tomu otočí maximálně kolmo vzhůru a kolmo dolu.
// Change rotation angles by mouse stepm_kAngle.AddScalar((float)aiStep[0]*0.01 ,1);m_kAngle.AddScalar((float)aiStep[1]*0.01 ,0);
Vrátí kurzor zpět do středu okna.
// Move mouse cursor to the middle of screenSDL_WarpMouse(aiMiddle[0], aiMiddle[1]);
Pokud je first person, nebo spectate mód kamery, tak se omezí rotace kamery tak, aby se otáčela maximálně kolmo vzhůru a kolmo dolu.
// If spectator or first person view than restric camera viewif((m_eCamView == K_CAM_FIRST_PERSON) || (m_eCamView == K_CAM_SPECTATE)){ RestrictCamView();}