Frustum camera

Any community contributions to libgdx go here! Some may get included in the core API when permission is granted.

Frustum camera

Postby Rob » Tue Apr 05, 2011 8:51 pm

I have just started using libgdx and now im currently in the process of porting some work I created before.

In my project I had a frustum projection setup where, at a given depth, coordinates would match the viewport pixel sizes... I basically want to be able to handle rendering like an ortho view at a given focus point ( when it comes to dimensions ), but with the depth of a frustum.

While looking through the source I found the Camera class, but only found the implementations for ortho and perspective projection, but no frustum. ( maybe im just not looking hard enough though :geek: )

As it seemed like a good idea to handle it this way Ive created my own Camera class and I thought maybe it could be of some use to anyone ( I am still testing to see if everything works like it should but at first sight it looks ok to me )...

I had to extend the Matrix4 class, because I could not find anything that could handle left,right,bottom,top,near,far to create a matrix.

Code: Select all
   public Matrix4 setToFrustum(float left, float right, float bottom, float top, float near, float far) {
        idt();
       
      val[M00] = 2 * near / (right - left);
      val[M10] = 0;
      val[M20] = 0;
      val[M30] = 0;
      val[M01] = 0;
      val[M11] = 2 * near / (top - bottom);
      val[M21] = 0;
      val[M31] = 0;
      val[M02] = (right + left) / (right - left);
      val[M12] = (top + bottom) / (top - bottom);
      val[M22] = -(far + near) / (far - near);
      val[M32] = -1;
      val[M03] = 0;
      val[M13] = 0;
      val[M23] = -2*far*near / (far - near);
      val[M33] = 0;     

      return this;
    }   


And implemented a Camera called FrustumFocalCamera

Code: Select all
public class FrustumFocalCamera extends Camera {

      /** frustum values and focal point **/
      float focal;
      float top;
      float bottom;
      float right;
      float left;
      
      /**
       * Constructs a new {@link FrustumFocalCamera } with the given viewport, near, far and focal point which should be "pixel-perfect"
       * size. The apsect ratio is derrived from the viewport size.
       *
       * @param viewportWidth the viewport width
       * @param viewportHeight the viewport height
       * @param near value
       * @param far value
       * @param focal point at which coordinations should match the viewport pixel size
       */
      public FrustumFocalCamera(float viewportWidth, float viewportHeight, float near, float far, float focal) {

         this.viewportWidth = viewportWidth;
         this.viewportHeight = viewportHeight;
         float aspect = viewportWidth/viewportHeight;
         
         this.near=near;
         this.far=far;
         this.focal=focal;
         
         this.top = (float)viewportHeight/2.0f * near / focal;
         this.bottom = -this.top;
         this.left = this.bottom * aspect;
         this.right = this.top * aspect;
         
      }
      
      final Vector3 tmp = new Vector3();
      
      @Override
      public void update() {
         
         projection.setToFrustum(left, right, bottom, top, near, far);
         view.setToLookAt(position, tmp.set(position).add(direction), up);   

         combined.set(projection).mul(view);
         invProjectionView.set(combined);
         invProjectionView.inv();
         frustum.update(invProjectionView);
         
      }   
}


On resize I setup the camera (near=1.0, far=100.0f, focal=50.0f)

Code: Select all
@Override
public void resize(int width, int height) {
      
        camera = new FrustumFocalCamera(width, height, 1.0f, 100.0f, 50.0f);

}


And now i can use normal pixel sizes at the given focal point

Code: Select all
//width=viewport width ex 480
//height=viewport height ex 800

        someMesh.setVertices(new float[] {
                -(width/2), -(height/2), -50, Color.toFloatBits(255, 0, 0, 255),
                (width/2), -(height/2), -50, Color.toFloatBits(255, 0, 0, 255),
                -(width/2), (height/2), -50, Color.toFloatBits(255, 0, 0, 255),
                (width/2)-1, (height/2)-2, -50, Color.toFloatBits(255, 0, 0, 255) });


And thats about it.... As said I havent tested it to the full extend, but rendering a simple Mesh works ok as far as I can see.
Rob
 
Posts: 4
Joined: Tue Apr 05, 2011 8:01 pm

Re: Frustum camera

Postby mzechner » Wed Apr 06, 2011 1:30 am

Hey, that's neat. I move this to the contributions sub-forum if you don't mind.

The Matrix4 class indeed misses the frustum setter. I will integrate your extension if you don't mind. For your camera class i have to check it out first. Given your permission i'd integrate that at some point as well if it works out as expected.

Good work!
mzechner
Site Admin
 
Posts: 4879
Joined: Sat Jul 10, 2010 3:50 pm

Re: Frustum camera

Postby Rob » Wed Apr 06, 2011 4:07 am

No problem,

Feel free to use it as you like. I mainly use this type of projection where I would normally use an ortho based projection.

Im already glad I found a well-maintained library which helps me with things like compatibility issues etc and not having the primary focus of being a game engine.
Rob
 
Posts: 4
Joined: Tue Apr 05, 2011 8:01 pm


Return to Libgdx Contributions

Who is online

Users browsing this forum: No registered users and 1 guest