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

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

Added support for BvHierarchy? Scene Manager to test app

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
515                mSceneMgr->setOption("RenderNodesForViz", &renderNodesForViz);
516                mSceneMgr->setOption("RenderNodesContentForViz", &renderNodesContentForViz);
517        }
518        else
519        {
520                mWindow->removeViewport(VIZ_VIEWPORT_Z_ORDER);
521                mVizCamera = false;
522                mSceneMgr->setOption("VisualizeCulledNodes", &mVizCamera);
523        }
524}
525
526void KdTreeAppListener::toggleShowBoxes()
527{
528        mShowTree = (mShowTree + 1) % SHOWTREE_MODES_NUM;
529        bool show = false, all = false;
530
531        switch (mShowTree)
532        {
533        case SHOWTREE_OFF:
534                break;
535        case SHOWTREE_HILITE:
536                show = true;
537                break;
538        case SHOWTREE_ALL:
539                show = all = true;
540                break;
541        }
542
543        // set display
544
545        if (mSceneMgr->getTypeName() == "OctreeSceneManager")
546                mSceneMgr->setOption("ShowOctree", &show);
547        else if (
548                mSceneMgr->getTypeName() == "KdTreeSceneManager" ||
549                mSceneMgr->getTypeName() == "KdTreeTerrainSceneManager")
550                mSceneMgr->setOption("ShowKdTree", &show);
551
552        // set showall
553        mSceneMgr->setOption("ShowAllBoxes", &all);
554
555        if (!show)
556                mHighlightLevelInfo->setCaption(": off");
557        else
558        {
559                int hl;
560                if (mSceneMgr->getOption("HiLiteLevel", &hl))
561                        mHighlightLevelInfo->setCaption(": " + StringConverter::toString(hl));
562                else
563                        mHighlightLevelInfo->setCaption(NA);
564        }
565}
566
567void KdTreeAppListener::toggleEnhancedVisibility()
568{
569        bool mode;
570        if (mSceneMgr->getOption("EnhancedVisibility", &mode))
571        {
572                mode = !mode;
573                if (mSceneMgr->setOption("EnhancedVisibility", &mode))
574                {
575                        if (mode)
576                                mEnhancedVisInfo->setCaption(": Enhanced");
577                        else
578                                mEnhancedVisInfo->setCaption(": Simple");
579
580                        mOptions.mEnhancedVisibility = mode;
581                }
582        }
583        else
584        {
585                mEnhancedVisInfo->setCaption(NA);
586        }
587}
588
589void KdTreeAppListener::toggleBuildMethod()
590{
591        int bm;
592
593        if (mSceneMgr->getOption("BuildMethod", &bm))
594        {
595                bm = (bm + 1) % KdTree::KDBM_SIZE;
596                if (mSceneMgr->setOption("BuildMethod", &bm))
597                {
598                        mBuildMethodInfo->setCaption(": " + BUILDMETHODCAPTION[bm]);
599                        mOptions.mBuildMethod = bm;
600                }
601        }
602        else
603        {
604                mBuildMethodInfo->setCaption(NA);
605        }
606}
607
608void KdTreeAppListener::toggleRenderMethod()
609{
610        int rm;
611
612        if (mSceneMgr->getOption("RenderMethod", &rm))
613        {
614                rm = (rm + 1) % KdTree::KDRM_SIZE;
615                if (mSceneMgr->setOption("RenderMethod", &rm))
616                {
617                        mRenderMethodInfo->setCaption(": " + RENDERMETHODCAPTION[rm]);
618                        mOptions.mRenderMethod = rm;
619                }
620        }
621        else
622        {
623                mRenderMethodInfo->setCaption(NA);
624        }
625
626        // hack to allow mode switching in OCM, cannot extract setting from sm
627        if (mOptions.mSceneManager == SM_OCM)
628        {
629                static int alg = CONV_KDT_TO_OCM_ALG(mOptions.mRenderMethod);
630                alg = (alg + 1) % 3;
631                if (mSceneMgr->setOption("Algorithm", &alg))
632                        mRenderMethodInfo->setCaption(": " + RENDERMETHODCAPTION[CONV_OCM_TO_KDT_ALG(alg)]);
633        }
634}
635
636bool KdTreeAppListener::processUnbufferedKeyInput(const FrameEvent& evt)
637{
638        // ignore all keystrokes except escape when in demo mode
639        if (mOptions.mDemoMode)
640        {
641                if (mInputDevice->isKeyDown(KC_ESCAPE))
642                        return false;
643                else
644                        return true;
645        }
646
647        if (mInputDevice->isKeyDown(KC_F1) && mTimeUntilNextToggle <= 0)
648        {
649                // TODO show help overlay
650        }
651
652        // show/hide vis viewport
653        if (mInputDevice->isKeyDown(KC_F2) && mTimeUntilNextToggle <= 0)
654        {
655                toggleVizCamera();
656                mTimeUntilNextToggle = 0.5;
657        }
658
659        // show/hide kdtree boxes
660        if (mInputDevice->isKeyDown(KC_F3) && mTimeUntilNextToggle <= 0)
661        {
662                toggleShowBoxes();
663                mTimeUntilNextToggle = 0.5;
664        }
665
666        if (mInputDevice->isKeyDown(KC_F4) && mTimeUntilNextToggle <= 0)
667        {
668                bool toggleShow;
669                mSceneMgr->getOption("ShowNodes", &toggleShow);
670                toggleShow = !toggleShow;
671                mSceneMgr->setOption("ShowNodes", &toggleShow);
672                mTimeUntilNextToggle = 0.5;
673        }
674
675        // demo recording stuff
676        if (mInputDevice->isKeyDown(KC_F5) && mTimeUntilNextToggle <= 0)
677        {
678                toggleRecord();
679                mTimeUntilNextToggle = 0.5;
680        }
681
682        if (mInputDevice->isKeyDown(KC_F6) && mTimeUntilNextToggle <= 0)
683        {
684                if (!mOptions.mDemoOutfileName.empty() && !mFrameList.empty())
685                        saveFrames(mOptions.mDemoOutfileName, mFrameList);
686                mTimeUntilNextToggle = 0.5;
687        }
688
689        if (mInputDevice->isKeyDown(KC_F7) && mTimeUntilNextToggle <= 0)
690        {
691                SceneNode *entnode = mSceneMgr->getSceneNode("AnchorNode");
692                if (!mOptions.myApp->saveSceneASCII(mOptions.mSceneOutfileName, entnode))
693                        LogManager::getSingleton().logMessage(
694                        "##Error##: Failed to save scene to " + mOptions.mSceneOutfileName);
695                mTimeUntilNextToggle = 0.5;
696        }
697
698        if (mInputDevice->isKeyDown(KC_F8) && mTimeUntilNextToggle <= 0)
699        {
700                // fill scene only once (for now), stop if anchor node exists
701                try
702                {
703                        SceneNode *entnode = mSceneMgr->getSceneNode("AnchorNode");
704                }
705                catch (Exception)
706                {
707                        // read interesting params from config file
708                        ConfigFile terrainconf;
709                        std::stringstream s;
710                        Real x,y,z;
711                       
712                        terrainconf.load("terrain.cfg");
713
714                        s << terrainconf.getSetting("PageWorldX");
715                        s >> x;
716                        s.clear();
717
718                        s << terrainconf.getSetting("MaxHeight");
719                        s >> y;
720                        s.clear();
721
722                        s << terrainconf.getSetting("PageWorldZ");
723                        s >> z;
724                        s.clear();
725
726                        mOptions.myApp->createTerrainScene(x, y * 0.3, z);
727
728                        // rebuild tree
729                        mSceneMgr->setOption("RebuildKdTree", 0);
730                }
731
732                mTimeUntilNextToggle = 0.5;
733        }
734
735
736        if (mInputDevice->isKeyDown(KC_F9) && mTimeUntilNextToggle <= 0)
737        {
738                togglePlayback();
739                mTimeUntilNextToggle = 0.5;
740        }
741
742        if (mInputDevice->isKeyDown(KC_0) && mTimeUntilNextToggle <= 0)
743        {
744                toggleBuildMethod();
745                mTimeUntilNextToggle = 0.5;
746        }
747
748        if (mInputDevice->isKeyDown(KC_SPACE) && mTimeUntilNextToggle <= 0)
749        {
750                toggleRenderMethod();
751                mTimeUntilNextToggle = 0.5;
752        }
753
754        if (mInputDevice->isKeyDown(KC_V) && mTimeUntilNextToggle <= 0)
755        {
756                toggleEnhancedVisibility();
757                mTimeUntilNextToggle = 0.5;
758        }
759
760        if (mInputDevice->isKeyDown(KC_C) && mTimeUntilNextToggle <= 0)
761        {
762                toggleUseViewCells();
763                mTimeUntilNextToggle = 0.5;
764        }
765
766        if (mInputDevice->isKeyDown(KC_X) && mTimeUntilNextToggle <= 0)
767        {
768                toggleUseVisibilityFilter();
769                mTimeUntilNextToggle = 0.5;
770        }
771
772        if (mInputDevice->isKeyDown(KC_B) && mTimeUntilNextToggle <= 0)
773        {
774                mSceneMgr->showBoundingBoxes( ! mSceneMgr->getShowBoundingBoxes() );
775                mTimeUntilNextToggle = 0.5;
776        }
777
778        const static int vizCamSpeedup = 12;
779        // moving the cull camera
780        if (mInputDevice->isKeyDown(KC_NUMPAD2))
781        {
782                mVizCamTransVect.y = -mMoveScale * vizCamSpeedup;
783        }
784        if (mInputDevice->isKeyDown(KC_NUMPAD8))
785        {
786                mVizCamTransVect.y = mMoveScale * vizCamSpeedup;
787        }
788        if (mInputDevice->isKeyDown(KC_NUMPAD4))
789        {
790                mVizCamTransVect.x = -mMoveScale * vizCamSpeedup;
791        }
792        if (mInputDevice->isKeyDown(KC_NUMPAD6))
793        {
794                mVizCamTransVect.x = mMoveScale * vizCamSpeedup;
795        }
796        if (mInputDevice->isKeyDown(KC_SUBTRACT))
797        {
798                mVizCamTransVect.z = mMoveScale * vizCamSpeedup;
799        }
800        if (mInputDevice->isKeyDown(KC_ADD))
801        {
802                mVizCamTransVect.z = -mMoveScale * vizCamSpeedup;
803        }
804
805        if ((mInputDevice->isKeyDown(KC_1) || mInputDevice->isKeyDown(KC_2)) && mTimeUntilNextToggle <= 0)
806        {
807                int currdepth;
808                if (mSceneMgr->getOption("KdTreeMaxDepth", &currdepth))
809                {
810                        if (mInputDevice->isKeyDown(KC_1))
811                                currdepth--;
812                        else if (mInputDevice->isKeyDown(KC_2))
813                                currdepth++;
814
815                        if (mSceneMgr->setOption("KdTreeMaxDepth", &currdepth))
816                        {
817                                mKdTreeMaxDepthInfo->setCaption(": " + StringConverter::toString(currdepth));
818                                int hl;
819                                if (mSceneMgr->getOption("HiLiteLevel", &hl))
820                                        mHighlightLevelInfo->setCaption(": " + StringConverter::toString(hl));
821                                else
822                                        mHighlightLevelInfo->setCaption(NA);
823                        }
824                }
825                else
826                {
827                        mKdTreeMaxDepthInfo->setCaption(NA);
828                        mHighlightLevelInfo->setCaption(NA);
829                }
830
831                if (mShowTree == SHOWTREE_OFF)
832                        mHighlightLevelInfo->setCaption(": off");
833
834                mTimeUntilNextToggle = 0.2;
835        }
836
837        if ((mInputDevice->isKeyDown(KC_3) || mInputDevice->isKeyDown(KC_4)) && mTimeUntilNextToggle <= 0)
838        {
839                int hl;
840                if (mSceneMgr->getOption("HiLiteLevel", &hl))
841                {
842                        if (mInputDevice->isKeyDown(KC_3))
843                                hl--;
844                        else if (mInputDevice->isKeyDown(KC_4))
845                                hl++;
846
847                        if (mSceneMgr->setOption("HiLiteLevel", &hl))
848                                mHighlightLevelInfo->setCaption(": " + StringConverter::toString(hl));
849                }
850                else
851                {
852                        mHighlightLevelInfo->setCaption(NA);
853                }
854
855                if (mShowTree == SHOWTREE_OFF)
856                        mHighlightLevelInfo->setCaption(": off");
857
858                mTimeUntilNextToggle = 0.2;
859        }
860
861
862        if ((mInputDevice->isKeyDown(KC_5) ||mInputDevice->isKeyDown(KC_6)) && mTimeUntilNextToggle <= 0)
863        {
864                Real kt;
865                if (mSceneMgr->getOption("KT", &kt))
866                {
867                        if (mInputDevice->isKeyDown(KC_5))
868                                kt -= 0.1;
869                        else if (mInputDevice->isKeyDown(KC_6))
870                                kt += 0.1;
871
872                        if (kt < 0.1)
873                                kt = 0.1;
874
875                        if (mSceneMgr->setOption("KT", &kt))
876                                mKTInfo->setCaption(": " + StringConverter::toString(kt));
877                }
878                else
879                {
880                        mKTInfo->setCaption(NA);
881                }
882
883                mTimeUntilNextToggle = 0.2;
884        }
885
886        if ((mInputDevice->isKeyDown(KC_7) || mInputDevice->isKeyDown(KC_8)) && mTimeUntilNextToggle <= 0)
887        {
888                Real ki;
889                if (mSceneMgr->getOption("KI", &ki))
890                {
891                        if (mInputDevice->isKeyDown(KC_7))
892                                ki -= 0.1;
893                        else if (mInputDevice->isKeyDown(KC_8))
894                                ki += 0.1;
895
896                        if (ki < 0.1)
897                                ki = 0.1;
898
899                        if (mSceneMgr->setOption("KI", &ki))
900                                mKIInfo->setCaption(": " + StringConverter::toString(ki));
901                }
902                else
903                {
904                        mKIInfo->setCaption(NA);
905                }
906
907                mTimeUntilNextToggle = 0.2;
908        }
909
910        if (mInputDevice->isKeyDown(KC_U) && mTimeUntilNextToggle <= 0)
911        {
912                mFreeMove = !mFreeMove;
913                String move = ": N/A";
914                if (mFreeMove)
915                        move = ": Free";
916                else
917                        move = ": Ground";
918
919                mMovementInfo->setCaption(move);
920
921                mTimeUntilNextToggle = 0.5;
922        }
923
924        if (mInputDevice->isKeyDown(KC_I) && mTimeUntilNextToggle <= 0)
925        {
926                mTopCamFollow = !mTopCamFollow;
927                String move = ": N/A";
928                if (mTopCamFollow)
929                        move = ": Follow";
930                else
931                        move = ": Free";
932
933                mTopCamInfo->setCaption(move);
934
935                mTimeUntilNextToggle = 0.5;
936        }
937
938        if (mInputDevice->isKeyDown(KC_BACK) && mTimeUntilNextToggle <= 0)
939        {
940                mSceneMgr->setOption("RebuildKdTree", 0);
941                mTimeUntilNextToggle = 1;
942        }
943
944        //if (mInputDevice->isKeyDown(KC_N) && mTimeUntilNextToggle <= 0)
945        //{
946        //      //Entity * ent = mSceneMgr->createEntity("randominsert" + StringConverter::toString(mSeqNum), "robot.mesh");
947        //      Entity * ent = mSceneMgr->createEntity("randominsert" + StringConverter::toString(mSeqNum), "razor.mesh");
948        //      //Vector3 position(Math::RangeRandom(100, 1125), -0, Math::RangeRandom(-1125, 1125));
949        //      Vector3 position(Math::RangeRandom(-5000, 5000), Math::RangeRandom(-5000, 5000), Math::RangeRandom(-5000, 5000));
950        //      //Quaternion orientation(Radian(Math::RangeRandom(-Math::PI, Math::PI)), Vector3::UNIT_Y);
951        //      Vector3 axis(Math::RangeRandom(-1,1),Math::RangeRandom(-1,1),Math::RangeRandom(-1,1));
952        //      axis.normalise();
953        //      Quaternion orientation(Radian(Math::RangeRandom(-Math::PI, Math::PI)), axis);
954        //      Vector3 scale(Math::RangeRandom(0.5, 5),Math::RangeRandom(0.5, 5),Math::RangeRandom(0.5, 5));
955        //      SceneNode * anchor = mSceneMgr->getSceneNode("AnchorNode");
956        //      SceneNode *sn = anchor->createChildSceneNode("RandomInsertNode" + StringConverter::toString(mSeqNum), position, orientation);
957        //      sn->attachObject(ent);
958        //      sn->setScale(scale);
959        //      mTimeUntilNextToggle = 0.5;
960        //      mSeqNum++;
961        //}
962
963        //if (mInputDevice->isKeyDown(KC_J) && mTimeUntilNextToggle <= 0)
964        //{
965        //      if (mSeqNum > 0)
966        //      {
967        //              mSeqNum--;
968        //              mSceneMgr->destroySceneNode("RandomInsertNode" + StringConverter::toString(mSeqNum));
969        //              mSceneMgr->destroyEntity("randominsert" + StringConverter::toString(mSeqNum));
970        //              mTimeUntilNextToggle = 0.5;
971        //      }
972        //}
973
974        //if (mInputDevice->isKeyDown(KC_P) && mTimeUntilNextToggle <= 0)
975        //{
976        //      LogManager::getSingleton().logMessage("############## Camera Position:");
977        //      LogManager::getSingleton().logMessage("############## " + StringConverter::toString(mCamera->getPosition()));
978        //      LogManager::getSingleton().logMessage("############## " + StringConverter::toString(mCamera->getOrientation()));
979        //      LogManager::getSingleton().logMessage("############## Cull Camera Position:");
980        //      LogManager::getSingleton().logMessage("############## " + StringConverter::toString(mTopCam->getPosition()));
981        //      LogManager::getSingleton().logMessage("############## " + StringConverter::toString(mTopCam->getOrientation()));
982        //      mTimeUntilNextToggle = 1.0;
983        //}
984
985        if (mInputDevice->isKeyDown(KC_A))
986        {
987                // Move camera left
988                mTranslateVector.x = -mMoveScale;
989        }
990
991        if (mInputDevice->isKeyDown(KC_D))
992        {
993                // Move camera RIGHT
994                mTranslateVector.x = mMoveScale;
995        }
996
997        /* Move camera forward by keypress. */
998        if (mInputDevice->isKeyDown(KC_UP) || mInputDevice->isKeyDown(KC_W) )
999        {
1000                mTranslateVector.z = -mMoveScale;
1001        }
1002
1003        /* Move camera backward by keypress. */
1004        if (mInputDevice->isKeyDown(KC_DOWN) || mInputDevice->isKeyDown(KC_S) )
1005        {
1006                mTranslateVector.z = mMoveScale;
1007        }
1008
1009        if (mInputDevice->isKeyDown(KC_PGUP))
1010        {
1011                // Move camera up
1012                mTranslateVector.y = mMoveScale;
1013        }
1014
1015        if (mInputDevice->isKeyDown(KC_PGDOWN))
1016        {
1017                // Move camera down
1018                mTranslateVector.y = -mMoveScale;
1019        }
1020
1021        if (mInputDevice->isKeyDown(KC_RIGHT))
1022        {
1023                mCamNode->yaw(-mRotScale, Ogre::Node::TS_WORLD);
1024        }
1025
1026        if (mInputDevice->isKeyDown(KC_LEFT))
1027        {
1028                mCamNode->yaw(mRotScale, Ogre::Node::TS_WORLD);
1029        }
1030
1031        if( mInputDevice->isKeyDown( KC_ESCAPE) )
1032        {           
1033                return false;
1034        }
1035
1036        // see if switching is on, and you want to toggle
1037        if (mInputTypeSwitchingOn && mInputDevice->isKeyDown(KC_M) && mTimeUntilNextToggle <= 0)
1038        {
1039                switchMouseMode();
1040                mTimeUntilNextToggle = 1;
1041        }
1042
1043        if (mInputTypeSwitchingOn && mInputDevice->isKeyDown(KC_K) && mTimeUntilNextToggle <= 0)
1044        {
1045                // must be going from immediate keyboard to buffered keyboard
1046                switchKeyMode();
1047                mTimeUntilNextToggle = 1;
1048        }
1049        if (mInputDevice->isKeyDown(KC_F) && mTimeUntilNextToggle <= 0)
1050        {
1051                mStatsOn = !mStatsOn;
1052                showDebugOverlay(mStatsOn);
1053
1054                mTimeUntilNextToggle = 1;
1055        }
1056        if (mInputDevice->isKeyDown(KC_T) && mTimeUntilNextToggle <= 0)
1057        {
1058                switch(mFiltering)
1059                {
1060                case TFO_BILINEAR:
1061                        mFiltering = TFO_TRILINEAR;
1062                        mAniso = 1;
1063                        break;
1064                case TFO_TRILINEAR:
1065                        mFiltering = TFO_ANISOTROPIC;
1066                        mAniso = 8;
1067                        break;
1068                case TFO_ANISOTROPIC:
1069                        mFiltering = TFO_BILINEAR;
1070                        mAniso = 1;
1071                        break;
1072                default:
1073                        break;
1074                }
1075                MaterialManager::getSingleton().setDefaultTextureFiltering(mFiltering);
1076                MaterialManager::getSingleton().setDefaultAnisotropy(mAniso);
1077
1078
1079                showDebugOverlay(mStatsOn);
1080
1081                mTimeUntilNextToggle = 1;
1082        }
1083
1084        if (mInputDevice->isKeyDown(KC_SYSRQ) && mTimeUntilNextToggle <= 0)
1085        {
1086                char tmp[20];
1087                sprintf(tmp, "screenshot_%d.png", ++mNumScreenShots);
1088                mWindow->writeContentsToFile(tmp);
1089                mTimeUntilNextToggle = 0.5;
1090                mWindow->setDebugText(String("Wrote ") + tmp);
1091        }
1092
1093        if (mInputDevice->isKeyDown(KC_R) && mTimeUntilNextToggle <=0)
1094        {
1095                mSceneDetailIndex = (mSceneDetailIndex+1)%3 ;
1096                switch(mSceneDetailIndex) {
1097                        case 0 : mCamera->setPolygonMode(PM_SOLID) ; break ;
1098                        case 1 : mCamera->setPolygonMode(PM_WIREFRAME) ; break ;
1099                        case 2 : mCamera->setPolygonMode(PM_POINTS) ; break ;
1100                }
1101                mTimeUntilNextToggle = 0.5;
1102        }
1103
1104        static bool displayCameraDetails = false;
1105        if (mInputDevice->isKeyDown(KC_P) && mTimeUntilNextToggle <= 0)
1106        {
1107                displayCameraDetails = !displayCameraDetails;
1108                mTimeUntilNextToggle = 0.5;
1109                if (!displayCameraDetails)
1110                {
1111                        mWindow->setDebugText("");
1112                }
1113                else
1114                {
1115                        LogManager::getSingleton().logMessage("############## Camera Position:");
1116                        LogManager::getSingleton().logMessage("############## " + StringConverter::toString(mCamera->getDerivedPosition()));
1117                        LogManager::getSingleton().logMessage("############## " + StringConverter::toString(mCamera->getDerivedOrientation()));
1118                        LogManager::getSingleton().logMessage("############## Cull Camera Position:");
1119                        LogManager::getSingleton().logMessage("############## " + StringConverter::toString(mTopCam->getPosition()));
1120                        LogManager::getSingleton().logMessage("############## " + StringConverter::toString(mTopCam->getOrientation()));
1121                }
1122        }
1123        if (displayCameraDetails)
1124        {
1125                // Print camera details
1126                mWindow->setDebugText("P: " + StringConverter::toString(mCamera->getDerivedPosition()) + " " +
1127                        "O: " + StringConverter::toString(mCamera->getDerivedOrientation()));
1128        }
1129
1130        // Return true to continue rendering
1131        return true;
1132}
1133
1134bool KdTreeAppListener::processUnbufferedMouseInput(const FrameEvent& evt)
1135{
1136        /* Rotation factors, may not be used if the second mouse button is pressed. */
1137
1138        /* If the second mouse button is pressed, then the mouse movement results in
1139        sliding the camera, otherwise we rotate. */
1140        if( mInputDevice->getMouseButton( 1 ) )
1141        {
1142                mTranslateVector.x += mInputDevice->getMouseRelativeX() * 0.13;
1143                mTranslateVector.y -= mInputDevice->getMouseRelativeY() * 0.13;
1144        }
1145        else
1146        {
1147                mRotX = Degree(-mInputDevice->getMouseRelativeX() * 0.13);
1148                mRotY = Degree(-mInputDevice->getMouseRelativeY() * 0.13);
1149        }
1150
1151
1152        return true;
1153}
1154
1155void KdTreeAppListener::moveCamera()
1156{
1157
1158        // Make all the changes to the camera
1159        // Note that YAW direction is around a fixed axis (freelook style) rather than a natural YAW (e.g. airplane)
1160        mCamNode->yaw(mRotX, Ogre::Node::TS_WORLD);
1161        mCamNode->pitch(mRotY);
1162        //mCamNode->moveRelative(mTranslateVector);
1163        mCamNode->translate(mCamNode->getLocalAxes(), mTranslateVector);
1164        mTopCam->moveRelative(mVizCamTransVect);
1165        if (mTopCamFollow)
1166        {
1167                Vector3 toppos = mTopCam->getPosition();
1168                Vector3 campos = mCamNode->getPosition();
1169                mTopCam->setPosition(Vector3::ZERO);
1170                mTopCam->setOrientation(Quaternion::IDENTITY);
1171                mTopCam->setPosition(campos.x, toppos.y, campos.z);
1172                mTopCam->pitch(Radian(-Math::HALF_PI));
1173        }
1174
1175        if (!mFreeMove)
1176        {
1177                if (mOptions.mSceneType == ST_TERRAIN)
1178                {
1179                        static Vector3 pos;
1180                        static Ray updateRay;
1181                        pos = mCamNode->getPosition();
1182                        updateRay.setOrigin(pos);
1183                        updateRay.setDirection(Vector3::NEGATIVE_UNIT_Y);
1184                        mRaySceneQuery->setRay(updateRay);
1185                        RaySceneQueryResult& qryResult = mRaySceneQuery->execute();
1186                        RaySceneQueryResult::iterator i = qryResult.begin();
1187                        if (i != qryResult.end() && i->worldFragment)
1188                        {
1189                                SceneQuery::WorldFragment* wf = i->worldFragment;
1190                                mCamNode->setPosition(pos.x, wf->singleIntersection.y + 10, pos.z);
1191                        }
1192                }
1193                else
1194                {
1195                        static Vector3 pos;
1196                        static Ray updateRay;
1197                        pos = mCamNode->getPosition();
1198                        updateRay.setOrigin(pos);
1199                        updateRay.setDirection(Vector3::NEGATIVE_UNIT_Y);
1200                        mRaySceneQuery->setRay(updateRay);
1201                        RaySceneQueryResult& qryResult = mRaySceneQuery->execute();
1202                        RaySceneQueryResult::iterator i = qryResult.begin();
1203                        while (i != qryResult.end() && i->movable)
1204                        {
1205                                if (i->movable->getName() != "PlayerCam")
1206                                {
1207                                        MovableObject *mov = i->movable;
1208                                        mCamNode->setPosition(pos.x, mov->getWorldBoundingBox().getCenter().y + 2, pos.z);
1209                                        break;
1210                                }
1211                                i++;
1212                        }
1213                }
1214        }
1215}
1216
1217// Override frameStarted event to process that (don't care about frameEnded)
1218bool KdTreeAppListener::frameStarted(const FrameEvent& evt)
1219{
1220        if(mWindow->isClosed())
1221                return false;
1222
1223        if (!mInputTypeSwitchingOn)
1224        {
1225                mInputDevice->capture();
1226        }
1227
1228
1229        if ( !mUseBufferedInputMouse || !mUseBufferedInputKeys)
1230        {
1231                // one of the input modes is immediate, so setup what is needed for immediate mouse/key movement
1232                if (mTimeUntilNextToggle >= 0)
1233                        mTimeUntilNextToggle -= evt.timeSinceLastFrame;
1234
1235                // If this is the first frame, pick a speed
1236                if (evt.timeSinceLastFrame == 0)
1237                {
1238                        mMoveScale = 1;
1239                        mRotScale = 0.1;
1240                }
1241                // Otherwise scale movement units by time passed since last frame
1242                else
1243                {
1244                        // Move about 100 units per second,
1245                        mMoveScale = mOptions.mMoveSpeed * evt.timeSinceLastFrame;
1246                        // Take about 10 seconds for full rotation
1247                        mRotScale = mOptions.mRotateSpeed * evt.timeSinceLastFrame;
1248                }
1249                mRotX = 0;
1250                mRotY = 0;
1251                mTranslateVector = Vector3::ZERO;
1252                mVizCamTransVect = Vector3::ZERO;
1253        }
1254
1255        if (mUseBufferedInputKeys)
1256        {
1257                // no need to do any processing here, it is handled by event processor and
1258                // you get the results as KeyEvents
1259        }
1260        else
1261        {
1262                if (processUnbufferedKeyInput(evt) == false)
1263                {
1264                        return false;
1265                }
1266        }
1267        if (mUseBufferedInputMouse)
1268        {
1269                // no need to do any processing here, it is handled by event processor and
1270                // you get the results as MouseEvents
1271        }
1272        else
1273        {
1274                if (processUnbufferedMouseInput(evt) == false)
1275                {
1276                        return false;
1277                }
1278        }
1279       
1280        // do nothing until delay passes to stabilize frame rate
1281        mWaitBeforeDemoStart -= evt.timeSinceLastFrame;
1282        if (mWaitBeforeDemoStart > 0.0)
1283        {
1284                // do full turn to preload geometry
1285                static Real dps = (360 / DEMO_WAIT);
1286                mCamNode->yaw(Radian(Degree(dps * evt.timeSinceLastFrame)), Ogre::Node::TS_WORLD);
1287                return true;
1288        }
1289
1290        // demo playback - replace position with stored one
1291        if (mAppState == AS_PLAYBACK)
1292        {
1293                // update time
1294                mTimeRemaining -= evt.timeSinceLastFrame;
1295
1296                // update stats
1297                ++ mDemoStats.mNumFrames;
1298                ++ mDemoStats.mTotalNumFrames;
1299                mDemoStats.mEllapsedTime += evt.timeSinceLastFrame;
1300                mDemoStats.mTotalEllapsedTime += evt.timeSinceLastFrame;
1301
1302                // set time display
1303                int m = (int)mDemoStats.mTotalEllapsedTime / 60;
1304                int s = (int)mDemoStats.mTotalEllapsedTime % 60;
1305
1306                mDemoTime->setCaption(
1307                        StringConverter::toString(m, 2, '0') + ":" +
1308                        StringConverter::toString(s, 2, '0'));
1309
1310                // set FPS display
1311                const RenderTarget::FrameStats& stats = mWindow->getStatistics();
1312                mDemoFPSDisp->setCaption(StringConverter::toString((int)stats.lastFPS));
1313
1314                // store fps when in demo mode
1315                if (mOptions.mDemoMode)
1316                {
1317                        // save FPS
1318                        mTimeUntilNextLogWrite -= evt.timeSinceLastFrame;
1319                        if (mTimeUntilNextLogWrite <= 0.0)
1320                        {
1321                                mTimeUntilNextLogWrite += mOptions.mDemoInterval;
1322                                //const RenderTarget::FrameStats& stats = mWindow->getStatistics();
1323                                //mDemoFPS.push_back(stats.lastFPS);
1324                                mDemoFPS.push_back(mDemoStats.mNumFrames / mDemoStats.mEllapsedTime);
1325                                mDemoStats.mNumFrames = 0;
1326                                mDemoStats.mEllapsedTime = 0.0f;
1327                        }
1328                }
1329
1330                static FrameList::iterator lastFrame;
1331                if (mCurrFrame == mFrameList.begin())
1332                        lastFrame = mCurrFrame;
1333
1334                // advance to next stored frame
1335                while (mTimeRemaining <= 0.0 && mCurrFrame != mFrameList.end())
1336                {
1337                        lastFrame = mCurrFrame;
1338                        ++ mCurrFrame;
1339                        mTimeRemaining += mCurrFrame->mElapsedTime;
1340                }
1341
1342                // when reached last frame, reset and stop playback
1343                if (mCurrFrame == mFrameList.end())
1344                {
1345                        togglePlayback();
1346                        // exit app when in demo mode
1347                        if (mOptions.mDemoMode)
1348                        {
1349                                saveLog();
1350                                if (mOptions.mBurnIn)
1351                                {
1352                                        mTimeUntilNextLogWrite = mOptions.mDemoInterval;
1353                                        togglePlayback();
1354                                }
1355                                else
1356                                {
1357                                        return false;
1358                                }
1359                        }
1360                }
1361                // interpolate position & orientation and modify move vectors
1362                else
1363                {
1364                       
1365                        // interpolation factor
1366                        Real factor = 1.0 - mTimeRemaining / mCurrFrame->mElapsedTime;
1367
1368                        // interpolate position and orientation
1369                        Vector3 pos = lastFrame->mPosition +
1370                                factor * (mCurrFrame->mPosition - lastFrame->mPosition);
1371
1372                        Quaternion or = Quaternion::Slerp(factor, lastFrame->mOrientation,
1373                                mCurrFrame->mOrientation);
1374
1375                        // update camera
1376                        mCamNode->setPosition(pos);
1377                        mCamNode->setOrientation(or);
1378
1379                        // update viz camera
1380                        mTopCam->moveRelative(mVizCamTransVect);
1381                        if (mTopCamFollow)
1382                        {
1383                                Vector3 toppos = mTopCam->getPosition();
1384                                Vector3 campos = mCamNode->getPosition();
1385                                mTopCam->setPosition(Vector3::ZERO);
1386                                mTopCam->setOrientation(Quaternion::IDENTITY);
1387                                mTopCam->setPosition(campos.x, toppos.y, campos.z);
1388                                mTopCam->pitch(Radian(-Math::HALF_PI));
1389                        }
1390
1391                }
1392        }
1393        else
1394        {
1395                if ( !mUseBufferedInputMouse || !mUseBufferedInputKeys)
1396                {
1397                        // one of the input modes is immediate, so update the movement vector
1398
1399                        moveCamera();
1400
1401                }
1402        }
1403
1404        //saveFrameInfo(evt.timeSinceLastFrame);
1405        if (mAppState == AS_RECORD)
1406        {
1407                // update stats
1408                ++ mDemoStats.mTotalNumFrames;
1409                mDemoStats.mTotalEllapsedTime += evt.timeSinceLastFrame;
1410
1411                // set time display
1412                int m = (int)mDemoStats.mTotalEllapsedTime / 60;
1413                int s = (int)mDemoStats.mTotalEllapsedTime % 60;
1414
1415                mDemoTime->setCaption(
1416                        StringConverter::toString(m, 2, '0') + ":" +
1417                        StringConverter::toString(s, 2, '0'));
1418
1419                // set FPS display
1420                const RenderTarget::FrameStats& stats = mWindow->getStatistics();
1421                mDemoFPSDisp->setCaption(StringConverter::toString((int)stats.lastFPS));
1422
1423                // store frame
1424                mFrameList.push_back(FrameInfo(mCamNode->getPosition(), mCamNode->getOrientation(), evt.timeSinceLastFrame));
1425        }
1426
1427
1428        //Camera        *followCam = mSceneMgr->getCamera("FollowCam");
1429        //if (followCam->getAutoTrackTarget() != 0)
1430        //{
1431        //      // Move the death thingy & update lookat camera FOV
1432        //      SceneNode *deathPivotNode = mSceneMgr->getSceneNode("deathPivotNode");
1433        //      SceneNode *deathNode = mSceneMgr->getSceneNode("movingNode");
1434        //      SceneNode *pivotNode = mSceneMgr->getSceneNode("pivotNode");
1435
1436        //      Vector3 fcpos = followCam->getPosition();
1437        //      Vector3 oldpos = deathNode->getWorldPosition();
1438
1439        //      Radian deltaAngle = Radian(evt.timeSinceLastFrame / mRotationPeriod * Math::TWO_PI);
1440        //      deathPivotNode->rotate(Vector3::UNIT_Y, deltaAngle);
1441        //      pivotNode->rotate(Vector3::UNIT_Y, deltaAngle * 4);
1442
1443        //      Vector3 pos = deathNode->getWorldPosition();
1444
1445        //      Real olddist = (oldpos - fcpos).length();
1446        //      Real dist = (pos - fcpos).length();
1447
1448        //      Radian oldfov = followCam->getFOVy();
1449        //      Radian fov = Radian(olddist / dist) * oldfov;
1450
1451        //      followCam->setFOVy(fov);
1452        //}
1453
1454        return true;
1455}
1456
1457bool KdTreeAppListener::frameEnded(const FrameEvent& evt)
1458{
1459        if (!mOptions.mDemoMode)
1460                updateStats();
1461
1462        return true;
1463}
1464
1465void KdTreeAppListener::switchMouseMode()
1466{
1467        mUseBufferedInputMouse = !mUseBufferedInputMouse;
1468        mInputDevice->setBufferedInput(mUseBufferedInputKeys, mUseBufferedInputMouse);
1469}
1470void KdTreeAppListener::switchKeyMode()
1471{
1472        mUseBufferedInputKeys = !mUseBufferedInputKeys;
1473        mInputDevice->setBufferedInput(mUseBufferedInputKeys, mUseBufferedInputMouse);
1474}
1475
1476void KdTreeAppListener::keyClicked(KeyEvent* e)
1477{
1478        if (e->getKeyChar() == 'm')
1479        {
1480                switchMouseMode();
1481        }
1482        else if (e->getKeyChar() == 'k')
1483        {
1484
1485                switchKeyMode();
1486        }
1487}
1488
1489/************************************************************************/
1490/* functions for recording & playback of demos                          */
1491/************************************************************************/
1492
1493//-----------------------------------------------------------------------------
1494void KdTreeAppListener::toggleRecord()
1495{
1496        // start recording
1497        if (mAppState == AS_NORMAL)
1498        {
1499                // change state
1500                mAppState = AS_RECORD;
1501
1502                // clear old recording
1503                mFrameList.clear();
1504
1505                // reset stats
1506                mDemoStats.mNumFrames = 0;
1507                mDemoStats.mTotalNumFrames = 0;
1508                mDemoStats.mEllapsedTime = 0.0f;
1509                mDemoStats.mTotalEllapsedTime = 0.0f;
1510        }
1511        // stop recording
1512        else if (mAppState == AS_RECORD)
1513        {
1514                // change state
1515                mAppState = AS_NORMAL;
1516
1517        }
1518        // update display
1519        setDemoOverlay();
1520}
1521
1522//-----------------------------------------------------------------------------
1523void KdTreeAppListener::togglePlayback()
1524{
1525        static Vector3 pos;
1526        static Quaternion or;
1527
1528        // start playback
1529        if (mAppState == AS_NORMAL && !mFrameList.empty())
1530        {
1531                // change state
1532                mAppState = AS_PLAYBACK;
1533
1534                // save old position
1535                pos = mCamNode->getPosition();
1536                or = mCamNode->getOrientation();
1537
1538                // reset demo
1539                mCurrFrame = mFrameList.begin();
1540                mTimeRemaining = mCurrFrame->mElapsedTime;
1541
1542                // reset stats
1543                mDemoStats.mNumFrames = 0;
1544                mDemoStats.mTotalNumFrames = 0;
1545                mDemoStats.mEllapsedTime = 0.0f;
1546                mDemoStats.mTotalEllapsedTime = 0.0f;
1547                mDemoFPS.clear();
1548        }
1549        // stop playback
1550        else if (mAppState == AS_PLAYBACK)
1551        {
1552                // change state
1553                mAppState = AS_NORMAL;
1554
1555                // restore old position
1556                mCamNode->setPosition(pos);
1557                mCamNode->setOrientation(or);
1558        }
1559
1560        // update display
1561        setDemoOverlay();
1562}
1563
1564
1565//-----------------------------------------------------------------------------
1566void KdTreeAppListener::saveFrames(const String& filename, FrameList& framelist)
1567{
1568        size_t dot = filename.find_last_of(".");
1569        String ext = filename.substr(dot + 1, filename.length());
1570        if (ext == "txt")
1571                saveFramesAscii(filename, framelist);
1572        else if (ext == "bin")
1573                saveFramesBinary(filename, framelist);
1574        else
1575                OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Invalid extension for demo file: " + ext, "KdTreeApp::loadFrames");
1576}
1577
1578//-----------------------------------------------------------------------------
1579void KdTreeAppListener::saveFramesAscii(const String& filename, FrameList& framelist)
1580{
1581        // open file
1582        std::ofstream dest(filename.c_str());
1583        if (dest.is_open())
1584        {
1585                FrameList::iterator it = framelist.begin();
1586                FrameList::iterator end = framelist.end();
1587
1588                // dump values
1589                while (it != end)
1590                {
1591                        dest <<
1592                                StringConverter::toString(it->mPosition) << " " <<
1593                                StringConverter::toString(it->mOrientation) << " " <<
1594                                StringConverter::toString(it->mElapsedTime) << "\n";
1595                        ++ it;
1596                }
1597
1598                dest.close();
1599        }
1600        else
1601        {
1602                LogManager::getSingleton().logMessage("##Error##: Failed to open file for saving demo: " + filename);
1603        }
1604
1605
1606}
1607
1608//-----------------------------------------------------------------------------
1609void KdTreeAppListener::saveFramesBinary(const String& filename, FrameList& framelist)
1610{
1611        std::ofstream dest(filename.c_str(), std::ios_base::out | std::ios_base::binary);
1612
1613        if (dest.is_open())
1614        {
1615                FrameList::iterator it = framelist.begin();
1616                FrameList::iterator end = framelist.end();
1617
1618                int size = sizeof(Real);
1619
1620                // dump values
1621                while (it != end)
1622                {
1623                        dest.write((char *)&it->mPosition.x, size);
1624                        dest.write((char *)&it->mPosition.y, size);
1625                        dest.write((char *)&it->mPosition.z, size);
1626                        dest.write((char *)&it->mOrientation.w, size);
1627                        dest.write((char *)&it->mOrientation.x, size);
1628                        dest.write((char *)&it->mOrientation.y, size);
1629                        dest.write((char *)&it->mOrientation.z, size);
1630                        dest.write((char *)&it->mElapsedTime, size);
1631                        ++ it;
1632                }
1633
1634                dest.close();
1635        }
1636        else
1637        {
1638                LogManager::getSingleton().logMessage("##Error##: Failed to open file for saving demo: " + filename);
1639        }
1640}
1641
1642//-----------------------------------------------------------------------------
1643void KdTreeAppListener::loadFrames(const String& filename, FrameList& framelist)
1644{
1645        size_t dot = filename.find_last_of(".");
1646        String ext = filename.substr(dot + 1, filename.length());
1647        if (ext == "txt")
1648                loadFramesAscii(filename, framelist);
1649        else if (ext == "bin")
1650                loadFramesBinary(filename, framelist);
1651        else
1652                OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Invalid extension for demo file: " + ext, "KdTreeApp::loadFrames");
1653}
1654
1655//-----------------------------------------------------------------------------
1656void KdTreeAppListener::loadFramesAscii(const String& filename, FrameList& framelist)
1657{
1658        // open file
1659        std::ifstream src(filename.c_str());
1660        if (src.is_open())
1661        {
1662                // clear the list
1663                framelist.clear();
1664
1665                Vector3 pos;
1666                Quaternion or;
1667                Real time;
1668
1669                while (!src.eof())
1670                {
1671                        src >> pos.x;   
1672                        src >> pos.y;   
1673                        src >> pos.z;
1674
1675                        src >> or.w;
1676                        src >> or.x;
1677                        src >> or.y;
1678                        src >> or.z;
1679
1680                        src >> time;
1681
1682                        framelist.push_back(FrameInfo(pos, or, time));
1683                }
1684
1685                // HACK pop last frame, was doubled while reading
1686                framelist.pop_back();
1687
1688                src.close();
1689        }
1690        else
1691        {
1692                LogManager::getSingleton().logMessage("##Error##: Failed to open file for reading demo: " + filename);
1693        }
1694}
1695
1696//-----------------------------------------------------------------------------
1697void KdTreeAppListener::loadFramesBinary(const String& filename, FrameList& framelist)
1698{
1699        // open file
1700        std::ifstream src(filename.c_str(), std::ios_base::out | std::ios_base::binary);
1701        if (src.is_open())
1702        {
1703                // clear the list
1704                framelist.clear();
1705
1706                int size = sizeof(Real);
1707
1708                Vector3 pos;
1709                Quaternion or;
1710                Real time;
1711
1712                while (!src.eof())
1713                {
1714                        src.read((char *)&pos.x, size);
1715                        src.read((char *)&pos.y, size);
1716                        src.read((char *)&pos.z, size);
1717                        src.read((char *)&or.w, size);
1718                        src.read((char *)&or.x, size);
1719                        src.read((char *)&or.y, size);
1720                        src.read((char *)&or.z, size);
1721                        src.read((char *)&time, size);
1722
1723                        framelist.push_back(FrameInfo(pos, or, time));
1724                }
1725
1726                // HACK pop last frame, was doubled while reading
1727                framelist.pop_back();
1728
1729                src.close();
1730        }
1731        else
1732        {
1733                LogManager::getSingleton().logMessage("##Error##: Failed to open file for reading demo: " + filename);
1734        }
1735}
1736
1737//-----------------------------------------------------------------------------
1738void KdTreeAppListener::saveLog()
1739{
1740        // field separator and record separator
1741        static const String fs = ",", rs ="\n", ds = ":";
1742        // stats
1743        Real minFPS = Math::POS_INFINITY, maxFPS = 0.0, avgFPS = 0.0;
1744        String line, storedname;
1745        String demopath, demoname;
1746        StringUtil::splitFilename(mOptions.mDemoInfileName, demoname, demopath);
1747       
1748        // check if logfile exists
1749        std::ifstream logread(mOptions.mDemoLogfileName.c_str());
1750        if (logread.is_open())
1751        {
1752                // read first line, shuold start with the name of the demo
1753                // if matches, OK, otherwise do something
1754                logread >> line;
1755                storedname = line.substr(0,line.find_first_of(','));
1756                logread.close();
1757                if (storedname != demoname)
1758                {
1759                        LogManager::getSingleton().logMessage(
1760                                "##Error##: Saved demo stats do not match the current demo: " +
1761                                storedname + " != " + demoname);
1762                        return;
1763                }
1764        }
1765        // otherwise write header
1766        else
1767        {
1768                std::ofstream logheader(mOptions.mDemoLogfileName.c_str());
1769                if (logheader.is_open())
1770                {
1771                        // demo title
1772                        logheader << demoname << fs;
1773                        // seconds
1774                        for (size_t i = 0; i < mDemoFPS.size(); i ++)
1775                        {
1776                                logheader << (i+1) << fs;
1777                        }
1778                        // minFPS, avgFPS, maxFPS, frames, time, render system, comment, record separator
1779                        logheader << "\"min FPS\"" << fs << "\"avg FPS\"" << fs << "\"max FPS\"" << fs
1780                                << "\"# Frames \"" << fs << "\"Total Time\"" << fs << "\"Comment\"" << fs
1781                                << "\"Render System\"" << rs;
1782                        logheader.close();
1783                }
1784                else
1785                {
1786                        LogManager::getSingleton().logMessage(
1787                                "##Error##: Failed to write log demo header to " +
1788                                mOptions.mDemoLogfileName);
1789                        return;
1790
1791                }
1792        }
1793
1794        // append current stats
1795        std::ofstream logwrite(mOptions.mDemoLogfileName.c_str(), std::ios_base::app);
1796        if (logwrite.is_open())
1797        {
1798                // gather info about ogre settings
1799                String rendersys = "\"" + Root::getSingleton().getRenderSystem()->getName();
1800                ConfigOptionMap rsopts = Root::getSingleton().getRenderSystem()->getConfigOptions();
1801                for (ConfigOptionMap::iterator it = rsopts.begin(); it != rsopts.end(); it ++)
1802                {
1803                        rendersys += " | " + it->first + " : " + it->second.currentValue;
1804                }
1805                rendersys += "\"";
1806
1807                // view cells used?
1808                String viewcells;
1809                if (mOptions.mViewCells == VCM_ON)
1810                        viewcells = ds + "VC";
1811                else if (mOptions.mViewCells == VCM_FILTER)
1812                        viewcells = ds + "VC+VF";
1813
1814                // demo settings
1815                logwrite << "\"" << SCENEMANAGER[mOptions.mSceneManager];
1816                if (mOptions.mSceneManager == SM_KDT || mOptions.mSceneManager == SM_KTE)
1817                {
1818                        // info about enhanced visibility if internal rendering
1819                        String senhvis;
1820                        if (mOptions.mRenderMethod == KdTree::KDRM_INTERNAL)
1821                        {
1822                                if (mOptions.mEnhancedVisibility)
1823                                        senhvis = "E" + ds;
1824                                else
1825                                        senhvis = "S" + ds;
1826                        }
1827
1828                        logwrite << ds << RENDERMETHOD[mOptions.mRenderMethod] << ds << senhvis <<
1829                                mOptions.mMaxDepth << ds << mOptions.mKT << ds << mOptions.mKI << ds <<
1830                                BUILDMETHOD[mOptions.mBuildMethod] << viewcells;
1831                }
1832                else if (mOptions.mSceneManager == SM_OCM && mOptions.mRenderMethod != KdTree::KDRM_INTERNAL)
1833                {
1834                        logwrite << ds << RENDERMETHOD[CONV_OCM_TO_KDT_ALG(mOptions.mRenderMethod)] << viewcells;
1835                }
1836                logwrite << "\"" << fs;
1837                // per second stats
1838                for (std::list<Real>::iterator it = mDemoFPS.begin(); it != mDemoFPS.end(); it ++)
1839                {
1840                        if (*it < minFPS)
1841                                minFPS = *it;
1842
1843                        if (*it > maxFPS)
1844                                maxFPS = *it;
1845
1846                        //avgFPS += *it;
1847
1848                        logwrite << (int)(*it) << fs;
1849
1850                }
1851                //avgFPS /= mDemoFPS.size();
1852                avgFPS = mDemoStats.mTotalNumFrames / mDemoStats.mTotalEllapsedTime;
1853                // minFPS, avgFPS, maxFPS, comment, record separator
1854                logwrite << (int)minFPS << fs << (int)avgFPS << fs << (int)maxFPS << fs
1855                        << mDemoStats.mTotalNumFrames << fs << mDemoStats.mTotalEllapsedTime << fs
1856                        << "\"" << mOptions.mComment << "\"" << fs << rendersys << rs;
1857                logwrite.close();
1858        }
1859        else
1860        {
1861                LogManager::getSingleton().logMessage(
1862                        "##Error##: Failed to write demo log to " +
1863                        mOptions.mDemoLogfileName);
1864        }
1865}
1866
1867//-----------------------------------------------------------------------------
1868void KdTreeAppListener::saveFrameInfo(Real elapsedTime)
1869{
1870        mFrameList.push_back(FrameInfo(mCamNode->getPosition(), mCamNode->getOrientation(), elapsedTime));
1871}
1872
1873//-----------------------------------------------------------------------------
1874void KdTreeAppListener::setDemoOverlay()
1875{
1876        // init overlay if not present
1877        if (!mDemoOverlay || !mDemoStatus || !mDemoTime)
1878        {
1879                OGRE_DELETE(mDemoOverlay);
1880                OGRE_DELETE(mDemoStatus);
1881                OGRE_DELETE(mDemoTime);
1882
1883                mDemoStatus = OverlayManager::getSingleton().createOverlayElement("Panel", "KdTree/DemoStatus");
1884                mDemoStatus->setMetricsMode(GMM_PIXELS);
1885                mDemoStatus->setDimensions(32, 32);
1886                mDemoStatus->setLeft(64);
1887
1888                mDemoTime = static_cast<TextAreaOverlayElement *>
1889                        (OverlayManager::getSingleton().createOverlayElement("TextArea", "KdTree/DemoTime"));
1890                mDemoTime->setMetricsMode(GMM_PIXELS);
1891                mDemoTime->setTop(6);
1892                mDemoTime->setLeft(104);
1893                mDemoTime->setFontName("TrebuchetMSBold");
1894                mDemoTime->setCharHeight(24.0);
1895                mDemoTime->setCaption("00:00");
1896
1897                mDemoFPSDisp = static_cast<TextAreaOverlayElement *>
1898                        (OverlayManager::getSingleton().createOverlayElement("TextArea", "KdTree/DemoFPS"));
1899                mDemoFPSDisp->setMetricsMode(GMM_PIXELS);
1900                mDemoFPSDisp->setAlignment(TextAreaOverlayElement::Right);
1901                mDemoFPSDisp->setTop(6);
1902                mDemoFPSDisp->setLeft(48);
1903                mDemoFPSDisp->setFontName("TrebuchetMSBold");
1904                mDemoFPSDisp->setCharHeight(24.0);
1905                mDemoFPSDisp->setCaption("0");
1906
1907                PanelOverlayElement *demoCont = static_cast<PanelOverlayElement *>
1908                        (OverlayManager::getSingleton().createOverlayElement("Panel", "KdTree/DemoTimePanel"));
1909                demoCont->setMetricsMode(GMM_PIXELS);
1910                demoCont->setHorizontalAlignment(GHA_CENTER);
1911                demoCont->setVerticalAlignment(GVA_TOP);
1912                demoCont->setTop(5);
1913                demoCont->setLeft(-80);
1914                demoCont->setDimensions(160, 32);
1915                demoCont->addChild(mDemoFPSDisp);
1916                demoCont->addChild(mDemoStatus);
1917                demoCont->addChild(mDemoTime);
1918                //demoCont->setMaterialName("Core/StatsBlockCenter");
1919
1920                mDemoOverlay = OverlayManager::getSingleton().create("KdTree/DemoOverlay");
1921                mDemoOverlay->setZOrder(500);
1922                //mDemoOverlay->add2D(static_cast<PanelOverlayElement *>(mDemoStatus));
1923                mDemoOverlay->add2D(demoCont);
1924        }
1925
1926        switch(mAppState)
1927        {
1928        case AS_NORMAL:
1929                mDemoOverlay->hide();
1930                break;
1931        case AS_PLAYBACK:
1932                mDemoStatus->setMaterialName("KdTree/DemoPlayButton");
1933                mDemoTime->setColourTop(ColourValue(0.5, 0.7, 0.5));
1934                mDemoTime->setColourBottom(ColourValue(0.3, 0.5, 0.3));
1935                mDemoFPSDisp->setColourTop(ColourValue(0.5, 0.7, 0.5));
1936                mDemoFPSDisp->setColourBottom(ColourValue(0.3, 0.5, 0.3));
1937                mDemoOverlay->show();
1938                break;
1939        case AS_RECORD:
1940                mDemoStatus->setMaterialName("KdTree/DemoRecordButton");
1941                mDemoTime->setColourTop(ColourValue(0.7, 0.5, 0.5));
1942                mDemoTime->setColourBottom(ColourValue(0.5, 0.3, 0.3));
1943                mDemoFPSDisp->setColourTop(ColourValue(0.7, 0.5, 0.5));
1944                mDemoFPSDisp->setColourBottom(ColourValue(0.5, 0.3, 0.3));
1945                mDemoOverlay->show();
1946                break;
1947        default:
1948            break;
1949        }
1950
1951}
Note: See TracBrowser for help on using the repository browser.