背景
我正在尝试使用LWJGL 3.0在Java中创建一款FPS游戏。我已经设置了一个相机类,它具有俯仰和偏航(滚动未被使用)。相机本身是继承自实体(Entity)的,因为它有一个模型。我希望这个模型总是出现在相机的“前方”,无论相机指向哪里。每个实体都有一个方法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());
}
我已经做了一些研究,但是我担心我在这个问题上卡得太久了,需要一些新的眼睛。当我尝试将这两个计算结合起来时,模型似乎在除了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)
),将该向量旋转pitch和yaw,然后将该向量乘以半径并加到相机位置。我尝试了这个方法,但我不知道如何通过角度旋转向量,并且在slick-utils Vector3f类中似乎没有Vector3f.rotate()
方法。非常感谢任何帮助,因为这已经让我头痛了几天。谢谢!