source: GTP/trunk/App/Demos/Vis/KdTreeDemo/OGRE/src/TestKdTreeAppListener.cpp @ 2455

Revision 2455, 54.2 KB checked in by mattausch, 17 years ago (diff)
Line 
1#include <fstream>
2#include <cstdlib>
3
4#include <OgrePanelOverlayElement.h>
5#include "TestKdTreeAppListener.h"
6#include "TestKdTree.h"
7#include <windows.h>
8
9const Real       KdTreeAppListener::DEMO_WAIT = 5.0;
10const String KdTreeAppListener::NA = ": N/A";
11const String KdTreeAppListener::RENDERMETHOD[] = { "INT", "VFC", "SWC", "CHC" };
12const String KdTreeAppListener::RENDERMETHODCAPTION[] =
13{
14        "Internal Frustum Culling",
15        "View Frustum Culling",
16        "Stop and Wait Culling",
17        "Coherent Hierarchical Culling"
18};
19const String KdTreeAppListener::BUILDMETHOD[] = { "RE", "PQ" };
20const String KdTreeAppListener::BUILDMETHODCAPTION[] = { "Recursive", "Priority Queue" };
21const String KdTreeAppListener::SCENEMANAGER[] = { "KDT", "KTE", "BVH","BIH", "OCM", "OCT", "TER", "GEN" };
22const String KdTreeAppListener::SCENEMANAGERNAME[] =
23{
24        "KdTreeSceneManager",
25        "KdTreeTerrainSceneManager",
26        "BvHierarchySceneManager",
27        "BiHierarchySceneManager",
28        "OcclusionCullingSceneManager",
29        "OctreeSceneManager",
30        "TerrainSceneManager",
31        "DefaultSceneManager"
32};
33
34void KdTreeAppListener::updateStats(void)
35{
36        static unsigned int opt = 0;
37        static char str[100];
38
39        static String currFps = "Current FPS: ";
40        static String avgFps = "Average FPS: ";
41        static String bestFps = "Best FPS: ";
42        static String worstFps = "Worst FPS: ";
43        static String tris = "Triangle Count: ";
44
45        // update stats when necessary
46        try {
47                OverlayElement* guiAvg = OverlayManager::getSingleton().getOverlayElement("Core/AverageFps");
48                OverlayElement* guiCurr = OverlayManager::getSingleton().getOverlayElement("Core/CurrFps");
49                OverlayElement* guiBest = OverlayManager::getSingleton().getOverlayElement("Core/BestFps");
50                OverlayElement* guiWorst = OverlayManager::getSingleton().getOverlayElement("Core/WorstFps");
51
52                const RenderTarget::FrameStats& stats = mWindow->getStatistics();
53
54                guiAvg->setCaption(avgFps + StringConverter::toString(stats.avgFPS));
55                guiCurr->setCaption(currFps + StringConverter::toString((int)stats.lastFPS));
56                guiBest->setCaption(bestFps + StringConverter::toString(stats.bestFPS)
57                        +" "+StringConverter::toString(stats.bestFrameTime)+" ms");
58                guiWorst->setCaption(worstFps + StringConverter::toString(stats.worstFPS)
59                        +" "+StringConverter::toString(stats.worstFrameTime)+" ms");
60
61                OverlayElement* guiTris = OverlayManager::getSingleton().getOverlayElement("Core/NumTris");
62                guiTris->setCaption(tris + StringConverter::toString(stats.triangleCount));
63
64                OverlayElement* guiDbg = OverlayManager::getSingleton().getOverlayElement("Core/DebugText");
65                guiDbg->setCaption(mWindow->getDebugText());
66
67
68                //-- culling stats
69                mSceneMgr->getOption("NumFrustumCulledNodes", &opt); sprintf(str,": %d", opt);
70                mFrustumCulledNodesInfo->setCaption(str);
71
72                mSceneMgr->getOption("NumQueryCulledNodes", &opt); sprintf(str,": %d", opt);
73                mQueryCulledNodesInfo->setCaption(str);
74
75                mSceneMgr->getOption("NumHierarchyNodes", &opt); sprintf(str,": %d", opt);
76                mHierarchyNodesInfo->setCaption(str);
77
78                mSceneMgr->getOption("NumRenderedNodes", &opt); sprintf(str,": %d", opt);
79                mRenderedNodesInfo->setCaption(str);
80
81                // take old value into account in order to create no sudden changes
82                mSceneMgr->getOption("NumQueriesIssued", &opt);
83                mDelayedQueriesIssued = mDelayedQueriesIssued * 0.8 + (float)opt * 0.2f;
84                sprintf(str,": %d", (int)mDelayedQueriesIssued);
85                mQueriesIssuedInfo->setCaption(str);
86
87                mSceneMgr->getOption("NumTraversedNodes", &opt);
88                mDelayedTraversedNodes = mDelayedTraversedNodes * 0.8 + (float)opt * 0.2f;
89                sprintf(str,": %d", (int)mDelayedTraversedNodes);
90                mTraversedNodesInfo->setCaption(str);
91        }
92        catch(...)
93        {
94                // ignore
95        }
96}
97
98// Constructor takes a RenderWindow because it uses that to determine input context
99KdTreeAppListener::KdTreeAppListener(RenderWindow* win, SceneManager* sm, const Options& options,
100                                                                         bool useBufferedInputKeys, bool useBufferedInputMouse):
101// basic
102mWindow(win),
103mSceneMgr(sm),
104mOptions(options),
105mUseBufferedInputKeys(useBufferedInputKeys),
106mUseBufferedInputMouse(useBufferedInputMouse),
107// elements
108mCamNode(0),
109mCamera(0),
110mTopCam(0),
111// toggle
112mStatsOn(true),
113mVizCamera(false),
114mFreeMove(false),
115mTopCamFollow(true),
116mShowTree(SHOWTREE_ALL),
117// view cells
118mViewCellsLoaded(false),
119mUseViewCells(false),
120mUseVisibilityFilter(false),
121//counters
122mSeqNum(0),
123mNumScreenShots(0),
124// rendering/texture options
125mSceneDetailIndex(PM_SOLID),
126//mFiltering(TFO_ANISOTROPIC),
127//mAniso(8),
128mFiltering(TFO_BILINEAR),
129mAniso(1),
130// chc stats
131mDelayedQueriesIssued(0.0f),
132mDelayedTraversedNodes(0.0f),
133// movement
134mTranslateVector(Vector3::ZERO),
135mVizCamTransVect(Vector3::ZERO),
136mRotX(0.0f),
137mRotY(0.0f),
138mMoveScale(0.0f),
139mRotScale(0.0f),
140mDeathAngle(0.0f),
141mRaySceneQuery(0),
142// just to stop toggles flipping too fast
143mTimeUntilNextToggle(0.0f),
144// stuff for walkthrough recording/playback
145mTimeUntilNextLogWrite(0.0f),
146mTimeRemaining(0.0f),
147mWaitBeforeDemoStart(0.0f),
148mAppState(AS_NORMAL)
149{
150        mInputTypeSwitchingOn = mUseBufferedInputKeys || mUseBufferedInputMouse;
151
152        if (mInputTypeSwitchingOn)
153        {
154                mEventProcessor = new EventProcessor();
155                mEventProcessor->initialise(win);
156                mEventProcessor->startProcessingEvents();
157                mEventProcessor->addKeyListener(this);
158                mInputDevice = mEventProcessor->getInputReader();
159
160        }
161        else
162        {
163                mInputDevice = PlatformManager::getSingleton().createInputReader();
164                mInputDevice->initialise(win,true, true);
165        }
166
167        MaterialManager::getSingleton().setDefaultTextureFiltering(mFiltering);
168        MaterialManager::getSingleton().setDefaultAnisotropy(mAniso);
169
170        mCamera = sm->getCamera("PlayerCam");
171        mTopCam = sm->getCamera("TopCam");
172        mCamNode = sm->getSceneNode("PlayerCamNode");
173
174        mRaySceneQuery = mSceneMgr->createRayQuery(Ray(mCamNode->getPosition(), Vector3::NEGATIVE_UNIT_Y));
175
176        mDebugOverlay = OverlayManager::getSingleton().getByName("Core/DebugOverlay");
177        mKdTreeOverlay = OverlayManager::getSingleton().getByName("KdTree/DebugOverlay");
178        mDemoOverlay = 0;
179        mDemoStatus = 0;
180        mDemoTime = 0;
181
182        // loading view cells overlay
183        mLoadingOverlay = OverlayManager::getSingleton().getByName("Example/Visibility/LoadingOverlay");
184        mMyLoadingInfo = OverlayManager::getSingleton().getOverlayElement("Example/Visibility/Loading/MyLoadingInfo");
185        mMyLoadingInfo->setCaption("loading view cells ...");
186
187        mLoadingOverlay->hide();
188
189        initKdTreeOverlay();
190        initStatsOverlay();
191
192        // set view cells
193        if (mOptions.mSceneType == ST_GEOMETRY)
194        {
195                switch(mOptions.mViewCells)
196                {
197                case VCM_ON:
198                        toggleUseViewCells();
199                        break;
200                case VCM_FILTER:
201                        toggleUseViewCells();
202                        toggleUseVisibilityFilter();
203                        break;
204                }
205        }
206
207        if (!mOptions.mDemoInfileName.empty())
208                loadFrames(mOptions.mDemoInfileName, mFrameList);
209
210        if (!mOptions.mDemoInfileName.empty() && mOptions.mDemoMode)
211        {
212                // force X second wait when in demo mode - avoids initial low framerate due to loading delays
213                mWaitBeforeDemoStart = DEMO_WAIT;
214                // wait one interval before first write
215                mTimeUntilNextLogWrite = mOptions.mDemoInterval;
216                // set playback icon
217                togglePlayback();
218                // hide all other overlays
219                mStatsOn = false;
220        }
221
222        showDebugOverlay(mStatsOn);
223        setDemoOverlay();
224}
225//-----------------------------------------------------------------------
226KdTreeAppListener::~KdTreeAppListener()
227{
228        if (mInputTypeSwitchingOn)
229        {
230                delete mEventProcessor;
231        }
232        else
233        {
234                PlatformManager::getSingleton().destroyInputReader( mInputDevice );
235        }
236}
237//-----------------------------------------------------------------------
238void KdTreeAppListener::initOverlayElement(OverlayElement **elInfo, String ext,
239        String name, int top, String caption)
240{
241        OverlayElement *el =
242                OverlayManager::getSingleton().getOverlayElement(ext + name);
243
244        (*elInfo) = OverlayManager::getSingleton().getOverlayElement(ext + name + "Info");
245        (*elInfo)->setCaption(caption);
246
247        el->setTop(top);
248        (*elInfo)->setTop(top);
249}
250//-----------------------------------------------------------------------
251void KdTreeAppListener::initStatsOverlay()
252{
253        const int border_height = 10;
254        const int vert_space = 15;
255
256        //-- visibility culling stats overlay
257        int top = border_height;
258
259        String ext = "KdTree/Visibility/";
260
261        initOverlayElement(&mFrustumCulledNodesInfo, ext, "FrustumCulledNodes", top, ": 0"); top += vert_space;
262        initOverlayElement(&mQueryCulledNodesInfo, ext, "QueryCulledNodes", top, ": 0"); top += vert_space;
263        initOverlayElement(&mTraversedNodesInfo, ext, "TraversedNodes", top, ": 0"); top += vert_space;
264        initOverlayElement(&mHierarchyNodesInfo, ext, "HierarchyNodes", top, ": 0"); top += vert_space;
265        initOverlayElement(&mRenderedNodesInfo, ext, "RenderedNodes", top, ": 0"); top += vert_space;
266        initOverlayElement(&mObjectsCountInfo, ext, "ObjectsCount", top, ": 0"); top += vert_space;
267        initOverlayElement(&mQueriesIssuedInfo, ext, "QueriesIssued", top, ": 0"); top += vert_space;
268
269        OverlayElement *visPanel = OverlayManager::getSingleton().
270                getOverlayElement("KdTree/VisibilityStatsPanel");
271
272        visPanel->setHeight(top + border_height);
273}
274//-----------------------------------------------------------------------
275void KdTreeAppListener::initKdTreeOverlay()
276{
277        const int border_height = 10;
278        const int vert_space = 15;
279        int top = border_height;
280
281        String ext = "KdTree/";
282        String sMD, sKT, sKI, sHL, sBM, sRM, sFM, sTC, sEV, sVC, sVF;
283
284        int maxd;
285        if (mSceneMgr->getOption("KdTreeMaxDepth", &maxd))
286                sMD = ": " + StringConverter::toString(maxd);
287        else
288                sMD = NA;
289
290        Real kt;
291        if (mSceneMgr->getOption("KT", &kt))
292                sKT = ": " + StringConverter::toString(kt);
293        else
294                sKT = NA;
295
296        Real ki;
297        if (mSceneMgr->getOption("KI", &ki))
298                sKI = ": " + StringConverter::toString(ki);
299        else
300                sKI = NA;
301
302        int hl;
303        if (mSceneMgr->getOption("HiLiteLevel", &hl))
304                sHL = ": " + StringConverter::toString(hl);
305        else
306                sHL = NA;
307        if (mShowTree == SHOWTREE_OFF)
308                sHL = ": off";
309
310        int bm;
311        if (mSceneMgr->getOption("BuildMethod", &bm))
312                sBM = ": " + BUILDMETHODCAPTION[bm];
313        else
314                sBM = NA;
315
316        int rm;
317        if (mSceneMgr->getOption("RenderMethod", &rm))
318                sRM = ": " + RENDERMETHODCAPTION[rm];
319        else
320                sRM = NA;
321
322        // hack to allow mode switching in OCM
323        if (mOptions.mSceneManager == SM_OCM)
324        {
325                rm = CONV_KDT_TO_OCM_ALG(mOptions.mRenderMethod);
326                sRM = ": " + RENDERMETHODCAPTION[CONV_OCM_TO_KDT_ALG(rm)];
327        }
328
329        bool enh;
330        if (mSceneMgr->getOption("EnhancedVisibility", &enh))
331        {
332                if (enh)
333                        sEV = ": Enhanced";
334                else
335                        sEV = ": Simple";
336        }
337        else
338        {
339                sEV = NA;
340        }
341
342        sFM = NA;
343        if (mFreeMove)
344                sFM = ": Free";
345        else
346                sFM = ": Ground";
347
348        sTC = NA;
349        if (mTopCamFollow)
350                sTC = ": Follow";
351        else
352                sTC = ": Free";
353
354        if (mSceneMgr->getOption("UseViewCells", &mUseViewCells) && mOptions.mSceneType == ST_GEOMETRY)
355        {
356                if (mUseViewCells)
357                        sVC = ": on";
358                else
359                        sVC = ": off";
360        }
361        else
362        {
363                if (mOptions.mSceneType == ST_GEOMETRY && mOptions.myApp->getViewCellsFileName() != "" &&
364                        (mOptions.mSceneManager == SM_KDT ||
365                         mOptions.mSceneManager == SM_KTE ||
366                         mOptions.mSceneManager == SM_OCM))
367                {
368                        sVC = ": off";
369                }
370                else
371                {
372                        sVC = NA;
373                }
374        }
375
376        if (mSceneMgr->getOption("UseVisibilityFilter", &mUseVisibilityFilter) && mOptions.mSceneType == ST_GEOMETRY)
377        {
378                if (mUseVisibilityFilter)
379                        sVF = ": on";
380                else
381                        sVF = ": off";
382        }
383        else
384        {
385                if (mOptions.mSceneType == ST_GEOMETRY && mOptions.myApp->getViewCellsFileName() != "" &&
386                        (mOptions.mSceneManager == SM_KDT ||
387                         mOptions.mSceneManager == SM_KTE ||
388                         mOptions.mSceneManager == SM_OCM))
389                {
390                        sVF = ": off";
391                }
392                else
393                {
394                        sVF = NA;
395                }
396        }
397
398        initOverlayElement(&mRenderMethodInfo, ext, "RenderMethod", top, sRM); top += vert_space;
399        initOverlayElement(&mEnhancedVisInfo, ext, "EnhancedVis", top, sEV); top += vert_space;
400        initOverlayElement(&mBuildMethodInfo, ext, "BuildMethod", top, sBM); top += vert_space;
401        initOverlayElement(&mKdTreeMaxDepthInfo, ext, "KdTreeMaxDepth", top, sMD); top += vert_space;
402        initOverlayElement(&mHighlightLevelInfo, ext, "HighlightLevel", top, sHL); top += vert_space;
403        initOverlayElement(&mKTInfo, ext, "KT", top, sKT); top += vert_space;
404        initOverlayElement(&mKIInfo, ext, "KI", top, sKI); top += vert_space;
405        initOverlayElement(&mMovementInfo, ext, "Movement", top, sFM); top += vert_space;
406        initOverlayElement(&mTopCamInfo, ext, "TopCam", top, sTC); top += vert_space;
407        initOverlayElement(&mViewCellsInfo, ext, "ViewCells", top, sVC); top += vert_space;
408        initOverlayElement(&mViewFilterInfo, ext, "ViewFilter", top, sVF); top += vert_space;
409
410        OverlayElement *visPanel = OverlayManager::getSingleton().
411                getOverlayElement("KdTree/OptionsPanel");
412
413        visPanel->setHeight(top + border_height);
414}
415
416void KdTreeAppListener::showDebugOverlay(bool show)
417{
418        if (mDebugOverlay && mKdTreeOverlay)
419        {
420                if (show)
421                {
422                        mDebugOverlay->show();
423                        mKdTreeOverlay->show();
424                }
425                else
426                {
427                        mDebugOverlay->hide();
428                        mKdTreeOverlay->hide();
429                }
430        }
431}
432
433void KdTreeAppListener::toggleUseViewCells()
434{
435        // viewcells apply only for scenes loaded from geometry
436        if (mOptions.mSceneType != ST_GEOMETRY ||
437                mOptions.myApp->getViewCellsFileName().empty())
438                return;
439
440        mUseViewCells = !mUseViewCells;
441
442
443        // load on demand
444        if (mUseViewCells && !mViewCellsLoaded)
445        {
446                mLoadingOverlay->show();
447
448                // call once to load view cell loading overlay
449                mWindow->update();
450                mViewCellsLoaded = mSceneMgr->setOption("LoadViewCells",
451                        mOptions.myApp->getViewCellsFileName().c_str());
452
453                if (!mViewCellsLoaded)
454                {
455                        LogManager::getSingleton().logMessage("#@#@ Error: loading view cells from " +
456                                mOptions.myApp->getViewCellsFileName() + " failed.");
457                }
458
459                mLoadingOverlay->hide();
460        }
461
462        if (mSceneMgr->setOption("UseViewCells", &mUseViewCells))
463        {
464                if (mUseViewCells)
465                        mViewCellsInfo->setCaption(": on");
466                else
467                        mViewCellsInfo->setCaption(": off");
468        }
469        else
470        {
471                mViewCellsInfo->setCaption(NA);
472        }
473}
474
475void KdTreeAppListener::toggleUseVisibilityFilter()
476{
477        mUseVisibilityFilter = !mUseVisibilityFilter;
478        if (mSceneMgr->setOption("UseVisibilityFilter", &mUseVisibilityFilter))
479        {
480                if (mUseVisibilityFilter)
481                        mViewFilterInfo->setCaption(": on");
482                else
483                        mViewFilterInfo->setCaption(": off");
484        }
485        else
486        {
487                mViewFilterInfo->setCaption(NA);
488        }
489}
490
491void KdTreeAppListener::toggleVizCamera()
492{
493        static int nodeVizMode = 0;
494
495        nodeVizMode = (nodeVizMode + 1) % NODEVIZ_MODES_NUM;
496
497        if (nodeVizMode != 0)
498        {
499                if (!mVizCamera)
500                {
501                        Viewport* tvp = mWindow->addViewport(mTopCam,
502                                VIZ_VIEWPORT_Z_ORDER, 0.66, 0.66, 0.34, 0.34);
503                        tvp->setBackgroundColour(ColourValue(1.0, 0.0, 0.0));
504                        tvp->setOverlaysEnabled(false);
505
506                        mTopCam->setAspectRatio(
507                                Real(tvp->getActualWidth())/Real(tvp->getActualHeight()));
508                        mVizCamera = true;
509                        mSceneMgr->setOption("VisualizeCulledNodes", &mVizCamera);
510                }
511
512                bool renderNodesForViz = (nodeVizMode == NODEVIZ_RENDER_NODES) ||
513                        (nodeVizMode == NODEVIZ_RENDER_NODES_AND_CONTENT);
514                bool renderNodesContentForViz = (nodeVizMode == NODEVIZ_RENDER_NODES_AND_CONTENT);
515                bool renderPvsForViz = nodeVizMode == NODEVIZ_RENDER_PVS;
516
517                mSceneMgr->setOption("RenderNodesForViz", &renderNodesForViz);
518                mSceneMgr->setOption("RenderNodesContentForViz", &renderNodesContentForViz);
519                mSceneMgr->setOption("RenderPvsForViz", &renderPvsForViz);
520
521        }
522        else
523        {
524                mWindow->removeViewport(VIZ_VIEWPORT_Z_ORDER);
525                mVizCamera = false;
526                mSceneMgr->setOption("VisualizeCulledNodes", &mVizCamera);
527        }
528}
529
530void KdTreeAppListener::toggleShowBoxes()
531{
532        mShowTree = (mShowTree + 1) % SHOWTREE_MODES_NUM;
533        bool show = false, all = false;
534
535        switch (mShowTree)
536        {
537        case SHOWTREE_OFF:
538                break;
539        case SHOWTREE_HILITE:
540                show = true;
541                break;
542        case SHOWTREE_ALL:
543                show = all = true;
544                break;
545        }
546
547        // set display
548
549        if (mSceneMgr->getTypeName() == "OctreeSceneManager")
550                mSceneMgr->setOption("ShowOctree", &show);
551        else if (
552                mSceneMgr->getTypeName() == "KdTreeSceneManager" ||
553                mSceneMgr->getTypeName() == "KdTreeTerrainSceneManager")
554                mSceneMgr->setOption("ShowKdTree", &show);
555
556        // set showall
557        mSceneMgr->setOption("ShowAllBoxes", &all);
558
559        if (!show)
560                mHighlightLevelInfo->setCaption(": off");
561        else
562        {
563                int hl;
564                if (mSceneMgr->getOption("HiLiteLevel", &hl))
565                        mHighlightLevelInfo->setCaption(": " + StringConverter::toString(hl));
566                else
567                        mHighlightLevelInfo->setCaption(NA);
568        }
569}
570
571void KdTreeAppListener::toggleEnhancedVisibility()
572{
573        bool mode;
574        if (mSceneMgr->getOption("EnhancedVisibility", &mode))
575        {
576                mode = !mode;
577                if (mSceneMgr->setOption("EnhancedVisibility", &mode))
578                {
579                        if (mode)
580                                mEnhancedVisInfo->setCaption(": Enhanced");
581                        else
582                                mEnhancedVisInfo->setCaption(": Simple");
583
584                        mOptions.mEnhancedVisibility = mode;
585                }
586        }
587        else
588        {
589                mEnhancedVisInfo->setCaption(NA);
590        }
591}
592
593void KdTreeAppListener::toggleBuildMethod()
594{
595        int bm;
596
597        if (mSceneMgr->getOption("BuildMethod", &bm))
598        {
599                bm = (bm + 1) % KdTree::KDBM_SIZE;
600                if (mSceneMgr->setOption("BuildMethod", &bm))
601                {
602                        mBuildMethodInfo->setCaption(": " + BUILDMETHODCAPTION[bm]);
603                        mOptions.mBuildMethod = bm;
604                }
605        }
606        else
607        {
608                mBuildMethodInfo->setCaption(NA);
609        }
610}
611
612void KdTreeAppListener::toggleRenderMethod()
613{
614        int rm;
615
616        if (mSceneMgr->getOption("RenderMethod", &rm))
617        {
618                rm = (rm + 1) % KdTree::KDRM_SIZE;
619                if (mSceneMgr->setOption("RenderMethod", &rm))
620                {
621                        mRenderMethodInfo->setCaption(": " + RENDERMETHODCAPTION[rm]);
622                        mOptions.mRenderMethod = rm;
623                }
624        }
625        else
626        {
627                mRenderMethodInfo->setCaption(NA);
628        }
629
630        // hack to allow mode switching in OCM, cannot extract setting from sm
631        if (mOptions.mSceneManager == SM_OCM)
632        {
633                static int alg = CONV_KDT_TO_OCM_ALG(mOptions.mRenderMethod);
634                alg = (alg + 1) % 3;
635                if (mSceneMgr->setOption("Algorithm", &alg))
636                        mRenderMethodInfo->setCaption(": " + RENDERMETHODCAPTION[CONV_OCM_TO_KDT_ALG(alg)]);
637        }
638}
639
640bool KdTreeAppListener::processUnbufferedKeyInput(const FrameEvent& evt)
641{
642        // ignore all keystrokes except escape when in demo mode
643        if (mOptions.mDemoMode)
644        {
645                if (mInputDevice->isKeyDown(KC_ESCAPE))
646                        return false;
647                else
648                        return true;
649        }
650
651        if (mInputDevice->isKeyDown(KC_F1) && mTimeUntilNextToggle <= 0)
652        {
653                // TODO show help overlay
654        }
655
656        // show/hide vis viewport
657        if (mInputDevice->isKeyDown(KC_F2) && mTimeUntilNextToggle <= 0)
658        {
659                toggleVizCamera();
660                mTimeUntilNextToggle = 0.5;
661        }
662
663        // show/hide kdtree boxes
664        if (mInputDevice->isKeyDown(KC_F3) && mTimeUntilNextToggle <= 0)
665        {
666                toggleShowBoxes();
667                mTimeUntilNextToggle = 0.5;
668        }
669
670        if (mInputDevice->isKeyDown(KC_F4) && mTimeUntilNextToggle <= 0)
671        {
672                bool toggleShow;
673                mSceneMgr->getOption("ShowNodes", &toggleShow);
674                toggleShow = !toggleShow;
675                mSceneMgr->setOption("ShowNodes", &toggleShow);
676                mTimeUntilNextToggle = 0.5;
677        }
678
679        // demo recording stuff
680        if (mInputDevice->isKeyDown(KC_F5) && mTimeUntilNextToggle <= 0)
681        {
682                toggleRecord();
683                mTimeUntilNextToggle = 0.5;
684        }
685
686        if (mInputDevice->isKeyDown(KC_F6) && mTimeUntilNextToggle <= 0)
687        {
688                if (!mOptions.mDemoOutfileName.empty() && !mFrameList.empty())
689                        saveFrames(mOptions.mDemoOutfileName, mFrameList);
690                mTimeUntilNextToggle = 0.5;
691        }
692
693        if (mInputDevice->isKeyDown(KC_F7) && mTimeUntilNextToggle <= 0)
694        {
695                SceneNode *entnode = mSceneMgr->getSceneNode("AnchorNode");
696                if (!mOptions.myApp->saveSceneASCII(mOptions.mSceneOutfileName, entnode))
697                        LogManager::getSingleton().logMessage(
698                        "##Error##: Failed to save scene to " + mOptions.mSceneOutfileName);
699                mTimeUntilNextToggle = 0.5;
700        }
701
702        if (mInputDevice->isKeyDown(KC_F8) && mTimeUntilNextToggle <= 0)
703        {
704                // fill scene only once (for now), stop if anchor node exists
705                try
706                {
707                        SceneNode *entnode = mSceneMgr->getSceneNode("AnchorNode");
708                }
709                catch (Exception)
710                {
711                        // read interesting params from config file
712                        ConfigFile terrainconf;
713                        std::stringstream s;
714                        Real x,y,z;
715                       
716                        terrainconf.load("terrain.cfg");
717
718                        s << terrainconf.getSetting("PageWorldX");
719                        s >> x;
720                        s.clear();
721
722                        s << terrainconf.getSetting("MaxHeight");
723                        s >> y;
724                        s.clear();
725
726                        s << terrainconf.getSetting("PageWorldZ");
727                        s >> z;
728                        s.clear();
729
730                        mOptions.myApp->createTerrainScene(x, y * 0.3, z);
731
732                        // rebuild tree
733                        mSceneMgr->setOption("RebuildKdTree", 0);
734                }
735
736                mTimeUntilNextToggle = 0.5;
737        }
738
739
740        if (mInputDevice->isKeyDown(KC_F9) && mTimeUntilNextToggle <= 0)
741        {
742                togglePlayback();
743                mTimeUntilNextToggle = 0.5;
744        }
745
746        if (mInputDevice->isKeyDown(KC_0) && mTimeUntilNextToggle <= 0)
747        {
748                toggleBuildMethod();
749                mTimeUntilNextToggle = 0.5;
750        }
751
752        if (mInputDevice->isKeyDown(KC_SPACE) && mTimeUntilNextToggle <= 0)
753        {
754                toggleRenderMethod();
755                mTimeUntilNextToggle = 0.5;
756        }
757
758        if (mInputDevice->isKeyDown(KC_V) && mTimeUntilNextToggle <= 0)
759        {
760                toggleEnhancedVisibility();
761                mTimeUntilNextToggle = 0.5;
762        }
763
764        if (mInputDevice->isKeyDown(KC_C) && mTimeUntilNextToggle <= 0)
765        {
766                toggleUseViewCells();
767                mTimeUntilNextToggle = 0.5;
768        }
769
770        if (mInputDevice->isKeyDown(KC_X) && mTimeUntilNextToggle <= 0)
771        {
772                toggleUseVisibilityFilter();
773                mTimeUntilNextToggle = 0.5;
774        }
775
776        if (mInputDevice->isKeyDown(KC_B) && mTimeUntilNextToggle <= 0)
777        {
778                mSceneMgr->showBoundingBoxes( ! mSceneMgr->getShowBoundingBoxes() );
779                mTimeUntilNextToggle = 0.5;
780        }
781
782        const static int vizCamSpeedup = 12;
783        // moving the cull camera
784        if (mInputDevice->isKeyDown(KC_NUMPAD2))
785        {
786                mVizCamTransVect.y = -mMoveScale * vizCamSpeedup;
787        }
788        if (mInputDevice->isKeyDown(KC_NUMPAD8))
789        {
790                mVizCamTransVect.y = mMoveScale * vizCamSpeedup;
791        }
792        if (mInputDevice->isKeyDown(KC_NUMPAD4))
793        {
794                mVizCamTransVect.x = -mMoveScale * vizCamSpeedup;
795        }
796        if (mInputDevice->isKeyDown(KC_NUMPAD6))
797        {
798                mVizCamTransVect.x = mMoveScale * vizCamSpeedup;
799        }
800        if (mInputDevice->isKeyDown(KC_SUBTRACT))
801        {
802                mVizCamTransVect.z = mMoveScale * vizCamSpeedup;
803        }
804        if (mInputDevice->isKeyDown(KC_ADD))
805        {
806                mVizCamTransVect.z = -mMoveScale * vizCamSpeedup;
807        }
808
809        if ((mInputDevice->isKeyDown(KC_1) || mInputDevice->isKeyDown(KC_2)) && mTimeUntilNextToggle <= 0)
810        {
811                int currdepth;
812                if (mSceneMgr->getOption("KdTreeMaxDepth", &currdepth))
813                {
814                        if (mInputDevice->isKeyDown(KC_1))
815                                currdepth--;
816                        else if (mInputDevice->isKeyDown(KC_2))
817                                currdepth++;
818
819                        if (mSceneMgr->setOption("KdTreeMaxDepth", &currdepth))
820                        {
821                                mKdTreeMaxDepthInfo->setCaption(": " + StringConverter::toString(currdepth));
822                                int hl;
823                                if (mSceneMgr->getOption("HiLiteLevel", &hl))
824                                        mHighlightLevelInfo->setCaption(": " + StringConverter::toString(hl));
825                                else
826                                        mHighlightLevelInfo->setCaption(NA);
827                        }
828                }
829                else
830                {
831                        mKdTreeMaxDepthInfo->setCaption(NA);
832                        mHighlightLevelInfo->setCaption(NA);
833                }
834
835                if (mShowTree == SHOWTREE_OFF)
836                        mHighlightLevelInfo->setCaption(": off");
837
838                mTimeUntilNextToggle = 0.2;
839        }
840
841        if ((mInputDevice->isKeyDown(KC_3) || mInputDevice->isKeyDown(KC_4)) && mTimeUntilNextToggle <= 0)
842        {
843                int hl;
844                if (mSceneMgr->getOption("HiLiteLevel", &hl))
845                {
846                        if (mInputDevice->isKeyDown(KC_3))
847                                hl--;
848                        else if (mInputDevice->isKeyDown(KC_4))
849                                hl++;
850
851                        if (mSceneMgr->setOption("HiLiteLevel", &hl))
852                                mHighlightLevelInfo->setCaption(": " + StringConverter::toString(hl));
853                }
854                else
855                {
856                        mHighlightLevelInfo->setCaption(NA);
857                }
858
859                if (mShowTree == SHOWTREE_OFF)
860                        mHighlightLevelInfo->setCaption(": off");
861
862                mTimeUntilNextToggle = 0.2;
863        }
864
865
866        if ((mInputDevice->isKeyDown(KC_5) ||mInputDevice->isKeyDown(KC_6)) && mTimeUntilNextToggle <= 0)
867        {
868                Real kt;
869                if (mSceneMgr->getOption("KT", &kt))
870                {
871                        if (mInputDevice->isKeyDown(KC_5))
872                                kt -= 0.1;
873                        else if (mInputDevice->isKeyDown(KC_6))
874                                kt += 0.1;
875
876                        if (kt < 0.1)
877                                kt = 0.1;
878
879                        if (mSceneMgr->setOption("KT", &kt))
880                                mKTInfo->setCaption(": " + StringConverter::toString(kt));
881                }
882                else
883                {
884                        mKTInfo->setCaption(NA);
885                }
886
887                mTimeUntilNextToggle = 0.2;
888        }
889
890        if ((mInputDevice->isKeyDown(KC_7) || mInputDevice->isKeyDown(KC_8)) && mTimeUntilNextToggle <= 0)
891        {
892                Real ki;
893                if (mSceneMgr->getOption("KI", &ki))
894                {
895                        if (mInputDevice->isKeyDown(KC_7))
896                                ki -= 0.1;
897                        else if (mInputDevice->isKeyDown(KC_8))
898                                ki += 0.1;
899
900                        if (ki < 0.1)
901                                ki = 0.1;
902
903                        if (mSceneMgr->setOption("KI", &ki))
904                                mKIInfo->setCaption(": " + StringConverter::toString(ki));
905                }
906                else
907                {
908                        mKIInfo->setCaption(NA);
909                }
910
911                mTimeUntilNextToggle = 0.2;
912        }
913
914        if (mInputDevice->isKeyDown(KC_U) && mTimeUntilNextToggle <= 0)
915        {
916                mFreeMove = !mFreeMove;
917                String move = ": N/A";
918                if (mFreeMove)
919                        move = ": Free";
920                else
921                        move = ": Ground";
922
923                mMovementInfo->setCaption(move);
924
925                mTimeUntilNextToggle = 0.5;
926        }
927
928        if (mInputDevice->isKeyDown(KC_I) && mTimeUntilNextToggle <= 0)
929        {
930                mTopCamFollow = !mTopCamFollow;
931                String move = ": N/A";
932                if (mTopCamFollow)
933                        move = ": Follow";
934                else
935                        move = ": Free";
936
937                mTopCamInfo->setCaption(move);
938
939                mTimeUntilNextToggle = 0.5;
940        }
941
942        if (mInputDevice->isKeyDown(KC_BACK) && mTimeUntilNextToggle <= 0)
943        {
944                mSceneMgr->setOption("RebuildKdTree", 0);
945                mTimeUntilNextToggle = 1;
946        }
947
948        //if (mInputDevice->isKeyDown(KC_N) && mTimeUntilNextToggle <= 0)
949        //{
950        //      //Entity * ent = mSceneMgr->createEntity("randominsert" + StringConverter::toString(mSeqNum), "robot.mesh");
951        //      Entity * ent = mSceneMgr->createEntity("randominsert" + StringConverter::toString(mSeqNum), "razor.mesh");
952        //      //Vector3 position(Math::RangeRandom(100, 1125), -0, Math::RangeRandom(-1125, 1125));
953        //      Vector3 position(Math::RangeRandom(-5000, 5000), Math::RangeRandom(-5000, 5000), Math::RangeRandom(-5000, 5000));
954        //      //Quaternion orientation(Radian(Math::RangeRandom(-Math::PI, Math::PI)), Vector3::UNIT_Y);
955        //      Vector3 axis(Math::RangeRandom(-1,1),Math::RangeRandom(-1,1),Math::RangeRandom(-1,1));
956        //      axis.normalise();
957        //      Quaternion orientation(Radian(Math::RangeRandom(-Math::PI, Math::PI)), axis);
958        //      Vector3 scale(Math::RangeRandom(0.5, 5),Math::RangeRandom(0.5, 5),Math::RangeRandom(0.5, 5));
959        //      SceneNode * anchor = mSceneMgr->getSceneNode("AnchorNode");
960        //      SceneNode *sn = anchor->createChildSceneNode("RandomInsertNode" + StringConverter::toString(mSeqNum), position, orientation);
961        //      sn->attachObject(ent);
962        //      sn->setScale(scale);
963        //      mTimeUntilNextToggle = 0.5;
964        //      mSeqNum++;
965        //}
966
967        //if (mInputDevice->isKeyDown(KC_J) && mTimeUntilNextToggle <= 0)
968        //{
969        //      if (mSeqNum > 0)
970        //      {
971        //              mSeqNum--;
972        //              mSceneMgr->destroySceneNode("RandomInsertNode" + StringConverter::toString(mSeqNum));
973        //              mSceneMgr->destroyEntity("randominsert" + StringConverter::toString(mSeqNum));
974        //              mTimeUntilNextToggle = 0.5;
975        //      }
976        //}
977
978        //if (mInputDevice->isKeyDown(KC_P) && mTimeUntilNextToggle <= 0)
979        //{
980        //      LogManager::getSingleton().logMessage("############## Camera Position:");
981        //      LogManager::getSingleton().logMessage("############## " + StringConverter::toString(mCamera->getPosition()));
982        //      LogManager::getSingleton().logMessage("############## " + StringConverter::toString(mCamera->getOrientation()));
983        //      LogManager::getSingleton().logMessage("############## Cull Camera Position:");
984        //      LogManager::getSingleton().logMessage("############## " + StringConverter::toString(mTopCam->getPosition()));
985        //      LogManager::getSingleton().logMessage("############## " + StringConverter::toString(mTopCam->getOrientation()));
986        //      mTimeUntilNextToggle = 1.0;
987        //}
988
989        if (mInputDevice->isKeyDown(KC_A))
990        {
991                // Move camera left
992                mTranslateVector.x = -mMoveScale;
993        }
994
995        if (mInputDevice->isKeyDown(KC_D))
996        {
997                // Move camera RIGHT
998                mTranslateVector.x = mMoveScale;
999        }
1000
1001        /* Move camera forward by keypress. */
1002        if (mInputDevice->isKeyDown(KC_UP) || mInputDevice->isKeyDown(KC_W) )
1003        {
1004                mTranslateVector.z = -mMoveScale;
1005        }
1006
1007        /* Move camera backward by keypress. */
1008        if (mInputDevice->isKeyDown(KC_DOWN) || mInputDevice->isKeyDown(KC_S) )
1009        {
1010                mTranslateVector.z = mMoveScale;
1011        }
1012
1013        if (mInputDevice->isKeyDown(KC_PGUP))
1014        {
1015                // Move camera up
1016                mTranslateVector.y = mMoveScale;
1017        }
1018
1019        if (mInputDevice->isKeyDown(KC_PGDOWN))
1020        {
1021                // Move camera down
1022                mTranslateVector.y = -mMoveScale;
1023        }
1024
1025        if (mInputDevice->isKeyDown(KC_RIGHT))
1026        {
1027                mCamNode->yaw(-mRotScale, Ogre::Node::TS_WORLD);
1028        }
1029
1030        if (mInputDevice->isKeyDown(KC_LEFT))
1031        {
1032                mCamNode->yaw(mRotScale, Ogre::Node::TS_WORLD);
1033        }
1034
1035        if( mInputDevice->isKeyDown( KC_ESCAPE) )
1036        {           
1037                return false;
1038        }
1039
1040        // see if switching is on, and you want to toggle
1041        if (mInputTypeSwitchingOn && mInputDevice->isKeyDown(KC_M) && mTimeUntilNextToggle <= 0)
1042        {
1043                switchMouseMode();
1044                mTimeUntilNextToggle = 1;
1045        }
1046
1047        if (mInputTypeSwitchingOn && mInputDevice->isKeyDown(KC_K) && mTimeUntilNextToggle <= 0)
1048        {
1049                // must be going from immediate keyboard to buffered keyboard
1050                switchKeyMode();
1051                mTimeUntilNextToggle = 1;
1052        }
1053        if (mInputDevice->isKeyDown(KC_F) && mTimeUntilNextToggle <= 0)
1054        {
1055                mStatsOn = !mStatsOn;
1056                showDebugOverlay(mStatsOn);
1057
1058                mTimeUntilNextToggle = 1;
1059        }
1060        if (mInputDevice->isKeyDown(KC_T) && mTimeUntilNextToggle <= 0)
1061        {
1062                switch(mFiltering)
1063                {
1064                case TFO_BILINEAR:
1065                        mFiltering = TFO_TRILINEAR;
1066                        mAniso = 1;
1067                        break;
1068                case TFO_TRILINEAR:
1069                        mFiltering = TFO_ANISOTROPIC;
1070                        mAniso = 8;
1071                        break;
1072                case TFO_ANISOTROPIC:
1073                        mFiltering = TFO_BILINEAR;
1074                        mAniso = 1;
1075                        break;
1076                default:
1077                        break;
1078                }
1079                MaterialManager::getSingleton().setDefaultTextureFiltering(mFiltering);
1080                MaterialManager::getSingleton().setDefaultAnisotropy(mAniso);
1081
1082
1083                showDebugOverlay(mStatsOn);
1084
1085                mTimeUntilNextToggle = 1;
1086        }
1087
1088        if (mInputDevice->isKeyDown(KC_SYSRQ) && mTimeUntilNextToggle <= 0)
1089        {
1090                char tmp[20];
1091                sprintf(tmp, "screenshot_%d.png", ++mNumScreenShots);
1092                mWindow->writeContentsToFile(tmp);
1093                mTimeUntilNextToggle = 0.5;
1094                mWindow->setDebugText(String("Wrote ") + tmp);
1095        }
1096
1097        if (mInputDevice->isKeyDown(KC_R) && mTimeUntilNextToggle <=0)
1098        {
1099                mSceneDetailIndex = (mSceneDetailIndex+1)%3 ;
1100                switch(mSceneDetailIndex) {
1101                        case 0 : mCamera->setPolygonMode(PM_SOLID) ; break ;
1102                        case 1 : mCamera->setPolygonMode(PM_WIREFRAME) ; break ;
1103                        case 2 : mCamera->setPolygonMode(PM_POINTS) ; break ;
1104                }
1105                mTimeUntilNextToggle = 0.5;
1106        }
1107
1108        static bool displayCameraDetails = false;
1109        if (mInputDevice->isKeyDown(KC_P) && mTimeUntilNextToggle <= 0)
1110        {
1111                displayCameraDetails = !displayCameraDetails;
1112                mTimeUntilNextToggle = 0.5;
1113                if (!displayCameraDetails)
1114                {
1115                        mWindow->setDebugText("");
1116                }
1117                else
1118                {
1119                        LogManager::getSingleton().logMessage("############## Camera Position:");
1120                        LogManager::getSingleton().logMessage("############## " + StringConverter::toString(mCamera->getDerivedPosition()));
1121                        LogManager::getSingleton().logMessage("############## " + StringConverter::toString(mCamera->getDerivedOrientation()));
1122                        LogManager::getSingleton().logMessage("############## Cull Camera Position:");
1123                        LogManager::getSingleton().logMessage("############## " + StringConverter::toString(mTopCam->getPosition()));
1124                        LogManager::getSingleton().logMessage("############## " + StringConverter::toString(mTopCam->getOrientation()));
1125                }
1126        }
1127        if (displayCameraDetails)
1128        {
1129                // Print camera details
1130                mWindow->setDebugText("P: " + StringConverter::toString(mCamera->getDerivedPosition()) + " " +
1131                        "O: " + StringConverter::toString(mCamera->getDerivedOrientation()));
1132        }
1133
1134        // Return true to continue rendering
1135        return true;
1136}
1137
1138bool KdTreeAppListener::processUnbufferedMouseInput(const FrameEvent& evt)
1139{
1140        /* Rotation factors, may not be used if the second mouse button is pressed. */
1141
1142        /* If the second mouse button is pressed, then the mouse movement results in
1143        sliding the camera, otherwise we rotate. */
1144        if( mInputDevice->getMouseButton( 1 ) )
1145        {
1146                mTranslateVector.x += mInputDevice->getMouseRelativeX() * 0.13;
1147                mTranslateVector.y -= mInputDevice->getMouseRelativeY() * 0.13;
1148        }
1149        else
1150        {
1151                mRotX = Degree(-mInputDevice->getMouseRelativeX() * 0.13);
1152                mRotY = Degree(-mInputDevice->getMouseRelativeY() * 0.13);
1153        }
1154
1155
1156        return true;
1157}
1158
1159void KdTreeAppListener::moveCamera()
1160{
1161
1162        // Make all the changes to the camera
1163        // Note that YAW direction is around a fixed axis (freelook style) rather than a natural YAW (e.g. airplane)
1164        mCamNode->yaw(mRotX, Ogre::Node::TS_WORLD);
1165        mCamNode->pitch(mRotY);
1166        //mCamNode->moveRelative(mTranslateVector);
1167        mCamNode->translate(mCamNode->getLocalAxes(), mTranslateVector);
1168        mTopCam->moveRelative(mVizCamTransVect);
1169        if (mTopCamFollow)
1170        {
1171                Vector3 toppos = mTopCam->getPosition();
1172                Vector3 campos = mCamNode->getPosition();
1173                mTopCam->setPosition(Vector3::ZERO);
1174                mTopCam->setOrientation(Quaternion::IDENTITY);
1175                mTopCam->setPosition(campos.x, toppos.y, campos.z);
1176                mTopCam->pitch(Radian(-Math::HALF_PI));
1177        }
1178
1179        if (!mFreeMove)
1180        {
1181                if (mOptions.mSceneType == ST_TERRAIN)
1182                {
1183                        static Vector3 pos;
1184                        static Ray updateRay;
1185                        pos = mCamNode->getPosition();
1186                        updateRay.setOrigin(pos);
1187                        updateRay.setDirection(Vector3::NEGATIVE_UNIT_Y);
1188                        mRaySceneQuery->setRay(updateRay);
1189                        RaySceneQueryResult& qryResult = mRaySceneQuery->execute();
1190                        RaySceneQueryResult::iterator i = qryResult.begin();
1191                        if (i != qryResult.end() && i->worldFragment)
1192                        {
1193                                SceneQuery::WorldFragment* wf = i->worldFragment;
1194                                mCamNode->setPosition(pos.x, wf->singleIntersection.y + 10, pos.z);
1195                        }
1196                }
1197                else
1198                {
1199                        static Vector3 pos;
1200                        static Ray updateRay;
1201                        pos = mCamNode->getPosition();
1202                        updateRay.setOrigin(pos);
1203                        updateRay.setDirection(Vector3::NEGATIVE_UNIT_Y);
1204                        mRaySceneQuery->setRay(updateRay);
1205                        RaySceneQueryResult& qryResult = mRaySceneQuery->execute();
1206                        RaySceneQueryResult::iterator i = qryResult.begin();
1207                        while (i != qryResult.end() && i->movable)
1208                        {
1209                                if (i->movable->getName() != "PlayerCam")
1210                                {
1211                                        MovableObject *mov = i->movable;
1212                                        mCamNode->setPosition(pos.x, mov->getWorldBoundingBox().getCenter().y + 2, pos.z);
1213                                        break;
1214                                }
1215                                i++;
1216                        }
1217                }
1218        }
1219}
1220
1221// Override frameStarted event to process that (don't care about frameEnded)
1222bool KdTreeAppListener::frameStarted(const FrameEvent& evt)
1223{
1224        if(mWindow->isClosed())
1225                return false;
1226
1227        if (!mInputTypeSwitchingOn)
1228        {
1229                mInputDevice->capture();
1230        }
1231
1232
1233        if ( !mUseBufferedInputMouse || !mUseBufferedInputKeys)
1234        {
1235                // one of the input modes is immediate, so setup what is needed for immediate mouse/key movement
1236                if (mTimeUntilNextToggle >= 0)
1237                        mTimeUntilNextToggle -= evt.timeSinceLastFrame;
1238
1239                // If this is the first frame, pick a speed
1240                if (evt.timeSinceLastFrame == 0)
1241                {
1242                        mMoveScale = 0.2;
1243                        mRotScale = 0.1;
1244                }
1245                // Otherwise scale movement units by time passed since last frame
1246                else
1247                {
1248                        // Move about 100 units per second,
1249                        mMoveScale = mOptions.mMoveSpeed * evt.timeSinceLastFrame;
1250                        // Take about 10 seconds for full rotation
1251                        mRotScale = mOptions.mRotateSpeed * evt.timeSinceLastFrame;
1252                }
1253                mRotX = 0;
1254                mRotY = 0;
1255                mTranslateVector = Vector3::ZERO;
1256                mVizCamTransVect = Vector3::ZERO;
1257        }
1258
1259        if (mUseBufferedInputKeys)
1260        {
1261                // no need to do any processing here, it is handled by event processor and
1262                // you get the results as KeyEvents
1263        }
1264        else
1265        {
1266                if (processUnbufferedKeyInput(evt) == false)
1267                {
1268                        return false;
1269                }
1270        }
1271        if (mUseBufferedInputMouse)
1272        {
1273                // no need to do any processing here, it is handled by event processor and
1274                // you get the results as MouseEvents
1275        }
1276        else
1277        {
1278                if (processUnbufferedMouseInput(evt) == false)
1279                {
1280                        return false;
1281                }
1282        }
1283       
1284        // do nothing until delay passes to stabilize frame rate
1285        mWaitBeforeDemoStart -= evt.timeSinceLastFrame;
1286        if (mWaitBeforeDemoStart > 0.0)
1287        {
1288                // do full turn to preload geometry
1289                static Real dps = (360 / DEMO_WAIT);
1290                mCamNode->yaw(Radian(Degree(dps * evt.timeSinceLastFrame)), Ogre::Node::TS_WORLD);
1291                return true;
1292        }
1293
1294        // demo playback - replace position with stored one
1295        if (mAppState == AS_PLAYBACK)
1296        {
1297                // update time
1298                mTimeRemaining -= evt.timeSinceLastFrame;
1299
1300                // update stats
1301                ++ mDemoStats.mNumFrames;
1302                ++ mDemoStats.mTotalNumFrames;
1303                mDemoStats.mEllapsedTime += evt.timeSinceLastFrame;
1304                mDemoStats.mTotalEllapsedTime += evt.timeSinceLastFrame;
1305
1306                // set time display
1307                int m = (int)mDemoStats.mTotalEllapsedTime / 60;
1308                int s = (int)mDemoStats.mTotalEllapsedTime % 60;
1309
1310                mDemoTime->setCaption(
1311                        StringConverter::toString(m, 2, '0') + ":" +
1312                        StringConverter::toString(s, 2, '0'));
1313
1314                // set FPS display
1315                const RenderTarget::FrameStats& stats = mWindow->getStatistics();
1316                mDemoFPSDisp->setCaption(StringConverter::toString((int)stats.lastFPS));
1317
1318                // store fps when in demo mode
1319                if (mOptions.mDemoMode)
1320                {
1321                        // save FPS
1322                        mTimeUntilNextLogWrite -= evt.timeSinceLastFrame;
1323                        if (mTimeUntilNextLogWrite <= 0.0)
1324                        {
1325                                mTimeUntilNextLogWrite += mOptions.mDemoInterval;
1326                                //const RenderTarget::FrameStats& stats = mWindow->getStatistics();
1327                                //mDemoFPS.push_back(stats.lastFPS);
1328                                mDemoFPS.push_back(mDemoStats.mNumFrames / mDemoStats.mEllapsedTime);
1329                                mDemoStats.mNumFrames = 0;
1330                                mDemoStats.mEllapsedTime = 0.0f;
1331                        }
1332                }
1333
1334                static FrameList::iterator lastFrame;
1335                if (mCurrFrame == mFrameList.begin())
1336                        lastFrame = mCurrFrame;
1337
1338                // advance to next stored frame
1339                while (mTimeRemaining <= 0.0 && mCurrFrame != mFrameList.end())
1340                {
1341                        lastFrame = mCurrFrame;
1342                        ++ mCurrFrame;
1343                        mTimeRemaining += mCurrFrame->mElapsedTime;
1344                }
1345
1346                // when reached last frame, reset and stop playback
1347                if (mCurrFrame == mFrameList.end())
1348                {
1349                        togglePlayback();
1350                        saveLog();
1351                        // exit app when in demo mode
1352                        if (mOptions.mDemoMode)
1353                        {
1354                                saveLog();
1355                                if (mOptions.mBurnIn)
1356                                {
1357                                        mTimeUntilNextLogWrite = mOptions.mDemoInterval;
1358                                        togglePlayback();
1359                                }
1360                                else
1361                                {
1362                                        return false;
1363                                }
1364                        }
1365                }
1366                // interpolate position & orientation and modify move vectors
1367                else
1368                {
1369                       
1370                        // interpolation factor
1371                        Real factor = 1.0 - mTimeRemaining / mCurrFrame->mElapsedTime;
1372
1373                        // interpolate position and orientation
1374                        Vector3 pos = lastFrame->mPosition +
1375                                factor * (mCurrFrame->mPosition - lastFrame->mPosition);
1376
1377                        Quaternion or = Quaternion::Slerp(factor, lastFrame->mOrientation,
1378                                mCurrFrame->mOrientation);
1379
1380                        // update camera
1381                        mCamNode->setPosition(pos);
1382                        mCamNode->setOrientation(or);
1383
1384                        // update viz camera
1385                        mTopCam->moveRelative(mVizCamTransVect);
1386                        if (mTopCamFollow)
1387                        {
1388                                Vector3 toppos = mTopCam->getPosition();
1389                                Vector3 campos = mCamNode->getPosition();
1390                                mTopCam->setPosition(Vector3::ZERO);
1391                                mTopCam->setOrientation(Quaternion::IDENTITY);
1392                                mTopCam->setPosition(campos.x, toppos.y, campos.z);
1393                                mTopCam->pitch(Radian(-Math::HALF_PI));
1394                        }
1395
1396                }
1397        }
1398        else
1399        {
1400                if ( !mUseBufferedInputMouse || !mUseBufferedInputKeys)
1401                {
1402                        // one of the input modes is immediate, so update the movement vector
1403
1404                        moveCamera();
1405
1406                }
1407        }
1408
1409        //saveFrameInfo(evt.timeSinceLastFrame);
1410        if (mAppState == AS_RECORD)
1411        {
1412                // update stats
1413                ++ mDemoStats.mTotalNumFrames;
1414                mDemoStats.mTotalEllapsedTime += evt.timeSinceLastFrame;
1415
1416                // set time display
1417                int m = (int)mDemoStats.mTotalEllapsedTime / 60;
1418                int s = (int)mDemoStats.mTotalEllapsedTime % 60;
1419
1420                mDemoTime->setCaption(
1421                        StringConverter::toString(m, 2, '0') + ":" +
1422                        StringConverter::toString(s, 2, '0'));
1423
1424                // set FPS display
1425                const RenderTarget::FrameStats& stats = mWindow->getStatistics();
1426                mDemoFPSDisp->setCaption(StringConverter::toString((int)stats.lastFPS));
1427
1428                // store frame
1429                mFrameList.push_back(FrameInfo(mCamNode->getPosition(), mCamNode->getOrientation(), evt.timeSinceLastFrame));
1430        }
1431
1432
1433        //Camera        *followCam = mSceneMgr->getCamera("FollowCam");
1434        //if (followCam->getAutoTrackTarget() != 0)
1435        //{
1436        //      // Move the death thingy & update lookat camera FOV
1437        //      SceneNode *deathPivotNode = mSceneMgr->getSceneNode("deathPivotNode");
1438        //      SceneNode *deathNode = mSceneMgr->getSceneNode("movingNode");
1439        //      SceneNode *pivotNode = mSceneMgr->getSceneNode("pivotNode");
1440
1441        //      Vector3 fcpos = followCam->getPosition();
1442        //      Vector3 oldpos = deathNode->getWorldPosition();
1443
1444        //      Radian deltaAngle = Radian(evt.timeSinceLastFrame / mRotationPeriod * Math::TWO_PI);
1445        //      deathPivotNode->rotate(Vector3::UNIT_Y, deltaAngle);
1446        //      pivotNode->rotate(Vector3::UNIT_Y, deltaAngle * 4);
1447
1448        //      Vector3 pos = deathNode->getWorldPosition();
1449
1450        //      Real olddist = (oldpos - fcpos).length();
1451        //      Real dist = (pos - fcpos).length();
1452
1453        //      Radian oldfov = followCam->getFOVy();
1454        //      Radian fov = Radian(olddist / dist) * oldfov;
1455
1456        //      followCam->setFOVy(fov);
1457        //}
1458
1459        return true;
1460}
1461
1462bool KdTreeAppListener::frameEnded(const FrameEvent& evt)
1463{
1464        if (!mOptions.mDemoMode)
1465                updateStats();
1466
1467        return true;
1468}
1469
1470void KdTreeAppListener::switchMouseMode()
1471{
1472        mUseBufferedInputMouse = !mUseBufferedInputMouse;
1473        mInputDevice->setBufferedInput(mUseBufferedInputKeys, mUseBufferedInputMouse);
1474}
1475void KdTreeAppListener::switchKeyMode()
1476{
1477        mUseBufferedInputKeys = !mUseBufferedInputKeys;
1478        mInputDevice->setBufferedInput(mUseBufferedInputKeys, mUseBufferedInputMouse);
1479}
1480
1481void KdTreeAppListener::keyClicked(KeyEvent* e)
1482{
1483        if (e->getKeyChar() == 'm')
1484        {
1485                switchMouseMode();
1486        }
1487        else if (e->getKeyChar() == 'k')
1488        {
1489
1490                switchKeyMode();
1491        }
1492}
1493
1494/************************************************************************/
1495/* functions for recording & playback of demos                          */
1496/************************************************************************/
1497
1498//-----------------------------------------------------------------------------
1499void KdTreeAppListener::toggleRecord()
1500{
1501        // start recording
1502        if (mAppState == AS_NORMAL)
1503        {
1504                // change state
1505                mAppState = AS_RECORD;
1506
1507                // clear old recording
1508                mFrameList.clear();
1509
1510                // reset stats
1511                mDemoStats.mNumFrames = 0;
1512                mDemoStats.mTotalNumFrames = 0;
1513                mDemoStats.mEllapsedTime = 0.0f;
1514                mDemoStats.mTotalEllapsedTime = 0.0f;
1515        }
1516        // stop recording
1517        else if (mAppState == AS_RECORD)
1518        {
1519                // change state
1520                mAppState = AS_NORMAL;
1521
1522        }
1523        // update display
1524        setDemoOverlay();
1525}
1526
1527//-----------------------------------------------------------------------------
1528void KdTreeAppListener::togglePlayback()
1529{
1530        static Vector3 pos;
1531        static Quaternion or;
1532
1533        // start playback
1534        if (mAppState == AS_NORMAL && !mFrameList.empty())
1535        {
1536                // change state
1537                mAppState = AS_PLAYBACK;
1538
1539                // save old position
1540                pos = mCamNode->getPosition();
1541                or = mCamNode->getOrientation();
1542
1543                // reset demo
1544                mCurrFrame = mFrameList.begin();
1545                mTimeRemaining = mCurrFrame->mElapsedTime;
1546
1547                // reset stats
1548                mDemoStats.mNumFrames = 0;
1549                mDemoStats.mTotalNumFrames = 0;
1550                mDemoStats.mEllapsedTime = 0.0f;
1551                mDemoStats.mTotalEllapsedTime = 0.0f;
1552                mDemoFPS.clear();
1553        }
1554        // stop playback
1555        else if (mAppState == AS_PLAYBACK)
1556        {
1557                // change state
1558                mAppState = AS_NORMAL;
1559
1560                // restore old position
1561                mCamNode->setPosition(pos);
1562                mCamNode->setOrientation(or);
1563        }
1564
1565        // update display
1566        setDemoOverlay();
1567}
1568
1569
1570//-----------------------------------------------------------------------------
1571void KdTreeAppListener::saveFrames(const String& filename, FrameList& framelist)
1572{
1573        size_t dot = filename.find_last_of(".");
1574        String ext = filename.substr(dot + 1, filename.length());
1575        if (ext == "txt")
1576                saveFramesAscii(filename, framelist);
1577        else if (ext == "bin")
1578                saveFramesBinary(filename, framelist);
1579        else
1580                OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Invalid extension for demo file: " + ext, "KdTreeApp::loadFrames");
1581}
1582
1583//-----------------------------------------------------------------------------
1584void KdTreeAppListener::saveFramesAscii(const String& filename, FrameList& framelist)
1585{
1586        // open file
1587        std::ofstream dest(filename.c_str());
1588        if (dest.is_open())
1589        {
1590                FrameList::iterator it = framelist.begin();
1591                FrameList::iterator end = framelist.end();
1592
1593                // dump values
1594                while (it != end)
1595                {
1596                        dest <<
1597                                StringConverter::toString(it->mPosition) << " " <<
1598                                StringConverter::toString(it->mOrientation) << " " <<
1599                                StringConverter::toString(it->mElapsedTime) << "\n";
1600                        ++ it;
1601                }
1602
1603                dest.close();
1604        }
1605        else
1606        {
1607                LogManager::getSingleton().logMessage("##Error##: Failed to open file for saving demo: " + filename);
1608        }
1609
1610
1611}
1612
1613//-----------------------------------------------------------------------------
1614void KdTreeAppListener::saveFramesBinary(const String& filename, FrameList& framelist)
1615{
1616        std::ofstream dest(filename.c_str(), std::ios_base::out | std::ios_base::binary);
1617
1618        if (dest.is_open())
1619        {
1620                FrameList::iterator it = framelist.begin();
1621                FrameList::iterator end = framelist.end();
1622
1623                int size = sizeof(Real);
1624
1625                // dump values
1626                while (it != end)
1627                {
1628                        dest.write((char *)&it->mPosition.x, size);
1629                        dest.write((char *)&it->mPosition.y, size);
1630                        dest.write((char *)&it->mPosition.z, size);
1631                        dest.write((char *)&it->mOrientation.w, size);
1632                        dest.write((char *)&it->mOrientation.x, size);
1633                        dest.write((char *)&it->mOrientation.y, size);
1634                        dest.write((char *)&it->mOrientation.z, size);
1635                        dest.write((char *)&it->mElapsedTime, size);
1636                        ++ it;
1637                }
1638
1639                dest.close();
1640        }
1641        else
1642        {
1643                LogManager::getSingleton().logMessage("##Error##: Failed to open file for saving demo: " + filename);
1644        }
1645}
1646
1647//-----------------------------------------------------------------------------
1648void KdTreeAppListener::loadFrames(const String& filename, FrameList& framelist)
1649{
1650        size_t dot = filename.find_last_of(".");
1651        String ext = filename.substr(dot + 1, filename.length());
1652        if (ext == "txt")
1653                loadFramesAscii(filename, framelist);
1654        else if (ext == "bin")
1655                loadFramesBinary(filename, framelist);
1656        else
1657                OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Invalid extension for demo file: " + ext, "KdTreeApp::loadFrames");
1658}
1659
1660//-----------------------------------------------------------------------------
1661void KdTreeAppListener::loadFramesAscii(const String& filename, FrameList& framelist)
1662{
1663        // open file
1664        std::ifstream src(filename.c_str());
1665        if (src.is_open())
1666        {
1667                // clear the list
1668                framelist.clear();
1669
1670                Vector3 pos;
1671                Quaternion or;
1672                Real time;
1673
1674                while (!src.eof())
1675                {
1676                        src >> pos.x;   
1677                        src >> pos.y;   
1678                        src >> pos.z;
1679
1680                        src >> or.w;
1681                        src >> or.x;
1682                        src >> or.y;
1683                        src >> or.z;
1684
1685                        src >> time;
1686
1687                        framelist.push_back(FrameInfo(pos, or, time));
1688                }
1689
1690                // HACK pop last frame, was doubled while reading
1691                framelist.pop_back();
1692
1693                src.close();
1694        }
1695        else
1696        {
1697                LogManager::getSingleton().logMessage("##Error##: Failed to open file for reading demo: " + filename);
1698        }
1699}
1700
1701//-----------------------------------------------------------------------------
1702void KdTreeAppListener::loadFramesBinary(const String& filename, FrameList& framelist)
1703{
1704        // open file
1705        std::ifstream src(filename.c_str(), std::ios_base::out | std::ios_base::binary);
1706        if (src.is_open())
1707        {
1708                // clear the list
1709                framelist.clear();
1710
1711                int size = sizeof(Real);
1712
1713                Vector3 pos;
1714                Quaternion or;
1715                Real time;
1716
1717                while (!src.eof())
1718                {
1719                        src.read((char *)&pos.x, size);
1720                        src.read((char *)&pos.y, size);
1721                        src.read((char *)&pos.z, size);
1722                        src.read((char *)&or.w, size);
1723                        src.read((char *)&or.x, size);
1724                        src.read((char *)&or.y, size);
1725                        src.read((char *)&or.z, size);
1726                        src.read((char *)&time, size);
1727
1728                        framelist.push_back(FrameInfo(pos, or, time));
1729                }
1730
1731                // HACK pop last frame, was doubled while reading
1732                framelist.pop_back();
1733
1734                src.close();
1735        }
1736        else
1737        {
1738                LogManager::getSingleton().logMessage("##Error##: Failed to open file for reading demo: " + filename);
1739        }
1740}
1741
1742//-----------------------------------------------------------------------------
1743void KdTreeAppListener::saveLog()
1744{
1745        // field separator and record separator
1746        static const String fs = ",", rs ="\n", ds = ":";
1747        // stats
1748        Real minFPS = Math::POS_INFINITY, maxFPS = 0.0, avgFPS = 0.0;
1749        String line, storedname;
1750        String demopath, demoname;
1751        StringUtil::splitFilename(mOptions.mDemoInfileName, demoname, demopath);
1752       
1753        // check if logfile exists
1754        std::ifstream logread(mOptions.mDemoLogfileName.c_str());
1755        if (logread.is_open())
1756        {
1757                // read first line, shuold start with the name of the demo
1758                // if matches, OK, otherwise do something
1759                logread >> line;
1760                storedname = line.substr(0,line.find_first_of(','));
1761                logread.close();
1762                if (storedname != demoname)
1763                {
1764                        LogManager::getSingleton().logMessage(
1765                                "##Error##: Saved demo stats do not match the current demo: " +
1766                                storedname + " != " + demoname);
1767                        return;
1768                }
1769        }
1770        // otherwise write header
1771        else
1772        {
1773                std::ofstream logheader(mOptions.mDemoLogfileName.c_str());
1774                if (logheader.is_open())
1775                {
1776                        // demo title
1777                        logheader << demoname << fs;
1778                        // seconds
1779                        for (size_t i = 0; i < mDemoFPS.size(); i ++)
1780                        {
1781                                logheader << (i + 1) << fs;
1782                        }
1783                        // minFPS, avgFPS, maxFPS, frames, time, render system, comment, record separator
1784                        logheader << "\"min FPS\"" << fs << "\"avg FPS\"" << fs << "\"max FPS\"" << fs
1785                                << "\"# Frames \"" << fs << "\"Total Time\"" << fs << "\"Comment\"" << fs
1786                                << "\"Render System\"" << rs;
1787                        logheader.close();
1788                }
1789                else
1790                {
1791                        LogManager::getSingleton().logMessage(
1792                                "##Error##: Failed to write log demo header to " +
1793                                mOptions.mDemoLogfileName);
1794                        return;
1795
1796                }
1797        }
1798
1799        // append current stats
1800        std::ofstream logwrite(mOptions.mDemoLogfileName.c_str(), std::ios_base::app);
1801        if (logwrite.is_open())
1802        {
1803                // gather info about ogre settings
1804                String rendersys = "\"" + Root::getSingleton().getRenderSystem()->getName();
1805                ConfigOptionMap rsopts = Root::getSingleton().getRenderSystem()->getConfigOptions();
1806                for (ConfigOptionMap::iterator it = rsopts.begin(); it != rsopts.end(); it ++)
1807                {
1808                        rendersys += " | " + it->first + " : " + it->second.currentValue;
1809                }
1810                rendersys += "\"";
1811
1812                // view cells used?
1813                String viewcells;
1814                if (mOptions.mViewCells == VCM_ON)
1815                        viewcells = ds + "VC";
1816                else if (mOptions.mViewCells == VCM_FILTER)
1817                        viewcells = ds + "VC+VF";
1818
1819                // demo settings
1820                logwrite << "\"" << SCENEMANAGER[mOptions.mSceneManager];
1821                if (mOptions.mSceneManager == SM_KDT || mOptions.mSceneManager == SM_KTE)
1822                {
1823                        // info about enhanced visibility if internal rendering
1824                        String senhvis;
1825                        if (mOptions.mRenderMethod == KdTree::KDRM_INTERNAL)
1826                        {
1827                                if (mOptions.mEnhancedVisibility)
1828                                        senhvis = "E" + ds;
1829                                else
1830                                        senhvis = "S" + ds;
1831                        }
1832
1833                        logwrite << ds << RENDERMETHOD[mOptions.mRenderMethod] << ds << senhvis <<
1834                                mOptions.mMaxDepth << ds << mOptions.mKT << ds << mOptions.mKI << ds <<
1835                                BUILDMETHOD[mOptions.mBuildMethod] << viewcells;
1836                }
1837                else if (mOptions.mSceneManager == SM_OCM && mOptions.mRenderMethod != KdTree::KDRM_INTERNAL)
1838                {
1839                        logwrite << ds << RENDERMETHOD[CONV_OCM_TO_KDT_ALG(mOptions.mRenderMethod)] << viewcells;
1840                }
1841                logwrite << "\"" << fs;
1842                // per second stats
1843                for (std::list<Real>::iterator it = mDemoFPS.begin(); it != mDemoFPS.end(); it ++)
1844                {
1845                        if (*it < minFPS)
1846                                minFPS = *it;
1847
1848                        if (*it > maxFPS)
1849                                maxFPS = *it;
1850
1851                        //avgFPS += *it;
1852
1853                        logwrite << (int)(*it) << fs;
1854
1855                }
1856                //avgFPS /= mDemoFPS.size();
1857                avgFPS = mDemoStats.mTotalNumFrames / mDemoStats.mTotalEllapsedTime;
1858                // minFPS, avgFPS, maxFPS, comment, record separator
1859                logwrite << (int)minFPS << fs << (int)avgFPS << fs << (int)maxFPS << fs
1860                        << mDemoStats.mTotalNumFrames << fs << mDemoStats.mTotalEllapsedTime << fs
1861                        << "\"" << mOptions.mComment << "\"" << fs << rendersys << rs;
1862                logwrite.close();
1863        }
1864        else
1865        {
1866                LogManager::getSingleton().logMessage(
1867                        "##Error##: Failed to write demo log to " +
1868                        mOptions.mDemoLogfileName);
1869        }
1870}
1871
1872//-----------------------------------------------------------------------------
1873void KdTreeAppListener::saveFrameInfo(Real elapsedTime)
1874{
1875        mFrameList.push_back(FrameInfo(mCamNode->getPosition(), mCamNode->getOrientation(), elapsedTime));
1876}
1877
1878//-----------------------------------------------------------------------------
1879void KdTreeAppListener::setDemoOverlay()
1880{
1881        // init overlay if not present
1882        if (!mDemoOverlay || !mDemoStatus || !mDemoTime)
1883        {
1884                OGRE_DELETE(mDemoOverlay);
1885                OGRE_DELETE(mDemoStatus);
1886                OGRE_DELETE(mDemoTime);
1887
1888                mDemoStatus = OverlayManager::getSingleton().createOverlayElement("Panel", "KdTree/DemoStatus");
1889                mDemoStatus->setMetricsMode(GMM_PIXELS);
1890                mDemoStatus->setDimensions(32, 32);
1891                mDemoStatus->setLeft(64);
1892
1893                mDemoTime = static_cast<TextAreaOverlayElement *>
1894                        (OverlayManager::getSingleton().createOverlayElement("TextArea", "KdTree/DemoTime"));
1895                mDemoTime->setMetricsMode(GMM_PIXELS);
1896                mDemoTime->setTop(6);
1897                mDemoTime->setLeft(104);
1898                mDemoTime->setFontName("TrebuchetMSBold");
1899                mDemoTime->setCharHeight(24.0);
1900                mDemoTime->setCaption("00:00");
1901
1902                mDemoFPSDisp = static_cast<TextAreaOverlayElement *>
1903                        (OverlayManager::getSingleton().createOverlayElement("TextArea", "KdTree/DemoFPS"));
1904                mDemoFPSDisp->setMetricsMode(GMM_PIXELS);
1905                mDemoFPSDisp->setAlignment(TextAreaOverlayElement::Right);
1906                mDemoFPSDisp->setTop(6);
1907                mDemoFPSDisp->setLeft(48);
1908                mDemoFPSDisp->setFontName("TrebuchetMSBold");
1909                mDemoFPSDisp->setCharHeight(24.0);
1910                mDemoFPSDisp->setCaption("0");
1911
1912                PanelOverlayElement *demoCont = static_cast<PanelOverlayElement *>
1913                        (OverlayManager::getSingleton().createOverlayElement("Panel", "KdTree/DemoTimePanel"));
1914                demoCont->setMetricsMode(GMM_PIXELS);
1915                demoCont->setHorizontalAlignment(GHA_CENTER);
1916                demoCont->setVerticalAlignment(GVA_TOP);
1917                demoCont->setTop(5);
1918                demoCont->setLeft(-80);
1919                demoCont->setDimensions(160, 32);
1920                demoCont->addChild(mDemoFPSDisp);
1921                demoCont->addChild(mDemoStatus);
1922                demoCont->addChild(mDemoTime);
1923                //demoCont->setMaterialName("Core/StatsBlockCenter");
1924
1925                mDemoOverlay = OverlayManager::getSingleton().create("KdTree/DemoOverlay");
1926                mDemoOverlay->setZOrder(500);
1927                //mDemoOverlay->add2D(static_cast<PanelOverlayElement *>(mDemoStatus));
1928                mDemoOverlay->add2D(demoCont);
1929        }
1930
1931        switch(mAppState)
1932        {
1933        case AS_NORMAL:
1934                mDemoOverlay->hide();
1935                break;
1936        case AS_PLAYBACK:
1937                mDemoStatus->setMaterialName("KdTree/DemoPlayButton");
1938                mDemoTime->setColourTop(ColourValue(0.5, 0.7, 0.5));
1939                mDemoTime->setColourBottom(ColourValue(0.3, 0.5, 0.3));
1940                mDemoFPSDisp->setColourTop(ColourValue(0.5, 0.7, 0.5));
1941                mDemoFPSDisp->setColourBottom(ColourValue(0.3, 0.5, 0.3));
1942                mDemoOverlay->show();
1943                break;
1944        case AS_RECORD:
1945                mDemoStatus->setMaterialName("KdTree/DemoRecordButton");
1946                mDemoTime->setColourTop(ColourValue(0.7, 0.5, 0.5));
1947                mDemoTime->setColourBottom(ColourValue(0.5, 0.3, 0.3));
1948                mDemoFPSDisp->setColourTop(ColourValue(0.7, 0.5, 0.5));
1949                mDemoFPSDisp->setColourBottom(ColourValue(0.5, 0.3, 0.3));
1950                mDemoOverlay->show();
1951                break;
1952        default:
1953            break;
1954        }
1955
1956}
Note: See TracBrowser for help on using the repository browser.