Java-Gaming.org Hi !
 Featured games (90) games approved by the League of Dukes Games in Showcase (780) Games in Android Showcase (233) games submitted by our members Games in WIP (856) games currently in development
 News: Read the Java Gaming Resources, or peek at the official Java tutorials
Pages: [1]
 ignore  |  Print
 LibGDX top down oblique camera view  (Read 2044 times) 0 Members and 1 Guest are viewing this topic.
FabulousFellini
 « Posted 2018-05-03 16:33:39 »

The time has come where I need to ask how to do this.  I experimented for about 5 hours last night trying to get this to work correctly.  I was trying to use (OrthographicCamera) camera.rotate() and camera.rotateAround() and I just can't seem to get the camera to rotate how I want it to.  Although it does rotate every other which way I don't want it to.  Currently it is just top down, and I want to tilt it backwards.  So basically two questions.  1:  Are these the correct methods to be using in order to achieve top down oblique view?   Can this be achieved by a 2d camera or should I switch it to 3d?  And when I tilt it backwards, I'm tilting along the Y axis, correct?  Sorry I'm such a noob and can't get this to work.

-FabulousFellini
www.fabulousfellini.com
KaiHH

JGO Kernel

Medals: 654

 « Reply #1 - Posted 2018-05-03 17:59:39 »

I am not entirely sure whether this is achievable via libGDX's OrthographicCamera alone, since it only seems to provide a rotate(angles) method which rotates around the view (i.e. Z) axis. But you need to rotate around the X axis. And you definitely need an orthographic/2D projection, not a perspective/3D one.

For this I would rather revert to the raw matrix operations you need.
You basically need this: O * R * T
where:
- O is a scale and translate transformation to transform coordinates in a "view extents" volume down to the unit cube. This is usually called some form of "ortho". In libGDX's Matrix4 class it is called 'setToOrtho'.
- R is a rotation of 45 degrees around the X axis. In libGDX this can be done via setToRotation(Vector3(1,0,0), 45).
- T is a translation of the negated camera position. There is a post-multiplying method in libGDX for that: translate().
Sadly, libGDX's Matrix4 class does not have post-multiplying methods for O and R, so you gonna need to use mul() for that.
So you create O and R using the mentioned methods and can post-multiply the translation onto R using Matrix4.translate() on R. Then, you need to multiply R to O with O.mul(R).

If you prefer, here are the necessary transformations expressed in "JOML language":
 1  2  3  4  5  6  7  8  9 `float ex = 4.0f; // <- 4 units in each directionfloat ar = (float)width/height;Matrix4f m = new Matrix4f()  // account for aspect ratio and view extents  . ortho(-ar*ex, ar*ex, -ex, +ex, 0, +10)  // rotate 45° down (i.e. rotate around the X axis)  . rotateX((float)Math.PI * 0.25f)  // translate by negated camera position  . translate(0, -1, -1);`

FabulousFellini
 « Reply #2 - Posted 2018-05-03 18:04:50 »

I am not entirely sure whether this is achievable via libGDX's OrthographicCamera alone, since it only seems to provide a rotate(angles) method which rotates around the view (i.e. Z) axis. But you need to rotate around the X axis. And you definitely need an orthographic/2D projection, not a perspective/3D one.

For this I would rather revert to the raw matrix operations you need.
You basically need this: O * R * T
where:
- O is a scale and translate transformation to transform coordinates in a "view extents" volume down to the unit cube. This is usually called some form of "ortho". In libGDX's Matrix4 class it is called 'setToOrtho'.
- R is a rotation of 45 degrees around the X axis. In libGDX this can be done via setToRotation(Vector3(1,0,0), 45).
- T is a translation of the negated camera position. There is a post-multiplying method in libGDX for that: translate().
Sadly, libGDX's Matrix4 class does not have post-multiplying methods for O and R, so you gonna need to use mul() for that.
So you create O and R using the mentioned methods and can post-multiply the translation onto R using Matrix4.translate() on R. Then, you need to multiply R to O with O.mul(R).

If you prefer, here are the necessary transformations expressed in "JOML language":
 1  2  3  4  5  6  7  8  9 `float ex = 4.0f; // <- 4 units in each directionfloat ar = (float)width/height;Matrix4f m = new Matrix4f()  // account for aspect ratio and view extents  . ortho(-ar*ex, ar*ex, -ex, +ex, 0, +10)  // rotate 45° down (i.e. rotate around the X axis)  . rotateX((float)Math.PI * 0.25f)  // translate by negated camera position  . translate(0, -1, -1);`

Thanks a lot for the deep explanation on how to do this.  I definitely wasn't / didn't think I had to go that in depth.  I'll mess around with this info and see if I can get it working.  Thanks man!

-FabulousFellini
www.fabulousfellini.com
KaiHH

JGO Kernel

Medals: 654

 « Reply #3 - Posted 2018-05-03 20:51:37 »

Btw. if you want to rather specify your camera in terms of a "look at" point/position and a distance to that point (along the view direction of the camera), you need the following transformations:
 1  2  3  4  5  6  7  8  9  10  11  12 `float ex = 4.0f; // <- 4 units in each directionfloat ar = (float)width/height;float dist = 5.0f; // <- distance from camera to lookat positionMatrix4f m = new Matrix4f()  // account for aspect ratio and view extents  . ortho(-ar*ex, ar*ex, -ex, +ex, 0, +10)  // translate camera "back" by the distance 'dist'  . translate(0, 0, -dist)  // rotate 45° down (i.e. rotate around the X axis)  . rotateX((float)Math.PI * 0.25f)  // translate by negated target/lookat position  . translate(-2, 0, 0); // <- look at (2, 0, 0)`

This is essentially the basis for an "arcball" camera. You can also add a rotation around the Y axis after the rotation around the X axis.
It should be straight forward to translate that to libGDX Matrix4 methods.
FabulousFellini
 « Reply #4 - Posted 2018-05-03 21:00:42 »

Ok cool, I can't wait to get home and try this stuff out!

-FabulousFellini
www.fabulousfellini.com
FabulousFellini
 « Reply #5 - Posted 2018-05-03 21:30:25 »

Just to be clear, do I put this stuff in the constructor for Matrix4?  Or do I create a Matrix4 and use matrix.setToRotation?

-FabulousFellini
www.fabulousfellini.com
KaiHH

JGO Kernel

Medals: 654

 « Reply #6 - Posted 2018-05-04 11:55:53 »

You create individual Matrix4 objects and call the respective methods on them.
Then you multiply them together with mul(), like so:
 `o.mul(t1).mul(r).mul(t2)`

The result will be stored in 'o'. Read the JavaDoc of libGDX's Matrix4.mul(Matrix4).

After all that, I am still a bit surprised that Google'ing for "libGDX oblique camera" or "libGDX oblique projection" does not yield any reasonable results... There is only one single question on stackexchange without any answer. Of course there are tons of resources on how to do that generally with linear algebra and matrices, but none using libGDX's camera abstractions.
FabulousFellini
 « Reply #7 - Posted 2018-05-05 19:36:35 »

You create individual Matrix4 objects and call the respective methods on them.
Then you multiply them together with mul(), like so:
 `o.mul(t1).mul(r).mul(t2)`

The result will be stored in 'o'. Read the JavaDoc of libGDX's Matrix4.mul(Matrix4).

After all that, I am still a bit surprised that Google'ing for "libGDX oblique camera" or "libGDX oblique projection" does not yield any reasonable results... There is only one single question on stackexchange without any answer. Of course there are tons of resources on how to do that generally with linear algebra and matrices, but none using libGDX's camera abstractions.

Yeah thanks for taking the time and having the patience to explain all of that.  I googled so much on how to do that with LibGDX and couldn't really find any solid examples of it (and I'll be the first to admit I'm not the best with math and how angles work when you have a z axis).  There are some good ones for isometric, but like I said in the other post, I probably shoudn't be trying to do iso, esp if I can't even figure out the top down oblique lol.   Hopefully this thread will help other people looking for this same question.  I'm working on animations right now and will try for the camera either later today or tomorrow.  Thanks again @KaiHH you were a super big help with all this!

-FabulousFellini
www.fabulousfellini.com
KaiHH

JGO Kernel

Medals: 654

 « Reply #8 - Posted 2018-05-06 18:49:15 »

You can also look at this very small LWJGL3/JOML demo to see how other oblique projections (such as cavalier) can be achieved easily with a custom matrix.
LibGDX's Matrix4 also has a constructor and a set method that you can give the 16 matrix element values in the form of a float[] array.
FabulousFellini
 « Reply #9 - Posted 2018-05-12 17:53:52 »

Am I anywhere close with this?  How it is now will kind of just cut off the bottom of the viewport and flips the y axis over.

 1  2  3  4  5  6  7  8  9  10  11  12  13  14 `private void initializeCamera() {      camera                   = new OrthographicCamera(cameraWidth, cameraHeight);      camera.position.x        = myGame.gameObjectLoader.player.getX();      camera.position.y        = myGame.gameObjectLoader.player.getY();      camera.setToOrtho(true, cameraWidth, cameraHeight);            float ex = 10f; // <- 4 units in each direction      float ar = (float) cameraWidth / cameraHeight;      matrixO.setToOrtho(-ar*ex, ar*ex, -ex, ex, 0, 10);      matrixR.setToRotation(new Vector3(1, 0, 0), 45);      matrixR.translate(0, -1, -1);      matrixT = matrixO.mul(matrixR);      camera.rotate(matrixT);   }`

One thing I'm confused about is ar:  is that the cameraWidth/cameraHeight?  Or is it supposed to be Gdx.graphics.getWidth()/height (I tried both).   CameraWidth = 10 at the moment and I don't specifiy a size for the window in the desktop launcher so it's size is whatever the default is.  So that code above is camera init().  Here is the camera update method:

 1  2  3  4  5  6  7  8  9  10  11 `@Override   protected void updateCamera() {      myGame.renderer.batch.setProjectionMatrix(camera.combined);      myGame.renderer.shapeRenderer.setProjectionMatrix(camera.combined);            if (!ScreenShake.screenIsShaking) {         camera.position.x = myGame.gameObjectLoader.player.getX();         camera.position.y = myGame.gameObjectLoader.player.getY();      }      camera.update();   }`

Sorry this is so confusing, and thanks again.

-FabulousFellini
www.fabulousfellini.com
Pages: [1]
 ignore  |  Print

 hadezbladez (695 views) 2018-11-16 13:46:03 hadezbladez (342 views) 2018-11-16 13:41:33 hadezbladez (677 views) 2018-11-16 13:35:35 hadezbladez (167 views) 2018-11-16 13:32:03 EgonOlsen (2359 views) 2018-06-10 19:43:48 EgonOlsen (2460 views) 2018-06-10 19:43:44 EgonOlsen (1461 views) 2018-06-10 19:43:20 DesertCoockie (2126 views) 2018-05-13 18:23:11 nelsongames (1888 views) 2018-04-24 18:15:36 nelsongames (2557 views) 2018-04-24 18:14:32
 Deployment and Packagingby mudlee2018-08-22 18:09:50Java Gaming Resourcesby gouessej2018-08-22 08:19:41Deployment and Packagingby gouessej2018-08-22 08:04:08Deployment and Packagingby gouessej2018-08-22 08:03:45Deployment and Packagingby philfrei2018-08-20 02:33:38Deployment and Packagingby philfrei2018-08-20 02:29:55Deployment and Packagingby philfrei2018-08-19 23:56:20Deployment and Packagingby philfrei2018-08-19 23:54:46
 java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org