[osg-users] multi camera rendering and pick issues

Emmanuel Roche roche.emmanuel at gmail.com
Tue Sep 23 04:07:07 PDT 2008


Okay, more information on this issue I mentioned:

I tested a scene where I have only two satellites (not too far away, the
same size) in two different sub camera (still under the main camera): in
that case, using the "Test 2" implementation [treating the camera as a
simple Group] gives correct picking results.

So now, I think the second part of the problem I have in my "normal" scene
is due to the scale difference between the objects: in the main camera, I
have a subcamera containing an "Earth" model (radius ~= 6371 units, since I
use km as unit) and in an other subcamera I have my satellite (typical size
~= 0.001 units as the satellite has a small size in meters...)

using the subcam:setClearMask(GL.Mode.GL_DEPTH_BUFFER_BIT) statement is
enough to display everything correctly even with those geant scale
differences [actually I also have a "Sun" object in an other subcamera with
real size (695 500 units :-( ), and real distance from the earth (150 000
000 units !!! ) :-S ]... maybe this can lead to an overflow of the precision
when performing the intersection tests ??? do those tests use floats or
doubles ?

regards,

Manu.



2008/9/23 Emmanuel Roche <roche.emmanuel at gmail.com>

> Hi everyone,
>
> I have an interesting issue here:
>
> I'm building a scene this way (the following is a lua script using
> osgIntrospection to manipulate OSG stuff) :
>
> local root = osg.Group()
> root:setName("Universe")
>
> -- we want to add this root object as a scene in the current project
> (otherwise it will never be found)
> -- this root object will be assigned as the scenedata for the master
> camera.
> local proj = vProj.ProjectManager.instance():getCurrent()
> proj:add_Scene(root)
>
> local view = vDisplay.DisplayManager.getViewer():getView(0)  -- here,
> getViewer() returns our osgViewer::CompositeViewer object
> local manip =
> reflection.cast(view:getCameraManipulator(),"vGA::ArcBallManipulator")
>
> -- now create the LTS project:
> require('LTS')
>
> local cam = view:getCamera()  -- this is the "main" camera, the scene data
> for this camera is the previously declared "root" object
> local subcam = osg.Camera()  -- we create a sub camera than we will add to
> the main scene (so an inderect child for the main camera...)
> subcam:setGraphicsContext(cam:getGraphicsContext())
> subcam:setViewport(cam:getViewport())
> subcam:setRenderOrder(osg.Camera.RenderOrder.POST_RENDER,3) -- We post
> render this subcamera with an arbitrary order.
> subcam:setClearMask(GL.Mode.GL_DEPTH_BUFFER_BIT) -- We want to render
> Universe scale scenes that's why we introduced this multi pass system.
> root:addChild(subcam)
>
> local st = vOGL.SceneTools;
> local pat = osg.PositionAttitudeTransform()
> pat:addChild(LTS.createDoubleCraft("K1")) -- Here we create a satellit
> object
> subcam:addChild(pat) -- And we add the object to the sub camera...
>
>
> ... this scene is rendered perfectly... but now I'm trying to "pick" items
> in the scene using the implementation found in
> osgViewer::View::computeIntersections(...) : If I put my "K1" object
> directly "in" the "main" camera everything is perfect, and I can pick
> intersections correctly. But when using this "subcam"  as parent then I get
> incorrect results :-( (intersections found when clicking on nothing, or no
> intersections found when cliking on sub parts of the object...)
>
> I gave a look at the osgUtil::IntersectionVisitor implementation... and I
> think everything is happening in this function:
>
> void IntersectionVisitor::apply(osg::Camera& camera)
> {
>     // osg::notify(osg::NOTICE)<<"apply(Camera&)"<<std::endl;
>
>     // note, commenting out right now because default Camera setup is with
> the culling active.  Should this be changed?
>     // if (!enter(camera)) return;
>
>     // osg::notify(osg::NOTICE)<<"inside apply(Camera&)"<<std::endl;
>
>     if (camera.getViewport()) pushWindowMatrix( camera.getViewport() );
>     pushProjectionMatrix( new osg::RefMatrix(camera.getProjectionMatrix())
> );
>     pushViewMatrix( new osg::RefMatrix(camera.getViewMatrix()) );
>     pushModelMatrix( new osg::RefMatrix() );
>
>     // now push an new intersector clone transform to the new local
> coordinates
>     push_clone();
>
>     traverse(camera);
>
>     // pop the clone.
>     pop_clone();
>
>     popModelMatrix();
>     popViewMatrix();
>     popProjectionMatrix();
>     if (camera.getViewport()) popWindowMatrix();
>
>     // leave();
> }
>
> I created my own "ExtendedIntersectorVisitor" (derived from this class) to
> override this function and I made multiple tests to handle the "main" camera
> and the "sub" cameras differently:
>
> void ExtendedIntersectionVisitor::apply(osg::Camera & camera) {
>     if(!cameraInitialized) {
>         cameraInitialized = true;
>         // The first time we get a camera object we use it to setup the
> camera details normaly:
>
>         if (camera.getViewport()) pushWindowMatrix( camera.getViewport() );
>         pushProjectionMatrix( new
> osg::RefMatrix(camera.getProjectionMatrix()) );
>         pushViewMatrix( new osg::RefMatrix(camera.getViewMatrix()) );
>         pushModelMatrix( new osg::RefMatrix() );
>
>         // now push an new intersector clone transform to the new local
> coordinates
>         push_clone();
>
>         traverse(camera);
>
>         // pop the clone.
>         pop_clone();
>
>         popModelMatrix();
>         popViewMatrix();
>         popProjectionMatrix();
>         if (camera.getViewport()) popWindowMatrix();
>     }
>     else {
>         // here I did multiple tests (one by one):
>
>         // Test 1: treat the camera as a transform  (took implementation
> from IntersectionVisitor::apply(osg::Transform&) )
>         if (!enter(*(camera.asTransform()))) return;
>
>         osg::ref_ptr<osg::RefMatrix> matrix = _modelStack.empty() ? new
> osg::RefMatrix() : new osg::RefMatrix(*_modelStack.back());
>         camera.computeLocalToWorldMatrix(*matrix,this);
>
>         pushModelMatrix(matrix.get());
>
>         // now push an new intersector clone transform to the new local
> coordinates
>         push_clone();
>
>         traverse(camera);
>
>         // pop the clone.
>         pop_clone();
>
>         popModelMatrix();
>
>         // tidy up an cached cull variables in the current intersector.
>         leave();
>        // End of Test 1
>
>        // Test 2: treat the camera as a osg::Group only!
>         if (!enter(*(camera.asGroup()))) return;
>
>         traverse(*(camera.asGroup()));
>
>         leave();
>        // End of test 2
>
>        // Test 3: just try not to push the model matrix, view matrix,
> projection or viewport, one by one:
>
>         if (camera.getViewport()) pushWindowMatrix( camera.getViewport() );
>         pushProjectionMatrix( new
> osg::RefMatrix(camera.getProjectionMatrix()) );
>         pushViewMatrix( new osg::RefMatrix(camera.getViewMatrix()) );
>         //pushModelMatrix( new osg::RefMatrix() );
>
>         // now push an new intersector clone transform to the new local
> coordinates
>         push_clone();
>
>         traverse(camera);
>
>         // pop the clone.
>         pop_clone();
>
>         //popModelMatrix();
>         popViewMatrix();
>         popProjectionMatrix();
>         if (camera.getViewport()) popWindowMatrix();
>         // End of Test 3
>     }
> }
>
>
> .. But none of this tests gave interesting result :-(... I really don't
> know where this problem may comes from then, and I really need to be able to
> pick objects in a Camera containing other sub cameras :-S. Do you have any
> clue about all that ? What am I doing wrong ?
>
> regards,
> Manu.
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.openscenegraph.org/pipermail/osg-users-openscenegraph.org/attachments/20080923/38d14c60/attachment-0003.htm>


More information about the osg-users mailing list