计算"lookat"旋转矢量



我已经有了一些代码,使用glm函数lookat,以便将相机指向目标(这是第三人称追逐相机的东西)。

这很好,但是我需要稍微不同的形式。

glm::lookat函数的问题是,你为它提供了一个眼睛位置矢量,目标位置矢量,然后是"向上"。旋转向量,它吐出一个完整的矩阵。

但是我只想要旋转矢量——方向——从相机所在的位置看目标。我需要输出是一个vec3旋转向量,而不是一个完整的mat4矩阵。

原因是,如果你想知道,是我已经有类-用于场景中的对象-存储位置矢量和旋转矢量,然后你调用getMatrix(),当你需要矩阵的时候。

这只是我的代码工作的一般方式,我想让相机在相同的基础上工作。但我需要一个版本的lookat,只是设置旋转矢量看一个目标(相同的输入-相机位置矢量,目标位置矢量,向上)。矢量-但一个旋转矢量的输出,而不是一个成熟的4x4矩阵)。

从位置和旋转创建矩阵,就像,后面发生的一个单独的阶段(我没有提到比例,因为基本上,到目前为止,它在我的代码中总是只有1.0)。

所以我想我要找的是lookat的一个版本,它接受相同的输入,但输出是vec3旋转向量。

只是角度,而不是完全组成的4x4矩阵,其中包含所有内容(因为试图从这样的矩阵中提取所有内容将比直接计算我想要的内容要困难得多)。

编辑:为了更精确,我沿着这些行编写了一些代码(示例内联可读性,实际上是将。h和。cpp分开):
class Entity
{
protected:
glm::vec3    position;
glm::vec3    orientation;
glm::vec3    scale;
public:
Entity(void)
{
position = glm::vec3(0.0, 0.0, 0.0);
orientation = glm::vec3(0.0, 0.0, 0.0);
scale = glm::vec3(1.0, 1.0, 1.0);
}
void setPosition(glm::vec3 nposition)
{
position = nposition;
}
void setOrientation(glm::vec3 norientation)
{
orientation = norientation;
}
glm::mat4 getMatrix(void)
{
glm::mat4 matrix = glm::mat4(1.0);
matrix = glm::translate(matrix, position);
matrix = glm::rotate(matrix, orientation.x, glm::vec3(1.0, 0.0, 0.0));
matrix = glm::rotate(matrix, orientation.y, glm::vec3(0.0, 1.0, 0.0));
matrix = glm::rotate(matrix, orientation.z, glm::vec3(0.0, 0.0, 1.0));
matrix = glm::scale(matrix, scale);
return matrix;
}
};

这个想法是游戏逻辑设置/操纵实体的位置和方向。然后,为了渲染,我们调用getMatrix,然后提供glm::mat4

目前,相机不是Entity,我只是直接使用glm::lookat来获得渲染矩阵。但是我想把相机作为一个实体,但是为了使它适合这个方案,我需要把它分解成同样的两个阶段的过程。

设置名为orientationglm::vec3查看目标点(带有特定的"up")向量)-相机的位置已经存储在类中-所以当我调用getMatrix进行渲染时,我得到的是glm::lookat吐出的glm::mat4

视图矩阵的方向是4x4视图矩阵的左上角3x3。这可以通过从glm::ma4构造glm::mat3来获得:

glm::mat4 view = glm::lookAt(eye, target, upVector);
glm::mat3 viewR = glm::mat3(view);

视图矩阵从世界空间变换到视图空间。因此,是该矩阵的逆矩阵决定了相机的方向和位置。如果你想要相机方向的3x3矩阵,你需要得到inverse矩阵:

glm::mat3 viewR = glm::mat3(view);
glm::mat3 cameraR = glm::inverse(viewR);

给定相机位置(eye),相机目标(target)和上矢量(upVector),可以在x轴向左,y轴为上矢量,z轴指向视线相反方向的右手坐标系中计算方向矩阵,如下:

glm::vec3 zAxis = glm::normalize(eye - target);
glm::vec3 xAxis = glm::normalize(glm::cross(upVector, zAxis));
glm::vec3 yAxis = glm::cross(zAxis, xAxis);
glm::mat3 cameraR = glm::mat3(xAxis, yAxis, zAxis);