# 类参数

``````private:
glm::vec3 cameraPosi;
glm::vec3 cameraFocus;
glm::vec3 cameraUp;
glm::vec3 dirZ;//正向
glm::vec3 dirX;//右向
glm::vec3 dirY;//上方
``````

dirX,Y,Z分别表示摄像机的三个坐标方向。

# 类函数声明

``````	//构造函数
camera();
//向视角前后移动
void moveForBackward(float meters);
//向视角左右移动
void moveLRward(float meters);
//向视角上下移动
void moveUpDownward(float meters);
//以交点为中心对摄像机位置进行旋转
void rotateCamera(float xRotate, float yRotate);
//获取lookat矩阵
glm::mat4 getViewMetrix();
``````

# 类函数实现

``````#include "camera.h"
camera::camera() :cameraPosi{ 0.0f,0.0f,0.3f }, cameraFocus{ 0.0f,0.0f,0.0f },
cameraUp{ 0.0f,0.1f,0.0f }
{
dirZ = glm::normalize(cameraPosi - cameraFocus);
dirX = glm::normalize(glm::cross(dirZ, cameraUp));
dirY = glm::normalize(glm::cross(dirZ, dirX));
}

void camera::moveForBackward(float meters)
{
if (glm::distance(cameraPosi, cameraFocus) >= 0.3f) {
cameraPosi += meters * dirZ;
}
else {
cameraPosi = dirZ * 0.3f + cameraFocus;
}
}

void camera::moveLRward(float meters)
{
cameraPosi  -= meters * dirX;//meters为正时，向左移动。
cameraFocus -= meters * dirX;
}

void camera::moveUpDownward(float meters)
{
cameraPosi += meters * dirY;
cameraFocus += meters * dirY;
}

void camera::rotateCamera(float xRotate, float yRotate)
{
glm::vec4 cameraPosi4v = glm::vec4(cameraPosi, 1.0f);
glm::vec4 dirY4v = glm::vec4(dirY, 1.0f);

glm::mat4 rotateMetrix = glm::mat4(1.0f);
cameraPosi4v = rotateMetrix * cameraPosi4v;

rotateMetrix = glm::mat4(1.0f);
cameraPosi4v = rotateMetrix * cameraPosi4v;
dirY4v = rotateMetrix * dirY4v;

dirY = glm::vec3(dirY4v.x, dirY4v.y, dirY4v.z);
cameraPosi = glm::vec3(cameraPosi4v.x, cameraPosi4v.y, cameraPosi4v.z);
resetDirXYZ();

}

glm::mat4 camera::getViewMetrix()
{
return glm::lookAt(cameraPosi,cameraFocus,dirY);
}

void camera::resetDirXYZ()
{
dirY = glm::normalize(dirY);
dirZ = glm::normalize(cameraPosi - cameraFocus);
dirX = glm::normalize(glm::cross(dirZ, dirY));
}

``````
1. camera::camera()：通过默认数据对dirXYZ进行初始化。

2. void camera::moveForBackward(float meters)。向前向后不改变焦点，且只能放大到一定程度。移动方向为dirZ轴。

3. void camera::moveLRward(float meters)。移动方向为X轴。

4. void camera::moveUpDownward(float meters)。移动方向为Y轴。

5. void camera::rotateCamera(float xRotate, float yRotate)。
对摄像机进行旋转会改变改变摄像机的方向轴。
通过将摄像机的三维坐标变化为齐次方程，再通过旋转矩阵修改，最后再转化为三维坐标。

沿摄像机Y轴为轴旋转只需计算摄像机位置，dirY轴方向不变，其他轴也可对应的计算出来。
但沿摄像机X轴旋转还需改变dirY轴方向，及需对dirY也做相同的旋转。

重点：最后不要忘了对摄像机的方向轴重设。及调用 resetDirXYZ() 。

``````void camera::resetDirXYZ()
{
dirY = glm::normalize(dirY);
dirZ = glm::normalize(cameraPosi - cameraFocus);
dirX = glm::normalize(glm::cross(dirZ, dirY));
}
``````
1. glm::mat4 camera::getViewMetrix()。通过get函数得到ViewMetrix，可以很好的提高摄像机移动效率，在获取VIew时才计算lookat函数。