Java-Gaming.org Hi !
Featured games (91)
games approved by the League of Dukes
Games in Showcase (764)
Games in Android Showcase (229)
games submitted by our members
Games in WIP (852)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  ignore  |  Print  
  LibGDX top down oblique camera view  (Read 1510 times)
0 Members and 1 Guest are viewing this topic.
Offline 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
Offline KaiHH

JGO Kernel


Medals: 525



« 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 direction
float 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);

Offline 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 direction
float 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
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline KaiHH

JGO Kernel


Medals: 525



« 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 direction
float ar = (float)width/height;
float dist = 5.0f; // <- distance from camera to lookat position
Matrix4f 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.
Offline 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
Offline 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
Offline KaiHH

JGO Kernel


Medals: 525



« 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.
Offline 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
Offline KaiHH

JGO Kernel


Medals: 525



« 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.
Offline 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  
 
 

 
EgonOlsen (591 views)
2018-06-10 19:43:48

EgonOlsen (695 views)
2018-06-10 19:43:44

EgonOlsen (478 views)
2018-06-10 19:43:20

DesertCoockie (838 views)
2018-05-13 18:23:11

nelsongames (1027 views)
2018-04-24 18:15:36

nelsongames (1083 views)
2018-04-24 18:14:32

ivj94 (1665 views)
2018-03-24 14:47:39

ivj94 (623 views)
2018-03-24 14:46:31

ivj94 (1501 views)
2018-03-24 14:43:53

Solater (569 views)
2018-03-17 05:04:08
Deployment and Packaging
by philfrei
2018-08-20 02:33:38

Deployment and Packaging
by philfrei
2018-08-20 02:29:55

Deployment and Packaging
by philfrei
2018-08-19 23:56:20

Deployment and Packaging
by philfrei
2018-08-19 23:54:46

Deployment and Packaging
by philfrei
2018-08-19 23:53:08

Deployment and Packaging
by philfrei
2018-08-19 23:50:04

Java Gaming Resources
by philfrei
2017-12-05 19:38:37

Java Gaming Resources
by philfrei
2017-12-05 19:37:39
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
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!