LOD地形根據(jù)視點(diǎn)的變化決定是否進(jìn)行網(wǎng)格分割,因此系統(tǒng)應(yīng)設(shè)計(jì)一個(gè)視點(diǎn)類,來管理視點(diǎn)相關(guān)的數(shù)據(jù)。這節(jié)介紹的視點(diǎn)類是通用的,在很多網(wǎng)站都可下到這個(gè)類的代碼,它可以用在OPENGL編程的各個(gè)場合,當(dāng)然朋友也可根據(jù)需要自己增加相應(yīng)功能!
/***********************************************************************
* Copyrights Reserved by QinGeSoftware
* Author : Qinge
* Filename : Camera.h 1.0
* Date: 2008-1-10
************************************************************************/
#pragma once
#include "Vector3.h"
class Camera
{
public:
Camera(void);
virtual ~Camera(void);
public:
CVector3 GetPosition(){return m_vPosition;} //獲得攝像機(jī)位置
CVector3 GetView(){return m_vView;} //獲得視線目標(biāo)點(diǎn)
CVector3 GetUpVector() {return m_vUpVector;} //獲得向上方向
CVector3 GetStrafe() {return m_vStrafe;} //獲得平移方向的單位向量
void PosotionCamera(float positionX, float positionY, float positionZ,
float viewX, float viewY, float viewZ,
float upVectorX, float upVectorY, float upVectorZ); //初始化攝像機(jī)
void RotateView(float angle, float X, float Y, float Z); //繞(x,y,z)旋轉(zhuǎn)angle
void SetViewByMouse(); //通過鼠標(biāo)旋轉(zhuǎn)場景
void RotateAroundPoint(CVector3 vCenter, float X, float Y, float Z); //繞點(diǎn)旋轉(zhuǎn)
void StrafeCamera(float speed); //平移攝像機(jī)
void MoveCamera(float speed); //沿視線方向移動(dòng)攝像機(jī)
void Look(); //設(shè)置視點(diǎn)相當(dāng)于glLookAt()
void Update(); //更新視點(diǎn)位置。
void CheckForMovement(); //檢查是否有視點(diǎn)變量更新
private:
CVector3 m_vPosition; //攝像機(jī)視點(diǎn)
CVector3 m_vView; //攝像機(jī)視線
CVector3 m_vUpVector; //攝像機(jī)向上方向
CVector3 m_vStrafe; //攝像機(jī)平移
const float fSpeed; //攝像機(jī)移動(dòng)速度
};
/***********************************************************************
* Copyrights Reserved by QinGeSoftware
* Author : Qinge
* Filename : Camera.cpp 1.0
* Date: 2008-1-10
************************************************************************/
#include "StdAfx.h"
#include "Camera.h"
Camera::Camera(void):fSpeed(5.0f)
{
m_vPosition = CVector3(0,0,0);
m_vView = CVector3(0.0,1.0,0.5);
m_vUpVector = CVector3(0.0,0.0,1.0);
}
Camera::~Camera(void)
{
}
void Camera::PosotionCamera(float positionX, float positionY, float positionZ, float viewX, float viewY, float viewZ, float upVectorX, float upVectorY, float upVectorZ)
{
m_vPosition = CVector3(positionX, positionY+200, positionZ);
m_vView = CVector3(viewX, viewY, viewZ);
m_vUpVector = CVector3(upVectorX, upVectorY, upVectorZ);
}
void Camera::SetViewByMouse()
{
CPoint m_CurPt,m_PrePt;
HDC hDC = ::GetDC(NULL);
float angleY, angleZ;
CVector3 m_uAixs, m_vViewDire;
unsigned long WIDTH, HEIGHT;
WIDTH =::GetDeviceCaps(hDC,HORZRES); //獲得屏幕分辨率
HEIGHT =::GetDeviceCaps(hDC,VERTRES); //
::GetCursorPos(&m_CurPt);
m_PrePt.x = WIDTH >>1; //分辨率/2
m_PrePt.y = HEIGHT >> 1;
::SetCursorPos(m_PrePt.x, m_PrePt.y); //固定光標(biāo)在屏幕中心
angleY = (m_CurPt.x - m_PrePt.x )/1000.0; //根據(jù)鼠標(biāo)移動(dòng)距離確定旋轉(zhuǎn)角度
angleZ = (m_CurPt.y - m_PrePt.y )/1000.0; //
m_vViewDire = m_vView - m_vPosition;
m_uAixs = m_vViewDire.CrossProduct(m_vViewDire,m_vUpVector); //得到平移向量
m_uAixs = m_uAixs.Normalize(m_uAixs);
RotateView(angleZ, m_uAixs.x, m_uAixs.y, m_uAixs.z); //繞任意軸旋轉(zhuǎn)
RotateView(angleY,0,1,0); //繞y軸旋轉(zhuǎn)
}
void Camera::RotateView(float angle, float x, float y, float z)
{
CVector3 vNewView;
CVector3 vView = m_vView - m_vPosition; //視線方向
float cosTheta = (float)cos(angle);
float sinTheta = (float)sin(angle);
//下面就是一個(gè)數(shù)學(xué)公式
vNewView.x = (cosTheta + (1 - cosTheta) * x * x) * vView.x;
vNewView.x += ((1 - cosTheta) * x * y - z * sinTheta) * vView.y;
vNewView.x += ((1 - cosTheta) * x * z + y * sinTheta) * vView.z;
vNewView.y = ((1 - cosTheta) * x * y + z * sinTheta) * vView.x;
vNewView.y += (cosTheta + (1 - cosTheta) * y * y) * vView.y;
vNewView.y += ((1 - cosTheta) * y * z - x * sinTheta) * vView.z;
vNewView.z = ((1 - cosTheta) * x * z - y * sinTheta) * vView.x;
vNewView.z += ((1 - cosTheta) * y * z + x * sinTheta) * vView.y;
vNewView.z += (cosTheta + (1 - cosTheta) * z * z) * vView.z;
m_vView = m_vPosition + vNewView; //視點(diǎn)+新向量=新視線目標(biāo)點(diǎn)
}
void Camera::StrafeCamera(float speed)
{
//給視線目標(biāo)點(diǎn),視點(diǎn)增加一個(gè)增量
m_vPosition.x += m_vStrafe.x * speed;
m_vPosition.z += m_vStrafe.z * speed;
m_vView.x += m_vStrafe.x * speed;
m_vView.z += m_vStrafe.z * speed;
}
void Camera::MoveCamera(float speed)
{
CVector3 vVector = m_vView - m_vPosition;
vVector = vVector.Normalize(vVector);
m_vPosition.x += vVector.x * speed; //沿視線方向移動(dòng)
m_vPosition.z += vVector.z * speed; //
m_vView.x += vVector.x * speed; //
m_vView.z += vVector.z * speed; //
}
void Camera::Update()
{
CVector3 vCross =m_vView.CrossProduct(m_vView - m_vPosition, m_vUpVector);
m_vStrafe = vCross.Normalize(vCross);
SetViewByMouse();
CheckForMovement();
}
void Camera::CheckForMovement() // 上下左右移動(dòng)視點(diǎn)
{
if(GetKeyState(VK_UP) & 0x80 || GetKeyState('W') & 0x80)
{
MoveCamera(fSpeed);
}
if(GetKeyState(VK_DOWN) & 0x80 || GetKeyState('S') & 0x80)
{
MoveCamera(-fSpeed);
}
if(GetKeyState(VK_LEFT) & 0x80 || GetKeyState('A') & 0x80)
{
StrafeCamera(-fSpeed);
}
if(GetKeyState(VK_RIGHT) & 0x80 || GetKeyState('D') & 0x80)
{
StrafeCamera(fSpeed);
}
}
void Camera::Look() //等于gluLookAt()
{
gluLookAt(m_vPosition.x, m_vPosition.y, m_vPosition.z,
m_vView.x, m_vView.y, m_vView.z,
m_vUpVector.x, m_vUpVector.y, m_vUpVector.z);
}