root/OpenSceneGraph/trunk/examples/osgkeyboardmouse/osgkeyboardmouse.cpp @ 5173

Revision 5173, 9.1 kB (checked in by robert, 9 years ago)

Revamped osgkeyboardmouse to use the osgGA.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1// C++ source file - (C) 2003 Robert Osfield, released under the OSGPL.
2//
3// Simple example of use of Producer::RenderSurface + KeyboardMouseCallback + SceneView
4// example that provides the user with control over view position with basic picking.
5
6#include <Producer/RenderSurface>
7#include <Producer/KeyboardMouse>
8#include <Producer/Trackball>
9
10#include <osg/Timer>
11#include <osg/io_utils>
12
13#include <osgUtil/SceneView>
14#include <osgUtil/IntersectVisitor>
15
16#include <osgDB/ReadFile>
17#include <osgDB/WriteFile>
18
19#include <osgGA/EventQueue>
20#include <osgGA/EventVisitor>
21#include <osgGA/TrackballManipulator>
22#include <osgGA/StateSetManipulator>
23
24#include <osgFX/Scribe>
25
26// Begining of glue classes to adapter Producer's keyboard mouse events to osgGA's abstraction events.
27class MyKeyboardMouseCallback : public Producer::KeyboardMouseCallback
28{
29public:
30
31    MyKeyboardMouseCallback(osgGA::EventQueue* eventQueue) :
32        _done(false),
33        _eventQueue(eventQueue)
34    {
35    }
36
37    virtual void shutdown()
38    {
39        _done = true;
40    }
41
42    virtual void specialKeyPress( Producer::KeyCharacter key )
43    {
44        if (key==Producer::KeyChar_Escape)
45                    shutdown();
46
47        _eventQueue->keyPress( (osgGA::GUIEventAdapter::KeySymbol) key );
48    }
49
50    virtual void specialKeyRelease( Producer::KeyCharacter key )
51    {
52        _eventQueue->keyRelease( (osgGA::GUIEventAdapter::KeySymbol) key );
53    }
54
55    virtual void keyPress( Producer::KeyCharacter key)
56    {
57        _eventQueue->keyPress( (osgGA::GUIEventAdapter::KeySymbol) key );
58    }
59
60    virtual void keyRelease( Producer::KeyCharacter key)
61    {
62        _eventQueue->keyRelease( (osgGA::GUIEventAdapter::KeySymbol) key );
63    }
64
65    virtual void mouseMotion( float mx, float my )
66    {
67        _eventQueue->mouseMotion( mx, my );
68    }
69
70    virtual void buttonPress( float mx, float my, unsigned int mbutton )
71    {
72        _eventQueue->mouseButtonPress(mx, my, mbutton);
73    }
74   
75    virtual void buttonRelease( float mx, float my, unsigned int mbutton )
76    {
77        _eventQueue->mouseButtonRelease(mx, my, mbutton);
78    }
79
80    bool done() { return _done; }
81
82private:
83
84    bool                                _done;
85    osg::ref_ptr<osgGA::EventQueue>     _eventQueue;
86};
87
88class MyActionAdapter : public osgGA::GUIActionAdapter, public osg::Referenced
89{
90public:
91    // Override from GUIActionAdapter
92    virtual void requestRedraw() {}
93
94    // Override from GUIActionAdapter
95    virtual void requestContinuousUpdate(bool =true) {}
96
97    // Override from GUIActionAdapter
98    virtual void requestWarpPointer(float ,float ) {}
99   
100};
101
102// End of glue classes to adapter Producer's keyboard mouse events to osgGA's abstraction events.
103
104
105int main( int argc, char **argv )
106{
107    if (argc<2)
108    {
109        std::cout << argv[0] <<": requires filename argument." << std::endl;
110        return 1;
111    }
112
113    // load the scene.
114    osg::ref_ptr<osg::Node> loadedModel = osgDB::readNodeFile(argv[1]);
115    if (!loadedModel)
116    {
117        std::cout << argv[0] <<": No data loaded." << std::endl;
118        return 1;
119    }
120   
121    // create the window to draw to.
122    osg::ref_ptr<Producer::RenderSurface> renderSurface = new Producer::RenderSurface;
123    renderSurface->setWindowName("osgkeyboardmouse");
124    renderSurface->setWindowRectangle(100,100,800,600);
125    renderSurface->useBorder(true);
126    renderSurface->realize();
127   
128
129    // create the view of the scene.
130    osg::ref_ptr<osgUtil::SceneView> sceneView = new osgUtil::SceneView;
131    sceneView->setDefaults();
132    sceneView->setSceneData(loadedModel.get());
133   
134    // create the event queue, note that Producer has the y axis increase upwards, like OpenGL, and contary to most Windowing toolkits, so
135    // we need to construct the event queue so that it knows about this convention.
136    osg::ref_ptr<osgGA::EventQueue> eventQueue = new osgGA::EventQueue(osgGA::GUIEventAdapter::Y_INCREASING_UPWARDS);
137
138    // set up a KeyboardMouse to manage the events comming in from the RenderSurface
139    osg::ref_ptr<Producer::KeyboardMouse>  kbm = new Producer::KeyboardMouse(renderSurface.get());
140
141    // create a KeyboardMouseCallback to handle the mouse events within this applications
142    osg::ref_ptr<MyKeyboardMouseCallback> kbmcb = new MyKeyboardMouseCallback(eventQueue.get());
143
144    // create a tracball manipulator to move the camera around in response to keyboard/mouse events
145    osg::ref_ptr<osgGA::TrackballManipulator> cameraManipulator = new osgGA::TrackballManipulator;
146
147    // keep a list of event handlers to manipulate the application/scene with in response to keyboard/mouse events
148    typedef std::list< osg::ref_ptr<osgGA::GUIEventHandler> > EventHandlers;
149    EventHandlers eventHandlers;
150   
151    osg::ref_ptr<osgGA::StateSetManipulator> statesetManipulator = new osgGA::StateSetManipulator;
152    statesetManipulator->setStateSet(sceneView->getGlobalStateSet());
153    eventHandlers.push_back(statesetManipulator.get());
154   
155    // create an event visitor to pass the events down to the scene graph nodes
156    osg::ref_ptr<osgGA::EventVisitor> eventVisitor = new osgGA::EventVisitor;
157
158    // create an action adapter to allow event handlers to request actions from the GUI.
159    osg::ref_ptr<MyActionAdapter> actionAdapter = new MyActionAdapter;
160
161    // record the timer tick at the start of rendering.   
162    osg::Timer_t start_tick = osg::Timer::instance()->tick();
163   
164    unsigned int frameNum = 0;
165
166    eventQueue->setStartTick(start_tick);
167
168    // set the mouse input range (note WindowSize name in appropriate here so osgGA::GUIEventAdapter API really needs looking at, Robert Osfield, June 2006).
169    // Producer defaults to using non-dimensional units, so we pass this onto osgGA, most windowing toolkits use pixel coords so use the window size instead.
170    eventQueue->getCurrentEventState()->setWindowSize(-1.0, -1.0, 1.0, 1.0);
171
172
173    // home the manipulator.
174    osg::ref_ptr<osgGA::GUIEventAdapter> dummyEvent =  eventQueue->createEvent();
175    cameraManipulator->setNode(sceneView->getSceneData());
176    cameraManipulator->home(*dummyEvent, *actionAdapter);
177
178
179    // main loop (note, window toolkits which take control over the main loop will require a window redraw callback containing the code below.)
180    while( renderSurface->isRealized() && !kbmcb->done())
181    {
182        // set up the frame stamp for current frame to record the current time and frame number so that animtion code can advance correctly
183        osg::FrameStamp* frameStamp = new osg::FrameStamp;
184        frameStamp->setReferenceTime(osg::Timer::instance()->delta_s(start_tick,osg::Timer::instance()->tick()));
185        frameStamp->setFrameNumber(frameNum++);
186       
187        // pass frame stamp to the SceneView so that the update, cull and draw traversals all use the same FrameStamp
188        sceneView->setFrameStamp(frameStamp);
189
190        // pass any keyboard mouse events onto the local keyboard mouse callback.
191        kbm->update( *kbmcb );
192       
193        // create an event to signal the new frame.
194        eventQueue->frame(frameStamp->getReferenceTime());
195
196        // get the event since the last frame.
197        osgGA::EventQueue::Events events;
198        eventQueue->takeEvents(events);
199
200        if (eventVisitor.valid())
201        {
202            eventVisitor->setTraversalNumber(frameStamp->getFrameNumber());
203        }
204
205        // dispatch the events in order of arrival.
206        for(osgGA::EventQueue::Events::iterator event_itr = events.begin();
207            event_itr != events.end();
208            ++event_itr)
209        {
210            bool handled = false;
211
212            if (eventVisitor.valid() && sceneView->getSceneData())
213            {
214                eventVisitor->reset();
215                eventVisitor->addEvent(event_itr->get());
216                sceneView->getSceneData()->accept(*eventVisitor);
217                if (eventVisitor->getEventHandled())
218                    handled = true;
219            }
220
221            if (cameraManipulator.valid() && !handled)
222            {
223                /*handled =*/ cameraManipulator->handle(*(*event_itr), *actionAdapter);
224            }
225
226            for(EventHandlers::iterator handler_itr=eventHandlers.begin();
227                handler_itr!=eventHandlers.end() && !handled;
228                ++handler_itr)
229            {   
230                handled = (*handler_itr)->handle(*(*event_itr),*actionAdapter,0,0);
231            }
232
233            // osg::notify(osg::NOTICE)<<"  Handled event "<<(*event_itr)->getTime()<<" "<< handled<<std::endl;
234
235        }
236
237
238        // update view matrices
239        if (cameraManipulator.valid())
240        {
241            sceneView->setViewMatrix(cameraManipulator->getInverseMatrix());
242        }
243
244        // update the viewport dimensions, incase the window has been resized.
245        sceneView->setViewport(0,0,renderSurface->getWindowWidth(),renderSurface->getWindowHeight());
246
247        // do the update traversal the scene graph - such as updating animations
248        sceneView->update();
249       
250        // do the cull traversal, collect all objects in the view frustum into a sorted set of rendering bins
251        sceneView->cull();
252       
253        // draw the rendering bins.
254        sceneView->draw();
255
256        // Swap Buffers
257        renderSurface->swapBuffers();
258    }
259
260    return 0;
261}
Note: See TracBrowser for help on using the browser.