root/OpenSceneGraph/trunk/include/osgViewer/ViewerEventHandlers @ 13376

Revision 13376, 22.6 kB (checked in by robert, 10 days ago)

Added shaders to support experimental shader based displacement mapping technique osgTerrain::ShaderTerrain?.

  • Property svn:eol-style set to native
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#ifndef OSGVIEWER_VIEWEREVENTHANDLERS
15#define OSGVIEWER_VIEWEREVENTHANDLERS 1
16
17#include <osg/AnimationPath>
18#include <osgText/Text>
19#include <osgGA/GUIEventHandler>
20#include <osgGA/AnimationPathManipulator>
21
22#include <osgViewer/GraphicsWindow>
23#include <osgViewer/Viewer>
24
25#include <osgDB/fstream>
26
27namespace osgViewer {
28
29/** Event handler for adding on screen help to Viewers.*/
30class OSGVIEWER_EXPORT HelpHandler : public osgGA::GUIEventHandler
31{
32    public:
33
34        HelpHandler(osg::ApplicationUsage* au=0);
35
36        void setApplicationUsage(osg::ApplicationUsage* au) { _applicationUsage = au; }
37        osg::ApplicationUsage* getApplicationUsage() { return _applicationUsage.get(); }
38        const osg::ApplicationUsage* getApplicationUsage() const { return _applicationUsage.get(); }
39
40        void setKeyEventTogglesOnScreenHelp(int key) { _keyEventTogglesOnScreenHelp = key; }
41        int getKeyEventTogglesOnScreenHelp() const { return _keyEventTogglesOnScreenHelp; }
42
43        void reset();
44
45        osg::Camera* getCamera() { return _camera.get(); }
46        const osg::Camera* getCamera() const { return _camera.get(); }
47
48        bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa);
49
50        /** Get the keyboard and mouse usage of this manipulator.*/
51        virtual void getUsage(osg::ApplicationUsage& usage) const;
52
53    protected:
54
55        void setUpHUDCamera(osgViewer::ViewerBase* viewer);
56
57        void setUpScene(osgViewer::ViewerBase* viewer);
58
59        osg::ref_ptr<osg::ApplicationUsage> _applicationUsage;
60
61        int                                 _keyEventTogglesOnScreenHelp;
62
63        bool                                _helpEnabled;
64
65        bool                                _initialized;
66        osg::ref_ptr<osg::Camera>           _camera;
67        osg::ref_ptr<osg::Switch>           _switch;
68
69};
70
71/**
72 * Event handler for adding on screen stats reporting to Viewers.
73 */
74class OSGVIEWER_EXPORT StatsHandler : public osgGA::GUIEventHandler
75{
76    public:
77
78        StatsHandler();
79
80        enum StatsType
81        {
82            NO_STATS = 0,
83            FRAME_RATE = 1,
84            VIEWER_STATS = 2,
85            CAMERA_SCENE_STATS = 3,
86            VIEWER_SCENE_STATS = 4,
87            LAST = 5
88        };
89
90        void setKeyEventTogglesOnScreenStats(int key) { _keyEventTogglesOnScreenStats = key; }
91        int getKeyEventTogglesOnScreenStats() const { return _keyEventTogglesOnScreenStats; }
92
93        void setKeyEventPrintsOutStats(int key) { _keyEventPrintsOutStats = key; }
94        int getKeyEventPrintsOutStats() const { return _keyEventPrintsOutStats; }
95
96        void setKeyEventToggleVSync(int key) { _keyEventToggleVSync = key; }
97        int getKeyEventToggleVSync() const { return _keyEventToggleVSync; }
98
99        double getBlockMultiplier() const { return _blockMultiplier; }
100
101        void reset();
102
103        osg::Camera* getCamera() { return _camera.get(); }
104        const osg::Camera* getCamera() const { return _camera.get(); }
105
106        virtual bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa);
107
108        /** Get the keyboard and mouse usage of this manipulator.*/
109        virtual void getUsage(osg::ApplicationUsage& usage) const;
110
111        /** This allows the user to register additional stats lines that will
112            be added to the graph. The stats for these will be gotten from the
113            viewer (viewer->getViewerStats()). The stats can be displayed in
114            either or all of the following ways:
115
116            - A numeric time beside the stat name
117              Requires that an elapsed time be recorded in the viewer's stats
118              for the "timeTakenName".
119            - A bar in the top bar graph
120              Requires that two times (relative to the viewer's start tick) be
121              recorded in the viewer's stats for the "beginTimeName" and
122              "endTimeName".
123            - A line in the bottom graph
124              Requires that an elapsed time be recorded in the viewer's stats
125              for the "timeTakenName" and that the value be used as an average.
126
127            If you don't want a numeric value and a line in the bottom line
128            graph for your value, pass the empty string for timeTakenName. If
129            you don't want a bar in the graph, pass the empty string for
130            beginTimeName and endTimeName.
131
132            @param label                 The label to be displayed to identify the line in the stats.
133            @param textColor             Will be used for the text label, the numeric time and the bottom line graph.
134            @param barColor              Will be used for the bar in the top bar graph.
135            @param timeTakenName         The name to be queried in the viewer stats for the numeric value (also used for the bottom line graph).
136            @param multiplier            The multiplier to apply to the numeric value before displaying it in the stats.
137            @param average               Whether to use the average value of the numeric value.
138            @param averageInInverseSpace Whether to average in inverse space (used for frame rate).
139            @param beginTimeName         The name to be queried in the viewer stats for the begin time for the top bar graph.
140            @param endTimeName           The name to be queried in the viewer stats for the end time for the top bar graph.
141            @param maxValue              The value to use as maximum in the bottom line graph. Stats will be clamped between 0 and that value, and it will be the highest visible value in the graph.
142          */
143        void addUserStatsLine(const std::string& label, const osg::Vec4& textColor, const osg::Vec4& barColor,
144                              const std::string& timeTakenName, float multiplier, bool average, bool averageInInverseSpace,
145                              const std::string& beginTimeName, const std::string& endTimeName, float maxValue);
146
147        void removeUserStatsLine(const std::string& label);
148
149protected:
150
151        void setUpHUDCamera(osgViewer::ViewerBase* viewer);
152        void setWindowSize(int width, int height);
153
154        osg::Geometry* createBackgroundRectangle(const osg::Vec3& pos, const float width, const float height, osg::Vec4& color);
155
156        osg::Geometry* createGeometry(const osg::Vec3& pos, float height, const osg::Vec4& colour, unsigned int numBlocks);
157
158        osg::Geometry* createFrameMarkers(const osg::Vec3& pos, float height, const osg::Vec4& colour, unsigned int numBlocks);
159
160        osg::Geometry* createTick(const osg::Vec3& pos, float height, const osg::Vec4& colour, unsigned int numTicks);
161
162        void createTimeStatsLine(const std::string& lineLabel, osg::Vec3 pos,
163                                 const osg::Vec4& textColor, const osg::Vec4& barColor, osg::Stats* viewerStats, osg::Stats* stats,
164                                 const std::string& timeTakenName, float multiplier, bool average, bool averageInInverseSpace,
165                                 const std::string& beginTimeName, const std::string& endTimeName);
166
167        void createCameraTimeStats(osg::Vec3& pos, bool acquireGPUStats, osg::Stats* viewerStats, osg::Camera* camera);
168
169        void setUpScene(osgViewer::ViewerBase* viewer);
170
171        void updateThreadingModelText();
172
173        int                                 _keyEventTogglesOnScreenStats;
174        int                                 _keyEventPrintsOutStats;
175        int                                 _keyEventToggleVSync;
176
177        int                                 _statsType;
178
179        bool                                _initialized;
180        osg::ref_ptr<osg::Camera>           _camera;
181
182        osg::ref_ptr<osg::Switch>           _switch;
183
184        osg::ref_ptr<osg::Geode>            _statsGeode;
185
186        ViewerBase::ThreadingModel          _threadingModel;
187        osg::ref_ptr<osgText::Text>         _threadingModelText;
188
189        unsigned int                        _frameRateChildNum;
190        unsigned int                        _viewerChildNum;
191        unsigned int                        _cameraSceneChildNum;
192        unsigned int                        _viewerSceneChildNum;
193        unsigned int                        _numBlocks;
194        double                              _blockMultiplier;
195
196        float                               _statsWidth;
197        float                               _statsHeight;
198
199        std::string                         _font;
200        float                               _startBlocks;
201        float                               _leftPos;
202        float                               _characterSize;
203        float                               _lineHeight;
204
205        struct UserStatsLine
206        {
207            std::string label;
208            osg::Vec4 textColor;
209            osg::Vec4 barColor;
210            std::string timeTakenName;
211            float multiplier;
212            bool average;
213            bool averageInInverseSpace;
214            std::string beginTimeName;
215            std::string endTimeName;
216            float maxValue;
217
218            UserStatsLine(const std::string& label_, const osg::Vec4& textColor_, const osg::Vec4& barColor_,
219                          const std::string& timeTakenName_, float multiplier_, bool average_, bool averageInInverseSpace_,
220                          const std::string& beginTimeName_, const std::string& endTimeName_, float maxValue_)
221                : label(label_), textColor(textColor_), barColor(barColor_),
222                  timeTakenName(timeTakenName_), multiplier(multiplier_), average(average_), averageInInverseSpace(averageInInverseSpace_),
223                  beginTimeName(beginTimeName_), endTimeName(endTimeName_), maxValue(maxValue_)
224            {
225            }
226        };
227
228        typedef std::vector<UserStatsLine>  UserStatsLines;
229        UserStatsLines                      _userStatsLines;
230
231};
232
233/** Event handler allowing to change the screen resolution (in windowed mode) and toggle between fullscreen and windowed mode. */
234class OSGVIEWER_EXPORT WindowSizeHandler : public osgGA::GUIEventHandler
235{
236public:
237
238        WindowSizeHandler();
239
240        /** Get the keyboard and mouse usage of this manipulator.*/
241        virtual void getUsage(osg::ApplicationUsage &usage) const;
242
243        void setKeyEventToggleFullscreen(int key) { _keyEventToggleFullscreen = key; }
244        int getKeyEventToggleFullscreen() const { return _keyEventToggleFullscreen; }
245
246        void setToggleFullscreen(bool flag) { _toggleFullscreen = flag; }
247        bool getToggleFullscreen() const { return _toggleFullscreen; }
248
249        void setKeyEventWindowedResolutionUp(int key) { _keyEventWindowedResolutionUp = key; }
250        int getKeyEventWindowedResolutionUp() const { return _keyEventWindowedResolutionUp; }
251        void setKeyEventWindowedResolutionDown(int key) { _keyEventWindowedResolutionDown = key; }
252        int getKeyEventWindowedResolutionDown() const { return _keyEventWindowedResolutionDown; }
253
254        void setChangeWindowedResolution(bool flag) { _changeWindowedResolution = flag; }
255        bool getChangeWindowedResolution() const { return _changeWindowedResolution; }
256
257        virtual bool handle(const osgGA::GUIEventAdapter &ea, osgGA::GUIActionAdapter &aa);
258
259protected:
260
261        void toggleFullscreen(osgViewer::GraphicsWindow *window);
262        void changeWindowedResolution(osgViewer::GraphicsWindow *window, bool increase);
263
264        unsigned int getNearestResolution(int screenWidth, int screenHeight, int width, int height) const;
265
266        int                     _keyEventToggleFullscreen;
267        bool                    _toggleFullscreen;
268
269        int                     _keyEventWindowedResolutionUp;
270        int                     _keyEventWindowedResolutionDown;
271        bool                    _changeWindowedResolution;
272        std::vector<osg::Vec2>  _resolutionList;
273        int                     _currentResolutionIndex;
274};
275
276/** Event handler allowing to change the viewer threading model */
277class OSGVIEWER_EXPORT ThreadingHandler : public osgGA::GUIEventHandler
278{
279public:
280
281        ThreadingHandler();
282
283        /** Get the keyboard and mouse usage of this manipulator.*/
284        virtual void getUsage(osg::ApplicationUsage &usage) const;
285
286        void setKeyEventChangeThreadingModel(int key) { _keyEventChangeThreadingModel = key; }
287        int getKeyEventChangeThreadingModel() const { return _keyEventChangeThreadingModel; }
288
289        void setChangeThreadingModel(bool flag) { _changeThreadingModel = flag; }
290        bool getChangeThreadingModel() const { return _changeThreadingModel; }
291
292        void setKeyEventChangeEndBarrierPosition(int key) { _keyEventChangeEndBarrierPosition = key; }
293        int getKeyEventChangeEndBarrierPosition() const { return _keyEventChangeEndBarrierPosition; }
294
295        void setChangeEndBarrierPosition(bool flag) { _changeEndBarrierPosition = flag; }
296        bool getChangeEndBarrierPosition() const { return _changeEndBarrierPosition; }
297
298        bool handle(const osgGA::GUIEventAdapter &ea, osgGA::GUIActionAdapter &aa);
299
300protected:
301
302        int             _keyEventChangeThreadingModel;
303        bool            _changeThreadingModel;
304
305        int             _keyEventChangeEndBarrierPosition;
306        bool            _changeEndBarrierPosition;
307
308        osg::Timer_t    _tickOrLastKeyPress;
309        bool            _done;
310};
311
312/**
313 * Event handler allowing the user to record the animation "path" of a camera. In it's current
314 * implementation, this handler cannot guarantee the final view matrix is correct; it is
315 * conceivable that the matrix may be one frame off. Eh--not a big deal! :)
316 * TODO: Write the file as we go, not when it's all done.
317 * TODO: Create an osgviewer on-screen indication that animation is taking place.
318*/
319class OSGVIEWER_EXPORT RecordCameraPathHandler : public osgGA::GUIEventHandler
320{
321public:
322
323        RecordCameraPathHandler(const std::string &filename = "saved_animation.path", float fps = 25.0f);
324
325        void setKeyEventToggleRecord(int key) { _keyEventToggleRecord = key; }
326        int getKeyEventToggleRecord() const { return _keyEventToggleRecord; }
327
328        void setKeyEventTogglePlayback(int key) { _keyEventTogglePlayback = key; }
329        int getKeyEventTogglePlayback() const { return _keyEventTogglePlayback; }
330
331        void setAutoIncrementFilename( bool autoinc = true ) { _autoinc = autoinc?0:-1; }
332
333        virtual void getUsage(osg::ApplicationUsage &usage) const;
334
335        bool handle(const osgGA::GUIEventAdapter &ea, osgGA::GUIActionAdapter &aa);
336
337protected:
338
339        std::string                                     _filename;
340        int                                             _autoinc;
341        osgDB::ofstream                                 _fout;
342
343        int                                             _keyEventToggleRecord;
344        int                                             _keyEventTogglePlayback;
345
346
347        bool                                            _currentlyRecording;
348        bool                                            _currentlyPlaying;
349        double                                          _interval;
350        double                                          _delta;
351        osg::Timer_t                                    _animStartTime;
352        osg::Timer_t                                    _lastFrameTime;
353        osg::ref_ptr<osg::AnimationPath>                _animPath;
354        osg::ref_ptr<osgGA::AnimationPathManipulator>   _animPathManipulator;
355        osg::ref_ptr<osgGA::CameraManipulator>          _oldManipulator;
356};
357
358/** Event handler for increase/decreasing LODScale.*/
359class OSGVIEWER_EXPORT LODScaleHandler : public osgGA::GUIEventHandler
360{
361    public:
362
363        LODScaleHandler();
364
365        void setKeyEventIncreaseLODScale(int key) { _keyEventIncreaseLODScale = key; }
366        int getKeyEventIncreaseLODScale() const { return _keyEventIncreaseLODScale; }
367
368        void setKeyEventDecreaseLODScale(int key) { _keyEventDecreaseLODScale = key; }
369        int getKeyEventDecreaseLODScale() const { return _keyEventDecreaseLODScale; }
370
371        bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa);
372
373        /** Get the keyboard and mouse usage of this manipulator.*/
374        virtual void getUsage(osg::ApplicationUsage& usage) const;
375
376    protected:
377
378
379        int _keyEventIncreaseLODScale;
380        int _keyEventDecreaseLODScale;
381
382
383};
384
385/** Event handler for toggling SyncToVBlank.*/
386class OSGVIEWER_EXPORT ToggleSyncToVBlankHandler : public osgGA::GUIEventHandler
387{
388    public:
389
390        ToggleSyncToVBlankHandler();
391
392        void setKeyEventToggleSyncToVBlankHandler(int key) { _keyEventToggleSyncToVBlank = key; }
393        int getKeyEventToggleSyncToVBlankHandler() const { return _keyEventToggleSyncToVBlank; }
394
395        bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa);
396
397        /** Get the keyboard and mouse usage of this manipulator.*/
398        virtual void getUsage(osg::ApplicationUsage& usage) const;
399
400    protected:
401
402
403        int _keyEventToggleSyncToVBlank;
404
405
406};
407
408
409/** Event handler that will capture the screen on key press. */
410class OSGVIEWER_EXPORT ScreenCaptureHandler : public osgGA::GUIEventHandler
411{
412    public:
413
414        /** Abstract base class for what to do when a screen capture happens. */
415        class CaptureOperation : public osg::Referenced
416        {
417            public:
418                virtual void operator()(const osg::Image& image, const unsigned int context_id) = 0;
419        };
420
421        /** Concrete implementation of a CaptureOperation that writes the screen capture to a file. */
422        class OSGVIEWER_EXPORT WriteToFile : public CaptureOperation
423        {
424            public:
425                enum SavePolicy
426                {
427                    OVERWRITE,
428                    SEQUENTIAL_NUMBER
429                    // ... any others?
430                };
431
432                WriteToFile(const std::string& filename, const std::string& extension, SavePolicy savePolicy = SEQUENTIAL_NUMBER);
433
434                virtual void operator()(const osg::Image& image, const unsigned int context_id);
435
436                void setSavePolicy(SavePolicy savePolicy) { _savePolicy = savePolicy; }
437                SavePolicy getSavePolicy() const { return _savePolicy; }
438
439            protected:
440
441                WriteToFile& operator = (const WriteToFile&) { return *this; }
442
443                const std::string _filename;
444                const std::string _extension;
445
446                SavePolicy _savePolicy;
447
448                std::vector<unsigned int> _contextSaveCounter;
449        };
450
451        /** @param numFrames >0: capture that number of frames. <0: capture all frames, call stopCapture() to stop it. */
452        ScreenCaptureHandler(CaptureOperation* defaultOperation = 0, int numFrames = 1);
453
454        void setKeyEventTakeScreenShot(int key) { _keyEventTakeScreenShot = key; }
455        int getKeyEventTakeScreenShot() const { return _keyEventTakeScreenShot; }
456
457        void setKeyEventToggleContinuousCapture(int key) { _keyEventToggleContinuousCapture = key; }
458        int getKeyEventToggleContinuousCapture() const { return _keyEventToggleContinuousCapture; }
459
460        void setCaptureOperation(CaptureOperation* operation);
461        CaptureOperation* getCaptureOperation() const;
462
463        // aa will point to an osgViewer::View, so we will take a screenshot
464        // of that view's graphics contexts.
465        virtual bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa);
466
467        /** Capture the given viewer's views on the next frame. */
468        virtual void captureNextFrame(osgViewer::ViewerBase& viewer);
469
470        /** Set the number of frames to capture.
471            @param numFrames >0: capture that number of frames. <0: capture all frames, call stopCapture() to stop it. */
472        void setFramesToCapture(int numFrames);
473
474        /** Get the number of frames to capture. */
475        int getFramesToCapture() const;
476
477        /** Start capturing any viewer(s) the handler is attached to at the
478            end of the next frame. */
479        void startCapture();
480
481        /** Stop capturing. */
482        void stopCapture();
483
484        /** Get the keyboard and mouse usage of this manipulator.*/
485        virtual void getUsage(osg::ApplicationUsage& usage) const;
486
487    protected:
488        bool _startCapture;
489        bool _stopCapture;
490
491        int _keyEventTakeScreenShot;
492        int _keyEventToggleContinuousCapture;
493        // there could be a key to start taking screenshots every new frame
494
495        osg::ref_ptr<CaptureOperation>          _operation;
496        osg::ref_ptr<osg::Camera::DrawCallback> _callback;
497
498        void addCallbackToViewer(osgViewer::ViewerBase& viewer);
499        void removeCallbackFromViewer(osgViewer::ViewerBase& viewer);
500        osg::Camera* findAppropriateCameraForCallback(osgViewer::ViewerBase& viewer);
501};
502
503/** InteractiveImage is an event handler that computes the mouse coordinates in an images coordinate frame
504  * and then passes keyboard and mouse events to it.  This event handler is useful for vnc or browser
505  * surfaces in the 3D scene.*/
506class OSGVIEWER_EXPORT InteractiveImageHandler : public osgGA::GUIEventHandler, public osg::Drawable::CullCallback
507{
508public:
509
510    /// Constructor to use when the InteractiveImage is in the 3D scene (i.e. not in a fullscreen HUD overlay).
511    InteractiveImageHandler(osg::Image* image);
512    /// Constructor to use when the InteractiveImage is in a fullscreen HUD overlay.
513    InteractiveImageHandler(osg::Image* image, osg::Texture2D* texture, osg::Camera* camera);
514
515    META_Object(osgViewer, InteractiveImageHandler);
516
517    virtual bool handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter& aa, osg::Object*, osg::NodeVisitor* nv);
518
519    virtual bool cull(osg::NodeVisitor* nv, osg::Drawable* drawable, osg::RenderInfo* renderInfo) const;
520
521protected:
522
523    virtual ~InteractiveImageHandler() {}
524
525    InteractiveImageHandler() {}
526
527    InteractiveImageHandler(const InteractiveImageHandler&,const osg::CopyOp& = osg::CopyOp::SHALLOW_COPY):
528        osg::Object(), osgGA::GUIEventHandler(), osg::Drawable::CullCallback(), _fullscreen(false) {}
529
530    bool mousePosition(osgViewer::View* view, osg::NodeVisitor* nv, const osgGA::GUIEventAdapter& ea, int& x, int &y) const;
531
532    void resize(int width, int height);
533
534    osg::observer_ptr<osg::Image>   _image;
535    osg::observer_ptr<osg::Texture2D> _texture;
536
537    bool                            _fullscreen;
538    osg::observer_ptr<osg::Camera>  _camera;
539
540};
541
542}
543
544#endif
Note: See TracBrowser for help on using the browser.