opengl - LibGDX 移动旋转相机

标签 opengl matrix camera rotation libgdx

我在使用 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 轴旋转,但它不起作用。我只能分别绕这个轴旋转。

对我来说,诀窍是:

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 轴旋转,而不是任何局部 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 中没有暴露正确的成员变量或者为什么不存在正确的向量计算方法,但这无论如何都会解决问题

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

最后一个注释:

您必须首先绕 X 轴旋转,因为绕 Y 轴旋转会更改您的局部 X 轴,需要重新计算(正确的向量)。

关于opengl - LibGDX 移动旋转相机,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14491650/

相关文章:

r - 扫描数据框中的每一列,然后将值更改为 R 中的二进制格式

prolog中的矩阵乘法

opengl - 计算着色器如何分配任务?

matlab - 在 matlab 中求解欠定方程组

Android - 拍摄的照片与预览不同

ios - iOS 上的白平衡 yield 不是独立的?

swift - AVFoundation:开始记录由于 "No active/enabled connection"而崩溃

c++ - 了解纹理如何与 CUDA 配合使用

java - LWJGL 3 - 渲染文本

c++ - glDrawElements 在不使用某些顶点属性时崩溃