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

Revision 13798, 10.3 kB (checked in by robert, 10 hours ago)

Changed the osgUI behaviour so that events are set to be handled by Widgets that have focus even if they don't directly use them.

  • Property svn:eol-style set to native
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    SwitchDOFVisitor(const SwitchDOFVisitor& sdfv, const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY) {}
53
54    META_Object(osg, SwitchDOFVisitor)
55   
56    virtual void apply(Group& node)
57    {
58        osgSim::MultiSwitch* pMSwitch = dynamic_cast<osgSim::MultiSwitch*>(&node);
59       
60        if (pMSwitch)
61        {
62            mSwitches.push_back(pMSwitch);
63        }
64
65        osg::NodeVisitor::apply(node);
66    }
67   
68    virtual void apply(Transform& node)
69    {
70        osgSim::DOFTransform* pDof = dynamic_cast<osgSim::DOFTransform*>(&node);
71       
72        if (pDof)
73        {
74            mDofs.push_back(pDof);
75            pDof->setAnimationOn(true);
76        }
77
78        osg::NodeVisitor::apply(node);
79    }
80
81    void nextSwitch()
82    {
83        for (size_t i=0; i < mSwitches.size(); i++)
84        {
85            if (mSwitches[i]->getSwitchSetList().size() > 1)
86            {
87                // Toggle through switchsets
88                unsigned int nextSwitchSet = mSwitches[i]->getActiveSwitchSet();
89                nextSwitchSet++;
90                if (nextSwitchSet >= mSwitches[i]->getSwitchSetList().size())
91                    nextSwitchSet = 0;
92                mSwitches[i]->setActiveSwitchSet(nextSwitchSet);
93            }
94            else if (mSwitches[i]->getSwitchSetList().size() == 1)
95            {
96                // If we have only one switchset, toggle values within this switchset
97                osgSim::MultiSwitch::ValueList values = mSwitches[i]->getValueList(0);
98                for (size_t j=0; j < values.size(); j++)
99                {
100                    if (values[j])
101                    {
102                        unsigned int nextValue = j+1;
103                        if (nextValue >= values.size())
104                            nextValue = 0;
105                        mSwitches[i]->setSingleChildOn(0, nextValue);
106                    }
107                }
108            }
109        }
110    }
111
112    void multiplyAnimation(float scale)
113    {
114        for (size_t i=0; i < mDofs.size(); i++)
115        {
116            mDofs[i]->setIncrementHPR(mDofs[i]->getIncrementHPR() * scale);
117            mDofs[i]->setIncrementScale(mDofs[i]->getIncrementScale() * scale);
118            mDofs[i]->setIncrementTranslate(mDofs[i]->getIncrementTranslate() * scale);
119        }
120    }
121
122    bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa)
123    {
124        osgViewer::Viewer* viewer = dynamic_cast<osgViewer::Viewer*>(&aa);
125        if (!viewer) return false;
126
127        if (ea.getHandled()) return false;
128
129        if(ea.getEventType()==GUIEventAdapter::KEYDOWN)
130        {
131
132            switch( ea.getKey() )
133            {
134                case osgGA::GUIEventAdapter::KEY_Right:
135                    // Toggle next switch
136                    nextSwitch();
137                    return true;
138                    break;
139                case osgGA::GUIEventAdapter::KEY_Up:
140                    // Increase animation speed
141                    multiplyAnimation(2);
142                    return true;
143                    break;
144                case osgGA::GUIEventAdapter::KEY_Down:
145                    // Decrease animation speed
146                    multiplyAnimation(0.5);
147                    return true;
148                    break;
149            }
150        }
151        return false;
152    }
153
154private:
155    std::vector<osgSim::MultiSwitch*> mSwitches;
156    std::vector<osgSim::DOFTransform*> mDofs;
157};
158
159void singleWindowSideBySideCameras(osgViewer::Viewer& viewer)
160{
161    osg::GraphicsContext::WindowingSystemInterface* wsi = osg::GraphicsContext::getWindowingSystemInterface();
162    if (!wsi)
163    {
164        osg::notify(osg::NOTICE)<<"Error, no WindowSystemInterface available, cannot create windows."<<std::endl;
165        return;
166    }
167   
168    unsigned int width, height;
169    wsi->getScreenResolution(osg::GraphicsContext::ScreenIdentifier(0), width, height);
170
171
172
173    // Not fullscreen
174    width /= 2;
175    height /= 2;
176
177    osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits;
178    traits->x = 100;
179    traits->y = 100;
180    traits->width = width;
181    traits->height = height;
182    traits->windowDecoration = true;
183    traits->doubleBuffer = true;
184    traits->sharedContext = 0;
185
186    osg::ref_ptr<osg::GraphicsContext> gc = osg::GraphicsContext::createGraphicsContext(traits.get());
187    if (gc.valid())
188    {
189        osg::notify(osg::INFO)<<"  GraphicsWindow has been created successfully."<<std::endl;
190
191        // need to ensure that the window is cleared make sure that the complete window is set the correct colour
192        // rather than just the parts of the window that are under the camera's viewports
193        gc->setClearColor(osg::Vec4f(0.2f,0.2f,0.6f,1.0f));
194        gc->setClearMask(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
195    }
196    else
197    {
198        osg::notify(osg::NOTICE)<<"  GraphicsWindow has not been created successfully."<<std::endl;
199    }
200
201
202    osg::Camera* master = viewer.getCamera();
203
204    // get the default settings for the camera
205    double fovy, aspectRatio, zNear, zFar;
206    master->getProjectionMatrixAsPerspective(fovy, aspectRatio, zNear, zFar);
207
208    // reset this for the actual apsect ratio of out created window
209    double windowAspectRatio = double(width)/double(height);
210    master->setProjectionMatrixAsPerspective(fovy, windowAspectRatio, 1.0, 10000.0);
211
212    master->setName("MasterCam");
213
214    osg::ref_ptr<osg::Camera> camera = new osg::Camera;
215    camera->setCullMask(1);
216    camera->setName("Left");
217    camera->setGraphicsContext(gc.get());
218    camera->setViewport(new osg::Viewport(0, 0, width/2, height));
219    GLenum buffer = traits->doubleBuffer ? GL_BACK : GL_FRONT;
220    camera->setDrawBuffer(buffer);
221    camera->setReadBuffer(buffer);
222    viewer.addSlave(camera.get(), osg::Matrixd::scale(1.0,0.5,1.0), osg::Matrixd());
223
224    camera = new osg::Camera;
225    camera->setCullMask(2);
226    camera->setName("Right");
227    camera->setGraphicsContext(gc.get());
228    camera->setViewport(new osg::Viewport(width/2, 0, width/2, height));
229    buffer = traits->doubleBuffer ? GL_BACK : GL_FRONT;
230    camera->setDrawBuffer(buffer);
231    camera->setReadBuffer(buffer);
232    viewer.addSlave(camera.get(), osg::Matrixd::scale(1.0,0.5,1.0), osg::Matrixd());
233}
234
235int main( int argc, char **argv )
236{
237    // use an ArgumentParser object to manage the program arguments.
238    osg::ArgumentParser arguments(&argc,argv);
239
240    if (argc<2)
241    {
242        std::cout << argv[0] <<": requires filename argument." << std::endl;
243        return 1;
244    }
245
246    osgViewer::Viewer viewer(arguments);
247   
248    std::string outputfile("output.osgt");
249    while (arguments.read("-o",outputfile)) {}
250
251    while (arguments.read("-s")) { viewer.setThreadingModel(osgViewer::Viewer::SingleThreaded); }
252    while (arguments.read("-g")) { viewer.setThreadingModel(osgViewer::Viewer::CullDrawThreadPerContext); }
253    while (arguments.read("-d")) { viewer.setThreadingModel(osgViewer::Viewer::DrawThreadPerContext); }
254    while (arguments.read("-c")) { viewer.setThreadingModel(osgViewer::Viewer::CullThreadPerCameraDrawThreadPerContext); }
255   
256    singleWindowSideBySideCameras(viewer);
257
258    viewer.setCameraManipulator( new osgGA::TrackballManipulator() );
259    viewer.addEventHandler(new osgViewer::StatsHandler);
260    viewer.addEventHandler(new osgViewer::ThreadingHandler);
261    viewer.addEventHandler(new osgViewer::WindowSizeHandler());
262    viewer.addEventHandler(new osgViewer::LODScaleHandler());
263    viewer.addEventHandler(new osgGA::StateSetManipulator());
264
265    SwitchDOFVisitor* visit = new SwitchDOFVisitor;
266    viewer.addEventHandler(visit);
267   
268    osg::ref_ptr<osg::Node> loadedModel;
269    // load the scene.
270    loadedModel = osgDB::readNodeFiles(arguments);
271
272    if (!loadedModel)
273    {
274        std::cout << argv[0] <<": No data loaded." << std::endl;
275        return 1;
276    }
277
278    osg::Group* group = new osg::Group;
279   
280    osg::Group* group1 = new osg::Group;
281    group1->addChild(loadedModel.get());
282    group1->setNodeMask(1);
283
284    // Uncomment these lines if you like to compare the loaded model to the resulting model in a merge/diff tool
285    //osgDB::writeNodeFile(*loadedModel.get(), "dummy1.osgt");
286
287    osgDB::writeNodeFile(*loadedModel.get(), outputfile);
288    osg::ref_ptr<osg::Node> convertedModel = osgDB::readNodeFile(outputfile);
289
290    //osgDB::writeNodeFile(*convertedModel.get(), "dummy2.osgt");
291
292    osg::Group* group2 = new osg::Group;
293    group2->addChild(convertedModel.get());
294    group2->setNodeMask(2);
295
296    // Activate DOF animations and collect switches
297    loadedModel->accept(*visit);
298    convertedModel->accept(*visit);
299
300    group->addChild(group1);
301    group->addChild(group2);
302
303    viewer.setSceneData(group);
304
305    viewer.setThreadingModel(osgViewer::Viewer::DrawThreadPerContext);
306    viewer.realize();
307
308    viewer.run();
309
310    return 0;
311}
Note: See TracBrowser for help on using the browser.