4

我在使用 LibGDX 构建的应用程序中遇到了一种情况,我需要相机能够旋转,用户也可以移动,并且能够缩放。我的用于移动和缩放相机的相机控件可以很好地工作,但是,当相机旋转时,相机会根据该旋转移动。例如,如果相机向左旋转 45 度,并且用户向右拖动以移动相机,它将向右上角移动,因为这是相机右侧现在指向的位置。相反,我需要相机始终相对于屏幕/用户输入移动,无论其旋转如何。

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

我怀疑这个看似简单的问题有一个优雅的解决方案,我可以对矩阵或类似的东西进行简单的计算,但是我对 OpenGL 的了解仍然非常缺乏,我似乎无法弄清楚到底需要发生什么要解决这个问题。任何来自更擅长 OpenGL 和所有这些矩阵的人的想法将不胜感激!

===编辑===

这里用来保存值的对象本质上只是我自己的 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;
4

1 回答 1

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”轴。为此,我们需要知道两个向量的叉积是什么。请参阅wiki 上的 Cross productlibgdx 类参考上的 crs()

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

长话短说:

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

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

我不明白为什么在 Vector3 中没有公开正确的成员变量或者为什么不存在正确的向量计算方法,但这无论如何都可以解决问题

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

最后一点:

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

于 2013-02-07T09:34:26.917 回答