[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