【问题标题】:Libgdx: Moving a rotated perspective cameraLibgdx:移动旋转的透视相机
【发布时间】:2015-10-08 09:29:09
【问题描述】:

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

另外最重要的是将我的batch的Transformation Matrix设置为camera.view

batch.setTransformationMatrix(camera.view)

【问题讨论】:

  • 不要将手势直接应用到相机上,而是将它们应用到一对 Matrix4 上,分别用于存储方向和位置。然后在渲染方法中,将这两个矩阵相乘并将它们应用到相机的视图中。您可能需要在此处交换方向/位置,不记得了:camera.view.set(orientation).mul(position); camera.update();

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


【解决方案1】:

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

render() 方法中:

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

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

【讨论】:

  • 我按照你说的做了,但相机甚至不再移动,camera.view.set 方法起作用并更新相机视图矩阵,这是我的代码:Matrix4 tmp = new Matrix4(); tmp.set(gestureHandler.position).mul(gestureHandler.orientation); camera.view.set(tmp); camera.update();
  • 非常感谢,您的指导对我帮助很大;-)
猜你喜欢
  • 1970-01-01
  • 2014-07-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-05-27
  • 1970-01-01
  • 1970-01-01
  • 2018-07-15
相关资源
最近更新 更多