Libgdx:移动旋转的透视相机

时间:2015-10-08 09:29:10

标签: android opengl-es libgdx opengl-es-2.0

我正在开发一个可视化环境地图的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)

1 个答案:

答案 0 :(得分:1)

不要将手势直接应用到相机,而是将它们应用于一对Matrix4,用于分别存储方向和位置。然后在渲染方法中,将两个矩阵相乘并将它们应用到相机的视图中。

render()方法中:

camera.view.set(orientation).mul(position); //Might need to swap orientation/position--don't remember. 
camera.update();

您的缩放方法很好,因为视野影响相机的投影矩阵而不是视图矩阵。