[osg-users] multi camera rendering and pick issues

Emmanuel Roche roche.emmanuel at gmail.com
Wed Sep 24 06:28:41 PDT 2008


Okay, I think I have something here:

I started from my first call on my CompositeViewer::frame()

then we get in renderingTraversals() --> runOperations() [for the Contexts]
--> renderer::cull_draw() ---> SceneView::cull() and here we have:

        _cullVisitor->setTraversalMask(_cullMask);
        bool computeNearFar =
cullStage(getProjectionMatrix(),getViewMatrix(),_cullVisitor.get(),_rendergraph.get(),_renderStage.get());

        if (computeNearFar)
        {
            CullVisitor::value_type zNear =
_cullVisitor->getCalculatedNearPlane();
            CullVisitor::value_type zFar =
_cullVisitor->getCalculatedFarPlane();

_cullVisitor->clampProjectionMatrix(getProjectionMatrix(),zNear,zFar);
        }

And that's where my latest problem comes from !!! This cull visitor uses the
Cull mask to somehow update the projection matrix... (and sorry, I put
breakpoint on setProjectionMatrix(...) but not on getProjectionMatrix() :-(
I didn't notice the reference this function returns...).

And if I'm lucking this may also explain why everything is messed up when I
use sub cameras: the sub camera graph don't get into this cullstage for the
main camera, do they ? and if not, the main projection gets corrupted the
same way and then since the "Root group" is not entered, the sub cameras are
not reached any way (or they can be sometimes because of those corrupted
projections) !!! So everything is clear now :-D [I've just made a simple
check with a sub camera instead of an hidden group].

Now that the problem is clarified, the big question is: What's the best
option to achieve the desired behavior (hide a node and still be able to
intersect with it, or use sub cameras) ???

I hope this little monologue may help other people stuck on that issue too
(if any :-) )


regards,
Manu.





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

> Some more news:
>
> I reverted to OSG 2.2 (I have the same problems with that version), and
> retrieved a full debug support, first I'm trying to solve the latest problem
> I faced (with the hidden node described in my previous mail), I'm using a
> scene like that:
>
>
> - Main camera
>     - Root group
>         - Hidden group
>             - Position Attitude Transform
>                 - Geode (with a sphere geometry inside).
>
> - On the main camera I use a cull mask of 0x1
> - on the Hidden group I switch between node mask 0x100 [not visible]  and
> 0x101 [visible]
> - And my intersectionVisitor still uses the traversal mask 0x100
>
> I went through all the process step by step (now that I retrieved my debug
> support, thanks god :-) !!!), and the conclusion I have for the moment is:
>
> --> This is all a Projection Matrix story !!!!
>
> -> In the BAD case (when I hide the "hidden group") my proj matrix has a
> certain value when I start the call view->computeIntersection(x,y,hits,mask)
> and this matrix is used in the push_clone() function in
> IntersectionVisitor::apply(osg::Camera&) to create a cloned Intersector (and
> thus this new LineSegmentIntersector gets an incorrect _start vector and the
> call IntersectionVisitor::enter(osg::Node&) fails when trying to enter the
> "Root group", and no intersection is found !).
>
> Now, I tried to put a breakpoint on both
> Camera::setProjectionMatrix(osg::Matrixf/d& ) as this seems to be the only
> "entry point" to modify a camera projection matrix... But I just CAN'T get
> on the point when the good camera projection is *correctly* set !!! is
> that done some other way ??? I keep investigating, I have no choice any
> way...
>
> regards,
> Manu.
>
>
>
>
> 2008/9/24 Emmanuel Roche <roche.emmanuel at gmail.com>
>
> :-(... I'm really going to cry now...
>>
>> Guys, I tried something else and I feel like I'm loosing my mind:
>>
>> Since I cannot pick anything when traversing a sub camera, I tried to
>> build my scene this way:
>> - the main View camera  (with cull mask set to 0x1)
>>   - my root group
>>     - a sub camera (with node mask set to 0x1)
>>       - a PositionAttitudeTransform (with a scale set)
>>         - an object
>>     - An hidden group (with node mask set to 0x100)
>>       - a link to the SAME previous PositionAttitudeTransform object.
>>
>> ... With that I still have a proper display (the default node mask is
>> 0xFFFFFFFF): only my sub camera is rendered and the hidden group is not
>> visible as expected.
>>
>> then for my IntersectionVisitor I obviously use the traversal mask 0x100 :
>> this way I was expecting to traverse my main camera and the hidden group,
>> but none of the sub camera... and guess what ? It's just not working !!!!
>> :-( It works if I don't hide my hidden group (giving it a node mask of
>> 0x101, but of course this doesn't make sense considering the goal I
>> have....)... So the IntersectionVisitor traversal also depends on the cull
>> mask or something like that ? I could really use some explanations on
>> that...
>>
>> By the way I'm using OSG 2.6...
>>
>> regards,
>> Manu.
>>
>>
>>
>> 2008/9/23 Emmanuel Roche <roche.emmanuel at gmail.com>
>>
>>> Okay...
>>>
>>>  I think I tried everything I could think about, unsuccessfully...
>>> unfortunately, I'm currently on WinXP with Visual Studio and for some
>>> obscure reason, I just cannot get/use the debug symbols from some of the OSG
>>> libraries (maybe beacuse I'm accessing those functions introspectively
>>> though a Lua release binary ? not sure about all that...) an as a result I
>>> cannot go deeper into those tests :-(
>>>
>>> But I've just discovered a new fact: this is at least partially linked to
>>> the scale of my object, I tried the following scene graph:
>>>
>>> - the main View camera
>>>   - my root group
>>>     - a sub camera
>>>       - a PositionAttitudeTransform (with a scale set)
>>>         - an object
>>>
>>> ---> then depending on the scale applied in the PositionAttitudeTransform
>>> I can pick parts of my object or not : the bigger the scale, the closer to
>>> the object I need to be to get some intersections (and I'm not even sure
>>> those intersections are correct...). So could there be a scale factor not
>>> applied somewhere ?? Or maybe, since my main camera renders no objects its
>>> near/far planes are set to minimal values and then those settings are not
>>> modified accordingly when going though a sub camera in an
>>> intersectionVisitor [this could explain why I cannot select objects if I'm
>>> not very very close to them (and depending on their scale)...] ?
>>>
>>> Is there an other way to render Univers scale + high precision scenes
>>> without using multiple cameras as children ??? I did a quick test using
>>> ClearNodes and setting the only camera left to "DO_NOT_COMPUTE_NEAR_FAR",
>>> but the results are not good (it seems to me that the ClearNodes clear the
>>> color buffer even when I only set the DEPTH_BUFFER_BIT mask... I really
>>> don't get it...).
>>>
>>> regards,
>>> Manu.
>>>
>>>
>>> 2008/9/23 Emmanuel Roche <roche.emmanuel at gmail.com>
>>>
>>>> Hi Robert,
>>>>
>>>> unfortunately I don't think this an available option in my current
>>>> project: our software is already relying quite heavily on our current
>>>> CompositteViewer / View structure  (a view per window [using wxWidgets], a
>>>> camera manipulator, a single scene graph that should not be cut into pieces,
>>>> etc... and any way, I think there is a real problem here (expect if there is
>>>> still something I missed) so I think for me (in both cases) it's important
>>>> to solve this issue instead of just bypassing it.
>>>>
>>>> I hope you will find some time to give a deeper look to this thread
>>>> later ;-), meanwhile I'm not giving up: I checked the setSceneData(node)
>>>> methods and it's basically the same just a camera->addChild(node) call... so
>>>> I may have the finger on something [as I expected a noticable difference].
>>>> I'll keep you informed.
>>>>
>>>> regards,
>>>> Manu.
>>>>
>>>> 2008/9/23 Robert Osfield <robert.osfield at gmail.com>
>>>>
>>>> Hi Manu,
>>>>>
>>>>> I don't have the head for complex emails or logic right now, so I
>>>>> won't five into the details of thread.  What does jump out from speed
>>>>> reading this email is why you don't use osgViewer::CompositeViewer
>>>>> with multipler Views as this would totally clear up an ambiguity about
>>>>> what camera each intersection test is made against.
>>>>>
>>>>> Robert.
>>>>>
>>>>> On Tue, Sep 23, 2008 at 5:42 PM, Emmanuel Roche
>>>>> <roche.emmanuel at gmail.com> wrote:
>>>>> > 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.
>>>>> >>
>>>>> >
>>>>> >
>>>>> > _______________________________________________
>>>>> > osg-users mailing list
>>>>> > osg-users at lists.openscenegraph.org
>>>>> >
>>>>> http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
>>>>> >
>>>>> >
>>>>> _______________________________________________
>>>>> osg-users mailing list
>>>>> osg-users at lists.openscenegraph.org
>>>>>
>>>>> http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
>>>>>
>>>>
>>>>
>>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.openscenegraph.org/pipermail/osg-users-openscenegraph.org/attachments/20080924/615703a6/attachment-0003.htm>


More information about the osg-users mailing list