【发布时间】:2018-12-05 15:59:41
【问题描述】:
背景
我正在尝试使用 LWJGL 3.0 在 Java 中创建 FPS 游戏。我已经设置了一个相机类,它有俯仰和偏航(不使用滚动)。相机本身扩展了实体,因为它有一个模型。无论相机指向何处,我都希望这个模型始终出现在相机“前面”。每个实体都有一个方法getTransformationMatrix(),它返回一个Matrix4f,然后将其传递给实体着色器。
问题
模型需要指向摄像头的方向,并围绕摄像头旋转,使其始终位于前方。这种情况下的物体是拿着枪的手,如下图所示。
我的尝试
我知道基本的三角学,所以我让物体分别正确地旋转俯仰和偏航。这是我当前的实现:
偏航
@Override
public Matrix4f getTransformationMatrix() {
modelX = getPosition().x + (radius * (float)Math.sin(Math.toRadians(getYaw())));
modelZ = getPosition().z + (radius * (float)Math.cos(Math.toRadians(getYaw())));
return Transform.createTransformationMatrix(new Vector3f(modelX, getPosition().y - 5, modelZ), new Vector3f(0, getYaw(), 0), getScale());
}
间距
@Override
public Matrix4f getTransformationMatrix() {
modelZ = getPosition().z + (radius * (float)Math.sin(Math.toRadians(getPitch())));
modelY = (getPosition().y - 5) + (radius * (float)Math.cos(Math.toRadians(getPitch())));
return Transform.createTransformationMatrix(new Vector3f(getPosition().x, modelY, modelZ), new Vector3f(getPitch(), 0, 0), getScale());
}
我已经进行了一些研究,但我担心我已经被困在这方面太久了,需要一些新的眼光。当我尝试将这 2 个计算结合起来时,当查看 0 以外的任何偏航角时,模型似乎以图形的形式移动。下面是我结合这些的尝试:
@Override
public Matrix4f getTransformationMatrix() {
float zAxis = (radius * (float)Math.sin(Math.toRadians(getPitch())));
modelY = (getPosition().y - 5) + (radius * (float)Math.cos(Math.toRadians(getPitch())));
modelZ = getPosition().z + (zAxis * (float)Math.cos(Math.toRadians(getYaw())));
modelX = getPosition().x + (radius * (float)Math.sin(Math.toRadians(getYaw())));
return Transform.createTransformationMatrix(new Vector3f(modelX, modelY, modelZ), new Vector3f(getPitch(), getYaw(), 0), getScale());
}
Transform.createTransformationMatrix() 如下所示:
public static Matrix4f createTransformationMatrix(Vector3f translation, Vector3f rotation, Vector3f scale) {
transform3d = new Matrix4f();
transform3d.setIdentity();
Matrix4f.translate(translation, transform3d, transform3d);
Matrix4f.rotate((float) Math.toRadians(rotation.x), new Vector3f(1, 0, 0), transform3d, transform3d);
Matrix4f.rotate((float) Math.toRadians(rotation.y), new Vector3f(0, 1, 0), transform3d, transform3d);
Matrix4f.rotate((float) Math.toRadians(rotation.z), new Vector3f(0, 0, 1), transform3d, transform3d);
Matrix4f.scale(scale, transform3d, transform3d);
return transform3d;
}
想法
一位朋友建议创建一个指向向上的单位向量(即new Vector3f(0, 1, 0))通过俯仰和偏航旋转向量,然后将向量乘以半径并将其添加到相机的位置。我试过这个,但我不知道如何将 Vector 旋转一个角度,而且 slick-utils Vector3f 类中似乎没有 Vector3f.rotate() 方法。非常感谢任何帮助,因为过去几天这一直让我头疼。谢谢!
【问题讨论】:
-
围绕任意轴旋转任意角度是一个 4x4 矩阵,如 here 所述。旋转 yaw 然后旋转 pitch 是两个矩阵的矩阵乘法。请注意顺序,它与 pitch 然后 yaw 不同。
-
你真的需要这个矩阵(即在世界上的位置)吗?将矩阵放在视图空间中是否足够,它是恒定的?当您绘制模型时,将视图矩阵设置为恒等式(因为您的模型已经在视图空间中)并适当地设置模型矩阵(可能只是远离相机的轻微平移)。
-
@NicoSchertler 我有一个传入着色器的视图矩阵,以及也传入的变换矩阵,然后它们在着色器中相乘以计算模型每个顶点的世界空间。您的建议将如何适用于此?我尝试在着色器中仅应用视图矩阵,但它无法正常工作
-
我是说不要应用视图矩阵(设置为标识)。然后,模型将具有相对于相机的恒定位置。
-
我到家时会检查并通知您,谢谢!
标签: java opengl rotation lwjgl angle