I'm showing a large map over a terrain. In the beginning the user sees the whole map from above (call it "position 0"). I want to create an animation before that, with the camera approaching the terrain from very far, up to the initial position (position 0). Only then the user will be able to control the camera with mouse and keyboard. The camera will also slow down as it approaches. The whole animation only needs to last 1 or 2 seconds.
I've tried following the first example of chapter 5 from osgCookbook (by Rui Wang & Xuelei Qian). My code is:
osg::Quat quad0;
controller->setTransformation(osg::Vec3(lonC,latC,800), quad0 ); // lonC and latC are central coordinates of the map. This works without the animation
// Animating the camera
osg::ref_ptr<osgAnimation::FloatLinearChannel> ch = new osgAnimation::FloatLinearChannel;
ch->setName( "euler" );
ch->setTargetName( "CamAnimCallback" );
osgAnimation::FloatKeyframeContainer* kfs = ch->getOrCreateSampler()->getOrCreateKeyframeContainer();
kfs->clear(); // why is this needed?
kfs->push_back( osgAnimation::FloatKeyframe(0.0, 800) ); // from up above...
kfs->push_back( osgAnimation::FloatKeyframe(1.0, 80) ); // down until it gets close to the map
osg::ref_ptr<osgAnimation::Animation> animation = new osgAnimation::Animation;
animation->setPlayMode( osgAnimation::Animation::ONCE );
animation->addChannel( ch.get() );
osg::ref_ptr<osgAnimation::UpdateMatrixTransform> updater = new osgAnimation::UpdateMatrixTransform("CamAnimCallback");
updater->getStackedTransforms().push_back( new osgAnimation::StackedTranslateElement("euler", osg::Vec3(lonC,latC,800)) ); // initial position
osg::ref_ptr<osgAnimation::BasicAnimationManager> manager = new osgAnimation::BasicAnimationManager;
manager->registerAnimation( animation.get() );
osgViewer::ViewerBase::Cameras cameras;
viewer.getCameras(cameras);
osg::Camera* camera = cameras[0];
camera->setUpdateCallback( updater.get() );
root->setUpdateCallback( manager.get() );
Then I tried to call the animation right before the main loop, and also after viewer.frame (running only once, due to "splash", that begins as true)
viewer.frame();
if( splash )
{
manager->playAnimation( animation.get() );
splash = false;
}
However, nothing worked. Any ideas or an example that does something like this?
Rodrigo.