[SOLVED] Frustum calcs for switching between Parallel and Ortho Projections

Hi All,
Hope everyone had/is having a nice holiday with plenty of “Nog” :wink:

I’m making an editor [everyone does] :wink: and since I enjoy Blender, that is what my editor is based upon. At present I have all the basic functionality (very basic) of the viewing using the keypad to rotate, roll, switch between views but here is the wall I’ve run up against and it might be the “Nog”.

When I toggle between Perspective and Orthographic (Perspective/Parallel) projections (I’ve used renderManager.setCamera(cam, true/false) which I have read the docs about the steps that uses, also I’ve used the cam.setParallelProjection(true/false)…) and both are smack on as to changing modes which is great but as I see in the Docs for the renderManager

Blockquote
First, the camera’s view port parameters are applied. Then, the camera’s view and projection matrices are set on the renderer. If ortho is true, then instead of using the camera’s view and projection matrices, an ortho matrix is computed and used instead of the view projection matrix. The ortho matrix converts from the range (0 ~ Width, 0 ~ Height, -1 ~ +1) to the clip range (-1 ~ +1, -1 ~ +1, -1 ~ +1).
Parameters:
cam - The camera to set
ortho - True if to use orthographic projection (for GUI rendering), false if to use the camera’s view and projection matrices.

Note: Many thanks to the engine showing “Your topic is similar to…” which is VERY useful but I’m unable to find my answer to the question which is;

When I change modes the frustum is changed (of course, and as expected) to where the camera seems either VERY close to the box in the centre of my grid (ORTHO/PARALLEL) or VERY far away when in Perspective…again this is expected but here is where I’m banging my head…HOW do I account for the projection changes so that, like in Blender, when in EITHER mode the camera shows the view at the same distance/depth.

That “should” be easy to accommodate but I sure as heck am at an impasse for the last 2 days on how to make the PERSPECTIVE/PARALLEL(ORTHO) projections appears as they do in Blender.

Many thanks in advance for some insight or just straight out formula for making the mode toggle to view like in Blender (equidistant in either mode).

Adam

In ortho, there is no such thing as “near” and “far”. All distances are… orthographic… ortho. No foreshortening based on distance, etc…

If you mean that it looks bigger or smaller then that’s entirely about where the sides of the frustum are.

1 Like

Hi @pspeed,
Thanks for the reply!

Yes, I might have worded it so that it sounded inept, but I did know about that for when I “Zoom” I am using a snippet from the zoom method in FlyCam

‘’’

   // derive fovY value
    float h = cam.getFrustumTop();
    float w = cam.getFrustumRight();
    float aspect = w / h;

    float near = cam.getFrustumNear();

    float fovY = FastMath.atan(h / near)
            / (FastMath.DEG_TO_RAD * .5f);
    float newFovY = fovY + value * 0.1f * zoomSpeed;
    if (newFovY > 0f) {
        // Don't let the FOV go zero or negative.
        fovY = newFovY;
    }

    h = FastMath.tan(fovY * FastMath.DEG_TO_RAD * .5f) * near;
    w = h * aspect;

    cam.setFrustumTop(h);
    cam.setFrustumBottom(-h);
    cam.setFrustumLeft(-w);
    cam.setFrustumRight(w);

‘’’
Note: Thanks @nehon for “again” posting on how to properly insert code…WORKS like a charm!!!

So I’ll play with it and see if can get the “seems near/far” (a wording I wish I didn’t use, though ‘near’ IS in the code) to fit with what I was hoping someone had already got their feet wet with.

All the best,

Adam

Here’s an excerpt from the camera update code I use in Maud:

            float far = 10f * range;
            float near = 0.01f * range;
            boolean parallel = status.isParallelProjection();
            if (parallel) {
                float halfHeight = 0.4f * range;
                float halfWidth = aspectRatio * halfHeight;
                camera.setFrustumBottom(-halfHeight);
                camera.setFrustumFar(far);
                camera.setFrustumLeft(-halfWidth);
                camera.setFrustumNear(near);
                camera.setFrustumRight(halfWidth);
                camera.setFrustumTop(halfHeight);
                camera.setParallelProjection(true);
            } else {
                float yDegrees = status.getFrustumYDegrees();
                camera.setFrustumPerspective(yDegrees, aspectRatio, near, far);
            }

Hi @sgold,

Many thanks for the speedy :wink: reply!!!

I’ll sift through that and get right back to you for I am still scratching my head over something that SHOULD (at least for myself) be easy. I just made a quick input mapping to F7 for debugging to see where I am at with the current frustum in Parallel then Projection and am perplexed over what I got which is;

Note: TBLR is Top, Bottom, Left, Right, with NF the Near/Far clipping planes

ORTHO: with

    cam.setParallelProjection(true); //Ortho ON
    cam.setLocation(new Vector3f(10f, 4f, 10f)); //Camera placement
    cam.lookAt(CENTER, Vector3f.UNIT_Y); //Looking @center

TBLR(h,-h,-w,w): 0.41421357, -0.41421357, -0.6059353, 0.6059353
NF: 1.0, 1000.0

PERSP: with

    cam.setParallelProjection(false); //Ortho OFF, Perspective ON
    cam.setLocation(new Vector3f(10f, 4f, 10f)); //Camera placement
    cam.lookAt(CENTER, Vector3f.UNIT_Y); //Looking @center

Though “Zoomed” to make it appear equidistant.
Got it (zoom amount) darn spot on for the “equi-distance”.

TBLR(h,-h,-w,w): 0.41421357, -0.41421357, -0.6059353, 0.6059353
NF: 1.0, 1000.0

The Near/Far was expected (just wanted all to know where my sub-conscious brought that wording into my initial post of which I apologize for looking inept).

The

SIDES of the frustum are EQUAL in both projection modes, hence the pointing out of where they are, well they are same though I am “zooming” to where both projections get the “equidistant” appearance that Blender does of which I’m trying to emulate…Gosh, everything thing else I am putting into this editor to make a mini Blender for JME is working like a charm, just the “frustum frustration” with my foggy head…

Many thanks @sgold for the snippet which I’ll pop in and see what comes up…stand by :wink:

Adam

Hi @sgold

I can see where your surname comes in handy for the snippet (MANY THANKS) is (pun intended but happy) Pure Gold!

The testing for which mode;

Is Awesome and so obvious I overlooked such in trying to brute force my way through…I should have stepped away from the problem and let my sub-processors work on that.

Anyway the

Section is exactly what I thought it should be and MANY thanks for the snippet to brace up this tired brain.

The…

… is EXACTLY what I was looking for, just over/under thinking on pounding my square peg into the proverbial round hole.

I do have ONE (MANY THANKS!!!) question ONLY to affirm/confirm that my thought processes are “on target” which is;

in “status” the method for calculating “getFrustumYDegrees” (THAT WAS THE KEY!!!):

How, did you code (or just the formula, to make sure I’m thinking in parallel) to get the “KEY” of “YDegrees”???

Mine is close, but for my notebook (always use one everybody, never failed me in 35+ years since I was taught to always have one on any project) what is the formula or code to get the “yDegrees” which IS THE ANSWER!!!

WooHoo and MANY THANKS!!!

I look forward to comparing notes/code for the yDegrees calculation!!!

Again, MANY THANKS and looking forward!!!

(a very happy) Adam

Edit Reason:
UPDATE!!!

PS: MAUD “Rocks”!!!

I am looking at the code from GitHub in order to answer my question of where the “yDegrees” calc came from…Gosh I’m over working myself and totally missed that (well, and a LOT of others…More NOG please :wink: )

Also sent a request to be an A-Tester for Maud (she rocked the 70’s and you bring her into the light again) MANY thanks on MANY levels!!!

Adam

y degrees should be your FOV… it shouldn’t really change after initial camera setup unless you really do want your FOV to change (and go from fisheye to zoom, etc.)

But note that they should not be. In projection, the sides of the frustum control something different than they do in ortho. I think you are starting to see that from sgold’s example. In ortho, put the sides far apart and your model will be smaller looking because you are viewing more space. Put them closer together, model gets bigger because you are viewing less space.

In perspective, the frustum parameters basically control the angle of view… which is different.

The planes represented by the two approaches will intersect at some point… Probably at m11 in the projection matrix… which is: (2 * Zn) / camHeight
…but I could be speaking out of my butt on that one. That’s the distance where one unit on screen is the same as one unit in perspective space. It may be irrelevant to this discussion.

2 Likes

Hi @pspeed,

Thanks for the;

I guess I’m over working myself and under thinking.

Also GREAT point on the

!!! Many thanks for pointing that out…What a year its been!!! Just trying to put 5 months of back logged (I’m working for myself but that is harder than for someone else most times) milestones accomplished before the YIKES 2018…That’s a “Star Trek” year!!! Seems like yesterday I was watch Kirk, Spock and the gang LIVE!!! Where does it go??? (Academic question)

I sure appreciate your and @sgold 's replies for this is what MAKES the JME community just that a “COMMUNITY” which is awesome!!!

Well off to Non-fisheye :wink: the FOV and get the y degrees spot on!!! Then a REAL “NOG” or few!!!

Again MANY thanks to you two!!!

Have the happiest rest of the holidays and a great year ahead…But I WILL get back to you before that to confirm ALL IS WELL :joy:

Adam

Well Many thanks to @sgold & @pspeed for pointing out the FOV which was the KEY to keeping the view the same in BOTH “perspective” & “parallel”!!!

Consider this one a lesson, especially for me, for it was so obvious (in hindsight, uh…20/20???) and MANY THANKS, I had the KEYS in my HANDS the whole time but was still searching the house to find them to get the car running…Like looking for my glasses whilst wearing them…INDEED!!!

Hey you two, MANY thanks, the Monkey Community is so fortunate to have people like yourselves there to lend a hand and NOW it’s all done and over, written in my notebook and logged in a VERY short 24 hour period!!!

My hats off to you Gents!!!

Consider this closed and Have a great rest of the Holidays and weekend…MANY THANKS!!!

Adam

2 Likes

As pspeed said, yDegrees measures the field of view. It’s measured on the screen’s vertical (Y) axis, in degrees; hence the name. In Maud, the field of view is currently fixed at 45 degrees, so the invocation of getFrustumYDegrees() could be optimized away.

though there is an example of that in TestParallelProjection in the engine.
With the code for zooming in and out

1 Like

Hi @nehon

In my original post (that could have been worded differently) YOU actually got exactly what I was thinking (THANKS!!!) and the code snippet you provided is BANG ON!!!

@sgold & @pspeed, I REALLY appreciate your input and @nehon YOU had the exact answer I was looking for THANKS!!!

I had misplaced my OpenGL Red Book which has the formulae and ideas behind it so that I could have figured it out but (gee, there is a web???) forgot to get a PDF version from the web to where it is not solely the FOV but is a make up of, well, exactly what you, @nehon, have in the TestParallelProjection.java code…again MANY THANKS, for that is what I was “posting” and you read it correctly…I toast you, and owe you a pint or more :wink: !!!

For anyone that needs, as I did and read before posting, oh and processing the salient points from TestParallelProjection.java, here is the online version that explains EXACTLY what I was looking for and is exactly represented in the code.

http://www.glprogramming.com/red/chapter03.html#name3

Note: There is PDF versions of the book to download (I am a physical book reader and didn’t look for the PDF which I now have, whew!) and the above link has GREAT illustrations WITH formulae to solve the projection switching conundrum I was having!

Many thanks to all for helping and @nehon who didn’t pick apart the semantics of what I was trying to get across and went straight for the answer!!!

What a way to end the year, MANY THANKS!!!

Adam

1 Like

Hi @sgold

Yeppers, I did exactly that with a 45 degree input then played with it.
I really appreciate your help!!!

I was looking for my “Red Book” and here is the specs for reference with great illustrations.

http://www.glprogramming.com/red/chapter03.html#name3

I sure appreciate you diving in and lending a hand and will do the same to help you and Mrs. Findlay

My project for me for now is to create a mini Blender then an “nbm” for others to use which eventually will be a level/scene editor with all the trimmings as in a real stage setup with cues, triggers, dolly, lighting, etc. but more on that on a different thread.

Many thanks and a Happy New Year!!!

Adam

It’s worth taking a tour through all of the test examples. They are included with the SDK and I learned 100 different JME things when I first started by looking through those. Render to texture? There. Reflection? There. Basic networking? There. (though that last one is a bit unfair because I wrote it. :))

2 Likes

Hi @pspeed

Yeppers, and not biased but very helpful!

I had a reply but the system (i.e. myself) messed up a tad bit.

What I wrote and am now writing is that MANY THANKS for showing the Test* programs.

I had honestly thought that they were in the JavaDocs as remnants of old code that didn’t get culled, hence why I overlooked them and MANY thanks for pointing them out with MANY thanks to whomever left them in there, that is some VERY helpful code snippets!!!

I will DEFINITELY look to the Test* snippets before posting albeit this has been a nice experience with being in contact with some VERY nice people!!!

Many thanks @pspeed for pointing these out and pointing me in the proper direction.

Have a great rest of the year and a Great and Happy New Year!!!

Adam