Hi Robert,
I'd realized osgProducer had this problem. I've put off dealing with
this part of my project until osgViewer became ready in the hope that
it could be made cleaner :-)
I can see that having a custom advance() should have the desired
effect, and I'll hack that in now. Are you open to adding "double
_simulationTime" to FrameStamp ? I just did a quick grep around and it
doesn't seem as though FrameStamp's are used in too many places
across OSG os it shouldn't be too much work to add it in. Then Viewer
could have an overloaded frame() and advance() methods, something like
...
class osgViewer
{
void frame()
{
...
advance();
...
}
void frame(double simulationTime)
{
// ...
advance(simulationTime);
// ...
}
void advance()
{
...
double t = osg::Timer::instance()->delta_s(_startTick,
osg::Timer::instance()->tick()) ;
_frameStamp->setReferenceTime(t);
_frameStamp->setSimulationTime(t);
_frameStamp->setFrameNumber(_frameStamp->getFrameNumber()+1);
...
}
void advance(double simulationTime)
{
...
double t = osg::Timer::instance()->delta_s(_startTick,
osg::Timer::instance()->tick()) ;
_frameStamp->setReferenceTime(t);
_frameStamp->setSimulationTime(simulationTime);
_frameStamp->setFrameNumber(_frameStamp->getFrameNumber()+1);
...
}
};
Then update traversals will be driven from _frameStamp->getSimulationTime().
Another way that this could be added in would be to have a notion of
an "external" frame stamp that could be driven from outside of the
Viewer. Something along the lines of -
class Viewer
{
Viewer() :_useExternalFrameStamp(false) ...
void setFrameStamp(osg::FrameStamp* frameStamp)
{
_useExternalFrameStamp = true;
_frameStamp = frameStamp;
}
// probably another function to switch this off ...
void useInternalFrameStamp();
void advance()
{
if (_done) return;
double prevousReferenceTime = _frameStamp->getReferenceTime();
int previousFrameNumber = _frameStamp->getFrameNumber();
if (!_useExternalFrameStamp)
{
double t = osg::Timer::instance()->delta_s(_startTick,
osg::Timer::instance()->tick()) ;
_frameStamp->setReferenceTime(t);
_frameStamp->setSimulationTime(t);
_frameStamp->setFrameNumber(_frameStamp->getFrameNumber()+1);
}
... etc ...
}
protected:
bool useExternalFrameStamp;
osg::ref_ptr<osg::FrameStamp> _frameStamp;
...etc...
};
In some ways the second seems a bit cleaner, no need to overload on methods.
BTW I notice that Viewer::setFrameStamp() isn't implemented at the
moment. I guess it doesn't make any sense to have it while advance()
is assuming it's operating on the it's own internally allocated
FrameStamp.
I would be happy to have a go at implementing this. Thoughts ?
-Drew
On 1/24/07, Robert Osfield <[EMAIL PROTECTED]> wrote:
Hi Drew,
As Richard suggest what we really need is a FrameStamp with both a
"real time" ReferenceTime and the possibility of SimulationTime. I
suggested this in another thread during the last couple of weeks.
However, all is not lost... osgViewer::Viewer and osgProducer::Viewer
both share the same use of osg::FrameStamp that controls the
ReferenceTime. In the case of osgViewer::Viewer there is a
getFrameStamp() method that you can use to set the time yourself. The
only cavate is that the Viewer::advance() method called by
Viewer::frame() updates the ReferenceTime. So what you need to do is
either not call advance() or simply update the FrameStamp after
advance is called.
If you look at Viewer::frame() you'll see its pretty straight forward,
the bits that do the hard word each frame are:
advance();
eventTraversal();
updateTraversal();
renderingTraversals();
You could easily just calls these in your main loop instead of calling
frame. i.e.
viewer.realize();
viewer.init();
while(!viewer.done())
{
viewer.advance();
viewer.getFrameStamp()->setReferenceTime(myTime);
viewer.eventTraversal();
viewer.updateTraversal();
viewer.renderingTraversals();
}
Another alternative is to subclass from osgViewer::Viewer and override
the advance() method as it virtual - like the rest of the above Viewer
methods, this is done so you can customize things just the way you
want. This route would allow you to continue calling frame() and have
your custom advance() done automatically.
The only downside to playing around with FrameStamp's ReferenceTime
would be the syncing of events and stats collection as they be
advancing in real time, not your modified time. Try it though and see
what happens :-) FYI, osgProducer::Viewer will had the same
problems w.r.t events and stats. Its this reason why FrameStamp
SimulationTime would be useful.
Robert.
_______________________________________________
osg-users mailing list
[email protected]
http://openscenegraph.net/mailman/listinfo/osg-users
http://www.openscenegraph.org/
--
Drew Whitehouse
ANU Supercomputer Facility Vizlab
_______________________________________________
osg-users mailing list
[email protected]
http://openscenegraph.net/mailman/listinfo/osg-users
http://www.openscenegraph.org/