[osg-users] multi camera rendering and pick issues

Emmanuel Roche roche.emmanuel at gmail.com
Tue Sep 23 14:51:50 PDT 2008


Oh, and by the way, the results seem to be exactly the same when I use the
osgUtil::IntersectVisitor instead of the new version... so, someone has a
clue ?

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/20080923/04c0eb7d/attachment-0003.htm>


More information about the osg-users mailing list