沿所有 3 个轴旋转对象以映射到玩家的相机 LookAt 矢量
Rotating object along all 3 axes to map to the player's camera LookAt vector
我有一个简单的 3D LookAt 矢量,我希望旋转玩家模型(一个简单的立方体)以显示 player/cube 正在注视的位置。
对于横向相机移动,我设法弄清楚并执行以下操作:
glTranslatef(position.x, position.y, position.z);
glRotatef(atan2(lookAt.z, lookAt.x) * 180 / PI, 0, 1, 0);
现在我知道要让相机上下移动以映射到渲染的立方体模型,我还需要围绕它的 x 轴和 z 轴旋转立方体,但我似乎无法弄清楚什么公式用于这两个。
OpenGL 将旋转整个坐标系(整个 space,不仅是一个立方体),所以在第一次旋转后你只需要绕 z 轴旋转。
// first rotation
glRotatef(-atan2(lookAt.z, lookAt.x) * 180 / PI, 0, 1, 0);
// second rotation
float d = sqrt(pow(lookAt.x,2) + pow(lookAt.z,2));
float pitch = atan2(lookAt.y, d);
glRotatef(pitch * 180 / PI, 0, 0, 1);
第一轮和第二轮:
我假设你的模型是沿着 x 轴(红色箭头)看的。我还假设 lookAt 是相对于模型位置给出的。
如果您熟悉矩阵数学,矩阵是一种更容易理解的方法。如果您不熟悉矩阵,本系列将介绍如何使用它们解决常见的游戏开发问题:https://www.youtube.com/playlist?list=PLW3Zl3wyJwWNQjMz941uyOIq3Nw6bcDYC 如果您想成为 3D 游戏程序员,熟悉矩阵是个好主意。
对于你的问题,你想要制作一个 translation/rotation 矩阵,它将盒子转换到适合你的位置。您可以单独制作一个平移矩阵和一个旋转矩阵,然后在最后取两者的乘积。我会尝试将其分解。
平移矩阵很简单,如果你的位置是
那么你的矩阵就是
![](https://latex.codecogs.com/gif.latex?T%20%3D%20%5Cbegin%7Bbmatrix%7D%201%20%26%200%20%26%200%20%26%20p_x%20%5C%5C%200%20%26%201%20%26%200%20%26%20p_y%20%5C%5C%200%20%26%200%20%26%201%20%26%20p_z%20%5C%5C%200%20%26%200%20%26%200%20%26%201%20%5C%5C%20%5Cend%7Bbmatrix%7D)
要构建旋转矩阵,您需要按照您想要的方式旋转标准基向量。然后,当您从这些旋转的基础向量创建矩阵时,该矩阵将以相同的方式旋转其他向量。例如,以标准基向量为例:
![](https://latex.codecogs.com/gif.latex?e_1%20%3D%20%5Cbegin%7Bbmatrix%7D%201%5C%5C0%5C%5C0%20%5Cend%7Bbmatrix%7D%20e_2%20%3D%20%5Cbegin%7Bbmatrix%7D%200%5C%5C1%5C%5C0%20%5Cend%7Bbmatrix%7D%20e_3%20%3D%20%5Cbegin%7Bbmatrix%7D%200%5C%5C0%5C%5C1%20%5Cend%7Bbmatrix%7D)
现在我要将
和
围绕
顺时针旋转 90 度:
![](https://latex.codecogs.com/gif.latex?e_1%20%3D%20%5Cbegin%7Bbmatrix%7D%200%5C%5C-1%5C%5C0%20%5Cend%7Bbmatrix%7D%20e_2%20%3D%20%5Cbegin%7Bbmatrix%7D%201%5C%5C0%5C%5C0%20%5Cend%7Bbmatrix%7D%20e_3%20%3D%20%5Cbegin%7Bbmatrix%7D%200%5C%5C0%5C%5C1%20%5Cend%7Bbmatrix%7D)
现在将它们放入一个矩阵中:
![](https://latex.codecogs.com/gif.latex?R%20%3D%20%5Cbegin%7Bbmatrix%7D%200%20%26%201%20%26%200%20%26%200%20%5C%5C%20-1%20%26%200%20%26%200%20%26%200%20%5C%5C%200%20%26%200%20%26%201%20%26%200%20%5C%5C%200%20%26%200%20%26%200%20%26%201%20%5C%5C%20%5Cend%7Bbmatrix%7D)
并且你有 R 是一个矩阵,它围绕
旋转 90 度。
在你的情况下,你想要旋转东西,使其面向你提供的矢量。这让事情变得简单,我们可以从该向量计算我们的基础向量。如果您的向量是
那么
我们可以使用叉积求解其他两个基向量。你知道角色永远不会转动他们的视线(对吧?)所以我们也可以使用全局向上向量。我将调用全局向上向量
。在您的情况下,您使用 y 作为 "up" 维度,因此全局向上向量将为
![](https://latex.codecogs.com/gif.latex?%5cvec%20u%20%3D%20%5Cbegin%7Bbmatrix%7D%200%5C%5C1%5C%5C0%20%5Cend%7Bbmatrix%7D)
然后:
![](https://latex.codecogs.com/gif.latex?%5C%5C%20e_3%27%20%3D%20-%5Cvec%20v%20%5Ctimes%20%5Cvec%20u%20%5C%5C%20e_3%20%3D%20%5Cfrac%20%7Be_3%27%7D%7B%7Ce_3%27%7C%7D%20%5C%5C%20e_2%20%3D%20e_1%20%5Ctimes%20e_3)
在第一行中,您在视图向量和向上向量之间进行叉积,以获得与两者正交的向量 - 这将作为归一化后的第三个基向量,即第二行。在第三行中,另一个叉积生成第二个基向量。这三个向量表示当标准基向量按照您希望的方式旋转时会发生什么。像这样将它们用作矩阵中的列:
![](https://latex.codecogs.com/gif.latex?R%20%3D%20%5Cbegin%7Bbmatrix%7D%20e_1_x%20%26%20e_2_x%20%26%20e_3_x%20%26%200%20%5C%5C%20e_1_y%20%26%20e_2_y%20%26%20e_3_y%20%26%200%20%5C%5C%20e_1_z%20%26%20e_2_z%20%26%20e_3_z%20%26%200%20%5C%5C%200%20%26%200%20%26%200%20%26%201%20%5C%5C%20%5Cend%7Bbmatrix%7D)
现在数学的最后一步是制作一个同时进行平移和旋转的最终矩阵,这一步很简单:![](https://latex.codecogs.com/gif.latex?M%20=%20TR)
然后使用 glLoadMatrix:
将该矩阵加载到 OpenGL 中
glLoadMatrixf(&M);
所有这些都在我链接的视频系列中得到了解释 :)
我有一个简单的 3D LookAt 矢量,我希望旋转玩家模型(一个简单的立方体)以显示 player/cube 正在注视的位置。
对于横向相机移动,我设法弄清楚并执行以下操作:
glTranslatef(position.x, position.y, position.z);
glRotatef(atan2(lookAt.z, lookAt.x) * 180 / PI, 0, 1, 0);
现在我知道要让相机上下移动以映射到渲染的立方体模型,我还需要围绕它的 x 轴和 z 轴旋转立方体,但我似乎无法弄清楚什么公式用于这两个。
OpenGL 将旋转整个坐标系(整个 space,不仅是一个立方体),所以在第一次旋转后你只需要绕 z 轴旋转。
// first rotation
glRotatef(-atan2(lookAt.z, lookAt.x) * 180 / PI, 0, 1, 0);
// second rotation
float d = sqrt(pow(lookAt.x,2) + pow(lookAt.z,2));
float pitch = atan2(lookAt.y, d);
glRotatef(pitch * 180 / PI, 0, 0, 1);
第一轮和第二轮:
我假设你的模型是沿着 x 轴(红色箭头)看的。我还假设 lookAt 是相对于模型位置给出的。
如果您熟悉矩阵数学,矩阵是一种更容易理解的方法。如果您不熟悉矩阵,本系列将介绍如何使用它们解决常见的游戏开发问题:https://www.youtube.com/playlist?list=PLW3Zl3wyJwWNQjMz941uyOIq3Nw6bcDYC 如果您想成为 3D 游戏程序员,熟悉矩阵是个好主意。
对于你的问题,你想要制作一个 translation/rotation 矩阵,它将盒子转换到适合你的位置。您可以单独制作一个平移矩阵和一个旋转矩阵,然后在最后取两者的乘积。我会尝试将其分解。
平移矩阵很简单,如果你的位置是那么你的矩阵就是
要构建旋转矩阵,您需要按照您想要的方式旋转标准基向量。然后,当您从这些旋转的基础向量创建矩阵时,该矩阵将以相同的方式旋转其他向量。例如,以标准基向量为例:
现在我要将 和
围绕
顺时针旋转 90 度:
现在将它们放入一个矩阵中:
并且你有 R 是一个矩阵,它围绕 旋转 90 度。
在你的情况下,你想要旋转东西,使其面向你提供的矢量。这让事情变得简单,我们可以从该向量计算我们的基础向量。如果您的向量是 那么
我们可以使用叉积求解其他两个基向量。你知道角色永远不会转动他们的视线(对吧?)所以我们也可以使用全局向上向量。我将调用全局向上向量
。在您的情况下,您使用 y 作为 "up" 维度,因此全局向上向量将为
然后:
在第一行中,您在视图向量和向上向量之间进行叉积,以获得与两者正交的向量 - 这将作为归一化后的第三个基向量,即第二行。在第三行中,另一个叉积生成第二个基向量。这三个向量表示当标准基向量按照您希望的方式旋转时会发生什么。像这样将它们用作矩阵中的列:
现在数学的最后一步是制作一个同时进行平移和旋转的最终矩阵,这一步很简单:
然后使用 glLoadMatrix:
将该矩阵加载到 OpenGL 中glLoadMatrixf(&M);
所有这些都在我链接的视频系列中得到了解释 :)