LibGDX移动旋转相机

时间:2013-01-24 00:01:50

标签: opengl matrix camera rotation libgdx

我在我的应用程序中出现了一个使用LibGDX构建的情况,我需要相机能够旋转,并且还可以由用户移动,以及能够进行缩放。我的相机控制可以漂亮地移动和缩放相机,但是,当相机旋转时,相机会根据该旋转移动。例如,如果摄像机向左转45度,并且用户向右拖动以移动摄像机,它将向右上方移动,因为这是摄像机右侧现在指向的位置。相反,我需要相机始终相对于屏幕/用户输入移动,无论其旋转如何。

我确实有一个解决这个问题的方法,那就是简单地使用“世界坐标”来定位相机,而不是将它基于我现在尝试使用的“窗口坐标”。这会产生非常不愉快的用户体验,因为它会使相机相当不稳定并导致我的缩放系统出现问题。我认为我可以通过大量的调整修补这些问题,但是,因为它已经使用窗口坐标这么平滑了,我真的更喜欢走那条路。

我怀疑这个看似简单的问题有一个优雅的解决方案,我可以对矩阵或类似的东西做一个简单的计算,但是我在OpenGL中的知识仍然很缺乏,我似乎无法弄清楚到底是什么需要发生修复它。来自更熟练使用OpenGL和所有这些矩阵的人的任何想法都将不胜感激!

=== EDIT ===

用于保存值的对象基本上只是我自己的Vector2版本,在应用程序的不同部分需要它。我不太清楚0.7f在那里的确切推理,但可能只是为了降低机芯的灵敏度,如果我将其移除,问题仍然存在。

camera.position.set(cameraStartPosition.getX() - ((zoomCurrentPosition.getX() - zoomStartPosition.getX()) * 0.7f), cameraStartPosition.getY() + ((zoomCurrentPosition.getY() - zoomStartPosition.getY())  * 0.7f), 0);

cameraStartPosition - 用户开始移动时相机的X和Y坐标。

zoomStartPosition - 开始缩放的初始触摸的X和Y坐标

zoomCurrentPosition - 当前控制缩放的触摸的X和Y坐标

这些中的x和y值直接来自touchDown和touchDragged方法。如果我改为在下面的代码之后放置设置它们的代码,它就会产生我在原始帖子中提到的问题,它会以应有的方式移动,但是非常不稳定。

    Vector3 vector = new Vector3(x, y, 0);
    camera.unproject(vector);
    x = (int) vector.x;
    y = CanvasAnywhereMain.HEIGHT - (int) vector.y;

1 个答案:

答案 0 :(得分:2)

当我编程轨道摄像机时,我今天正在处理类似的问题。我将尽力描述你如何处理这个问题。

我希望我的轨道摄像机能够同时绕X轴和Y轴旋转,但它无法正常工作。我只能分别绕这个轴旋转。

我的诀窍是:

Vector3 target = Vector3.zero
Vector3 right = new Vector().set(camera.direction).crs(camera.up).nor();

// This angles usualy comes from touchDragged event in your input processor
// class implementing the InputProcessor, where you do your calculations
deltaAngleX = 1.1f;
deltaAngleY = 1.9f;

// Rotate around X axis
camera.rotateAround(target, right, deltaAngleX);

// Rotate around Y
camera.updateRotation(Vector3.Y, deltaAngleY);

当您围绕Y轴旋转时,一切都很好,因为Y轴不会根据您的X旋转而改变。你总是希望围绕世界Y轴旋转,而不是任何本地旋转。

但是当您在X周围旋转时,您无法使用Vector3.X,因为此轴不会相对于您的相机位置和方向。所以我们需要计算相机的“局部Y”轴。要做到这一点,我们需要知道两个向量的Cross乘积是什么。请参阅Cross product on wikicrs() on libgdx class reference

以下代码片段将返回新的Vector3,它将指向相对于当前相机的右轴。请注意,存在nor()调用,因为我们想要规范化该向量。

长话短说:

Vector3 right = new Vector().set(direction).crs(up).nor();

Crs从两个向量创建叉积矢量(在我们的例子中是camera.direction和camera.up)。

我不明白为什么在Vector3中没有公开正确的成员变量或为什么没有正确的矢量计算方法,但是无论如何这都会有所作为

只需很少的代码编辑,您就可以围绕所需的轴移动播放器,相机或世界上任何东西。您只需要了解基本的Vector操作,因此我建议您继续使用它们

最后一点:

您必须先绕X轴旋转,因为围绕Y旋转会改变您需要重新计算的局部X轴(右侧矢量)。