root/OpenSceneGraph/trunk/examples/osgcompositeviewer/osgmultiplecameras.cpp @ 6851

Revision 5999, 9.1 kB (checked in by robert, 8 years ago)

Cleaned up CompositeViewer? interface and added event traversal of views

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
2 *
3 * This library is open source and may be redistributed and/or modified under 
4 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
5 * (at your option) any later version.  The full license is in LICENSE file
6 * included with this distribution, and on the openscenegraph.org website.
7 *
8 * This library is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 * OpenSceneGraph Public License for more details.
12*/
13
14#include <osgUtil/Optimizer>
15#include <osgDB/ReadFile>
16
17#include <osg/Material>
18#include <osg/Geode>
19#include <osg/BlendFunc>
20#include <osg/Depth>
21#include <osg/Projection>
22#include <osg/PolygonOffset>
23#include <osg/MatrixTransform>
24#include <osg/Camera>
25#include <osg/FrontFace>
26
27#include <osgText/Text>
28
29#include <osgGA/TrackballManipulator>
30#include <osgGA/FlightManipulator>
31#include <osgGA/StateSetManipulator>
32
33#include <osgViewer/CompositeViewer>
34
35#include <osgFX/Scribe>
36
37#include <osg/io_utils>
38
39// class to handle events with a pick
40class PickHandler : public osgGA::GUIEventHandler {
41public:
42
43    PickHandler():
44        _mx(0.0f),
45        _my(0.0f) {}
46       
47    ~PickHandler() {}
48   
49    bool handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter& aa)
50    {
51        osgViewer::View* view = dynamic_cast<osgViewer::View*>(&aa);
52        if (!view) return false;
53       
54        switch(ea.getEventType())
55        {
56            case(osgGA::GUIEventAdapter::PUSH):
57            {
58                _mx = ea.getX();
59                _my = ea.getY();
60                break;
61            }
62            case(osgGA::GUIEventAdapter::RELEASE):
63            {
64                if (_mx==ea.getX() && _my==ea.getY())
65                {
66                    pick(view, ea.getX(), ea.getY());
67                }
68                break;
69            }
70            default:
71                break;
72        }
73        return false;
74    }
75   
76    void pick(osgViewer::View* view, float x, float y)
77    {
78        osg::Node* node = 0;
79        osg::Group* parent = 0;
80
81        osgUtil::LineSegmentIntersector::Intersections intersections;
82        if (view->computeIntersections(x, y, intersections))
83        {
84            osgUtil::LineSegmentIntersector::Intersection intersection = *intersections.begin();
85            osg::NodePath& nodePath = intersection.nodePath;
86            node = (nodePath.size()>=1)?nodePath[nodePath.size()-1]:0;
87            parent = (nodePath.size()>=2)?dynamic_cast<osg::Group*>(nodePath[nodePath.size()-2]):0;
88        }       
89
90        // now we try to decorate the hit node by the osgFX::Scribe to show that its been "picked"
91        if (parent && node)
92        {
93
94            osgFX::Scribe* parentAsScribe = dynamic_cast<osgFX::Scribe*>(parent);
95            if (!parentAsScribe)
96            {
97                // node not already picked, so highlight it with an osgFX::Scribe
98                osgFX::Scribe* scribe = new osgFX::Scribe();
99                scribe->addChild(node);
100                parent->replaceChild(node,scribe);
101            }
102            else
103            {
104                // node already picked so we want to remove scribe to unpick it.
105                osg::Node::ParentList parentList = parentAsScribe->getParents();
106                for(osg::Node::ParentList::iterator itr=parentList.begin();
107                    itr!=parentList.end();
108                    ++itr)
109                {
110                    (*itr)->replaceChild(parentAsScribe,node);
111                }
112            }
113        }
114
115    }
116   
117    float _mx, _my;
118
119};
120
121
122int main( int argc, char **argv )
123{
124
125    // use an ArgumentParser object to manage the program arguments.
126    osg::ArgumentParser arguments(&argc,argv);
127   
128    // read the scene from the list of file specified commandline args.
129    osg::ref_ptr<osg::Node> scene = osgDB::readNodeFiles(arguments);
130
131    if (!scene) return 1;
132
133    // construct the viewer.
134    osgViewer::CompositeViewer viewer;
135   
136   
137    if (arguments.read("-1"))
138    {
139        {
140            osgViewer::View* view = new osgViewer::View;
141            view->setSceneData(osgDB::readNodeFile("fountain.osg"));
142
143            view->setUpViewAcrossAllScreens();
144            view->setCameraManipulator(new osgGA::TrackballManipulator);
145            viewer.addView(view);
146        }
147    }
148
149    if (arguments.read("-2"))
150    {
151
152        // view one
153        {
154            osgViewer::View* view = new osgViewer::View;
155            viewer.addView(view);
156
157            view->setUpViewOnSingleScreen(0);
158            view->setSceneData(scene.get());
159            view->setCameraManipulator(new osgGA::TrackballManipulator);
160
161            // add the state manipulator
162            osg::ref_ptr<osgGA::StateSetManipulator> statesetManipulator = new osgGA::StateSetManipulator;
163            statesetManipulator->setStateSet(view->getCamera()->getOrCreateStateSet());
164
165            view->addEventHandler( statesetManipulator.get() );
166        }
167       
168        // view two
169        {
170            osgViewer::View* view = new osgViewer::View;
171            viewer.addView(view);
172
173            view->setUpViewOnSingleScreen(1);
174            view->setSceneData(scene.get());
175            view->setCameraManipulator(new osgGA::TrackballManipulator);
176           
177            // add the handler for doing the picking
178            view->addEventHandler(new PickHandler());
179        }
180    }
181   
182
183    if (arguments.read("-3") || viewer.getNumViews()==0)
184    {   
185
186        osg::GraphicsContext::WindowingSystemInterface* wsi = osg::GraphicsContext::getWindowingSystemInterface();
187        if (!wsi)
188        {
189            osg::notify(osg::NOTICE)<<"Error, no WindowSystemInterface available, cannot create windows."<<std::endl;
190            return 1;
191        }
192
193        unsigned int width, height;
194        wsi->getScreenResolution(osg::GraphicsContext::ScreenIdentifier(0), width, height);
195
196        osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits;
197        traits->x = 100;
198        traits->y = 100;
199        traits->width = 1000;
200        traits->height = 800;
201        traits->windowDecoration = true;
202        traits->doubleBuffer = true;
203        traits->sharedContext = 0;
204
205        osg::ref_ptr<osg::GraphicsContext> gc = osg::GraphicsContext::createGraphicsContext(traits.get());
206        if (gc.valid())
207        {
208            osg::notify(osg::INFO)<<"  GraphicsWindow has been created successfully."<<std::endl;
209
210            // need to ensure that the window is cleared make sure that the complete window is set the correct colour
211            // rather than just the parts of the window that are under the camera's viewports
212            gc->setClearColor(osg::Vec4f(0.2f,0.2f,0.6f,1.0f));
213            gc->setClearMask(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
214        }
215        else
216        {
217            osg::notify(osg::NOTICE)<<"  GraphicsWindow has not been created successfully."<<std::endl;
218        }
219
220        // view one
221        {
222            osgViewer::View* view = new osgViewer::View;
223            viewer.addView(view);
224
225            view->setSceneData(scene.get());
226            view->getCamera()->setViewport(new osg::Viewport(0,0, traits->width/2, traits->height/2));
227            view->getCamera()->setGraphicsContext(gc.get());
228            view->setCameraManipulator(new osgGA::TrackballManipulator);
229
230            // add the state manipulator
231            osg::ref_ptr<osgGA::StateSetManipulator> statesetManipulator = new osgGA::StateSetManipulator;
232            statesetManipulator->setStateSet(view->getCamera()->getOrCreateStateSet());
233
234            view->addEventHandler( statesetManipulator.get() );
235        }
236
237        // view two
238        {
239            osgViewer::View* view = new osgViewer::View;
240            viewer.addView(view);
241
242            view->setSceneData(scene.get());
243            view->getCamera()->setViewport(new osg::Viewport(traits->width/2,0, traits->width/2, traits->height/2));
244            view->getCamera()->setGraphicsContext(gc.get());
245            view->setCameraManipulator(new osgGA::TrackballManipulator);
246           
247            // add the handler for doing the picking
248            view->addEventHandler(new PickHandler());
249           
250        }
251
252        // view three
253        {
254            osgViewer::View* view = new osgViewer::View;
255            viewer.addView(view);
256
257            view->setSceneData(osgDB::readNodeFile("cessnafire.osg"));
258
259            view->getCamera()->setProjectionMatrixAsPerspective(30.0, double(traits->width) / double(traits->height/2), 1.0, 1000.0);
260            view->getCamera()->setViewport(new osg::Viewport(0, traits->height/2, traits->width, traits->height/2));
261            view->getCamera()->setGraphicsContext(gc.get());
262            view->setCameraManipulator(new osgGA::TrackballManipulator);
263        }
264
265    }
266   
267    while (arguments.read("-s")) { viewer.setThreadingModel(osgViewer::CompositeViewer::SingleThreaded); }
268    while (arguments.read("-g")) { viewer.setThreadingModel(osgViewer::CompositeViewer::ThreadPerContext); }
269    while (arguments.read("-c")) { viewer.setThreadingModel(osgViewer::CompositeViewer::ThreadPerCamera); }
270 
271     // run the viewer's main frame loop
272     return viewer.run();
273}
Note: See TracBrowser for help on using the browser.