/* -*-c++-*- * Copyright (C) 2008 Cedric Pinson * * This library is open source and may be redistributed and/or modified under * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or * (at your option) any later version. The full license is in LICENSE file * included with this distribution, and on the openscenegraph.org website. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * OpenSceneGraph Public License for more details. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include struct GeometryFinder : public osg::NodeVisitor { osg::ref_ptr _geom; GeometryFinder() : osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN) {} void apply(osg::Geode& geode) { if (_geom.valid()) return; for (unsigned int i = 0; i < geode.getNumDrawables(); i++) { osg::Geometry* geom = dynamic_cast(geode.getDrawable(i)); if (geom) { _geom = geom; return; } } } }; osg::Geometry* getShape(const std::string& name) { osg::Node* shape0 = osgDB::readNodeFile(name); GeometryFinder finder; shape0->accept(finder); return finder._geom.get(); } int main (int argc, char* argv[]) { osg::ArgumentParser arguments(&argc, argv); osgViewer::Viewer viewer(arguments); osgAnimation::Animation* animation = new osgAnimation::Animation; osgAnimation::FloatLinearChannel* channel0 = new osgAnimation::FloatLinearChannel; channel0->getOrCreateSampler()->getOrCreateKeyframeContainer()->push_back(osgAnimation::FloatKeyframe(0,0.0)); channel0->getOrCreateSampler()->getOrCreateKeyframeContainer()->push_back(osgAnimation::FloatKeyframe(1,1.0)); channel0->setTargetName("MorphNodeCallback"); channel0->setName("0"); osgAnimation::FloatLinearChannel* channel1 = new osgAnimation::FloatLinearChannel; channel1->getOrCreateSampler()->getOrCreateKeyframeContainer()->push_back(osgAnimation::FloatKeyframe(0,1.0)); channel1->getOrCreateSampler()->getOrCreateKeyframeContainer()->push_back(osgAnimation::FloatKeyframe(1,0.0)); channel1->setTargetName("MorphNodeCallback"); channel1->setName("1"); animation->addChannel(channel0); animation->addChannel(channel1); animation->setName("Morph"); animation->computeDuration(); animation->setPlaymode(osgAnimation::Animation::PPONG); osgAnimation::BasicAnimationManager* bam = new osgAnimation::BasicAnimationManager; bam->registerAnimation(animation); osg::Geometry* geom0 = getShape("morphtarget_shape0.osg"); if (!geom0) { std::cerr << "can't read morphtarget_shape0.osg" << std::endl; return 0; } osg::Geometry* geom1 = getShape("morphtarget_shape1.osg"); if (!geom1) { std::cerr << "can't read morphtarget_shape1.osg" << std::endl; return 0; } // initialize with the first shape osgAnimation::MorphGeometry* morph = new osgAnimation::MorphGeometry(*geom0); morph->addMorphTarget(geom0); morph->addMorphTarget(geom1); viewer.setCameraManipulator(new osgGA::TrackballManipulator()); osg::Group* scene = new osg::Group; scene->addUpdateCallback(bam); osg::Geode* geode = new osg::Geode; geode->addDrawable(morph); geode->addUpdateCallback(new osgAnimation::UpdateMorph("MorphNodeCallback")); scene->addChild(geode); viewer.addEventHandler(new osgViewer::StatsHandler()); viewer.addEventHandler(new osgViewer::WindowSizeHandler()); viewer.addEventHandler(new osgGA::StateSetManipulator(viewer.getCamera()->getOrCreateStateSet())); // let's run ! viewer.setSceneData( scene ); viewer.realize(); bam->playAnimation(animation); while (!viewer.done()) { viewer.frame(); } osgDB::writeNodeFile(*scene, "morph_scene.osg"); return 0; }