From 6ae07ce0e290800da6cab95d9b4698cd54a32eac Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Mon, 24 Nov 2008 14:37:15 +0000 Subject: [PATCH] From Roland Smeenk, "This application can be used for testing plugins that can both read and write a certain file format. It will display the original file next to the written and reread file. Example: osgsidebyside -o cow.dae cow.osg This example will read cow.osg, write cow.dae, read cow.dae and display cow.osg on the left side and cow.dae on the right side of the view. Possible interactions: KEY_UP Speedup DOF animation KEY_DOWN SlowDown DOF animation KEY_RIGHT Toggle all MultiSwitches" --- examples/CMakeLists.txt | 1 + examples/osgsidebyside/CMakeLists.txt | 7 + examples/osgsidebyside/osgsidebyside.cpp | 311 +++++++++++++++++++++++ 3 files changed, 319 insertions(+) create mode 100644 examples/osgsidebyside/CMakeLists.txt create mode 100644 examples/osgsidebyside/osgsidebyside.cpp diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index b7588040f..5a4146120 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -88,6 +88,7 @@ IF(DYNAMIC_OPENSCENEGRAPH) ADD_SUBDIRECTORY(osgsharedarray) ADD_SUBDIRECTORY(osgsimplifier) ADD_SUBDIRECTORY(osgsimulation) + ADD_SUBDIRECTORY(osgsidebyside) ADD_SUBDIRECTORY(osgslice) ADD_SUBDIRECTORY(osgspacewarp) ADD_SUBDIRECTORY(osgspheresegment) diff --git a/examples/osgsidebyside/CMakeLists.txt b/examples/osgsidebyside/CMakeLists.txt new file mode 100644 index 000000000..56c15a77e --- /dev/null +++ b/examples/osgsidebyside/CMakeLists.txt @@ -0,0 +1,7 @@ +#this file is automatically generated + + +SET(TARGET_SRC osgsidebyside.cpp) +SET(TARGET_ADDED_LIBRARIES osgSim ) +#### end var setup ### +SETUP_EXAMPLE(osgsidebyside) diff --git a/examples/osgsidebyside/osgsidebyside.cpp b/examples/osgsidebyside/osgsidebyside.cpp new file mode 100644 index 000000000..c0f77bcf5 --- /dev/null +++ b/examples/osgsidebyside/osgsidebyside.cpp @@ -0,0 +1,311 @@ +/* OpenSceneGraph example, osgcamera. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +* THE SOFTWARE. +*/ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +using namespace osg; +using namespace osgGA; + + +class SwitchDOFVisitor : public osg::NodeVisitor, public osgGA::GUIEventHandler +{ +public: + SwitchDOFVisitor(): + osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN) + { + } + + virtual void apply(Group& node) + { + osgSim::MultiSwitch* pMSwitch = dynamic_cast(&node); + + if (pMSwitch) + { + mSwitches.push_back(pMSwitch); + } + + osg::NodeVisitor::apply(node); + } + + virtual void apply(Transform& node) + { + osgSim::DOFTransform* pDof = dynamic_cast(&node); + + if (pDof) + { + mDofs.push_back(pDof); + pDof->setAnimationOn(true); + } + + osg::NodeVisitor::apply(node); + } + + void nextSwitch() + { + for (size_t i=0; i < mSwitches.size(); i++) + { + if (mSwitches[i]->getSwitchSetList().size() > 1) + { + // Toggle through switchsets + unsigned int nextSwitchSet = mSwitches[i]->getActiveSwitchSet(); + nextSwitchSet++; + if (nextSwitchSet >= mSwitches[i]->getSwitchSetList().size()) + nextSwitchSet = 0; + mSwitches[i]->setActiveSwitchSet(nextSwitchSet); + } + else if (mSwitches[i]->getSwitchSetList().size() == 1) + { + // If we have only one switchset, toggle values within this switchset + osgSim::MultiSwitch::ValueList values = mSwitches[i]->getValueList(0); + for (size_t j=0; j < values.size(); j++) + { + if (values[j]) + { + unsigned int nextValue = j+1; + if (nextValue >= values.size()) + nextValue = 0; + mSwitches[i]->setSingleChildOn(0, nextValue); + } + } + } + } + } + + void multiplyAnimation(float scale) + { + for (size_t i=0; i < mDofs.size(); i++) + { + mDofs[i]->setIncrementHPR(mDofs[i]->getIncrementHPR() * scale); + mDofs[i]->setIncrementScale(mDofs[i]->getIncrementScale() * scale); + mDofs[i]->setIncrementTranslate(mDofs[i]->getIncrementTranslate() * scale); + } + } + + bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa) + { + osgViewer::Viewer* viewer = dynamic_cast(&aa); + if (!viewer) return false; + + if (ea.getHandled()) return false; + + if(ea.getEventType()==GUIEventAdapter::KEYDOWN) + { + + int key = ea.getKey() ; + + switch( ea.getKey() ) + { + case osgGA::GUIEventAdapter::KEY_Right: + // Toggle next switch + nextSwitch(); + return true; + break; + case osgGA::GUIEventAdapter::KEY_Up: + // Increase animation speed + multiplyAnimation(2); + return true; + break; + case osgGA::GUIEventAdapter::KEY_Down: + // Decrease animation speed + multiplyAnimation(0.5); + return true; + break; + } + } + return false; + } + +private: + std::vector mSwitches; + std::vector mDofs; +}; + +void singleWindowSideBySideCameras(osgViewer::Viewer& viewer) +{ + osg::GraphicsContext::WindowingSystemInterface* wsi = osg::GraphicsContext::getWindowingSystemInterface(); + if (!wsi) + { + osg::notify(osg::NOTICE)<<"Error, no WindowSystemInterface available, cannot create windows."<getScreenResolution(osg::GraphicsContext::ScreenIdentifier(0), width, height); + + // Not fullscreen + width /= 2; + height /= 2; + + osg::ref_ptr traits = new osg::GraphicsContext::Traits; + traits->x = 100; + traits->y = 100; + traits->width = width; + traits->height = height; + traits->windowDecoration = true; + traits->doubleBuffer = true; + traits->sharedContext = 0; + + osg::ref_ptr gc = osg::GraphicsContext::createGraphicsContext(traits.get()); + if (gc.valid()) + { + osg::notify(osg::INFO)<<" GraphicsWindow has been created successfully."<setClearColor(osg::Vec4f(0.2f,0.2f,0.6f,1.0f)); + gc->setClearMask(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + } + else + { + osg::notify(osg::NOTICE)<<" GraphicsWindow has not been created successfully."<getProjectionMatrixAsPerspective(fovy, aspectRatio, zNear, zFar); + master->setProjectionResizePolicy(osg::Camera::VERTICAL); + fovy = 90; + aspectRatio = 1; + master->setProjectionMatrixAsPerspective(fovy, aspectRatio, zNear, zFar); + + double h = osg::absolute(tan(osg::DegreesToRadians(fovy / 2))); + double w = h * aspectRatio; + double fovx = osg::absolute(osg::RadiansToDegrees(atan(w)) * 2); + + master->setName("MasterCam"); + + osg::ref_ptr camera = new osg::Camera; + camera->setCullMask(1); + camera->setName("Left"); + camera->setGraphicsContext(gc.get()); + camera->setViewport(new osg::Viewport(0, 0, width/2, height)); + GLenum buffer = traits->doubleBuffer ? GL_BACK : GL_FRONT; + camera->setDrawBuffer(buffer); + camera->setReadBuffer(buffer); + viewer.addSlave(camera.get(), osg::Matrixd(), osg::Matrixd()); + + camera = new osg::Camera; + camera->setCullMask(2); + camera->setName("Right"); + camera->setGraphicsContext(gc.get()); + camera->setViewport(new osg::Viewport(width/2, 0, width/2, height)); + buffer = traits->doubleBuffer ? GL_BACK : GL_FRONT; + camera->setDrawBuffer(buffer); + camera->setReadBuffer(buffer); + viewer.addSlave(camera.get(), osg::Matrixd(), osg::Matrixd()); +} + +int main( int argc, char **argv ) +{ + // use an ArgumentParser object to manage the program arguments. + osg::ArgumentParser arguments(&argc,argv); + + if (argc<2) + { + std::cout << argv[0] <<": requires filename argument." << std::endl; + return 1; + } + + osgViewer::Viewer viewer(arguments); + + std::string outputfile("output.osg"); + while (arguments.read("-o",outputfile)) {} + + while (arguments.read("-s")) { viewer.setThreadingModel(osgViewer::Viewer::SingleThreaded); } + while (arguments.read("-g")) { viewer.setThreadingModel(osgViewer::Viewer::CullDrawThreadPerContext); } + while (arguments.read("-d")) { viewer.setThreadingModel(osgViewer::Viewer::DrawThreadPerContext); } + while (arguments.read("-c")) { viewer.setThreadingModel(osgViewer::Viewer::CullThreadPerCameraDrawThreadPerContext); } + + singleWindowSideBySideCameras(viewer); + + viewer.setCameraManipulator( new osgGA::TrackballManipulator() ); + viewer.addEventHandler(new osgViewer::StatsHandler); + viewer.addEventHandler(new osgViewer::ThreadingHandler); + viewer.addEventHandler(new osgViewer::WindowSizeHandler()); + viewer.addEventHandler(new osgViewer::LODScaleHandler()); + viewer.addEventHandler(new osgGA::StateSetManipulator()); + + SwitchDOFVisitor* visit = new SwitchDOFVisitor; + viewer.addEventHandler(visit); + + osg::ref_ptr loadedModel; + // load the scene. + loadedModel = osgDB::readNodeFiles(arguments); + + if (!loadedModel) + { + std::cout << argv[0] <<": No data loaded." << std::endl; + return 1; + } + + osg::Group* group = new osg::Group; + + osg::Group* group1 = new osg::Group; + group1->addChild(loadedModel.get()); + group1->setNodeMask(1); + + // Uncomment these lines if you like to compare the loaded model to the resulting model in a merge/diff tool + //osgDB::writeNodeFile(*loadedModel.get(), "dummy1.osg"); + + osgDB::writeNodeFile(*loadedModel.get(), outputfile); + osg::ref_ptr convertedModel = osgDB::readNodeFile(outputfile); + + //osgDB::writeNodeFile(*convertedModel.get(), "dummy2.osg"); + + osg::Group* group2 = new osg::Group; + group2->addChild(convertedModel.get()); + group2->setNodeMask(2); + + // Activate DOF animations and collect switches + loadedModel->accept(*visit); + convertedModel->accept(*visit); + + group->addChild(group1); + group->addChild(group2); + + viewer.setSceneData(group); + + viewer.setThreadingModel(osgViewer::Viewer::DrawThreadPerContext); + viewer.realize(); + + viewer.run(); + + return 0; +} +