我是3D编程的新手,我正在尝试使用LibGDX实现一个跟随我的模型的相机。我在相机实现方面遇到问题,我非常感谢一些建议。正如我所说,我是新手(特别是数学),下面的代码几乎肯定不会那么棒:
要同时旋转我的对象和相机,我使用以下代码,其中inst是模型实例:
// right
inst.transform.rotate(new Vector3(0,1,0), -1);
Common.cam.rotate(Vector3.Y, -1f);
// left
inst.transform.rotate(new Vector3(0,1,0), 1);
Common.cam.rotate(Vector3.Y, 1f);
要移动我使用的对象:
// forward
Common.inst.transform.mul(new Matrix4(new Vector3(0,0,((float)-0.2)),
new Quaternion(0,0,0,0), new Vector3(1,1,1)));
// back
Common.inst.transform.mul(new Matrix4(new Vector3(0,0,((float)0.2)),
new Quaternion(0,0,0,0), new Vector3(1,1,1)));
我的相机目前设置如下:
Vector3 pos = inst.transform.getTranslation(new Vector3(0,0,0));
pos.z += 5;
cam.position.set(pos);
这段代码工作正常,但问题是相机在固定位置时应该调整自己直接在模型面向的新方向后面。我可能没有清楚地阐明这一点,所以我直观地表达了这一点:
^模型(黑色)和相机(红色)没有旋转
^轮换时正在发生的事情
^需要发生什么
我想如果我的数学更强,这不会太难实现,但我完全失去了如何实现这种行为。如果有人能指出我正确的方向,那就太好了。
非常感谢!
答案 0 :(得分:1)
问题在于你是在世界空间中翻译相机,而不是在旋转之后翻译本地空间。相机的位置和旋转存储在两个Vector3中,而不是矩阵。
在应用相机之前,您需要旋转相机的平移向量。
顺便说一下,如果你每帧都实例化很多对象,你就会遇到GC口吃问题。此外,Matrix4类已有一个translate方法,因此您无需手动将其乘以另一个矩阵来转换对象。
我会修改如下:
//rotate player
float playerRotation = left ? 1 : -1; //TODO (should involve delta time...)
inst.transform.rotate(Vector3.Y, playerRotation);
//translate player
float playerZtranslation = forward ? 0.2f : -0.2f; //TODO (should involve delta time...)
inst.translate(0, 0, playerZtranslation );
//move camera to position of player.
inst.transform.getTranslation(camera.position);
//rotate camera to face same direction as player
inst.transform.getRotation(mTempRotation); //mTempRotation is a member Quaternion variable to avoid unnecessary instantiations every frame.
camera.direction.set(0,0,-1).rotate(mTempRotation);//reset and rotate to match current player angle
//rotate translation vector to match angle of player
mTempTranslation.set(0,0,5).rotate(mTempRotation); //mTempTranslation is a member Vector3 variable to avoid unnecessary instantiations every frame.
//and apply it.
cam.position.add(mTempTranslation);
编辑(见评论): 也许试试这个:
//rotate and transform player variables
mPlayerYAngle += left ? 1 : -1; //TODO (should involve delta time...)
mPlayerPosition.add(0, 0, forward ? 0.2f : -0.2f); //TODO (should involve delta time...)
//apply changes by resetting transform to identity and applying variables
inst.transform.idt().translate(mPlayerPosition).rotate(Vector3.Y, mPlayerYAngle );
//move camera to position of player.
camera.position.set(mPlayerPosition);
//rotate camera to face same direction as player
camera.direction.set(0,0,-1).rotate(mPlayerYAngle ,0,1,0);//reset and rotate to match current player angle
//rotate translation vector to match angle of player
mTempTranslation.set(0,0,5).rotate(mPlayerYAngle ,0,1,0);
//and apply it.
cam.position.add(mTempTranslation);