source: GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/src/OBAOgreFrameListenerMode.cpp @ 961

Revision 961, 14.0 KB checked in by igarcia, 18 years ago (diff)
Line 
1
2#include "OBAOgreFrameListenerMode.h"
3
4namespace OBA {
5
6void OSceneCallback::OnCameraCreate(Ogre::Camera* pCamera, TiXmlElement* pCameraDesc)
7{
8        // If a camera of name "FirstCamera" is loaded, it will be set as the default current
9        if(pCamera->getName() == "FirstCamera")
10                Ogre::Root::getSingleton().getAutoCreatedWindow()->getViewport(0)->setCamera(pCamera);
11}
12
13OgreFrameListenerMode::OgreFrameListenerMode(Ogre::RenderWindow *win, unsigned int ogreFrameListenerModeHandle, bool useBufferedInputKeys, bool useBufferedInputMouse)
14{
15        mOgreFrameListenerModeHandle = ogreFrameListenerModeHandle;
16
17        mDebugOverlay = Ogre::OverlayManager::getSingleton().getByName("Core/DebugOverlay");
18       
19        mInputTypeSwitchingOn = useBufferedInputKeys || useBufferedInputMouse;
20        mUseBufferedInputKeys = useBufferedInputKeys;
21        mUseBufferedInputMouse = useBufferedInputMouse;
22
23        mRotateSpeed = 36;
24        mMoveSpeed = 100;
25
26    mWindow = win;
27
28        Ogre::LogManager::getSingleton().logMessage("mWindow.IsClosed->" + Ogre::StringConverter::toString(mWindow->isClosed()));
29
30    mStatsOn = true;
31        mNumScreenShots = 0;
32        mTimeUntilNextToggle = 0;
33    mSceneDetailIndex = 0;
34    mMoveScale = 0.0f;
35    mRotScale = 0.0f;
36        mTranslateVector = Ogre::Vector3::ZERO;
37    mAniso = 1;
38        mFiltering = Ogre::TFO_BILINEAR;
39
40    showDebugOverlay(true);
41}
42
43OgreFrameListenerMode::~OgreFrameListenerMode()
44{
45}
46
47void OgreFrameListenerMode::updateStats(void)
48{
49        static Ogre::String currFps = "Current FPS: ";
50    static Ogre::String avgFps = "Average FPS: ";
51    static Ogre::String bestFps = "Best FPS: ";
52    static Ogre::String worstFps = "Worst FPS: ";
53    static Ogre::String tris = "Triangle Count: ";
54
55    // update stats when necessary
56    try {
57        Ogre::OverlayElement* guiAvg = Ogre::OverlayManager::getSingleton().getOverlayElement("Core/AverageFps");
58        Ogre::OverlayElement* guiCurr = Ogre::OverlayManager::getSingleton().getOverlayElement("Core/CurrFps");
59        Ogre::OverlayElement* guiBest = Ogre::OverlayManager::getSingleton().getOverlayElement("Core/BestFps");
60        Ogre::OverlayElement* guiWorst = Ogre::OverlayManager::getSingleton().getOverlayElement("Core/WorstFps");
61
62        const Ogre::RenderTarget::FrameStats& stats = mWindow->getStatistics();
63
64        guiAvg->setCaption(avgFps + Ogre::StringConverter::toString(stats.avgFPS));
65        guiCurr->setCaption(currFps + Ogre::StringConverter::toString(stats.lastFPS));
66        guiBest->setCaption(bestFps + Ogre::StringConverter::toString(stats.bestFPS)
67            +" "+ Ogre::StringConverter::toString(stats.bestFrameTime)+" ms");
68        guiWorst->setCaption(worstFps + Ogre::StringConverter::toString(stats.worstFPS)
69            +" "+ Ogre::StringConverter::toString(stats.worstFrameTime)+" ms");
70
71        Ogre::OverlayElement* guiTris = Ogre::OverlayManager::getSingleton().getOverlayElement("Core/NumTris");
72        guiTris->setCaption(tris + Ogre::StringConverter::toString(stats.triangleCount));
73
74        Ogre::OverlayElement* guiDbg = Ogre::OverlayManager::getSingleton().getOverlayElement("Core/DebugText");
75        guiDbg->setCaption(mWindow->getDebugText());
76    }
77    catch(...)
78    {
79        // ignore
80    }
81}
82
83bool OgreFrameListenerMode::processUnbufferedKeyInput(const Ogre::FrameEvent& evt)
84{
85        if (mInputDevice->isKeyDown(Ogre::KC_A))
86    {
87        // Move camera left
88        mTranslateVector.x = -mMoveScale;
89    }
90
91        if (mInputDevice->isKeyDown(Ogre::KC_D))
92    {
93        // Move camera RIGHT
94        mTranslateVector.x = mMoveScale;
95    }
96
97    /* Move camera forward by keypress. */
98        if (mInputDevice->isKeyDown(Ogre::KC_UP) || mInputDevice->isKeyDown(Ogre::KC_W) )
99    {
100        mTranslateVector.z = -mMoveScale;
101    }
102
103    /* Move camera backward by keypress. */
104        if (mInputDevice->isKeyDown(Ogre::KC_DOWN) || mInputDevice->isKeyDown(Ogre::KC_S) )
105    {
106        mTranslateVector.z = mMoveScale;
107    }
108
109        if (mInputDevice->isKeyDown(Ogre::KC_PGUP))
110    {
111        // Move camera up
112        mTranslateVector.y = mMoveScale;
113    }
114
115        if (mInputDevice->isKeyDown(Ogre::KC_PGDOWN))
116    {
117        // Move camera down
118        mTranslateVector.y = -mMoveScale;
119    }
120
121        if (mInputDevice->isKeyDown(Ogre::KC_RIGHT))
122    {
123        mCamera->yaw(-mRotScale);
124    }
125       
126        if (mInputDevice->isKeyDown(Ogre::KC_LEFT))
127    {
128        mCamera->yaw(mRotScale);
129    }
130
131        // We can cycle cameras with the 'c' key
132        if (mInputDevice->isKeyDown(Ogre::KC_C) && (mTimeUntilNextToggle <= 0))
133        {                       
134
135                Ogre::Camera* firstCam;
136                Ogre::Camera* currentCam = mWindow->getViewport(0)->getCamera();
137
138                Ogre::Viewport* vp = mWindow->getViewport(0);
139
140                Ogre::SceneManager::CameraIterator it = mSceneMgr->getCameraIterator();
141
142                if(it.hasMoreElements())
143                {
144                        firstCam = it.peekNextValue();
145                }
146
147                while(it.hasMoreElements())
148                {                       
149                        Ogre::Camera* cam = it.getNext();
150
151                        if(currentCam == cam)
152                        {
153                                Ogre::Camera* camera = it.hasMoreElements() ? it.getNext() : firstCam;
154                                vp->setCamera(camera);                                 
155                        }
156                }
157                mTimeUntilNextToggle = 0.5f;           
158        }
159
160        // see if switching is on, and you want to toggle
161        if (mInputTypeSwitchingOn && mInputDevice->isKeyDown(Ogre::KC_M) && mTimeUntilNextToggle <= 0)
162    {
163                switchMouseMode();
164        mTimeUntilNextToggle = 1;
165    }
166
167        if (mInputTypeSwitchingOn && mInputDevice->isKeyDown(Ogre::KC_K) && mTimeUntilNextToggle <= 0)
168    {
169                // must be going from immediate keyboard to buffered keyboard
170                switchKeyMode();
171        mTimeUntilNextToggle = 1;
172    }
173        if (mInputDevice->isKeyDown(Ogre::KC_F) && mTimeUntilNextToggle <= 0)
174    {
175        mStatsOn = !mStatsOn;
176        showDebugOverlay(mStatsOn);
177
178        mTimeUntilNextToggle = 1;
179    }
180        if (mInputDevice->isKeyDown(Ogre::KC_T) && mTimeUntilNextToggle <= 0)
181    {
182        switch(mFiltering)
183        {
184                case Ogre::TFO_BILINEAR:
185            mFiltering = Ogre::TFO_TRILINEAR;
186            mAniso = 1;
187            break;
188        case Ogre::TFO_TRILINEAR:
189            mFiltering = Ogre::TFO_ANISOTROPIC;
190            mAniso = 8;
191            break;
192        case Ogre::TFO_ANISOTROPIC:
193            mFiltering = Ogre::TFO_BILINEAR;
194            mAniso = 1;
195            break;
196        default:
197            break;
198        }
199        Ogre::MaterialManager::getSingleton().setDefaultTextureFiltering(mFiltering);
200        Ogre::MaterialManager::getSingleton().setDefaultAnisotropy(mAniso);
201
202
203        showDebugOverlay(mStatsOn);
204
205        mTimeUntilNextToggle = 1;
206    }
207
208    if (mInputDevice->isKeyDown(Ogre::KC_SYSRQ) && mTimeUntilNextToggle <= 0)
209    {
210                char tmp[20];
211                sprintf(tmp, "screenshot_%d.png", ++mNumScreenShots);
212        mWindow->writeContentsToFile(tmp);
213        mTimeUntilNextToggle = 0.5;
214                mWindow->setDebugText(Ogre::String("Wrote ") + tmp);
215    }
216       
217        if (mInputDevice->isKeyDown(Ogre::KC_R) && mTimeUntilNextToggle <=0)
218        {
219                mSceneDetailIndex = (mSceneDetailIndex+1)%3 ;
220                switch(mSceneDetailIndex) {
221                        case 0 : mCamera->setPolygonMode(Ogre::PM_SOLID) ; break ;
222                        case 1 : mCamera->setPolygonMode(Ogre::PM_WIREFRAME) ; break ;
223                        case 2 : mCamera->setPolygonMode(Ogre::PM_POINTS) ; break ;
224                }
225                mTimeUntilNextToggle = 0.5;
226        }
227
228    static bool displayCameraDetails = false;
229    if (mInputDevice->isKeyDown(Ogre::KC_P) && mTimeUntilNextToggle <= 0)
230    {
231        displayCameraDetails = !displayCameraDetails;
232        mTimeUntilNextToggle = 0.5;
233        if (!displayCameraDetails)
234            mWindow->setDebugText("");
235    }
236    if (displayCameraDetails)
237    {
238        // Print camera details
239        mWindow->setDebugText("P: " + Ogre::StringConverter::toString(mCamera->getDerivedPosition()) + " " +
240            "O: " + Ogre::StringConverter::toString(mCamera->getDerivedOrientation()));
241    }
242
243    // Return true to continue rendering
244    return true;
245}
246
247bool OgreFrameListenerMode::processUnbufferedMouseInput(const Ogre::FrameEvent& evt)
248{
249    /* Rotation factors, may not be used if the second mouse button is pressed. */
250
251    /* If the second mouse button is pressed, then the mouse movement results in
252        sliding the camera, otherwise we rotate. */
253    if( mInputDevice->getMouseButton( 1 ) )
254    {
255        mTranslateVector.x += mInputDevice->getMouseRelativeX() * 0.13;
256        mTranslateVector.y -= mInputDevice->getMouseRelativeY() * 0.13;
257    }
258    else
259    {
260        mRotX = Ogre::Degree(-mInputDevice->getMouseRelativeX() * 0.13);
261        mRotY = Ogre::Degree(-mInputDevice->getMouseRelativeY() * 0.13);
262    }
263
264        return true;
265}
266
267bool OgreFrameListenerMode::frameEnded(const Ogre::FrameEvent& evt)
268{
269        updateStats();
270
271        return true;
272}
273
274bool OgreFrameListenerMode::frameStarted(const Ogre::FrameEvent& evt, Ogre::InputReader *inputDevice)
275{
276        mInputDevice = inputDevice;
277
278        if(mWindow->isClosed())
279        return false;   
280
281        if ( !mUseBufferedInputMouse || !mUseBufferedInputKeys)
282        {
283                // one of the input modes is immediate, so setup what is needed for immediate mouse/key movement
284                if (mTimeUntilNextToggle >= 0)
285                {
286                        mTimeUntilNextToggle -= evt.timeSinceLastFrame;
287                }
288
289                // If this is the first frame, pick a speed
290                if (evt.timeSinceLastFrame == 0)
291                {
292                        mMoveScale = 1;
293                        mRotScale = 0.1;
294                }
295                // Otherwise scale movement units by time passed since last frame
296                else
297                {
298                        // Move about 100 units per second,
299                        mMoveScale = mMoveSpeed * evt.timeSinceLastFrame;
300                        // Take about 10 seconds for full rotation
301                        mRotScale = mRotateSpeed * evt.timeSinceLastFrame;
302                }
303                mRotX = 0;
304        mRotY = 0;
305            mTranslateVector = Ogre::Vector3::ZERO;
306        }
307
308    if (mUseBufferedInputKeys)
309    {
310        // no need to do any processing here, it is handled by event processor and
311                // you get the results as KeyEvents
312    }
313    else
314    {
315        if (processUnbufferedKeyInput(evt) == false)
316                {
317                        return false;
318                }
319    }
320    if (mUseBufferedInputMouse)
321    {
322        // no need to do any processing here, it is handled by event processor and
323                // you get the results as MouseEvents
324    }
325    else
326    {
327        if (processUnbufferedMouseInput(evt) == false)
328                {
329                        return false;
330                }
331    }
332
333        if ( !mUseBufferedInputMouse || !mUseBufferedInputKeys)
334        {
335                // one of the input modes is immediate, so update the movement vector
336
337                moveCamera();
338
339        }
340
341        static Ogre::Real currentTime = 0;
342
343        // We update all loaded animations each frame
344        Ogre::SceneManager::AnimationIterator animationIt = mSceneMgr->getAnimationIterator();
345
346        while(animationIt.hasMoreElements())
347        {
348                Ogre::Animation* animation = animationIt.getNext();
349               
350                const Ogre::Animation::NodeTrackList& trackList = animation->_getNodeTrackList();
351               
352                Ogre::Animation::NodeTrackList::const_iterator it = trackList.begin();
353                Ogre::Animation::NodeTrackList::const_iterator iend = trackList.end();
354
355                for(; it != iend; ++it) {
356                        const Ogre::NodeAnimationTrack* track = it->second;
357                        track->getAssociatedNode()->resetToInitialState();
358                }
359               
360                currentTime += evt.timeSinceLastFrame;
361                animation->apply(currentTime);
362        }               
363 
364        return true;
365}
366
367void OgreFrameListenerMode::moveCamera()
368{
369
370    // Make all the changes to the camera
371    // Note that YAW direction is around a fixed axis (freelook style) rather than a natural YAW (e.g. airplane)
372    mCamera->yaw(mRotX);
373    mCamera->pitch(mRotY);
374    mCamera->moveRelative(mTranslateVector);
375}
376       
377void OgreFrameListenerMode::showDebugOverlay(bool show)
378{
379    if (mDebugOverlay)
380    {
381        if (show)
382        {
383            mDebugOverlay->show();
384        }
385        else
386        {
387            mDebugOverlay->hide();
388        }
389    }
390}
391
392void OgreFrameListenerMode::switchMouseMode()
393{
394    mUseBufferedInputMouse = !mUseBufferedInputMouse;
395        mInputDevice->setBufferedInput(mUseBufferedInputKeys, mUseBufferedInputMouse);
396}
397
398void OgreFrameListenerMode::switchKeyMode()
399{
400    mUseBufferedInputKeys = !mUseBufferedInputKeys;
401        mInputDevice->setBufferedInput(mUseBufferedInputKeys, mUseBufferedInputMouse);
402}
403
404void OgreFrameListenerMode::keyClicked(Ogre::KeyEvent* e)
405{
406        if (e->getKeyChar() == 'm')
407        {
408                switchMouseMode();
409        }
410        else if (e->getKeyChar() == 'k')
411        {
412                switchKeyMode();
413        }
414
415}
416
417void OgreFrameListenerMode::keyPressed(Ogre::KeyEvent* e)
418{
419}
420
421void OgreFrameListenerMode::keyReleased(Ogre::KeyEvent* e)
422{
423}
424
425void OgreFrameListenerMode::chooseSceneManager(void)
426{
427    // Create the SceneManager, in this case a generic one
428        mSceneMgr = Ogre::Root::getSingleton().createSceneManager(Ogre::ST_GENERIC, "SceneMgr_" + Ogre::StringConverter::toString(mOgreFrameListenerModeHandle));
429}
430
431Ogre::SceneManager* OgreFrameListenerMode::getSceneManager(void)
432{
433        return mSceneMgr;
434}
435
436void OgreFrameListenerMode::createCamera(void)
437{
438    // Create the camera
439    mCamera = mSceneMgr->createCamera("SceneMgr_" + Ogre::StringConverter::toString(mOgreFrameListenerModeHandle) + "_Camera");
440
441    // Position it at 200 in Z direction
442    mCamera->setPosition(Ogre::Vector3(0.0, 0.0, 200.0));
443    // Look back along -Z
444    mCamera->lookAt(Ogre::Vector3(0.0, 0.0, -300.0));
445    mCamera->setNearClipDistance(2.0);
446}
447
448void OgreFrameListenerMode::createViewports(void)
449{
450    // Create one viewport, entire window
451        if (mWindow->getNumViewports() == 0)
452        {
453                Ogre::Viewport* vp = mWindow->addViewport(mCamera,mOgreFrameListenerModeHandle);
454                vp->setBackgroundColour(Ogre::ColourValue(0.0, 0.0, 0.0));
455        }
456        // Alter the camera aspect ratio to match the viewport
457        mCamera->setAspectRatio(
458                Ogre::Real(mWindow->getViewport(0)->getActualWidth()) / Ogre::Real(mWindow->getViewport(0)->getActualHeight()));
459}
460
461unsigned int OgreFrameListenerMode::getHandle()
462{
463        return mOgreFrameListenerModeHandle;
464}
465
466Ogre::Camera* OgreFrameListenerMode::getCamera()
467{
468        return mCamera;
469}
470
471void OgreFrameListenerMode::loadScene(Ogre::String filename)
472{
473        // Create an oE_Loader Callback object to post-process created objects
474        OSceneCallback oeCallback;
475       
476        mOScene = new OSMScene(mSceneMgr, mWindow);
477
478        // Initialises with the scene to be loaded and the callback if requiered
479        mOScene->initialise(filename.c_str(), &oeCallback);
480
481        // create and setup the scene in the root node
482        mOScene->createScene();
483}
484
485void OgreFrameListenerMode::createScene()
486{
487
488}
489
490void OgreFrameListenerMode::destroyScene()
491{
492
493}
494
495}
Note: See TracBrowser for help on using the repository browser.