cameraclass是一个相机类,它的作用是生成非常重要的观察矩阵。本小节涉及到一点数学知识,相对前面需要只是填充,调用,算是比较有趣的吧。
cameraclass.h
1 #pragma once 2 #include <d3d11.h> 3 #include <d3dcompiler.h> 4 #include <D3DX11.h> 5 #include <xnamath.h> 6 7 #pragma comment(lib,"d3dx11.lib") 8 #pragma comment(lib,"d3d11.lib") 9 #pragma comment(lib,"d3dcompiler.lib") 10 11 class cameraclass 12 { 13 public: 14 cameraclass(); 15 ~cameraclass(); 16 17 private: 18 XMMATRIX m_viewMatrix; 19 XMVECTOR m_eye; 20 XMVECTOR m_at; 21 XMVECTOR m_up; 22 23 public: 24 void Getviewmatrix(XMMATRIX& viewMatrix); 25 void SetPositon(float x, float y, float z); 26 void SetTarget(float x, float y, float z); 27 void SetRotation(float x, float y, float z); 28 void Setfar_near(float d); 29 };
向量m_eye,m_up,m_at分别是相机位置(向量类型也可以作为位置),相机向上的方向在世界坐标的表示,观察的目标的位置。用这些就能最终生成观察矩阵。
这里只讲两个函数SetRotation()和Setfar_near()。其他的都很简单。
SetRotation()是设置相机俯仰角,偏航角,翻滚角。即使向量CT绕x,y,z(红色)旋转。
Setfar_near()是设置相机与自己看到的目标的距离的函数。即设置C点往CT方向做正负平移。
camera.cpp
1 #include "cameraclass.h" 2 3 4 cameraclass::cameraclass() 5 { 6 m_eye = XMVectorSet(0, 0, -5, 0); 7 m_at = XMVectorSet(0, 0, 0, 0); 8 m_up = XMVectorSet(0, 1, 0, 0); 9 } 10 11 12 cameraclass::~cameraclass() 13 { 14 } 15 16 17 void cameraclass::Getviewmatrix(XMMATRIX& viewMatrix) 18 { 19 m_viewMatrix = XMMatrixLookAtLH(m_eye, m_at, m_up); 20 viewMatrix = m_viewMatrix; 21 } 22 23 24 void cameraclass::SetPositon(float x, float y, float z) 25 { 26 m_eye = XMVectorSet(x, y, z, 0); 27 } 28 29 30 void cameraclass::SetTarget(float x, float y, float z) 31 { 32 m_at = XMVectorSet(x, y, z, 0); 33 } 34 35 36 void cameraclass::SetRotation(float x, float y, float z) 37 { 38 XMMATRIX Matrix; 39 40 Matrix = XMMatrixLookAtLH(m_eye, m_at, m_up); 41 Matrix *= XMMatrixRotationRollPitchYaw(x, y, z); 42 43 XMVECTOR v = m_at - m_eye; 44 m_at = XMVector3TransformNormal(v, Matrix); 45 } 46 47 48 void cameraclass::Setfar_near(float d) 49 { 50 XMVECTOR v, u, w; 51 v = m_at - m_eye; 52 w = XMVector3Normalize(v); 53 u = w*-d; 54 v += u; 55 m_eye = m_at - v; 56 }
SetRotation():
- 根据当前的相机位置,目标位置,向上向量得到当前的观察矩阵
- 再将当前的观察矩阵乘以旋转矩阵得到平移到相机位置后的旋转矩阵
- 将目标位置减去相机位置得到CT向量
- CT向量乘以旋转矩阵得到新的CT’向量
- CT'向量就是新的相机观察点向量,所以观察点的位置也可以用CT‘向量表示
Setfar_near():
- 获取CT向量并用v表示
- 获取v向量的单位向量w
- 将单位向量乘以移动的距离得到平移向量u
- 将v加上u得到新的CT向量
- 目标位置减去新的CT向量即是相机的位置
Getviewmatrix()
将处理好的相机位置,观察目标位置并相机向上向量作为输入,调用dx11API就得到观察矩阵。
本小节所做的东西很少,也就是一个很简单的例子。平时工作中会因为各种需求而计算观察矩阵,我们可以根据需求做相应的变换。不过在图形学里,这种需求一般不多。更多的是对模型,颜色,材质,世界空间的设计和探索