?? camera.cpp
字號:
//========================================================
/**
* @file Camera.cpp
*
* 項目描述: 3DS文件載入
* 文件描述: 攝像機類
* 適用平臺: Windows98/2000/NT/XP
*
* 作者: WWBOSS
* 電子郵件: wwboss123@gmail.com
* 創建日期: 2006-12-06
* 修改日期: 2006-12-07
*
*/
//========================================================
#include "stdafx.h"
#include "Camera.h" /**< 包含攝像機頭文件 */
#include "Vector.h" /**< 包含向量類 */
#include "GLFrame.h"
Camera* Camera::m_pCamera = NULL;
/** 構造函數 */
Camera::Camera()
{
/** 初始化向量值 */
Vector3 zero = Vector3(0.0, 0.0, 0.0);
Vector3 view = Vector3(0.0, 1.0, 0.5);
Vector3 up = Vector3(0.0, 0.0, 1.0);
/** 初始化攝像機 */
m_Position = zero;
m_View = view;
m_UpVector = up;
m_Speed = 0.1f;
m_pCamera = this;
}
Camera::~Camera()
{
}
/** 設置攝像機的位置,朝向和向上向量 */
void Camera::setCamera( float positionX, float positionY, float positionZ,
float viewX, float viewY, float viewZ,
float upVectorX, float upVectorY, float upVectorZ)
{
/** 構造向量 */
Vector3 Position = Vector3(positionX, positionY, positionZ);
Vector3 View = Vector3(viewX, viewY, viewZ);
Vector3 UpVector = Vector3(upVectorX, upVectorY, upVectorZ);
/** 設置攝像機 */
m_Position = Position;
m_View = View;
m_UpVector = UpVector;
}
/** 旋轉攝像機方向 */
void Camera::rotateView(float angle, float x, float y, float z)
{
Vector3 newView;
/** 計算方向向量 */
Vector3 view = m_View - m_Position;
/** 計算 sin 和cos值 */
float cosTheta = (float)cos(angle);
float sinTheta = (float)sin(angle);
/** 計算旋轉向量的x值 */
newView.x = (cosTheta + (1 - cosTheta) * x * x) * view.x;
newView.x += ((1 - cosTheta) * x * y - z * sinTheta) * view.y;
newView.x += ((1 - cosTheta) * x * z + y * sinTheta) * view.z;
/** 計算旋轉向量的y值 */
newView.y = ((1 - cosTheta) * x * y + z * sinTheta) * view.x;
newView.y += (cosTheta + (1 - cosTheta) * y * y) * view.y;
newView.y += ((1 - cosTheta) * y * z - x * sinTheta) * view.z;
/** 計算旋轉向量的z值 */
newView.z = ((1 - cosTheta) * x * z - y * sinTheta) * view.x;
newView.z += ((1 - cosTheta) * y * z + x * sinTheta) * view.y;
newView.z += (cosTheta + (1 - cosTheta) * z * z) * view.z;
/** 更新攝像機的方向 */
m_View = m_Position + newView;
}
/** 用鼠標旋轉攝像機 */
void Camera::setViewByMouse()
{
POINT mousePos; /**< 保存當前鼠標位置 */
int middleX = GetSystemMetrics(SM_CXSCREEN) >> 1; /**< 得到屏幕寬度的一半 */
int middleY = GetSystemMetrics(SM_CYSCREEN) >> 1; /**< 得到屏幕高度的一半 */
float angleY = 0.0f; /**< 攝像機左右旋轉角度 */
float angleZ = 0.0f; /**< 攝像機上下旋轉角度 */
static float currentRotX = 0.0f;
/** 得到當前鼠標位置 */
GetCursorPos(&mousePos);
ShowCursor(TRUE);
/** 如果鼠標沒有移動,則不用更新 */
if( (mousePos.x == middleX) && (mousePos.y == middleY) )
return;
/** 設置鼠標位置在屏幕中心 */
SetCursorPos(middleX, middleY);
/**< 得到鼠標移動方向 */
angleY = (float)( (middleX - mousePos.x) ) / 1000.0f;
angleZ = (float)( (middleY - mousePos.y) ) / 1000.0f;
static float lastRotX = 0.0f; /**< 用于保存旋轉角度 */
lastRotX = currentRotX;
/** 跟蹤攝像機上下旋轉角度 */
currentRotX += angleZ;
/** 如果上下旋轉弧度大于1.0,我們截取到1.0并旋轉 */
if(currentRotX > 1.0f)
{
currentRotX = 1.0f;
/** 根據保存的角度旋轉方向 */
if(lastRotX != 1.0f)
{
/** 通過叉積找到與旋轉方向垂直的向量 */
Vector3 vAxis = m_View - m_Position;
vAxis = vAxis.crossProduct(m_UpVector);
vAxis = vAxis.normalize();
///旋轉
rotateView( 1.0f - lastRotX, vAxis.x, vAxis.y, vAxis.z);
}
}
/** 如果旋轉弧度小于-1.0,則也截取到-1.0并旋轉 */
else if(currentRotX < -1.0f)
{
currentRotX = -1.0f;
if(lastRotX != -1.0f)
{
/** 通過叉積找到與旋轉方向垂直的向量 */
Vector3 vAxis = m_View - m_Position;
vAxis = vAxis.crossProduct(m_UpVector);
vAxis = vAxis.normalize();
///旋轉
rotateView( -1.0f - lastRotX, vAxis.x, vAxis.y, vAxis.z);
}
}
/** 否則就旋轉angleZ度 */
else
{
/** 找到與旋轉方向垂直向量 */
Vector3 vAxis = m_View - m_Position;
vAxis = vAxis.crossProduct(m_UpVector);
vAxis = vAxis.normalize();
///旋轉
rotateView(angleZ, vAxis.x, vAxis.y, vAxis.z);
}
/** 總是左右旋轉攝像機 */
rotateView(angleY, 0, 1, 0);
}
/** 左右移動攝像機 */
void Camera::yawCamera(float speed)
{
Vector3 yaw;
Vector3 oldPos,oldView;
Vector3 cross = m_View - m_Position;
oldPos = m_Position;
oldView = m_View;
cross = cross.crossProduct(m_UpVector);
///歸一化向量
yaw = cross.normalize();
m_Position.x += yaw.x * speed;
m_Position.z += yaw.z * speed;
m_View.x += yaw.x * speed;
m_View.z += yaw.z * speed;
/** 進行邊界檢查和限定 */
if(m_View.x > MAP_WIDTH - 20 || m_View.x < 2*CELL_WIDTH)
{
m_Position.x = oldPos.x ;
m_View.x = oldView.x;
}
if(m_View.z > MAP_WIDTH - 20 || m_View.z < 2*CELL_WIDTH)
{
m_Position.z = oldPos.z ;
m_View.z = oldView.z;
}
}
/** 前后移動攝像機 */
void Camera::moveCamera(float speed)
{
/** 計算方向向量 */
Vector3 vector = m_View - m_Position;
vector = vector.normalize(); /**< 單位化 */
Vector3 oldPos,oldView;
oldPos = m_Position;
oldView = m_View;
/** 更新攝像機 */
m_Position.x += vector.x * speed; /**< 根據速度更新位置 */
m_Position.z += vector.z * speed;
m_Position.y += vector.y * speed;
m_View.x += vector.x * speed; /**< 根據速度更新方向 */
m_View.y += vector.y * speed;
m_View.z += vector.z * speed;
/** 進行邊界檢查和限定 */
if(m_View.x > MAP_WIDTH - 20 || m_View.x < 2*CELL_WIDTH)
{
m_Position.x = oldPos.x ;
m_View.x = oldView.x;
}
if(m_View.z > MAP_WIDTH - 20 || m_View.z < 2*CELL_WIDTH)
{
m_Position.z = oldPos.z ;
m_View.z = oldView.z;
}
}
/** 設置視點 */
void Camera::setLook()
{
/** 設置視口 */
gluLookAt(m_Position.x, m_Position.y, m_Position.z,
m_View.x, m_View.y, m_View.z,
m_UpVector.x, m_UpVector.y, m_UpVector.z);
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -