【问题标题】:LibGDX Moving a Rotated CameraLibGDX 移动旋转相机
【发布时间】:2013-01-24 00:01:49
【问题描述】:

我在使用 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;

【问题讨论】:

  • 您能否添加一些代码来显示您现在如何移动/旋转相机?
  • 此时我的输入代码相当大,所以现在我只放置移动相机本身的线,以及我用来将 x 和 y 转换为的块“世界空间”,主要用于应用程序中的其他触摸事件。我很乐意根据需要发布更多内容,我只是不想发布大量不必要的代码。另外,现在,我只是使用 camera.rotate(value) 旋转相机。由于这些问题,我还没有建立一个可以正确控制它的系统。

标签: opengl matrix camera rotation libgdx


【解决方案1】:

我今天在编写轨道相机时遇到了类似的问题。我将尝试向您描述我是如何处理这个问题的。

我希望我的轨道相机能够同时围绕 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 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 轴(右向量)。

【讨论】:

  • 我在Camera 类中找不到updateRotation 函数。这是什么?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-07-18
相关资源
最近更新 更多