[osg-users] objects not showing when zoomed in (orthographic projection)

189 views
Skip to first unread message

Ron Mayer

unread,
Jul 16, 2012, 11:51:36 AM7/16/12
to osg-...@lists.openscenegraph.org
Hi,

I am trying to solve a problem we posted before here (http://forum.openscenegraph.org/viewtopic.php?p=47733#47733).

My application starts without touching the zoom level only setting the camera projection and view matrices (frustum and look-at position).
My program then adds an 'x' made out of 2 lines to the scene, but the 'x' does not show until I zoom out and another object appears in the view.
I am using orthographic projection, and zooming is done by adjusting the camera's frustum (right left top bottom) by a factor.

Here is a picture (ignore the green cross-hair):

[Image: http://img839.imageshack.us/img839/1662/disappearingobj.jpg ] (http://imageshack.us/photo/my-images/839/disappearingobj.jpg/)

If I zoom in - it goes away ... zoom out, shows the moment the other object is in the view. If I play with the zoom for a while, eventually the 'x' does not go away anymore.
I also tried it with another graphic object (not an 'x') to make sure it is not the lines of the 'x', but the problem shows also in the other objects.



Things I tried to fix the problem (and did not work):

- As to Paul Martz's suggestion - tried turning off AutoTransform.

- Also tried Paul's second suggestion - debugging the projection and view matrices of our camera. I found out we were using a child class of TrackballManipulator, and that the projection and view matrices were modified by the manipulator in each frame call ... So I went and quickly wrote my own manipulator (inheriting from StandardManipulator). I looked at FirstPersonManipulator for help in implementing the get\set matrix\transformation methods.
In my implementation, the graphics camera should be looking at the z = 0 plane at any time (perpendicular to the plane), and the position is somewhere above the z=0 plane (these values are set by the application).Debugged this, and I noticed something (not me) is also changing the right,left,bottom,top of the camera's frustum. I am OK with this since the view matrix (camera location and orientation) is correct and not changed between frames. But still I could not understand why I can't see the 'x'!

- I thought the 'x' may be clipped out of the near\far of the frustum, so I tried setComputeNearFarMode(osg::CullSettings:O_NOT_COMPUTE_NEAR_FAR).

Any help is appreciated

Thank you!

Ron[/img]

------------------
Read this topic online here:
http://forum.openscenegraph.org/viewtopic.php?p=48873#48873





_______________________________________________
osg-users mailing list
osg-...@lists.openscenegraph.org
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org

Ron Mayer

unread,
Jul 16, 2012, 6:09:35 PM7/16/12
to osg-...@lists.openscenegraph.org
Hi,


Followup:
I tried isolating the problem by playing with the cull settings. I tried setting to
DO_NOT_COMPUTE_NEAR_FAR -

camera->setComputeNearFarMode(osg::CullSettings::DO_NOT_COMPUTE_NEAR_FAR);

also I turned off VIEW_FRUSTUM_SIDES_CULLING:

camera->setCullingMode(camera->getCullingMode() & ~osg::CullSettings::VIEW_FRUSTUM_SIDES_CULLING);

which the two together seemed to fix the problem. Though I can't submit this code since it would be very inefficient.

I am continuing to work on this, I will come back with updates if I find anything else.

Cheers,
Ron

------------------
Read this topic online here:
http://forum.openscenegraph.org/viewtopic.php?p=48880#48880

Robert Osfield

unread,
Jul 17, 2012, 6:43:52 AM7/17/12
to osg-...@lists.openscenegraph.org
Hi Ron,

My guess would be that it's an issue of near/far clipping. Personally
I wouldn't mix orthographic projection with a general purpose camera
manipulator as they are written for full 3D perspective views, and
when you moving in and out of the scene in a orthographic view things
won't work visually. The problem is a bit like trying use a hammer to
screw in a screw, as much as you might try it won't work properly.

For application I use orthographic views for map, isometric or side
elevation views where the viewer can move laterally but not into the
scene and would be very careful about introducing any allowing free
form rotation. If you want full movement in the scene you really
need a proper 3D view for visualization to behave correct as end users
would expect from a 3D environment, for this you really need to use a
perspective view.

Robert.

Ron Mayer

unread,
Jul 17, 2012, 11:29:12 AM7/17/12
to osg-...@lists.openscenegraph.org
Hi Robert and thanks for the reply

We actually want to display our scene as a map (or CAD-like view), with the ability to zoom in\out, and moving the camera laterally (no rotation or orbiting for this mode).
For zooming we do not move our camera into the scene at all. Instead, we achieve a ‘zooming’-like effect by expanding or contracting the [left,right, top, bottom] boundaries of the frustum (am I still using a hammer to screw in a screw?)

I suspect it may not be a near/far clipping problem since the problem persists even if I turn off near/far clipping (by setting DO_NOT_COMPUTE_NEAR_FAR).

The problem went away only after I turned off VIEW_FRUSTUM_SIDES_CULLING, which implies the ‘x’ object is getting culled by the side ‘walls’ of the orthographic frustum.

I would like to get some more insight into the cull traversal, to understand why it gets culled out. Is there a place I can look at to learn how the culling works?
I will be starting to debug Renderer::cull_draw(), not sure if that's the best place to look.

Thanks again
Ron

------------------
Read this topic online here:

http://forum.openscenegraph.org/viewtopic.php?p=48901#48901

Robert Osfield

unread,
Jul 18, 2012, 4:40:46 AM7/18/12
to osg-...@lists.openscenegraph.org
Hi Ron,

If the objects are being culled by the sides of the frustum then it
suggests that the bounding volumes of the objects are erroneous for
some reason. Culling is all done by the osgUtil::CullVisitor, you
could put break points in OpenSceneGraph/src/osgUtil/CullVisitor.cpp
to see what it's doing. Looking at the bounding volumes will be the
best place to look though, if there is dynamically scaled objects then
this may well be a good area to look at.

Robert.

Ron Mayer

unread,
Jul 18, 2012, 4:51:29 PM7/18/12
to osg-...@lists.openscenegraph.org
UPDATE:

Let me start by saying Paul was right 8) . It is the AutoTransform! The 'x' did not show when I turned off AutoTransform because it may have been obscured by another object, so I falsely thought it was not the AutoTransform.

I spent the day debugging the bound speheres for culling and I found the problem. Here is what happens:

1) I add the new 'x' to my scene with an AutoTransform and AutoScaleToScreen=true
2) frame() is called
3) OSG prepares for culling and calls scene->getSceneData()->getBound() to calculate the bounding sphere of the scene (ViewerBase.cpp line #760)
4) The graph gets traversed in a depth-first manner, recursevly computing the spheres
5) At some point our AutoTransform is reached, and computeBound() is called (Node line #366)
6) But allas, AutoTransform::computeBound() returns an invalid bound since the _firstTimeToInitEyePoint flag is true! (AutoTransform.cpp line #389)
7) The _firstTimeToInitEyePoint flag gets a false value only after the first CullVisitor has visited the AutoTransform, which happens only AFTER the computation of the bound returns (AutoTransform.cpp lines 199 - 229).
8 ) But at that time it is too late since the value of _boundingSphereComputed is set to true (Node line #370) so the invalid AutoTransform sphere does not get recalculated until later.

What I did is set a breakpoint in AutoTransform::computeBound(), and set _firstTimeToInitEyePoint to false inside the debugger, and then the 'x' showed.

So to summarize the problem - the implementation of AutoTransform::computeBound()will return a valid spehere only if the AutoTransform node was visited by the CullVisitor at least once, but since it is called before the culling, it caches an invalid transform.
I am not sure if this is a bug or because I may not be seeing the whole picture.

Our plan to solve this is writing our own BoundCallback and set it on the AutoTransform of our 'x'.
The new BoundCallback will return a small sphere (let's say radius 2, center 000) becuse our 'x' only represents a point in the space, and we want it to behave like a HUD element. This will also make the calculation of the bounding spheres of parent nodes of the 'x''s more accurate since it will take into account only the point in space with the small sphere around it.

If it works for us, it might be worth thinking about adding this solution to the osg code. But I need more guidance on that, so thank you again! :).


Cheers,
Ron

------------------
Read this topic online here:
http://forum.openscenegraph.org/viewtopic.php?p=48923#48923

Thrall, Bryan

unread,
Jul 18, 2012, 5:10:23 PM7/18/12
to osg-...@lists.openscenegraph.org
Ron Mayer wrote on 2012-07-18:
> So to summarize the problem - the implementation of
> AutoTransform::computeBound()will return a valid spehere only if the
> AutoTransform node was visited by the CullVisitor at least once, but
> since it is called before the culling, it caches an invalid transform.
I
> am not sure if this is a bug or because I may not be seeing the whole
> picture.

Does osg::Node::setInitialBound() help?

--
Bryan Thrall
Principal Software Engineer
FlightSafety International
bryan....@flightsafety.com

Ron Mayer

unread,
Jul 20, 2012, 9:08:41 AM7/20/12
to osg-...@lists.openscenegraph.org

bthrall wrote:
>
> Does osg::Node::setInitialBound() help?
>


Thanks Bryan,

Looks like that should work, but I did not try it because It seems like I had a second problem and I applied another fix for the 2 problems (next post).

------------------
Read this topic online here:
http://forum.openscenegraph.org/viewtopic.php?p=48955#48955

Ron Mayer

unread,
Jul 20, 2012, 9:34:42 AM7/20/12
to osg-...@lists.openscenegraph.org
UPDATE:

I did not end implementing my own BoundCallback since I found another problem in my code.

The parent node of the 'x' nodes are boundaries of different types, for example:

[root]
|
[boundary made of lines]
|
[3d boundary as a box]
/ | \
[x] [x] [x]

These boundaries are used to present the user with the boundaries of the area occupied by the 'x' objects.
Originally, I disabled the boundaries (just had them as transforms with no drawables) to isolate my 'x' problem (as described above).

But then when I went and added back the boundaries (with my fix of making sure _firstTimeToInitEyePoint was false) I found that the boundary boxes now were culled out of the scene!

So I continued debugging the calculation of bounding spheres and I found another problem - this time in our code.
To implement the dimensions of the boundary boxes we added a new NodeCallback on the boundary nodes. Each time an 'x' is added to the scene, we visited the graph upwards and marked the boundaries as dirty.
Then in the next frame, the callback would calculate the dimensions of the boundary by running an osg::ComputeBoundsVisitor on the sub-graph, and using the bounding box returned by the visitor to set the scale matrix of the boundary node.

When I was debugging I noticed we were scaling the boundary nodes to negative numbers, which made the radius an infinite value, and screwed up the bounding sphere calculation.

The problem is in the code of our boundary node callback:


Code:
// get the bounding box of all children contained in this boundingNode
osg::ComputeBoundsVisitor visitor;
boundingNode->accept(visitor);
osg::BoundingBox bb = visitor.getBoundingBox();

// scale and translate the boundingNode accordingly
osg::Matrixd translationTx = osg::Matrixd::translate(bb.center().x(), bb.center().y(), ourCenterZ);
osg::Matrixd scaleTx = osg::Matrixd::scale( (bb.xMax() - bb.xMin()) * scaleVector.x(), (bb.yMax() - bb.yMin()) * scaleVector.y(), ourZ);




In the last line of that code, it turned out the max value returned from the bounding box was to the left of the min value.
This made us scale in a negative number. (one would assume the min of a bounding box is always to the left of the max ...)

So I went and added fabs to the subtraction:


Code:
osg::Matrixd scaleTx = osg::Matrixd::scale( fabs(bb.xMax() - bb.xMin()) * scaleVector.x(), fabs(bb.yMax() - bb.yMin()) * scaleVector.y(), ourZ);



and everything showed correctly - our bounding nodes and the 'x' objects.
The only problem left is when the camera is over our boundary objects, I get these debug messages in the console:


> CullVisitor::apply(Geode&) detected NaN,
> depth=1.#QNAN, center=(0 0 0),
> matrix={
> -1.#IND -1.#IND -1.#IND -1.#IND
> -1.#IND -1.#IND -1.#IND -1.#IND
> 0 0 5 0
> 200 0 -2002.5 1
> }


which I am going to look into next.

Cheers!
Ron

------------------
Read this topic online here:
http://forum.openscenegraph.org/viewtopic.php?p=48957#48957
Reply all
Reply to author
Forward
0 new messages