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

Revision 1312, 54.0 KB checked in by szydlowski, 18 years ago (diff)

per-frame-stats with internal rendering - use depth pass issue unresolved

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