[osg-users] update slave camera with frame scheme ON_DEMAND

Gianni Ambrosio g.ambrosio+osg at gmail.com
Tue Aug 4 07:49:16 PDT 2015


Hi All,
I have a global cross axes object that is not correctly updated calling frame() when frame scheme is set to ON_DEMAND.

Here some code.

I have a ViewerWidget that is a CompositeViewer:

class ViewerWidget : public osgQt::GLWidget, public osgViewer::CompositeViewer

In the constructor I create an osgViewer::View that is the main view. I create a CrossAxes object and set it as slave camera. I create a timer to call the update() method of GLWidget which internally calls paintEvent method. I enable the ON_DEMAND flag and set a NodeTrackerManipulator (here is a subclass, but I don't think the manipulator makes any difference)

ViewerWidget::ViewerWidget(...) {
   osgViewer::View* view = new osgViewer::View;
   addView(view);

   crosscamera = new CrossAxes(70.0);
   view->addSlave(crosscamera, false);
   view->setSceneData(root);
      
   connect(&timer, SIGNAL(timeout()), this, SLOT(update()));

   setRunFrameScheme(ON_DEMAND);
   
   getView(0)->setCameraManipulator(new viframework::viosg::NodeTrackerManipulator(getView(0)));
}

On paintEvent I check the frame scheme mode and checkNeedToDoFrame() before calling frame().

void ViewerWidget::paintEvent(QPaintEvent* iEvent)
{
   if (osgViewer::ViewerBase::CONTINUOUS == getRunFrameScheme() || true == checkNeedToDoFrame()) {
      frame();
   }
}

CrossAxes is an osg::Camera. Here is the constructor.

CrossAxes::CrossAxes(double iLength)
:  length(iLength)
{
   setReferenceFrame(osg::Transform::ABSOLUTE_RF);
   // only clear the depth buffer
   setClearMask(GL_DEPTH_BUFFER_BIT);
   // draw subgraph after main camera view.
   setRenderOrder(osg::Camera::POST_RENDER);
   // we don't want the camera to grab event focus from the viewers main camera(s).
   setAllowEventFocus(false); 
   // setup update callback, so we can update it's view matrix
   setUpdateCallback(new AxesCameraUpdateCallback);

   // put the axes under the hud transformation node
   osg::PositionAttitudeTransform* transform = new osg::PositionAttitudeTransform;
   transform->setPosition(osg::Vec3(0, 0, -(iLength*1.4))); // put "inside" the screen (z=-100) to avoid clipping
   transform->addChild(createAxesGeometry(length));
   transform->addChild(createAxesLabels(length));
   addChild(transform);
}

Now the problem. I implemented some defaults views to set point of view of 3D scene towards X+, X-, Y+, Y-, Z+, Z-. To do that I use for example:

void ViewerWidget::setViewTowardsXPlus()
{
   nodeTrackerManipulator->setTransformation(osg::Vec3d(-nodeTrackerManipulator->getDistance(), 0.0, 0.0), osg::Vec3d(0.0, 0.0, 0.0), nodeTrackerManipulator->getHomeUpPosition());
}

At the end of setTransformation there is a "view->requestRedraw()" call. 

The problem I see is that calling setViewTowardsXPlus() the 3D scene is updated correctly by the frame() call (I verified it is called indeed!) but the CrossAxes object is not updated. Unexpectedly, if I call frame() a second time also the CrossAxes is correctly updated.

Is there an obvious reason for that?

Regards,
Gianni

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








More information about the osg-users mailing list