Has anyone successfully hacked 3D FireMonkey to use an orthographic projection instead of the normal perspective projection? (That is, a 3D view where objects do not get smaller with distance.)

Has anyone successfully hacked 3D FireMonkey to use an orthographic projection instead of the normal perspective projection? (That is, a 3D view where objects do not get smaller with distance.)

I got some way there a few months ago hooking some matrix and camera functions (thanks Delphi Detours!) but it's not perfect, and I haven't got picking working at all.

I would really like this and would give millions of internet points to anyone who has got it working.

(In fact until I found it didn't exist, I had expected FMX already had it - orthographic projections are widely used in business 3D apps. Marco Cantù, any chance in XE8? Or from an unreleased internal build?

Also, you may wonder if there is some connection between this question and the one I just asked about affine 2D transformations. Yes, because the polygon I want to draw is an orthographically projected rectangle, where I've done all the 3D work myself, have its four corners in 2D space, and want to draw it on a 2D FMX surface.)

#firemonkey   #orthographic  #3d

Comments

  1. Hasan Ali Ayar 
    I guess your test cases involve normalized coordinates only?
    What happens if you change a, b, and c,
    such that the model coordinates are no longer normalized?
    I introduced this new hurdle into the test case,
    and solved it, but so far only in the test.

    //Model
    var a,b,c: single; //all 1.0 for normalized coordinates
      Vertices[0] := Point3D(+0.5*a, +0.5*b, -0.5*c);
      Vertices[1] := Point3D(-0.5*a, -0.5*b, -0.5*c);
      Vertices[2] := Point3D(+0.5*a, -0.5*b, +0.5*c);
      Vertices[3] := Point3D(-0.5*a, +0.5*b, +0.5*c);

    //The mesh is then created with Width, Height, Depth = 1.0
    //The mesh is then scaled with Model.Scale 

    In TContext3D.Pick I introduced local var sx, sy: single
      sx := -(1.0 + FCenterOffset.X - (2.0 * (X / FWidth )));
      sy :=  (1.0 + FCenterOffset.Y - (2.0 * (Y / FHeight)));

    and I have the same for ortho:

      vPos := NullVector3D;
      matProj := GetProjectionMatrix;
      sx := sx / matProj.m11;
      sy := sy / matProj.m22;
      vNear := Vector3D(sx, sy, 1);
      RayPos := vNear;
      RayDir := Camera.AbsoluteDirection;

    The sign of vNear.Z may be different because of my camera settings.

    ReplyDelete
  2. Gustav Schubert 
    My last comment suggests the same solution with yours. Only vNear.Z is different as you stated.

    And yes, i did not test the code for non-normalized coordinates exclusively.

    ReplyDelete
  3. Testing if pick works properly can be a bit fuzzy.

    The intention of my last comment was to get confirmation that scaling is breaking the solution.

    I found that it is a good idea to test with non-normalized coordinates as well. I have combined the two test projects, the one for the orthographic camera and the other one for picking. In order to test if pick is working properly I move the mouse slowly towards the edge of the shape and see if the color of the shape changes when the mouse pointer touches the edge. I do this manually for different locations around the visible edge of the shape. Then I rotate the shape and test again.

    When the shape is not rotated it works perfectly in both ortho and perspective mode. When the shape is rotated, then it works still perfectly in ortho mode, using your solution Hasan Ali Ayar  , while it works only approximately in perspective mode, but it is still quite good in perspective mode, just not perfect.

    Next when I scale the object, it gets more interesting. At this point it seems necessary to specify what scaling means, what the test project looks like, which Delphi version is used, and how to make it work.

    ReplyDelete

Post a Comment