root/OpenSceneGraph/trunk/examples/osgsidebyside/osgsidebyside.cpp @ 9229

Revision 9229, 10.3 kB (checked in by robert, 5 years ago)

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?"


Line 
1/* OpenSceneGraph example, osgcamera.
2*
3*  Permission is hereby granted, free of charge, to any person obtaining a copy
4*  of this software and associated documentation files (the "Software"), to deal
5*  in the Software without restriction, including without limitation the rights
6*  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7*  copies of the Software, and to permit persons to whom the Software is
8*  furnished to do so, subject to the following conditions:
9*
10*  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
11*  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
12*  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
13*  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
14*  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
15*  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
16*  THE SOFTWARE.
17*/
18
19
20#include <osgDB/ReadFile>
21#include <osgDB/WriteFile>
22#include <osgViewer/Viewer>
23#include <osgViewer/ViewerEventHandlers>
24#include <osgGA/TrackballManipulator>
25#include <osgGA/FlightManipulator>
26#include <osgGA/AnimationPathManipulator>
27#include <osgGA/GUIEventHandler>
28#include <osgGA/StateSetManipulator>
29#include <osg/PolygonMode>
30#include <osgUtil/Optimizer>
31#include <osg/Depth>
32#include <iostream>
33#include <osg/Switch>
34#include <osgSim/MultiSwitch>
35#include <osgSim/DOFTransform>
36
37#include <osg/AlphaFunc>
38#include <osg/BlendFunc>
39
40using namespace osg;
41using namespace osgGA;
42
43
44class SwitchDOFVisitor : public osg::NodeVisitor, public osgGA::GUIEventHandler
45{
46public:
47    SwitchDOFVisitor():
48      osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN)
49    {
50    }
51
52    virtual void apply(Group& node)
53    {
54        osgSim::MultiSwitch* pMSwitch = dynamic_cast<osgSim::MultiSwitch*>(&node);
55       
56        if (pMSwitch)
57        {
58            mSwitches.push_back(pMSwitch);
59        }
60
61        osg::NodeVisitor::apply(node);
62    }
63   
64    virtual void apply(Transform& node)
65    {
66        osgSim::DOFTransform* pDof = dynamic_cast<osgSim::DOFTransform*>(&node);
67       
68        if (pDof)
69        {
70            mDofs.push_back(pDof);
71            pDof->setAnimationOn(true);
72        }
73
74        osg::NodeVisitor::apply(node);
75    }
76
77    void nextSwitch()
78    {
79        for (size_t i=0; i < mSwitches.size(); i++)
80        {
81            if (mSwitches[i]->getSwitchSetList().size() > 1)
82            {
83                // Toggle through switchsets
84                unsigned int nextSwitchSet = mSwitches[i]->getActiveSwitchSet();
85                nextSwitchSet++;
86                if (nextSwitchSet >= mSwitches[i]->getSwitchSetList().size())
87                    nextSwitchSet = 0;
88                mSwitches[i]->setActiveSwitchSet(nextSwitchSet);
89            }
90            else if (mSwitches[i]->getSwitchSetList().size() == 1)
91            {
92                // If we have only one switchset, toggle values within this switchset
93                osgSim::MultiSwitch::ValueList values = mSwitches[i]->getValueList(0);
94                for (size_t j=0; j < values.size(); j++)
95                {
96                    if (values[j])
97                    {
98                        unsigned int nextValue = j+1;
99                        if (nextValue >= values.size())
100                            nextValue = 0;
101                        mSwitches[i]->setSingleChildOn(0, nextValue);
102                    }
103                }
104            }
105        }
106    }
107
108    void multiplyAnimation(float scale)
109    {
110        for (size_t i=0; i < mDofs.size(); i++)
111        {
112            mDofs[i]->setIncrementHPR(mDofs[i]->getIncrementHPR() * scale);
113            mDofs[i]->setIncrementScale(mDofs[i]->getIncrementScale() * scale);
114            mDofs[i]->setIncrementTranslate(mDofs[i]->getIncrementTranslate() * scale);
115        }
116    }
117
118    bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa)
119    {
120        osgViewer::Viewer* viewer = dynamic_cast<osgViewer::Viewer*>(&aa);
121        if (!viewer) return false;
122
123        if (ea.getHandled()) return false;
124
125        if(ea.getEventType()==GUIEventAdapter::KEYDOWN)
126        {
127
128            int key = ea.getKey() ;
129
130            switch( ea.getKey() )
131            {
132                case osgGA::GUIEventAdapter::KEY_Right:
133                    // Toggle next switch
134                    nextSwitch();
135                    return true;
136                    break;
137                case osgGA::GUIEventAdapter::KEY_Up:
138                    // Increase animation speed
139                    multiplyAnimation(2);
140                    return true;
141                    break;
142                case osgGA::GUIEventAdapter::KEY_Down:
143                    // Decrease animation speed
144                    multiplyAnimation(0.5);
145                    return true;
146                    break;
147            }
148        }
149        return false;
150    }
151
152private:
153    std::vector<osgSim::MultiSwitch*> mSwitches;
154    std::vector<osgSim::DOFTransform*> mDofs;
155};
156
157void singleWindowSideBySideCameras(osgViewer::Viewer& viewer)
158{
159    osg::GraphicsContext::WindowingSystemInterface* wsi = osg::GraphicsContext::getWindowingSystemInterface();
160    if (!wsi)
161    {
162        osg::notify(osg::NOTICE)<<"Error, no WindowSystemInterface available, cannot create windows."<<std::endl;
163        return;
164    }
165   
166    unsigned int width, height;
167    wsi->getScreenResolution(osg::GraphicsContext::ScreenIdentifier(0), width, height);
168
169    // Not fullscreen
170    width /= 2;
171    height /= 2;
172
173    osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits;
174    traits->x = 100;
175    traits->y = 100;
176    traits->width = width;
177    traits->height = height;
178    traits->windowDecoration = true;
179    traits->doubleBuffer = true;
180    traits->sharedContext = 0;
181
182    osg::ref_ptr<osg::GraphicsContext> gc = osg::GraphicsContext::createGraphicsContext(traits.get());
183    if (gc.valid())
184    {
185        osg::notify(osg::INFO)<<"  GraphicsWindow has been created successfully."<<std::endl;
186
187        // need to ensure that the window is cleared make sure that the complete window is set the correct colour
188        // rather than just the parts of the window that are under the camera's viewports
189        gc->setClearColor(osg::Vec4f(0.2f,0.2f,0.6f,1.0f));
190        gc->setClearMask(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
191    }
192    else
193    {
194        osg::notify(osg::NOTICE)<<"  GraphicsWindow has not been created successfully."<<std::endl;
195    }
196
197    double aspectRatioScale = 1.0;
198
199    osg::Camera* master = viewer.getCamera();
200    double fovy, aspectRatio, zNear, zFar;
201    master->getProjectionMatrixAsPerspective(fovy, aspectRatio, zNear, zFar);
202    master->setProjectionResizePolicy(osg::Camera::VERTICAL);
203    fovy = 90;
204    aspectRatio = 1;
205    master->setProjectionMatrixAsPerspective(fovy, aspectRatio, zNear, zFar);
206
207    double h = osg::absolute(tan(osg::DegreesToRadians(fovy / 2)));
208    double w = h * aspectRatio;
209    double fovx = osg::absolute(osg::RadiansToDegrees(atan(w)) * 2);
210
211    master->setName("MasterCam");
212
213    osg::ref_ptr<osg::Camera> camera = new osg::Camera;
214    camera->setCullMask(1);
215    camera->setName("Left");
216    camera->setGraphicsContext(gc.get());
217    camera->setViewport(new osg::Viewport(0, 0, width/2, height));
218    GLenum buffer = traits->doubleBuffer ? GL_BACK : GL_FRONT;
219    camera->setDrawBuffer(buffer);
220    camera->setReadBuffer(buffer);
221    viewer.addSlave(camera.get(), osg::Matrixd(), osg::Matrixd());
222
223    camera = new osg::Camera;
224    camera->setCullMask(2);
225    camera->setName("Right");
226    camera->setGraphicsContext(gc.get());
227    camera->setViewport(new osg::Viewport(width/2, 0, width/2, height));
228    buffer = traits->doubleBuffer ? GL_BACK : GL_FRONT;
229    camera->setDrawBuffer(buffer);
230    camera->setReadBuffer(buffer);
231    viewer.addSlave(camera.get(), osg::Matrixd(), osg::Matrixd());
232}
233
234int main( int argc, char **argv )
235{
236    // use an ArgumentParser object to manage the program arguments.
237    osg::ArgumentParser arguments(&argc,argv);
238
239    if (argc<2)
240    {
241        std::cout << argv[0] <<": requires filename argument." << std::endl;
242        return 1;
243    }
244
245    osgViewer::Viewer viewer(arguments);
246   
247    std::string outputfile("output.osg");
248    while (arguments.read("-o",outputfile)) {}
249
250    while (arguments.read("-s")) { viewer.setThreadingModel(osgViewer::Viewer::SingleThreaded); }
251    while (arguments.read("-g")) { viewer.setThreadingModel(osgViewer::Viewer::CullDrawThreadPerContext); }
252    while (arguments.read("-d")) { viewer.setThreadingModel(osgViewer::Viewer::DrawThreadPerContext); }
253    while (arguments.read("-c")) { viewer.setThreadingModel(osgViewer::Viewer::CullThreadPerCameraDrawThreadPerContext); }
254   
255    singleWindowSideBySideCameras(viewer);
256
257    viewer.setCameraManipulator( new osgGA::TrackballManipulator() );
258    viewer.addEventHandler(new osgViewer::StatsHandler);
259    viewer.addEventHandler(new osgViewer::ThreadingHandler);
260    viewer.addEventHandler(new osgViewer::WindowSizeHandler());
261    viewer.addEventHandler(new osgViewer::LODScaleHandler());
262    viewer.addEventHandler(new osgGA::StateSetManipulator());
263
264    SwitchDOFVisitor* visit = new SwitchDOFVisitor;
265    viewer.addEventHandler(visit);
266   
267    osg::ref_ptr<osg::Node> loadedModel;
268    // load the scene.
269    loadedModel = osgDB::readNodeFiles(arguments);
270
271    if (!loadedModel)
272    {
273        std::cout << argv[0] <<": No data loaded." << std::endl;
274        return 1;
275    }
276
277    osg::Group* group = new osg::Group;
278   
279    osg::Group* group1 = new osg::Group;
280    group1->addChild(loadedModel.get());
281    group1->setNodeMask(1);
282
283    // Uncomment these lines if you like to compare the loaded model to the resulting model in a merge/diff tool
284    //osgDB::writeNodeFile(*loadedModel.get(), "dummy1.osg");
285
286    osgDB::writeNodeFile(*loadedModel.get(), outputfile);
287    osg::ref_ptr<osg::Node> convertedModel = osgDB::readNodeFile(outputfile);
288
289    //osgDB::writeNodeFile(*convertedModel.get(), "dummy2.osg");
290
291    osg::Group* group2 = new osg::Group;
292    group2->addChild(convertedModel.get());
293    group2->setNodeMask(2);
294
295    // Activate DOF animations and collect switches
296    loadedModel->accept(*visit);
297    convertedModel->accept(*visit);
298
299    group->addChild(group1);
300    group->addChild(group2);
301
302    viewer.setSceneData(group);
303
304    viewer.setThreadingModel(osgViewer::Viewer::DrawThreadPerContext);
305    viewer.realize();
306
307    viewer.run();
308
309    return 0;
310}
Note: See TracBrowser for help on using the browser.