// -*-c++-*- #include #include #include #include #include // // A simple demo demonstrating usage of osg::Sequence. // // simple event handler to start/stop sequences class MyEventHandler : public osgGA::GUIEventHandler { public: /// Constructor. MyEventHandler(std::vector* seq) { _seq = seq; } /// Handle events. virtual bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter&) { bool handled = false; if (ea.getEventType() == osgGA::GUIEventAdapter::KEYDOWN) { const char keys[] = "!@#$%^&*()"; for (unsigned int i = 0; i < (sizeof(keys) / sizeof(keys[0])); i++) { if (i < _seq->size() && ea.getKey() == keys[i]) { // toggle sequence osg::Sequence* seq = (*_seq)[i]; osg::Sequence::SequenceMode mode = seq->getMode(); switch (mode) { case osg::Sequence::START: seq->setMode(osg::Sequence::PAUSE); break; case osg::Sequence::STOP: seq->setMode(osg::Sequence::START); break; case osg::Sequence::PAUSE: seq->setMode(osg::Sequence::RESUME); break; default: break; } std::cerr << "Toggled sequence " << i << std::endl; handled = true; } } } return handled; } /// accept visits. virtual void accept(osgGA::GUIEventHandlerVisitor&) {} private: std::vector* _seq; }; osg::Sequence* generateSeq(osg::Sequence::LoopMode mode, float speed, int nreps, std::vector& model) { osg::Sequence* seqNode = new osg::Sequence; // add children, show each child for 1.0 seconds for (unsigned int i = 0; i < model.size(); i++) { seqNode->addChild(model[i]); seqNode->setTime(i, 1.0f); } // interval seqNode->setInterval(mode, 0, -1); // speed-up factor and number of repeats for entire sequence seqNode->setDuration(speed, nreps); // stopped seqNode->setMode(osg::Sequence::STOP); return seqNode; } int main( int argc, char **argv ) { // use an ArgumentParser object to manage the program arguments. osg::ArgumentParser arguments(&argc,argv); // set up the usage document, in case we need to print out how to use this program. arguments.getApplicationUsage()->setDescription(arguments.getApplicationName()+" is the example which demonstrates use of osg::Sequence."); arguments.getApplicationUsage()->setCommandLineUsage(arguments.getApplicationName()+" [options] filename ..."); arguments.getApplicationUsage()->addCommandLineOption("-h or --help","Display this information"); // construct the viewer. osgProducer::Viewer viewer(arguments); // set up the value with sensible default event handlers. viewer.setUpViewer(osgProducer::Viewer::STANDARD_SETTINGS); // get details on keyboard and mouse bindings used by the viewer. viewer.getUsage(*arguments.getApplicationUsage()); // if user request help write it out to cout. if (arguments.read("-h") || arguments.read("--help")) { arguments.getApplicationUsage()->write(std::cout); return 1; } // any option left unread are converted into errors to write out later. arguments.reportRemainingOptionsAsUnrecognized(); // report any errors if they have occured when parsing the program aguments. if (arguments.errors()) { arguments.writeErrorMessages(std::cout); return 1; } if (arguments.argc()<=1) { arguments.getApplicationUsage()->write(std::cout,osg::ApplicationUsage::COMMAND_LINE_OPTION); return 1; } // assumes any remaining parameters are models std::vector model; for (int i = 1; i < arguments.argc(); i++) { std::cerr << "Loading " << arguments[i] << std::endl; osg::Node* node = osgDB::readNodeFile(arguments[i]); if (node) model.push_back(node); } if (model.empty()) { return -1; } // root osg::Group* rootNode = new osg::Group; // create sequences std::vector seq; const osg::Sequence::LoopMode mode[] = { osg::Sequence::LOOP, osg::Sequence::SWING, osg::Sequence::LOOP }; const float speed[] = { 0.5f, 1.0f, 1.5f }; const int nreps[] = { -1, 5, 1 }; float x = 0.0f; for (unsigned int j = 0; j < (sizeof(speed) / sizeof(speed[0])); j++) { osg::Sequence* seqNode = generateSeq(mode[j], speed[j], nreps[j], model); if (!seqNode) continue; seq.push_back(seqNode); // position sequence osg::Matrix matrix; matrix.makeTranslate(x, 0.0, 0.0); osg::MatrixTransform* xform = new osg::MatrixTransform; xform->setMatrix(matrix); xform->addChild(seqNode); rootNode->addChild(xform); x += seqNode->getBound()._radius * 1.5f; } // add model to viewer. viewer.setSceneData(rootNode); // register additional event handler viewer.getEventHandlerList().push_front(new MyEventHandler(&seq)); // create the windows and run the threads. viewer.realize(); while( !viewer.done() ) { // wait for all cull and draw threads to complete. viewer.sync(); // update the scene by traversing it with the the update visitor which will // call all node update callbacks and animations. viewer.update(); // fire off the cull and draw traversals of the scene. viewer.frame(); } // wait for all cull and draw threads to complete before exit. viewer.sync(); return 0; }