LibGDX 移动旋转的相机

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;

你能添加一些代码来展示你现在是如何移动/旋转相机的吗? - P.T.
我的输入代码目前相当庞大,因此现在我只公布了移动相机本身的行和我用于将x和y转换为“世界空间”的块,主要是为了应用程序中的其他触摸事件。如有必要,我很乐意发布更多内容,但我不想发布大块不必要的代码。另外,现在,我只是使用camera.rotate(value)简单地旋转相机。由于这些问题,我还没有制作控制它正确的系统。 - Synthetik
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”轴。为此,我们需要知道两个向量的叉积是什么。请参见维基上的叉积libgdx类引用上的crs()
以下代码片段将返回一个新的Vector3,它将指向相对于当前相机的正确轴。请注意,nor()调用存在,因为我们要规范化该向量。
长话短说:
Vector3 right = new Vector().set(direction).crs(up).nor();

Crs从两个向量(在我们的情况下为camera.direction和camera.up)创建叉积向量。
我不明白为什么Vector3中的右成员变量没有暴露,或者为什么没有右向量计算方法,但是这样做也可以解决问题。
通过少量代码编辑,您可以将您的玩家、相机或任何其他物体移动到您需要的轴周围。 您只需要理解基本的向量操作,因此我建议您对它们进行了解。
最后注意:
您必须首先绕X轴旋转,因为绕Y轴旋转会更改您的本地X轴,需要重新计算(即右向量)。

Camera 类中我找不到 updateRotation 函数。它是什么? - Nolesh

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接