OpenGL – libgdx mobile rotating camera

I have a situation in my application, built with LibGDX, I need the camera to be able to rotate, and can also be moved by the user, as well as to be able to zoom. My camera control The camera can be moved and zoomed beautifully, but when the camera rotates, the camera moves according to that rotation. For example, if the camera turns 45 degrees to the left and the user drags to the right to move the camera, it will move to the upper right because This 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 a solution to this problem, that It simply uses the “world coordinates” to position the camera, instead of basing it on the “window coordinates” I am trying to use now. This creates a very unpleasant user experience because it makes the camera quite unstable and causes my zoom system There is a problem. I assume that I can fix these problems with a lot of adjustments, but because it has been so smooth with window coordinates, I really prefer to go that way.

I suspect this seems simple There is an elegant solution to the problem, I can do a simple calculation on a matrix or something similar, but my knowledge in OpenGL is still lacking, and I can’t seem to figure out what exactly needs to happen to solve this problem. From more proficient Any ideas from people using OpenGL and all these matrices would be greatly appreciated!

===Edit===

The object used to save the value is basically just my own version of Vector2, which is necessary for different parts of the application. I don’t I know the exact reasoning of 0.7f there, but it may only be to reduce the sensitivity of the movement. If I remove it, the problem still exists.

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

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

zoomStartPosition – The X and Y coordinates of the initial touch to start zooming

zoomCurrentPosition – The X and Y coordinates of the touch currently controlling the zoom

The x and y values ​​of these come directly from the touchDown and touchDragged methods. If I change the code to set them after the code below, it will Generated the problem I mentioned in the original post, it will move the way it should, but it is very unstable.

Vector3 vector = new Vector3(x, y, 0 );
camera.unproject(vector);
x = (int) vector.x;
y = CanvasAnywhereMain.HEIGHT-(int) vector.y;
I encountered a similar problem when programming the orbital camera. I will try to describe how I dealt with this problem. < p>

I want my orbit camera to be able to rotate around the X and Y axis at the same time, but it does not work properly. I can only rotate around this axis separately.

My The trick is:

Vector3 target = V ector3.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);

< p>When you rotate around the Y axis, everything is fine, because the Y axis does not change based on your X rotation. You always want to rotate around the world Y axis, not any local rotation.

But when you rotate around X, you cannot use Vector3.X because this axis will not be relative to your camera position and orientation. So we need to calculate the “local Y” axis of the camera. To do this, we You need to know what the Cross product of two vectors is. Please refer to Cross product on wiki and crs() on libgdx class reference

The following code snippet will return a new Vector3, which will point to the current camera Right axis. Please note that there is a nor() call because we want to normalize the vector.

To make a long story short:

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

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

I don’t understand why the correct member variables are not exposed in Vector3 or why there is no correct vector calculation method, but it will help anyway

< p>With very little code editing, you can move the player, camera or anything in the world around the desired axis. You only need to understand the basic Vector operations, so I suggest you continue to use them

Final explanation:

You must first rotate around the X axis, because rotating around Y will change the local X axis (right vector) that you need to recalculate.

< /p>

I have a situation in my application, built with LibGDX, I need the camera to be able to rotate, and can also be moved by the user, as well as to be able to zoom. My camera control can move beautifully and Zoom the camera, but when the camera is rotated, the camera will move according to 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 to the upper right because this is the right side of the camera The location where it is now pointing. Instead, I need the camera to always move relative to the screen/user input, regardless of its rotation.

I do have a solution to this problem, and that is to simply use ” “World Coordinates” to locate the camera instead of basing it on the “Window Coordinates” I am trying to use now. This creates a very unpleasant user experience because it makes the camera quite unstable and causes problems with my zoom system. I assume I can fix these problems with a lot of adjustments, but because it has been so smooth using window coordinates, I really prefer to go that way.

I suspect that this seemingly simple problem has an elegant The solution, I can do a simple calculation on a matrix or something similar, but my knowledge in OpenGL is still lacking, and I can’t seem to figure out what exactly needs to happen to solve this problem. From more proficient use of OpenGL and all of this Any ideas from the Matrix people would be greatly appreciated!

===Edit===

The object used to save the value is basically just my own version of Vector2, which is necessary for different parts of the application. I don’t I know the exact reasoning of 0.7f there, but it may only be to reduce the sensitivity of the movement. If I remove it, the problem still exists.

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

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

zoomStartPosition – The X and Y coordinates of the initial touch to start zooming

zoomCurrentPosition – The X and Y coordinates of the touch currently controlling the zoom

The x and y values ​​of these come directly from the touchDown and touchDragged methods. If I change the code to set them after the code below, it will Generated the problem I mentioned in the original post, it will move the way it should, but it is very unstable.

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

I encountered a similar problem when programming an orbital camera. I will try to describe how I dealt with this problem.

I hope I The orbital camera can rotate around the X and Y axis at the same time, but it does not work properly. I can only rotate around this axis separately.

My trick is:

Vector3 target = Vector3.zero
Vector3 right = new Vector().set(camera.directio n).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);

When you rotate around the Y axis, everything is fine because the Y axis is not Will change according to your X rotation. You always want to rotate around the world Y axis, not any local rotation.

But when you rotate around X, you cannot use Vector3.X because of this The axis will not be relative to your camera position and orientation. So we need to calculate the “local Y” axis of the camera. To do this, we need to know what the Cross product of the two vectors is. See Cross product on wiki and crs () on libgdx class reference

The code snippet below will return a new Vector3, which will point to the right axis relative to the current camera. Note that there is a nor() call because we want to normalize the vector .

Long story short:

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

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

I don’t understand why the correct member variables are not exposed in Vector3 or why There is no correct vector calculation method, but it will help anyway

With very little code editing, you can move the player, camera, or anything in the world around the desired axis. You only need to understand the basic Vector operations, so I suggest you continue to use them

Final explanation:

You must first rotate around the X axis, because rotating around Y will change the local X axis (right vector) that you need to recalculate.

< p>

Leave a Comment

Your email address will not be published.