/* -*-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. * * Authors: * Cedric Pinson * jeremy Moles */ #include "AnimtkViewerKeyHandler" #include "AnimtkViewerGUI" #include #include #include #include #include #include #include #include #include #include #include #include #include #include const int WIDTH = 1440; const int HEIGHT = 900; osg::Geode* createAxis() { osg::Geode* geode = new osg::Geode(); osg::Geometry* geometry = new osg::Geometry(); osg::Vec3Array* vertices = new osg::Vec3Array(); osg::Vec4Array* colors = new osg::Vec4Array(); vertices->push_back(osg::Vec3(0.0f, 0.0f, 0.0f)); vertices->push_back(osg::Vec3(1.0f, 0.0f, 0.0f)); vertices->push_back(osg::Vec3(0.0f, 0.0f, 0.0f)); vertices->push_back(osg::Vec3(0.0f, 1.0f, 0.0f)); vertices->push_back(osg::Vec3(0.0f, 0.0f, 0.0f)); vertices->push_back(osg::Vec3(0.0f, 0.0f, 1.0f)); colors->push_back(osg::Vec4(1.0f, 0.0f, 0.0f, 1.0f)); colors->push_back(osg::Vec4(1.0f, 0.0f, 0.0f, 1.0f)); colors->push_back(osg::Vec4(0.0f, 1.0f, 0.0f, 1.0f)); colors->push_back(osg::Vec4(0.0f, 1.0f, 0.0f, 1.0f)); colors->push_back(osg::Vec4(0.0f, 0.0f, 1.0f, 1.0f)); colors->push_back(osg::Vec4(0.0f, 0.0f, 1.0f, 1.0f)); geometry->setVertexArray(vertices); geometry->setColorArray(colors, osg::Array::BIND_PER_VERTEX); geometry->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::LINES, 0, 6)); geometry->getOrCreateStateSet()->setMode(GL_LIGHTING, false); geode->addDrawable(geometry); return geode; } struct AnimationManagerFinder : public osg::NodeVisitor { osg::ref_ptr _am; AnimationManagerFinder() : osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN) {} void apply(osg::Node& node) { if (_am.valid()) return; if (node.getUpdateCallback()) { osgAnimation::AnimationManagerBase* b = dynamic_cast(node.getUpdateCallback()); if (b) { _am = new osgAnimation::BasicAnimationManager(*b); return; } } traverse(node); } }; struct AddHelperBone : public osg::NodeVisitor { AddHelperBone() : osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN) {} void apply(osg::Transform& node) { osgAnimation::Bone* bone = dynamic_cast(&node); if (bone) bone->addChild(createAxis()); traverse(node); } }; int main(int argc, char** argv) { osg::ArgumentParser arguments(&argc, argv); arguments.getApplicationUsage()->setApplicationName(arguments.getApplicationName()); arguments.getApplicationUsage()->setDescription(arguments.getApplicationName()+" is an example for viewing osgAnimation animations."); arguments.getApplicationUsage()->addCommandLineOption("-h or --help","List command line options."); arguments.getApplicationUsage()->addCommandLineOption("--drawbone","draw helps to display bones."); if (arguments.read("-h") || arguments.read("--help")) { arguments.getApplicationUsage()->write(std::cout, osg::ApplicationUsage::COMMAND_LINE_OPTION); return 0; } if (arguments.argc()<=1) { arguments.getApplicationUsage()->write(std::cout, osg::ApplicationUsage::COMMAND_LINE_OPTION); return 1; } bool drawBone = false; if (arguments.read("--drawbone")) drawBone = true; osgViewer::Viewer viewer(arguments); osg::ref_ptr group = new osg::Group(); osg::ref_ptr loadedmodel = osgDB::readRefNodeFiles(arguments); osg::Group* node = dynamic_cast(loadedmodel.get()); if(!node) { std::cout << arguments.getApplicationName() <<": No data loaded" << std::endl; return 1; } // Set our Singleton's model. AnimationManagerFinder finder; node->accept(finder); if (finder._am.valid()) { std::string playModeOpt; if (arguments.read("--play-mode", playModeOpt)) { osgAnimation::Animation::PlayMode playMode = osgAnimation::Animation::LOOP; if (osgDB::equalCaseInsensitive(playModeOpt, "ONCE")) playMode = osgAnimation::Animation::ONCE; else if (osgDB::equalCaseInsensitive(playModeOpt, "STAY")) playMode = osgAnimation::Animation::STAY; else if (osgDB::equalCaseInsensitive(playModeOpt, "LOOP")) playMode = osgAnimation::Animation::LOOP; else if (osgDB::equalCaseInsensitive(playModeOpt, "PPONG")) playMode = osgAnimation::Animation::PPONG; for (osgAnimation::AnimationList::const_iterator animIter = finder._am->getAnimationList().begin(); animIter != finder._am->getAnimationList().end(); ++animIter) { (*animIter)->setPlayMode(playMode); } } node->setUpdateCallback(finder._am.get()); AnimtkViewerModelController::setModel(finder._am.get()); } else { osg::notify(osg::WARN) << "no osgAnimation::AnimationManagerBase found in the subgraph, no animations available" << std::endl; } if (drawBone) { osg::notify(osg::INFO) << "Add Bones Helper" << std::endl; AddHelperBone addHelper; node->accept(addHelper); } node->addChild(createAxis()); AnimtkViewerGUI* gui = new AnimtkViewerGUI(&viewer, WIDTH, HEIGHT, 0x1234); osg::Camera* camera = gui->createParentOrthoCamera(); node->setNodeMask(0x0001); group->addChild(node); group->addChild(camera); viewer.addEventHandler(new AnimtkKeyEventHandler()); viewer.addEventHandler(new osgViewer::StatsHandler()); viewer.addEventHandler(new osgViewer::WindowSizeHandler()); viewer.addEventHandler(new osgGA::StateSetManipulator(viewer.getCamera()->getOrCreateStateSet())); viewer.addEventHandler(new osgWidget::MouseHandler(gui)); viewer.addEventHandler(new osgWidget::KeyboardHandler(gui)); viewer.addEventHandler(new osgWidget::ResizeHandler(gui, camera)); viewer.setSceneData(group.get()); viewer.setUpViewInWindow(40, 40, WIDTH, HEIGHT); return viewer.run(); }