Java/libgdx 3D模型旋转错误
Java/libgdx 3D model rotation error
问题:我的玩家模型应该转向最后一次鼠标点击的方向,但它不是慢慢转动而是以所有可能的方式旋转(游戏有一个等距视图,模型应该只围绕 Y 旋转轴,但它也绕 X 轴和 Z 轴旋转)。
以下方法(在 render() 中调用)负责模型的转向行为:
public static void turnUnit(){
if(Gdx.input.isButtonPressed(Input.Buttons.LEFT)){
mX = Gdx.input.getX();
mY = Gdx.input.getY();
angle = (float) (180+Math.atan2(mX-Gdx.graphics.getWidth()/2, mY-Gdx.graphics.getHeight()/2)*(180/Math.PI));
newAngle = ((((currentAngle - angle) % 360) + 540) % 360) - 180;
turning = newAngle/60*turnRate;
currentAngle = currentAngle-turning;
}
TestGround.player.transform.setToRotation(Vector3.Y, currentAngle).setTranslation(posX,0,posZ);
}
和移动方法(也在 render() 中调用):
public static void movement(){
if(northM==true){
TestGround.player.transform.trn(0,0,-1f);
}
if(southM==true){
TestGround.player.transform.trn(0,0,1f);
}
if(westM==true){
TestGround.player.transform.trn(-1f,0,0);
}
if(eastM==true){
TestGround.player.transform.trn(1f,0,0);
}
posX = TestGround.player.transform.getTranslation(Vector3.X).x;
posY = TestGround.player.transform.getTranslation(Vector3.Y).y;
posZ = TestGround.player.transform.getTranslation(Vector3.Z).z;
}
尝试在最后一行使用 "rotate",但转得更快。
此外,尽管这对我来说毫无意义,但经过一些测试后,似乎移动方法以某种方式干扰了转动方法(向特定方向移动将以特定方式旋转模型)。
我是不是做错了什么?
附加信息:
- 最初我使用简单的轮询来获取所有键盘和鼠标输入
- 用一种大方法计算 movement/rotation,一切正常
很好
- 决定使用libgdx的inputprocessor,使代码更具可读性和开放性
Matrix4#getTranslation(Vector3)
方法会将指定向量设置为矩阵的平移分量,并return 将其用于链接。这意味着您作为参数提供给 TestGround.player.transform.getTranslation(vector)
方法的向量将被设置(读取:覆盖)到模型实例的翻译(位置)。
所以,在调用的情况下:
TestGround.player.transform.getTranslation(Vector3.Y)
这实际上会将 Vector3.Y
变量从默认值 [x:0, y:1, z:0]
修改为矩阵的翻译组件设置的值。这将导致使用 Vector3.Y
变量的任何其他调用(例如您对 setToRotation
的调用)表现不同。
要解决这个问题,您可以将最后几行修改为:
Vector3 pos = new Vector3();
TestGround.player.transform.getTranslation(pos);
posX = pos.x;
posY = pos.y;
posZ = pos.z;
请注意,您应该将 Vector3
的创建移出该方法,因此最好删除 posX
、posY
和 posZ
成员pos
成员。
所以,您可能想知道两个问题:
为什么 getTranslation
方法修改它的参数? 这是因为 libGDX 旨在避免产生垃圾,因为那样会产生问题在某些平台上,例如 Android。因此,不是每次调用该方法时都创建一个新的 Vector3
,它允许您指定要重用的那个 class 的实例。由于这个原因,您将在整个库的多个位置看到这种模式。
为什么甚至可以修改 Vector3.Y
,使其无用并导致各种问题? 这是因为 Vector3
class 是可变的,不封装其成员。所以实际上它允许你做 vector.x += 3;
而不是强迫你调用 vector.setX(vector.getX() + 3);
。这是出于可读性和性能原因(尽管后者可能因目标平台而异)。此外,java 不支持与 const
.
相当的东西
问题:我的玩家模型应该转向最后一次鼠标点击的方向,但它不是慢慢转动而是以所有可能的方式旋转(游戏有一个等距视图,模型应该只围绕 Y 旋转轴,但它也绕 X 轴和 Z 轴旋转)。
以下方法(在 render() 中调用)负责模型的转向行为:
public static void turnUnit(){
if(Gdx.input.isButtonPressed(Input.Buttons.LEFT)){
mX = Gdx.input.getX();
mY = Gdx.input.getY();
angle = (float) (180+Math.atan2(mX-Gdx.graphics.getWidth()/2, mY-Gdx.graphics.getHeight()/2)*(180/Math.PI));
newAngle = ((((currentAngle - angle) % 360) + 540) % 360) - 180;
turning = newAngle/60*turnRate;
currentAngle = currentAngle-turning;
}
TestGround.player.transform.setToRotation(Vector3.Y, currentAngle).setTranslation(posX,0,posZ);
}
和移动方法(也在 render() 中调用):
public static void movement(){
if(northM==true){
TestGround.player.transform.trn(0,0,-1f);
}
if(southM==true){
TestGround.player.transform.trn(0,0,1f);
}
if(westM==true){
TestGround.player.transform.trn(-1f,0,0);
}
if(eastM==true){
TestGround.player.transform.trn(1f,0,0);
}
posX = TestGround.player.transform.getTranslation(Vector3.X).x;
posY = TestGround.player.transform.getTranslation(Vector3.Y).y;
posZ = TestGround.player.transform.getTranslation(Vector3.Z).z;
}
尝试在最后一行使用 "rotate",但转得更快。
此外,尽管这对我来说毫无意义,但经过一些测试后,似乎移动方法以某种方式干扰了转动方法(向特定方向移动将以特定方式旋转模型)。
我是不是做错了什么?
附加信息:
- 最初我使用简单的轮询来获取所有键盘和鼠标输入
- 用一种大方法计算 movement/rotation,一切正常 很好
- 决定使用libgdx的inputprocessor,使代码更具可读性和开放性
Matrix4#getTranslation(Vector3)
方法会将指定向量设置为矩阵的平移分量,并return 将其用于链接。这意味着您作为参数提供给 TestGround.player.transform.getTranslation(vector)
方法的向量将被设置(读取:覆盖)到模型实例的翻译(位置)。
所以,在调用的情况下:
TestGround.player.transform.getTranslation(Vector3.Y)
这实际上会将 Vector3.Y
变量从默认值 [x:0, y:1, z:0]
修改为矩阵的翻译组件设置的值。这将导致使用 Vector3.Y
变量的任何其他调用(例如您对 setToRotation
的调用)表现不同。
要解决这个问题,您可以将最后几行修改为:
Vector3 pos = new Vector3();
TestGround.player.transform.getTranslation(pos);
posX = pos.x;
posY = pos.y;
posZ = pos.z;
请注意,您应该将 Vector3
的创建移出该方法,因此最好删除 posX
、posY
和 posZ
成员pos
成员。
所以,您可能想知道两个问题:
为什么 getTranslation
方法修改它的参数? 这是因为 libGDX 旨在避免产生垃圾,因为那样会产生问题在某些平台上,例如 Android。因此,不是每次调用该方法时都创建一个新的 Vector3
,它允许您指定要重用的那个 class 的实例。由于这个原因,您将在整个库的多个位置看到这种模式。
为什么甚至可以修改 Vector3.Y
,使其无用并导致各种问题? 这是因为 Vector3
class 是可变的,不封装其成员。所以实际上它允许你做 vector.x += 3;
而不是强迫你调用 vector.setX(vector.getX() + 3);
。这是出于可读性和性能原因(尽管后者可能因目标平台而异)。此外,java 不支持与 const
.