[osg-users] multi camera rendering and pick issues

Emmanuel Roche roche.emmanuel at gmail.com
Tue Sep 23 09:42:30 PDT 2008


Hello again...

I did other tests, my idea was:

I have a single main camera displaying a root object [an osg::Group] and
this root object contains 5 or 6 osg::Camera object as direct children. And
those "sub cameras" contain pieces of the scene I want to display. Since (I
don't know why, but) using an IntersectVisitor gives completely incorrect
result on the main camera in that case, I decided to use my
intersectionvisitor with each sub camera one by one... in that case
everything should behave as if each of my sub camera was the root object
when it's traversed, no ?... but the answer is: NO... :-( this case doesn't
seem to be the same as using a single camera containing objects as the
intersection results are still completely false

So my big question is now : what's the difference (from a "camera point of
view when it comes to intersections") between view->setSceneData(node) and
camera->addChild(node) ??? I keep investigating... :-) but any shortcut
would really be appreciated :-).

regards,
Manu.

PS: here is the main part of the code concerning the previous idea I
mentioned if someone wants to have a look...

    osg::Camera* cam = view->getCamera();
    osg::Matrixd vm;
    osg::Matrixd pm;
    osg::ref_ptr<osg::Viewport> vp;

    osgUtil::LineSegmentIntersector::Intersections hits;

    vDisplay::DisplayManager::CameraDeq& cams =
vDisplay::DisplayManager::getRegisteredCameras(view);
    for(vDisplay::DisplayManager::CameraDeq::iterator it = cams.begin(); it
!= cams.end(); ++it) {

        osgUtil::LineSegmentIntersector::CoordinateFrame cf =
osgUtil::Intersector::PROJECTION; //(*it)->getViewport() ?
osgUtil::Intersector::WINDOW : osgUtil::Intersector::PROJECTION;
        osg::ref_ptr< osgUtil::LineSegmentIntersector > picker = new
osgUtil::LineSegmentIntersector(cf, x, y);

        //osgUtil::IntersectionVisitor iv(picker.get());
        vOGL::ExtendedIntersectionVisitor iv(picker.get());
        iv.setTraversalMask(0xFFFFFFFF);

        // Reconfigure the camera:
        vm = (*it)->getViewMatrix();  // these are actually identity
matrices as only the main camera is manipulated....
        pm = (*it)->getProjectionMatrix();
        vp = (*it)->getViewport();

        (*it)->setViewMatrix(cam->getViewMatrix());
        (*it)->setProjectionMatrix(cam->getProjectionMatrix());
        (*it)->setViewport(cam->getViewport());

        if ((*it)->getViewport()) iv.pushWindowMatrix( (*it)->getViewport()
);
        iv.pushProjectionMatrix( new
osg::RefMatrix((*it)->getProjectionMatrix()) );
        iv.pushViewMatrix( new osg::RefMatrix((*it)->getViewMatrix()) );
        iv.pushModelMatrix( new osg::RefMatrix() );

        (*it)->accept(iv);

        iv.popModelMatrix();
        iv.popViewMatrix();
        iv.popProjectionMatrix();
        if ((*it)->getViewport()) iv.popWindowMatrix();

        (*it)->setViewMatrix(vm);
        (*it)->setProjectionMatrix(pm);
        (*it)->setViewport(vp.get());

        if (picker->containsIntersections())
        {
            hits = picker->getIntersections();
            vLog::logInfo("Got %d intersections",hits.size());
            return true;
        }
    }




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/fc209a95/attachment-0003.htm>


More information about the osg-users mailing list