source: GTP/trunk/Lib/Geom/OgreStuff/include/ExampleRefAppFrameListener.h @ 1809

Revision 1809, 11.7 KB checked in by gumbau, 18 years ago (diff)
Line 
1/*
2-----------------------------------------------------------------------------
3This source file is part of OGRE
4    (Object-oriented Graphics Rendering Engine)
5For the latest info, see http://www.ogre3d.org/
6
7Copyright (c) 2000-2005 The OGRE Team
8Also see acknowledgements in Readme.html
9
10You may use this sample code for anything you like, it is not covered by the
11LGPL like the rest of the engine.
12-----------------------------------------------------------------------------
13*/
14
15/*
16-----------------------------------------------------------------------------
17Filename:    ExampleFrameListener.h
18Description: Defines an example frame listener which responds to frame events.
19             This frame listener just moves a specified camera around based on
20             keyboard and mouse movements.
21             Mouse:    Freelook
22             W or Up:  Forward
23             S or Down:Backward
24             A:           Step left
25             D:        Step right
26             PgUp:     Move upwards
27             PgDown:   Move downwards
28             O/P:       Yaw the root scene node (and it's children)
29             I/K:       Pitch the root scene node (and it's children)
30             F:           Toggle frame rate stats on/off
31-----------------------------------------------------------------------------
32*/
33
34#ifndef __ExampleRefAppFrameListener_H__
35#define __ExampleRefAppFrameListener_H__
36
37#include "OgreReferenceAppLayer.h"
38#include "OgreKeyEvent.h"
39#include "OgreEventListeners.h"
40#include "OgreException.h"
41
42using namespace Ogre;
43using namespace OgreRefApp;
44
45class ExampleRefAppFrameListener: public FrameListener, public KeyListener
46{
47private:
48    void updateStats(void)
49    {
50        static String currFps = "Current FPS: ";
51        static String avgFps = "Average FPS: ";
52        static String bestFps = "Best FPS: ";
53        static String worstFps = "Worst FPS: ";
54        static String tris = "Triangle Count: ";
55
56        // update stats when necessary
57        OverlayElement* guiAvg = OverlayManager::getSingleton().getOverlayElement("Core/AverageFps");
58        OverlayElement* guiCurr = OverlayManager::getSingleton().getOverlayElement("Core/CurrFps");
59        OverlayElement* guiBest = OverlayManager::getSingleton().getOverlayElement("Core/BestFps");
60        OverlayElement* guiWorst = OverlayManager::getSingleton().getOverlayElement("Core/WorstFps");
61       
62        guiAvg->setCaption(avgFps + StringConverter::toString(mWindow->getAverageFPS()));
63        guiCurr->setCaption(currFps + StringConverter::toString(mWindow->getLastFPS()));
64        guiBest->setCaption(bestFps + StringConverter::toString(mWindow->getBestFPS())
65            +" "+StringConverter::toString(mWindow->getBestFrameTime())+" ms");
66        guiWorst->setCaption(worstFps + StringConverter::toString(mWindow->getWorstFPS())
67            +" "+StringConverter::toString(mWindow->getWorstFrameTime())+" ms");
68           
69        OverlayElement* guiTris = OverlayManager::getSingleton().getOverlayElement("Core/NumTris");
70        guiTris->setCaption(tris + StringConverter::toString(mWindow->getTriangleCount()));
71
72        OverlayElement* guiDbg = OverlayManager::getSingleton().getOverlayElement("Core/DebugText");
73        guiDbg->setCaption(mWindow->getDebugText());
74    }
75   
76public:
77    // Constructor takes a RenderWindow because it uses that to determine input context
78    ExampleRefAppFrameListener(RenderWindow* win, CollideCamera* cam, bool useBufferedInputKeys = false, bool useBufferedInputMouse = false)
79    {
80        mUseBufferedInputKeys = useBufferedInputKeys;
81                mUseBufferedInputMouse = useBufferedInputMouse;
82                mInputTypeSwitchingOn = mUseBufferedInputKeys || mUseBufferedInputMouse;
83
84                if (mInputTypeSwitchingOn)
85                {
86            mEventProcessor = new EventProcessor();
87                        mEventProcessor->initialise(win);
88                        mEventProcessor->startProcessingEvents();
89                        mEventProcessor->addKeyListener(this);
90                        mInputDevice = mEventProcessor->getInputReader();
91
92                }
93        else
94        {
95            mInputDevice = PlatformManager::getSingleton().createInputReader();
96            mInputDevice->initialise(win,true, true);
97        }
98        mCamera = cam;
99        mWindow = win;
100        mStatsOn = true;
101                mNumScreenShots = 0;
102                mTimeUntilNextToggle = 0;
103
104        showDebugOverlay(true);
105    }
106    virtual ~ExampleRefAppFrameListener()
107    {
108                if (mInputTypeSwitchingOn)
109                {
110            delete mEventProcessor;
111                }
112        else
113        {
114            PlatformManager::getSingleton().destroyInputReader( mInputDevice );
115        }
116    }
117
118    bool processUnbufferedKeyInput(const FrameEvent& evt)
119    {
120        if (mInputDevice->isKeyDown(KC_A))
121        {
122            // Move camera left
123            mTranslateVector.x = -mMoveScale;
124        }
125
126        if (mInputDevice->isKeyDown(KC_D))
127        {
128            // Move camera RIGHT
129            mTranslateVector.x = mMoveScale;
130        }
131
132        /* Move camera forward by keypress. */
133        if (mInputDevice->isKeyDown(KC_UP) || mInputDevice->isKeyDown(KC_W) )
134        {
135            mTranslateVector.z = -mMoveScale;
136        }
137        /* Move camera forward by mousewheel. */
138        if( mInputDevice->getMouseRelativeZ() > 0 )
139        {
140            mTranslateVector.z = -mMoveScale * 8.0;
141        }
142
143        /* Move camera backward by keypress. */
144        if (mInputDevice->isKeyDown(KC_DOWN) || mInputDevice->isKeyDown(KC_S) )
145        {
146            mTranslateVector.z = mMoveScale;
147        }
148
149        /* Move camera backward by mouse wheel. */
150        if( mInputDevice->getMouseRelativeZ() < 0 )
151        {
152            mTranslateVector.z = mMoveScale * 8.0;
153        }
154
155        if (mInputDevice->isKeyDown(KC_PGUP))
156        {
157            // Move camera up
158            mTranslateVector.y = mMoveScale;
159        }
160
161        if (mInputDevice->isKeyDown(KC_PGDOWN))
162        {
163            // Move camera down
164            mTranslateVector.y = -mMoveScale;
165        }
166
167        if (mInputDevice->isKeyDown(KC_RIGHT))
168        {
169            mCamera->yaw(-mRotScale);
170        }
171               
172        if (mInputDevice->isKeyDown(KC_LEFT))
173        {
174            mCamera->yaw(mRotScale);
175        }
176
177        if( mInputDevice->isKeyDown( KC_ESCAPE) )
178        {           
179            return false;
180        }
181
182                // see if switching is on, and you want to toggle
183        if (mInputTypeSwitchingOn && mInputDevice->isKeyDown(KC_M) && mTimeUntilNextToggle <= 0)
184        {
185                        switchMouseMode();
186            mTimeUntilNextToggle = 1;
187        }
188
189        if (mInputTypeSwitchingOn && mInputDevice->isKeyDown(KC_K) && mTimeUntilNextToggle <= 0)
190        {
191                        // must be going from immediate keyboard to buffered keyboard
192                        switchKeyMode();
193            mTimeUntilNextToggle = 1;
194        }
195        if (mInputDevice->isKeyDown(KC_F) && mTimeUntilNextToggle <= 0)
196        {
197            mStatsOn = !mStatsOn;
198            showDebugOverlay(mStatsOn);
199
200            mTimeUntilNextToggle = 1;
201        }
202
203        if (mInputDevice->isKeyDown(KC_SYSRQ) && mTimeUntilNextToggle <= 0)
204        {
205                        StringUtil::StrStreamType tmp;
206                        tmp << "screenshot_" << ++mNumScreenShots << ".png";
207            mWindow->writeContentsToFile(tmp.str());
208            mTimeUntilNextToggle = 0.5;
209                        mWindow->setDebugText(String("Wrote ") + tmp.str());
210        }
211
212
213
214        // Return true to continue rendering
215        return true;
216    }
217
218    bool processUnbufferedMouseInput(const FrameEvent& evt)
219    {
220        /* Rotation factors, may not be used if the second mouse button is pressed. */
221
222        /* If the second mouse button is pressed, then the mouse movement results in
223           sliding the camera, otherwise we rotate. */
224        if( mInputDevice->getMouseButton( 1 ) )
225        {
226            mTranslateVector.x += mInputDevice->getMouseRelativeX() * 0.13;
227            mTranslateVector.y -= mInputDevice->getMouseRelativeY() * 0.13;
228        }
229        else
230        {
231            mRotX = Degree(-mInputDevice->getMouseRelativeX() * 0.13);
232            mRotY = Degree(-mInputDevice->getMouseRelativeY() * 0.13);
233        }
234
235
236                return true;
237        }
238
239        void moveCamera()
240        {
241
242        // Make all the changes to the camera
243        // Note that YAW direction is around a fixed axis (freelook style) rather than a natural YAW (e.g. airplane)
244        mCamera->yaw(mRotX);
245        mCamera->pitch(mRotY);
246        mCamera->translate(mTranslateVector);
247
248
249        }
250
251    void showDebugOverlay(bool show)
252    {   
253        Overlay* o = OverlayManager::getSingleton().getByName("Core/DebugOverlay");
254        if (!o)
255            OGRE_EXCEPT( Exception::ERR_ITEM_NOT_FOUND, "Could not find overlay Core/DebugOverlay",
256                "showDebugOverlay" );
257        if (show)
258        {
259            o->show();
260        }
261        else
262        {
263            o->hide();
264        }
265    }
266
267    // Override frameEnded event
268    bool frameEnded(const FrameEvent& evt)
269    {
270
271        if (!mInputTypeSwitchingOn)
272        {
273            mInputDevice->capture();
274        }
275
276
277                if ( !mUseBufferedInputMouse || !mUseBufferedInputKeys)
278                {
279                        // one of the input modes is immediate, so setup what is needed for immediate mouse/key movement
280                        if (mTimeUntilNextToggle >= 0)
281                                mTimeUntilNextToggle -= evt.timeSinceLastFrame;
282
283                        // If this is the first frame, pick a speed
284                        if (evt.timeSinceLastFrame == 0)
285                        {
286                                mMoveScale = 0.5;
287                                mRotScale = 0.1;
288                        }
289                        // Otherwise scale movement units by time passed since last frame
290                        else
291                        {
292                                // Move about 50 units per second,
293                                mMoveScale = 50.0 * evt.timeSinceLastFrame;
294                                // Take about 10 seconds for full rotation
295                                mRotScale = Degree(36 * evt.timeSinceLastFrame);
296                        }
297                        mRotX = 0;
298            mRotY = 0;
299                mTranslateVector = Vector3::ZERO;
300                }
301
302        if (mUseBufferedInputKeys)
303        {
304            // no need to do any processing here, it is handled by event processor and
305                        // you get the results as KeyEvents
306        }
307        else
308        {
309            if (processUnbufferedKeyInput(evt) == false)
310                        {
311                                return false;
312                        }
313        }
314        if (mUseBufferedInputMouse)
315        {
316            // no need to do any processing here, it is handled by event processor and
317                        // you get the results as MouseEvents
318        }
319        else
320        {
321            if (processUnbufferedMouseInput(evt) == false)
322                        {
323                                return false;
324                        }
325        }
326
327                if ( !mUseBufferedInputMouse || !mUseBufferedInputKeys)
328                {
329                        // one of the input modes is immediate, so update the movement vector
330
331                        moveCamera();
332
333                }
334
335        // Perform simulation step
336        World::getSingleton().simulationStep(evt.timeSinceLastFrame);
337
338        updateStats();
339                return true;
340    }
341
342        void switchMouseMode()
343        {
344        mUseBufferedInputMouse = !mUseBufferedInputMouse;
345                mInputDevice->setBufferedInput(mUseBufferedInputKeys, mUseBufferedInputMouse);
346        }
347        void switchKeyMode()
348        {
349        mUseBufferedInputKeys = !mUseBufferedInputKeys;
350                mInputDevice->setBufferedInput(mUseBufferedInputKeys, mUseBufferedInputMouse);
351        }
352
353        void keyClicked(KeyEvent* e)
354        {
355                if (e->getKeyChar() == 'm')
356                {
357                        switchMouseMode();
358                }
359                else if (e->getKeyChar() == 'k')
360                {
361
362                        switchKeyMode();
363                }
364
365        }
366        void keyPressed(KeyEvent* e) {}
367        void keyReleased(KeyEvent* e) {}
368
369protected:
370    EventProcessor* mEventProcessor;
371    InputReader* mInputDevice;
372    CollideCamera* mCamera;
373    Vector3 mTranslateVector;
374    RenderWindow* mWindow;
375    bool mStatsOn;
376    bool mUseBufferedInputKeys, mUseBufferedInputMouse, mInputTypeSwitchingOn;
377        unsigned int mNumScreenShots;
378    float mMoveScale;
379    Radian mRotScale;
380    // just to stop toggles flipping too fast
381    Real mTimeUntilNextToggle ;
382    Radian mRotX, mRotY;
383
384};
385
386#endif
Note: See TracBrowser for help on using the repository browser.