[我看过三年前的帖子,提出了一个关于如何使用glm::lookAt
实现此目标的类似问题,但无法完全将其应用于我的游戏。
我有一个摄像机和播放器模型在曲线上移动。这是通过计算曲线上的点并用glm::translate (identityMatrix, positionCameraIsCurrentlyAt)
简单地将玩家移动到那里来完成的,因此我在曲线上有当前位置,还有nextPosition
。我现在想使用转换矩阵旋转模型,但似乎无法完成。我的第一个想法是计算一个向量currentPosition - nextPosition
以获得我应该面对的向量,我称该向量为targetPoint
。并通过将启动时将其简单地设置为(0,0,1)来计算我当前面临的矢量(当您朝负z方向移动时,我想这就是模型的方向),并在旋转后将其更新为targetPoint
矢量。向量的bot归一化。
代码看起来像这样:
glm::vec3 targetPoint = glm::normalize(position - curveIter->calcCurvePosition(curveProgress));
glm::mat4 rotationMatrix = glm::rotate(modelMatrix, glm::radians(glm::angle(pointingTowards, targetPoint)), glm::vec3(0.0, 1.0, 0.0));
glm::mat4 translationMatrix = glm::translate(modelMatrix, position);
// Test print vectors and angle
std::cout << targetPoint.x << ", " << targetPoint.y << ", " << targetPoint.z << ", " << "pointing towards: " << pointingTowards.x << ", " <<pointingTowards.y << ", " << pointingTowards.z << ", " << glm::angle(glm::normalize(pointingTowards), forward) << std::endl;
pointingTowards = targetPoint;
// Test print vectors and angle
std::cout << targetPoint.x << ", " << targetPoint.y << ", " << targetPoint.z << ", " << "pointing towards: " << pointingTowards.x << ", " << pointingTowards.y << ", " << pointingTowards.z << ", " << glm::angle(glm::normalize(pointingTowards), forward) << std::endl;
return translationMatrix*rotationMatrix;
这根本没有旋转模型。我打印了矢量和角度以检查它们和结果,其中:
targetPoint
:(-0.97509,0,0.22181)
pointingTowards
:(-0.97509,0,0.22181)
angle
:3.14159
所以似乎它们都太小了。我想这可能是归一化的结果。但是,该方法说两个向量都需要归一化。 angle
始终为Pi,这看起来可能很奇怪,但是由于曲线是一个圆。显然,这对于第一个angle
为2.35469是不正确的,因为矢量分别为targetPoint
(-0.708167,0,0.706045)和pointingTowards
:(0,0,1)。
任何想法,我在这里做错了什么?非常感谢!
假设您有一个position
和一个targetPoint
。您可以定义upVec
并通过Cross product计算旋转矩阵的轴,如下所示:
glm::vec3 upVec(0, 1, 0);
glm::vec3 z_axis = glm::normalize(targetPoint - position);
glm::vec3 x_axis = glm::normalize(glm::cross(upVec, z_axis));
glm::vec3 y_axis = glm::normalize(glm::cross(z_axis, x_axis));
glm::mat4 rotationMatrix(
glm::vec4(x_axis, 0),
glm::vec4(y_axis, 0),
glm::vec4(z_axis, 0),
glm::vec4(0, 0, 0, 1));
另一种可能性是使用Quaternion。
#include <glm/gtx/quaternion.hpp>
将旋转从(0,0,1)定义为tragetVec
,并将四元数转换为旋转矩阵:
glm::vec3 tragetVec = glm::normalize(targetPoint - position);
glm::quat rotQuat = glm::rotation(glm::vec3(0, 0, 1), tragetVec);
rotationMatrix = glm::toMat4(rotQuat);