一.介绍
哇!到了传说中的3D摄像机啦!
之前我们写的东东,都是观察点不动,通过世界变换让东西动,今天,通过三维摄像机我们就可以改变我们的观察点,观察方向,随意在三维空间中驰骋。之前我们所设定的视角都是通过D3DXMatrixLookAtLH这个函数,通过几个设定好的向量,将视角初始化的,而在程序真正运行时,视角就不再改变了,而这次,我们要实时的生成视角变换矩阵,实时的改变我们的视角,我们所谓的摄像机就是这个原理。
我们通过一个类来封装摄像机,这个类主要的字段就是用四个分量:右分量(rightvector)、上分量(up vector)、观察分量(lookvector)和位置分量(position vector),来确定一个摄像机相对于世界坐标系的位置和朝向。并根据这四个分量计算出一个取景变换矩阵,然后通过取景变换(VIEWTRANSFORM)实现改变视角。
通过这些分量,我们可以确定摄像机的位置和朝向。操作有平移和旋转,那么一共就有6中操作:
(1)沿着观察分量平移(前进后退)
(2)沿着观察分量旋转(左右翻滚)
(3)沿着右分量平移(左右移动)
(4)沿着右分量旋转(朝上下看)
(5)沿着上分量平移(上下移动)
(6)沿着上分量旋转(朝左右看)
二.操作
void CCamera::CalculateViewMatrix(D3DXMATRIX *pMatrix)
{
//规范化三个向量使之成为正交矩阵
//规范化观察向量
D3DXVec3Normalize(&m_vLookVector, &m_vLookVector);
//使上向量与观察向量垂直
D3DXVec3Cross(&m_vUpVector, &m_vLookVector, &m_vRightVector);
//规范化上向量
D3DXVec3Normalize(&m_vUpVector, &m_vUpVector);
//右向量与上向量垂直
D3DXVec3Cross(&m_vRightVector, &m_vUpVector, &m_vLookVector);
//规范化右向量
D3DXVec3Normalize(&m_vRightVector, &m_vRightVector);
//创建取景变换矩阵
pMatrix->_11 = m_vRightVector.x;
pMatrix->_12 = m_vUpVector.x;
pMatrix->_13 = m_vLookVector.x;
pMatrix->_14 = 0.0f;
pMatrix->_21 = m_vRightVector.y;
pMatrix->_22 = m_vUpVector.y;
pMatrix->_23 = m_vLookVector.y;
pMatrix->_24 = 0.0f;
pMatrix->_31 = m_vRightVector.z;
pMatrix->_32 = m_vUpVector.z;
pMatrix->_33 = m_vLookVector.z;
pMatrix->_34 = 0.0f;
pMatrix->_41 = -D3DXVec3Dot(&m_vRightVector, &m_vCameraPosition);
pMatrix->_42 = -D3DXVec3Dot(&m_vUpVector, &m_vCameraPosition);
pMatrix->_43 = -D3DXVec3Dot(&m_vLookVector, &m_vCameraPosition);
pMatrix->_44 = 1.0f;
}
这样,我们就可以根据摄像机类中的四个向量(相机位置,上分量,右分量,观察分量)获得取景变换的矩阵,通过指针传递参数。这样,我们实时的根据这个矩阵进行取景变换,就可以得到实时的画面情况。而我们在逻辑部分要做的就是改变摄像机类中的各个分量即可。
/************************************************************************/
/* 封装一个摄像机类 */
/************************************************************************/
#ifndef __CCAMERA_H_
#define __CCAMERA_H_
#include "stdafx.h"
#pragma once
class CCamera
{
private:
//成员变量
IDirect3DDevice9* m_pDevice; //D3D设备对象
D3DXVECTOR3 m_vRightVector; //右分量向量
D3DXVECTOR3 m_vUpVector; //上分量向量
D3DXVECTOR3 m_vLookVector; //观察分量向量
D3DXVECTOR3 m_vCameraPosition; //摄像机位置
D3DXVECTOR3 m_vTargetPosition; //观察目标位置
D3DXMATRIX m_matView; //取景变换矩阵
D3DXMATRIX m_matProj; //投影变换矩阵
public:
CCamera(IDirect3DDevice9* pDevice);
~CCamera(void);
//计算取景变换矩阵
void CalculateViewMatrix(D3DXMATRIX *pMatrix);
//获得投影矩阵
void GetProjectionMatrix(D3DXMATRIX* pMatrix){*pMatrix = m_matProj;}
//获得当前摄像机位置向量
void GetCameraPosition(D3DXVECTOR3* pVector){*pVector = m_vCameraPosition;}
//返回当前观察向量
void GetLookVector(D3DXVECTOR3* pVector){*pVector = m_vLookVector;}
//设置摄像机观察位置向量(默认参数为NULL)
void SetTargetPosition(D3DXVECTOR3* pVector = NULL);
//设置摄像机所在位置向量(默认参数为NULL)
void SetCameraPosition(D3DXVECTOR3* pVector = NULL);
//设置取景变换矩阵(默认参数为NULL)
void SetViewMatrix(D3DXMATRIX* pMatrix = NULL);
//设置投影变换矩阵(默认参数为NULL)
void SetProjectionMartix(D3DMATRIX* pMatrix = NULL);
//沿着right分量平移
void MoveAlongRightVec(float fUnits);
//沿着up分量平移
void MoveAlongUpVec(float fUnits);
//沿着look