LibGDX 移动旋转相机 [英] LibGDX Moving a Rotated Camera

查看:33
本文介绍了LibGDX 移动旋转相机的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I've come to a situation in my application, built using LibGDX, where I need the camera to be able to rotate, and also be moveable by the user, as well as being able to be zoomed. My camera controls for moving and zooming the camera work beautifully, however, when the camera is rotated, the camera is then moved based on that rotation. For example, if the camera is turned 45 degrees to the left, and the user drags to the right to move the camera, it will move towards the upper right, because that is where the right side of the camera is now pointing. Instead, I need the camera to always move relative to the screen/user input, regardless of its rotation.

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

I do have one solution for this problem, and that is to simply use "world coordinates" to position the camera, rather than basing it on the "window coordinates" I am trying to use now. This creates a very unpleasant user experience though, as it makes the camera fairly choppy and causes problems with my zooming system. I assume I could patch those problems up with a lot of tweaking, however, because it is so much smoother already using the window coordinates, I would really prefer to go that route.

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

I suspect there is an elegant solution to this seemingly simple problem, where I could do a simple calculation on a matrix or something along those lines, however my knowledge in OpenGL is still pretty lacking and I cannot seem to figure out what exactly needs to happen to fix it. Any ideas from someone more adept with OpenGL and all of this matrices would be greatly appreciated!

===编辑===

这里用来保存值的对象本质上只是我自己的 Vector2 版本,它在应用程序的不同部分中是必需的.我不太记得里面 0.7f 的确切原因,但大概只是为了降低机芯的灵敏度,如果我将其移除,问题仍然存在.

The objects used to hold the values here are essentially just my own version of Vector2, which was required in a different part of the application. I can't quite remember the exact reasoning for the 0.7f in there, but presumably it was just to lower the sensitivity of the movement, and the problem still persists if I remove it.

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

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

cameraStartPosition - The X and Y coordinates of the camera when the user starts to move it.

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

zoomStartPosition - The X and Y coordinates of the initial touch that starts the zoom

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

zoomCurrentPosition - The X and Y coordinates where the touch that controls the zoom currently is

其中的 x 和 y 值直接取自 touchDown 和 touchDragged 方法.如果我将设置这些的代码放在以下代码之后,则会产生我在原始帖子中提到的问题,它会按照应有的方式移动,但非常不稳定.

The x and y values in those are taken directly from the touchDown and touchDragged methods. If I instead place the code that sets those after the following code, it creates the problem I mentioned in the original post, where it moves the way it should, but very choppy.

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

推荐答案

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

I was dealing with similar problem today when I was programming orbit camera. I will try to describe you how I dealt with this issue.

我希望我的轨道相机能够同时围绕 X 轴和 Y 轴旋转,但它不起作用.我只能分别绕着这个轴旋转.

I wanted my orbit camera to be able to rotate around X and Y axis in the same time, but it was not working. I was able to rotate around this axes only respectively.

对我来说诀窍是:

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 轴旋转,而不是任何局部的.

When you are rotating around Y axis everything is fine because Y axis does not change depending on your X rotation. You always want to rotate around the world Y axis, not any local one.

但是当您围绕 X 旋转时,您不能使用 Vector3.X,因为该轴不会与您的相机位置和方向相关.所以我们需要计算相机的局部 Y"轴.为此,我们需要知道两个向量的叉积是什么.请参阅 wiki 上的交叉产品crs() on libgdx 类参考

But when you are rotating around X you can not use Vector3.X because this axis will not be relative to your camera position and direction. So we need to calculate "local Y" axis of your camera. To do that we need to know what Cross product of two vectors is. Please see Cross product on wiki and crs() on libgdx class reference

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

Following code fragment will return new Vector3, which will be pointing to the right axis relative to the current camera. Note the nor() call is present because we want to normalize that vector.

长话短说:

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

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

Crs creates cross product vector from two vectors (in our case camera.direction and camera.up).

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

I don't understand why in Vector3 the right member variable is not exposed or why right vector calculation method is not present, but this will do the trick anyway

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

With few code edits you can move your player, camera or anything in the world around the axis you need. You just need to understand the basic Vector operations so I recommend you going trough them

最后一点:

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

You must rotate around X axis first because rotating around Y changes your local X axis which will need to be recalculated (the right vector).

这篇关于LibGDX 移动旋转相机的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆