旋转播放器模型以指向一个点

问题描述 投票:0回答:1

[我看过三年前的帖子,提出了一个关于如何使用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)。

任何想法,我在这里做错了什么?非常感谢!

c++ opengl glm-math
1个回答
0
投票

假设您有一个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);
© www.soinside.com 2019 - 2024. All rights reserved.