📄 camera.cpp
字号:
#include "StdAfx.h"
#include ".\camera.h"
CCamera::CCamera(void)
{
float pos=50;
m_cameraType = Land;
D3DXVECTOR3 eye(0.0f,0.0f,-pos);
D3DXVECTOR3 lookat(0.0f,0.0f,pos);
D3DXVECTOR3 up(0.0f,1.0f,0.0f);
m_fov=D3DX_PI/4;
m_width=m_height=0;
m_fn=1000;
m_zn=1;
SetView( &eye, &lookat, &up);
}
CCamera::CCamera(CameraType type)
{
float pos=50;
m_cameraType = type;
D3DXVECTOR3 eye(0.0f,0.0f,-pos);
D3DXVECTOR3 lookat(0.0f,0.0f,pos);
D3DXVECTOR3 up(0.0f,1.0f,0.0f);
m_fov=D3DX_PI/4;
m_width=m_height=0;
m_fn=10000;
m_zn=1;
SetView( &eye, &lookat, &up);
}
CCamera::~CCamera(void)
{
}
void CCamera::GetViewMatrix(D3DXMATRIXA16* matView){
D3DXMatrixIdentity(matView);
D3DXMatrixLookAtLH(matView,&m_vEyePos,&m_vLookat,&m_vUp);
}
void CCamera::GetProjectMatrix(D3DXMATRIXA16* proj,float fovy,float aspect,float zn,float zf){
D3DXMatrixIdentity(proj);
D3DXMatrixPerspectiveFovLH(proj,fovy,aspect,zn,zf);
}
void CCamera::SetView( D3DXVECTOR3* pvEye,D3DXVECTOR3* pvLookat,D3DXVECTOR3* pvUp){
m_vEyePos=*pvEye;
m_vLookat=*pvLookat;
m_vUp=*pvUp;
D3DXVec3Cross(&m_vRight,&m_vUp,&m_vLookat);
}
void CCamera::Flush(){
SetView( &m_vEyePos, &m_vLookat, &m_vUp);
}
void CCamera::setCameraType(CameraType type){
m_cameraType=type;
}
CCamera::CameraType CCamera::getCameraType(){
return m_cameraType;
}
D3DXVECTOR3* CCamera::GetUp(){
return &m_vUp;
}
void CCamera::SetUp( D3DXVECTOR3* pv ){
m_vUp = *pv;
}
D3DXVECTOR3* CCamera::GetLookat() {
return &m_vLookat;
}
void CCamera::SetLookat( D3DXVECTOR3* pv ) {
m_vLookat = *pv;
}
D3DXVECTOR3* CCamera::GetEyePos() {
return &m_vEyePos;
}
void CCamera::SetEyePos( D3DXVECTOR3* pv ) {
m_vEyePos = *pv;
}
void CCamera::RotateLocalX( float angle )
{
D3DXMATRIXA16 matRot;
D3DXMatrixIdentity(&matRot);
D3DXMatrixRotationAxis( &matRot, &m_vRight, angle );
D3DXVec3TransformCoord(&m_vUp,&m_vUp,&matRot);
D3DXVec3TransformCoord(&m_vLookat,&m_vLookat,&matRot);
}
// 以摄像机坐标系的 Y轴为准旋转一定的角度 angle.
void CCamera::RotateLocalY( float angle )
{
D3DXMATRIXA16 matRot;
D3DXMatrixIdentity(&matRot);
if( m_cameraType == Land )
D3DXMatrixRotationY(&matRot, angle);
if( m_cameraType == Air )
D3DXMatrixRotationAxis(&matRot, &m_vUp, angle);
D3DXVec3TransformCoord(&m_vRight,&m_vRight, &matRot);
D3DXVec3TransformCoord(&m_vLookat,&m_vLookat, &matRot);
}
void CCamera::RotateLocalZ( float angle ){
if( m_cameraType == Air )
{
D3DXMATRIX matRot;
D3DXMatrixIdentity(&matRot);
D3DXMatrixRotationAxis(&matRot, &m_vLookat, angle);
D3DXVec3TransformCoord(&m_vRight,&m_vRight, &matRot);
D3DXVec3TransformCoord(&m_vUp,&m_vUp, &matRot);
}
}
void CCamera::MoveLocalX( float dist )
{
D3DXVECTOR3 right=m_vRight-m_vEyePos;
D3DXVec3Normalize(&right,&right);
if( m_cameraType == Land )
m_vEyePos += D3DXVECTOR3(right.x, 0.0f, right.z) * dist;
if( m_cameraType == Air )
m_vEyePos += right * dist;
}
// 按照摄像机坐标系 Y轴方向前进 dist.(后退时,可以输入 -dist.)
void CCamera::MoveLocalY( float dist )
{
D3DXVECTOR3 up=m_vUp-m_vEyePos;
D3DXVec3Normalize(&up,&up);
// move only on y-axis for land object
if( m_cameraType == Land )
m_vEyePos.y += dist;
if( m_cameraType == Air )
m_vEyePos += up * dist;
}
// 按照摄像机坐标系 Z轴方向前进 dist.(后退时,可以输入 -dist.)
void CCamera::MoveLocalZ( float dist )
{
D3DXVECTOR3 look=m_vLookat-m_vEyePos;
D3DXVec3Normalize(&look,&look);
if( m_cameraType == Land)
m_vEyePos += D3DXVECTOR3(look.x, 0.0f, look.z) * dist;
if( m_cameraType == Air )
m_vEyePos += look * dist;
look.y=0;
m_vLookat=m_vLookat+2*look;
}
// 把摄像机移动至世界坐标系的 *pv值的位置.
void CCamera::MoveTo( D3DXVECTOR3* pv )
{
D3DXVECTOR3 dv = *pv - m_vEyePos;
m_vEyePos = *pv;
m_vLookat += dv;
}
void CCamera::Set2DCamera(LPDIRECT3DDEVICE9 device,float windowW,float windowH){
D3DXMATRIX matOrtho;
D3DXMATRIX matIdentity;
//准备投影矩阵为正交矩阵,没有近大远小效果
D3DXMatrixOrthoLH(&matOrtho, windowW, windowH,
0.0f, 100000.0f);
device->SetTransform(D3DTS_PROJECTION, &matOrtho);
//准备单位矩阵
D3DXMatrixIdentity(&matIdentity);
//设置世界变换
device->SetTransform(D3DTS_WORLD, &matIdentity);
//设置视图变换
device->SetTransform(D3DTS_VIEW, &matIdentity);
}
void CCamera::Set3DCamera(LPDIRECT3DDEVICE9 device,float windowW,float windowH,float zn,float fn,float frustumFar){
m_width=windowW;
m_height=windowH;
m_zn=zn;
m_fn=fn;
D3DXMATRIXA16 world;
D3DXMatrixIdentity(&world);
device->SetTransform(D3DTS_WORLD,&world);
//设置投影矩阵
D3DXMATRIXA16 projection;
GetProjectMatrix(&projection,m_fov,m_width/m_height,zn,fn);
device->SetTransform(D3DTS_PROJECTION,&projection);
//设置视矩阵
D3DXMATRIXA16 m_view;
GetViewMatrix(&m_view);
device->SetTransform(D3DTS_VIEW,&m_view);
}
D3DXVECTOR3 CCamera::GetDirection(){
D3DXVECTOR3 cameraDir;
D3DXVECTOR3 eye,look;
look=m_vLookat;
eye=m_vEyePos;
cameraDir =look-eye;
D3DXVec3Normalize(&cameraDir,&cameraDir);
return cameraDir;
}
bool CCamera::CameraCanSee(D3DXVECTOR3 pos,float maxLength){
D3DXVECTOR3 objDir=pos-m_vEyePos;
if(maxLength>0){
float length=D3DXVec3Length(&objDir);
if(length>=maxLength||length>=m_fn)
return false;
}
D3DXVECTOR3 cameraDir=GetDirection();
//单位化
D3DXVec3Normalize(&cameraDir,&cameraDir);
D3DXVec3Normalize(&objDir,&objDir);
float anglecos=D3DXVec3Dot(&cameraDir,&objDir);
if(anglecos<=0)
return false;
float fixThet=cos((m_fov*m_width)/(2*m_height)); //横向视锥控制
if(anglecos<=fixThet)
return false;
return true;
}
D3DXVECTOR3 CCamera::GetCursorRay(POINT point){
D3DXVECTOR3 vPickRayDir;
D3DXMATRIXA16 matProj;
D3DXMatrixPerspectiveFovLH(&matProj,m_fov,m_width/m_height,m_zn,m_fn);
//计算屏幕空间的坐标(-1,-1)~(1,1)
D3DXVECTOR3 v;
v.x = ((-1+2* point.x/float( m_width))) / matProj._11;
v.y = (( 1-2* point.y/float( m_height))) / matProj._22;
v.z = 1.0f;
//获得视图变换矩阵的逆矩阵
D3DXMATRIXA16 matView, mat;
D3DXMatrixLookAtLH(&matView,(D3DXVECTOR3*)&m_vEyePos,(D3DXVECTOR3*)&m_vLookat,&D3DXVECTOR3(0,1,0));
D3DXMatrixInverse( &mat, NULL, &matView );
//把上述坐标转换成世界坐标
vPickRayDir.x = v.x*mat._11 + v.y*mat._21 + v.z*mat._31;
vPickRayDir.y = v.x*mat._12 + v.y*mat._22 + v.z*mat._32;
vPickRayDir.z = v.x*mat._13 + v.y*mat._23 + v.z*mat._33;
D3DXVec3Normalize(&vPickRayDir,&vPickRayDir);
return vPickRayDir;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -