第七课,OpenGL之摄像机类

类参数

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));
}


  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函数。

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片