Issues with 3D scene layout and plane positioning using libgdx

Hi all.

I’ve been using libgdx to experiment with it’s 3D api, and currently have a test program set up as shown in this screenshot:

Pastebin of relevant portions of the code: http://pastebin.com/kvqK609n

It’s drawing 4 planes out using MeshPartBuilder and applying a texture to each. It also uses a PerspectiveCamera to display the scene.

My questions:

  • Why do I need to double the z-axis units to get the correct ‘cube’ shape appearing? As seen in the code, I need to use +2 for the z coordinates whereas x and y are only -1/+1

  • I would like to end up with a scene where the corners of the “floor” and “walls” are stretched into the corners of the viewport, as shown by the red dashed lines. What would be the “correct” way to do this? I’ve tried all sorts of adjustments with the PerspectiveCamera aspect ratio, or manually adjusting the vertex locations of the planes but nothing has seemed to work quite right. I’m not sure if the “wall” and “floor” planes should actually be larger in units that the back plane, or simply visually stretched somehow via the camera.

Thanks in advance for any help!

To achieve what you want, do the following:

  • build a unit cube (ranging from [-1…1] in all dimensions)
  • build a projection transformation with 90 degrees vertical field-of-view
  • build a view transformation which translates the camera to (0, 0, 2)
  • leave aspect-ratio to 1.0
    This will result in the front corners of your open cube to align with the viewport corners, regardless of the aspect ratio of your viewport.

Thanks for the reply!

I did those tweaks you mentioned and that gave me pretty close to what I was imagining. I noticed that it’s quite easy to distort the view a lot by resizing the window to weird aspect ratios, is there any way to “fix” the aspect ratio so that this can’t happen regardless of window size?

You cannot have both, your cube corners align with the viewport corners AND have the cube be an actual undistorted cube, obviously. :slight_smile:
You must decide on one or the other. If you want the cube to not be distorted and resemble an actual cube, then you just set the correct aspect ratio in your perspective projection.

EDIT:
Just one note. There is but one thing that you can tweak, which is the vertical field-of-view of your camera.
You can place your camera farther away from your cube and reduce the field-of-view angle in such a way that your perspective projection becomes more and more an orthographic projection. (this is as if one would “zoom in” with a real camera)
That will result in the sides of the cube become more “parallel” to the view direction of the camera in the final image.
For any field-of-view angle in the open interval ]0…180[ degrees you need to set your camera to the position
(0, 0, 1 + 1 / (float)Math.tan(fovInRadians / 2.0))
to still have your cube’s top and bottom edges align with the viewport’s bottom and top edges.
The reason why you had to choose (0, 0, 2) in the above example with 90deg fov was exactly because
(0, 0, 1 + 1/tan(90deg / 2)) = (0, 0, 2).
The first ‘1’ is the distance that we must move the camera “back” to be on the cube’s front face at (0, 0, 1).
And the ratio of 1/tan(…) is the amount of distance we need to further move back for the camera’s viewing frustum to capture the whole cube, where the ‘1’ in that ratio is the half-height of the cube (which is the “opposite leg” in that tangent computation).

Why not recreate the projection matrix on a resize event?

Thanks for the answers everyone. In the end I tweaked my idea slightly so that the edges do not need to be up against the edges of the screen, and also made use of ExtendViewport so that it doesn’t warp when resizing.