类参数
private:
glm::vec3 cameraPosi;
glm::vec3 cameraFocus;
glm::vec3 cameraUp;
glm::vec3 dirZ;//正向
glm::vec3 dirX;//右向
glm::vec3 dirY;//上方
定义cameraPosi,cameraFocus,及cameraUp可以确定摄像机的初始位置。
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);
rotateMetrix = glm::rotate(rotateMetrix, glm::radians(xRotate), -dirY);
cameraPosi4v = rotateMetrix * cameraPosi4v;
rotateMetrix = glm::mat4(1.0f);
rotateMetrix = glm::rotate(rotateMetrix, glm::radians(yRotate), -dirX);
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));
}
-
camera::camera():通过默认数据对dirXYZ进行初始化。
-
void camera::moveForBackward(float meters)。向前向后不改变焦点,且只能放大到一定程度。移动方向为dirZ轴。
-
void camera::moveLRward(float meters)。移动方向为X轴。
-
void camera::moveUpDownward(float meters)。移动方向为Y轴。
-
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));
}
- glm::mat4 camera::getViewMetrix()。通过get函数得到ViewMetrix,可以很好的提高摄像机移动效率,在获取VIew时才计算lookat函数。
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END
暂无评论内容