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

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