我正在开发一个可视化环境地图的Android应用程序,目前我正在使用libgdx绘制地图,也就像用户应该能够缩放,旋转和移动地图的任何地图应用程序一样,
我开发了一个GestureHandler
类,它实现GestureListener
接口并与PerspectiveCamera
交互(因为我将来会使用3d组件):
@Override
public boolean pan(float x, float y, float deltaX, float deltaY) {
float tempX = (mapView.getCamera().position.x - deltaX * 0.5f);
float tempY = (mapView.getCamera().position.y + deltaY * 0.5f);
mapView.getCamera().position.set(
MathUtils.lerp(mapView.getCamera().position.x, tempX, mapView.getCamera().fieldOfView / 100),
MathUtils.lerp(mapView.getCamera().position.y, tempY, mapView.getCamera().fieldOfView / 100),
mapView.getCamera().position.z);
mapView.getCamera().update();
return false;
}
float initialDistance = 0;
float initialAngle = 0;
float distance = 0;
private void zoom(Vector2 initialPointer1, Vector2 initialPointer2, Vector2 pointer1, Vector2 pointer2)
{
initialDistance = initialPointer1.dst(initialPointer2);
float iDeltaX = initialPointer2.x - initialPointer1.x;
float iDeltaY = initialPointer2.y - initialPointer1.y;
initialAngle = (float)Math.atan2((double)iDeltaY,(double)iDeltaX) * MathUtils.radiansToDegrees;
if(initialAngle < 0)
initialAngle = 360 - (-initialAngle);
distance = initialPointer1.dst(pointer2);
float deltaX = pointer2.x - initialPointer1.x;
float deltaY = pointer2.y - initialPointer1.y;
newAngle = (float)Math.atan2((double)deltaY,(double)deltaX) * MathUtils.radiansToDegrees;
if(newAngle < 0)
newAngle = 360 - (-newAngle);
//Log.e("test", distance + " " + initialDistance);
//Log.e("test", newAngle + " " + initialAngle);
float ratio = initialDistance/distance;
mapView.getCamera().fieldOfView = MathUtils.clamp(initialZoomScale * ratio, 1f, 100.0f);
Log.e("zoom", String.valueOf(mapView.getCamera().fieldOfView));
mapView.getCamera().update();
}
@Override
public boolean pinch(Vector2 initialPointer1, Vector2 initialPointer2, Vector2 pointer1, Vector2 pointer2) {
zoom(initialPointer1, initialPointer2, pointer1, pointer2);
float delta1X = pointer2.x - pointer1.x;
float delta1Y = pointer2.y - pointer1.y;
newAngle = (float)Math.atan2((double)delta1Y,(double)delta1X) * MathUtils.radiansToDegrees;
if(newAngle < 0)
newAngle = 360 - (-newAngle);
System.out.println("new "+newAngle);
if(newAngle - currentAngle >= 0.01000f)
{
System.out.println("Increasing");
mapView.getCamera().rotate(0.5f,0,0,1);
}
else if(newAngle - currentAngle <= -0.010000f) {
System.out.println("DEcreasing");
mapView.getCamera().rotate(-0.5f,0,0,1);
}
if(Math.abs(newAngle - currentAngle) >= 0.01000f)
{
currentAngle = newAngle;
}
return true;
}
一切都很好,直到我不旋转相机,就像旋转相机后this unsolved similar question一样,移动会受到应用旋转的影响。任何帮助都会特别提示代码吗?
修改
经过多方努力,我终于解决了它, 正如Tenfour04在他的answer中所说,我不得不使用两个单独的矩阵进行变换和旋转,最后将它们的乘法结果设置为使用以下方式查看相机矩阵:
camera.view.set(position).mul(orientation);
同样最重要的是将我的批次的转换矩阵设置为camera.view
:
batch.setTransformationMatrix(camera.view)
答案 0 :(得分:1)
不要将手势直接应用到相机,而是将它们应用于一对Matrix4,用于分别存储方向和位置。然后在渲染方法中,将两个矩阵相乘并将它们应用到相机的视图中。
在render()
方法中:
camera.view.set(orientation).mul(position); //Might need to swap orientation/position--don't remember.
camera.update();
您的缩放方法很好,因为视野影响相机的投影矩阵而不是视图矩阵。