source: trunk/VUT/work/TestCullingTerrain/TerrainFrameListener.cpp @ 183

Revision 183, 43.3 KB checked in by mattausch, 19 years ago (diff)

added iv-reader library, testing code, and resources

Line 
1#include <OgreNoMemoryMacros.h>
2#include <CEGUI/CEGUI.h>
3#include <../CEGUIRenderer/include/OgreCEGUIRenderer.h>
4#include <../CEGUIRenderer/include/OgreCEGUIResourceProvider.h>
5#include <../CEGUIRenderer/include/OgreCEGUITexture.h>
6#include <OgreMemoryMacros.h>
7#include "TerrainFrameListener.h"
8#include "OgrePlatformQueryManager.h"
9#include "OgreVisibilityTerrainSceneManager.h"
10#include "VisibilityInfo.h"
11#include "OgreOcclusionQueriesQueryManager.h"
12#include "TestCullingTerrainApplication.h"
13
14
15//-- captions for overlays
16String TerrainFrameListener::msAlgorithmCaptions[] =
17{
18        "Coherent Hierarchical Culling",
19        "View Frustum Culling",
20        "Stop and Wait Culling"
21};
22
23String TerrainFrameListener::msQueryTypeCaptions[] =
24{
25        "from camera",
26        "from viewpoint"
27};
28
29String TerrainFrameListener::msQueryRelativeVisCaptions[] =
30{
31        "visible pixels",
32        "relative visibility"
33};
34
35String TerrainFrameListener::msQueryMethodCaptions[] =
36{
37        "occlusion queries",
38        "item buffer"
39};
40
41Real TerrainFrameListener::msObjectTerrainOffsets[] =
42{
43        0,
44        -0.1,
45        //7,
46        0
47};
48
49Real TerrainFrameListener::msObjectScales[] =
50{
51        0.1,
52        0.03,
53        //0.1,
54        0.04
55};
56
57String TerrainFrameListener::msObjectCaptions[] =
58{
59        "robot",
60        //"athene",
61        "natFX_Tree1_LOD2",
62        //"tree2",
63        //"HongKong_Tower",
64        "ninja"
65        //"ogrehead"
66};
67
68// output file for frame info
69const char* frames_out_filename = "frame.out";
70// output file for object positions / orientations
71const char* objects_out_filename = "objects.out";
72
73
74//-----------------------------------------------------------------------
75TerrainFrameListener::TerrainFrameListener(RenderWindow* win, Camera* cam,
76                                                                           SceneManager *sceneManager,
77                                                                           CEGUI::Renderer *renderer,
78                                                                           TerrainContentGenerator *sceneGenerator,
79                                                                           Camera *vizCamera,
80                                                                           SceneNode *camNode,
81                                                                           Light *sunLight,
82                                                                           TestCullingTerrainApplication *app):
83mCamera(cam),
84mWindow(win),
85mNumScreenShots(0),
86mTimeDelay(0),
87mSceneDetailIndex(0),
88mMoveScale(0.0f),
89mRotScale(0.0f),
90mTranslateVector(Vector3::ZERO),
91mAniso(1),
92mFiltering(TFO_BILINEAR),
93mGUIRenderer(renderer),
94mSceneMgr(sceneManager),
95mCurrentObject(NULL),
96mTerrainContentGenerator(sceneGenerator),
97mVisibilityThreshold(0),
98mAssumedVisibility(0),
99mCurrentAlgorithm(GtpVisibility::VisibilityEnvironment::COHERENT_HIERARCHICAL_CULLING),
100//mCurrentAlgorithm(GtpVisibility::VisibilityEnvironment::FRUSTUM_CULLING),
101mNodeVizMode(NODEVIZ_NONE),
102mVizCameraHeight(Real(2500.0)),
103mCamNode(camNode),
104mAppState(WALKTHROUGH),
105mCurrentFrame(0),
106mReplayTimeElapsed(0),
107mRotateSpeed(72),
108mMoveSpeed(50),
109mVizCamera(vizCamera),
110mStatsOn(true),
111mShutdownRequested(false),
112mLMouseDown(false),
113mRMouseDown(false),
114mShowOctree(false),
115mUseDepthPass(false),
116mTestGeometryForVisibleLeaves(false),
117mShowVisualization(false),
118mCullCamera(false),
119mRecord(false),
120mShowShadows(false),
121mShowHelp(false),
122mDisplayCameraDetails(false),
123mVisualizeCulledNodes(false),
124mSunLight(sunLight),
125mShiftPressed(false),
126mShowQueryStats(false),
127mQueryManager(NULL),
128mVisibilityManager(NULL),
129mDelayedQueriesIssued(0.0),
130mDelayedTraversedNodes(0.0),
131mCurrentObjectType(0),
132mApplication(app),
133mUseAnimation(false),
134mDeleteObjects(false),
135mUseItemBuffer(false),
136mItemBufferMode(GtpVisibility::QueryManager::PATCH_VISIBILITY)
137{
138        //mInputDevice = PlatformManager::getSingleton().createInputReader();
139        //mInputDevice->initialise(win, true, true);
140
141        mEventProcessor = new EventProcessor();
142       
143        mEventProcessor->initialise(win);
144        mEventProcessor->startProcessingEvents();
145        mEventProcessor->addMouseListener(this);
146        mEventProcessor->addMouseMotionListener(this);
147        mEventProcessor->addKeyListener(this);
148
149        mInputDevice = mEventProcessor->getInputReader();       
150
151        // create ray query executor, used to place objects in terrain
152        mRayQueryExecutor = new RayQueryExecutor(mSceneMgr);
153       
154        //-- overlays
155        mDebugOverlay = OverlayManager::getSingleton().getByName("Core/DebugOverlay");
156        mHelpOverlay = OverlayManager::getSingleton().getByName("Example/Visibility/HelpOverlay");
157        mQueryOverlay = OverlayManager::getSingleton().getByName("Example/Visibility/QueryOverlay");
158        mCullStatsOverlay = OverlayManager::getSingleton().getByName("Example/Visibility/CullStatsOverlay");
159
160        initVisStatsOverlay(); // visibility stats overlay
161        initHelpOverlay(); // help overlay
162        initQueryOverlay(); // visibility query stats overlay
163
164        // show stats overlays
165        showStats(true);
166       
167        // set culling algorithm type
168        setAlgorithm(mCurrentAlgorithm);
169
170        // set scene manager options
171        mSceneMgr->setOption("TestGeometryForVisibleLeaves", &mTestGeometryForVisibleLeaves);
172
173        // apply delayed rendering (i.e., transparents after hierarchical culling pass)
174        // only if optimization is not used
175        bool delayRenderTransparents = !mTestGeometryForVisibleLeaves;
176
177        mSceneMgr->setOption("DelayRenderTransparents", &delayRenderTransparents);
178        mSceneMgr->setOption("UseDepthPass", &mUseDepthPass);
179       
180        mSceneMgr->setOption("ShowOctree", &mShowOctree);
181        mSceneMgr->setOption("CullCamera", &mCullCamera);
182        mSceneMgr->setOption("PrepareVisualization", &mShowVisualization);
183
184        setObjectType(mCurrentObjectType);
185
186        // reset statistics
187        resetStats();
188}
189//-----------------------------------------------------------------------
190TerrainFrameListener::~TerrainFrameListener()
191{
192        delete mRayQueryExecutor;
193        delete mEventProcessor;
194
195        if (mQueryManager)
196        {
197                delete mQueryManager;
198                mQueryManager = NULL;
199        }
200}
201//-----------------------------------------------------------------------
202void TerrainFrameListener::mouseMoved(MouseEvent *e)
203{
204        // Update CEGUI with the mouse motion
205    CEGUI::System::getSingleton().injectMouseMove(e->getRelX() *
206                mGUIRenderer->getWidth(), e->getRelY() * mGUIRenderer->getHeight());
207}
208//-----------------------------------------------------------------------
209void TerrainFrameListener::mousePressed(MouseEvent* e)
210{
211     // Left mouse button down
212     if (e->getButtonID() & InputEvent::BUTTON0_MASK)
213     {
214                 CEGUI::MouseCursor::getSingleton().hide();
215
216                 // Setup the ray scene query
217         Ray mouseRay = mCamera->getCameraToViewportRay(e->getX(), e->getY());
218                 
219                 //Vector3 queryResult; mRayQueryExecutor->executeRayQuery(&queryResult, mouseRay);
220                 
221                 Real val = Math::RangeRandom(0, 360); // random rotation
222
223                 // get results, create a node/entity on the position
224                 mCurrentObject = mTerrainContentGenerator->GenerateSceneObject(
225                         mouseRay.getOrigin()/*queryResult*/, Vector3(val, 0, 0),
226                         msObjectCaptions[mCurrentObjectType]);
227               
228         mLMouseDown = true;
229     }
230     // Right mouse button down
231     else if (e->getButtonID() & InputEvent::BUTTON1_MASK)
232     {
233         CEGUI::MouseCursor::getSingleton().hide();
234         mRMouseDown = true;
235     }
236}
237//-----------------------------------------------------------------------
238void TerrainFrameListener::mouseDragDropped(MouseEvent* e)
239{
240        // Left mouse button up
241    if (e->getButtonID() & InputEvent::BUTTON0_MASK)
242    {
243                CEGUI::MouseCursor::getSingleton().show();
244               
245            mLMouseDown = false;
246    }
247    // Right mouse button up
248    else if (e->getButtonID() & InputEvent::BUTTON1_MASK)
249    {
250        CEGUI::MouseCursor::getSingleton().show();
251
252                mRMouseDown = false;
253    }
254}
255//-----------------------------------------------------------------------
256void TerrainFrameListener::mouseReleased(MouseEvent* e)
257{
258    // Left mouse button up
259    if (e->getButtonID() & InputEvent::BUTTON0_MASK)
260    {
261                CEGUI::MouseCursor::getSingleton().show();
262               
263                // start animation: only robot has animation phases
264                if (mCurrentObject && (mCurrentObjectType == TestCullingTerrainApplication::ROBOT))
265                {
266                        // HACK: not neccesary the last element
267                        Entity *ent = mTerrainContentGenerator->GetGeneratedEntities()->back();
268                        EntityState *entState = new EntityState(ent, EntityState::MOVING, Math::RangeRandom(0.5, 1.5));
269                        mApplication->getEntityStates().push_back(entState);
270                }
271
272            mLMouseDown = false;
273    }
274    // Right mouse button up
275    else if (e->getButtonID() & InputEvent::BUTTON1_MASK)
276    {
277        CEGUI::MouseCursor::getSingleton().show();
278
279        mRMouseDown = false;
280    }
281}
282//-----------------------------------------------------------------------
283void TerrainFrameListener::mouseDragged(MouseEvent *e)
284 {
285         // If we are dragging the left mouse button.           
286         if (mLMouseDown)
287     {
288                 if (!mCurrentObject)
289                         return;
290
291                 Vector3 queryResult;
292                 Ray mouseRay = mCamera->getCameraToViewportRay(e->getX(), e->getY());
293
294                 if (mRayQueryExecutor->executeRayQuery(&queryResult, mouseRay))
295                 {
296                         // apply offset so object is ON terrain
297                         queryResult.y += msObjectTerrainOffsets[mCurrentObjectType];
298                         mCurrentObject->setPosition(queryResult);
299                 }
300     }
301         // If we are dragging the right mouse button.
302         if (mRMouseDown)
303         {
304                 //mCamera->yaw(-e->getRelX() * mRotateSpeed);
305                 //mCamera->pitch(-e->getRelY() * mRotateSpeed);
306                 mCamNode->yaw(-e->getRelX() * mRotateSpeed);
307                 mCamNode->pitch(-e->getRelY() * mRotateSpeed);
308         }
309}
310//-----------------------------------------------------------------------
311bool TerrainFrameListener::frameStarted(const FrameEvent &evt)
312{
313        if (mWindow->isClosed())
314        {
315        return false;
316        }
317       
318        if (mDeleteObjects)
319        {
320                mApplication->deleteEntityStates();
321                mTerrainContentGenerator->RemoveGeneratedObjects();
322                mDeleteObjects = false;
323        }
324
325        if (mUseAnimation) // update animations
326        {
327                mApplication->updateAnimations(evt.timeSinceLastFrame);
328        }
329
330        if (mDisplayCameraDetails)  // Print camera details
331    {       
332        mWindow->setDebugText("P: " + StringConverter::toString(mCamera->getDerivedPosition()) +
333                        " " + "O: " + StringConverter::toString(mCamera->getDerivedOrientation()));
334    }
335
336        //-- setup what is needed for immediate mouse/key movement
337        if (mTimeDelay >= 0)
338        {
339                mTimeDelay -= evt.timeSinceLastFrame;
340        }
341       
342        // If this is the first frame, pick a speed
343        if (evt.timeSinceLastFrame == 0)
344        {
345                mMoveScale = 1;
346                mRotScale = 0.1;
347        }
348        // Otherwise scale movement units by time passed since last frame
349        else
350        {
351                // Move about 100 units per second,
352                mMoveScale = mMoveSpeed * evt.timeSinceLastFrame;
353                // Take about 10 seconds for full rotation
354                mRotScale = mRotateSpeed * evt.timeSinceLastFrame;
355        }
356
357        mRotX = 0;
358        mRotY = 0;
359        mTranslateVector = Vector3::ZERO;
360
361        if (!processUnbufferedKeyInput(evt))
362        {
363                return false;
364        }
365/*      if (!processUnbufferedMouseInput(evt))
366        {       return false;   }*/
367
368        // --- set parameters for visualization
369        if (mShowVisualization)
370        {
371                // important for visualization => draw octree bounding boxes
372                mSceneMgr->setOption("ShowOctree", &mShowVisualization);
373               
374                // ---- setup visualization camera
375
376                mVizCamera->setPosition(0, 0, 0);
377                mVizCamera->setOrientation(Quaternion::IDENTITY);
378
379                Vector3 camPos = mCamNode->getPosition();
380                mVizCamera->setPosition(camPos.x, mVizCameraHeight, camPos.z);
381
382                // point down -Z axis
383                mVizCamera->pitch(Radian(Degree(270.0)));
384
385                // rotation arounnd X axis
386                mVizCamera->yaw(Math::ATan2(-mCamera->getDerivedDirection().x,
387                        -mCamera->getDerivedDirection().z));
388               
389                // move by a constant so view plane is on bottom of viewport
390                mVizCamera->moveRelative(Vector3(0, 800, 0));
391        }
392
393        //-- set application state
394        switch (mAppState)
395        {
396        case REPLAY:
397                setCurrentFrameInfo(evt.timeSinceLastFrame);
398                break;
399        case WALKTHROUGH:
400                //-- if we are recording camera status per frame
401                if (mRecord)
402                {
403                        addFrameInfo(mCamNode, evt.timeSinceLastFrame);
404                        // print recording message
405                        mWindow->setDebugText("Recording frame " +
406                                StringConverter::toString(mFrameInfo.size() - 1));
407                }       
408                // move camera according to input
409                moveCamera();
410
411                // clamp camera so we always walk along the terrain
412                mApplication->Clamp2Terrain(mCamNode, 10);
413                break;
414
415        default:
416                break;
417        };     
418
419        return true;
420}
421//-----------------------------------------------------------------------
422void TerrainFrameListener::applyVisibilityQuery(bool fromPoint, bool relativeVisibility,
423                                                                                                bool useItemBuffer)
424{
425        // TODO: change this (does not work with other scene manager plugins)
426        VisibilityTerrainSceneManager *sm =
427                dynamic_cast<VisibilityTerrainSceneManager *>(mSceneMgr);
428
429        int itemBufferMode = useItemBuffer ? mItemBufferMode : 0;
430       
431        int queryModes = 0;
432        queryModes |= GtpVisibility::QueryManager::PATCH_VISIBILITY;
433        queryModes |= GtpVisibility::QueryManager::GEOMETRY_VISIBILITY;
434        queryModes |= GtpVisibility::QueryManager::NODE_VISIBILITY;
435       
436        mQueryManager = new OcclusionQueriesQueryManager(sm->GetHierarchyInterface(),
437                        mWindow->getViewport(0), queryModes, itemBufferMode);
438
439        //mQueryManager = new PlatformQueryManager(sm->GetHierarchyInterface(), mWindow->getViewport(0), false);
440       
441        sm->GetVisibilityManager()->SetQueryManager(mQueryManager);
442
443        InfoContainer<GtpVisibility::NodeInfo> visibleNodes;
444        InfoContainer<GtpVisibility::MeshInfo> visibleGeometry;
445        InfoContainer<GtpVisibility::PatchInfo> visiblePatches;
446
447
448        if (fromPoint)
449        {
450                mQueryManager->
451                        ComputeFromPointVisibility(mCamNode->getPosition(), &visibleNodes,
452                                                                           &visibleGeometry, &visiblePatches, relativeVisibility);
453        }
454        else
455        {
456                mQueryManager->ComputeCameraVisibility(*mCamera,
457                            &visibleNodes, &visibleGeometry, &visiblePatches, relativeVisibility);
458        }
459               
460        std::stringstream d;
461        d << "Query mode: " << queryModes << ", "
462          << msQueryTypeCaptions[fromPoint ?  1 : 0].c_str() << " "
463          << msQueryRelativeVisCaptions[relativeVisibility ? 1 : 0].c_str() << " "
464      << msQueryMethodCaptions[useItemBuffer ? 1 : 0].c_str();
465        LogManager::getSingleton().logMessage(d.str());
466
467
468        float averageNodeVis = 0, averageGeometryVis = 0, averagePatchVis = 0;
469        int geomSize = 0, nodesSize = 0, patchSize = 0;
470
471        InfoContainer<GtpVisibility::MeshInfo>::iterator geomIt, geomIt_end = visibleGeometry.end();
472
473        for (geomIt = visibleGeometry.begin(); geomIt != geomIt_end; ++geomIt)
474        {
475                // add if not 0
476                if ((*geomIt).GetVisiblePixels())
477                {
478                        float vis = relativeVisibility ?
479                                (*geomIt).ComputeRelativeVisibility() : (float)(*geomIt).GetVisiblePixels();
480       
481                        averageGeometryVis += vis;
482                        ++ geomSize;
483                       
484                        std::stringstream d;
485                        d << "Geometry " << geomSize << " id: " << (*geomIt).GetMesh()->getSubEntity(0)->getId()
486                          << " visibility: "  << (*geomIt).GetVisiblePixels() << ", " << (*geomIt).GetProjectedPixels();
487                        LogManager::getSingleton().logMessage(d.str());
488                }
489        }
490
491        InfoContainer<GtpVisibility::NodeInfo>::iterator nodesIt, nodesIt_end = visibleNodes.end();
492
493        for (nodesIt = visibleNodes.begin(); nodesIt != nodesIt_end; ++nodesIt)
494        {
495                // add if not 0
496                if ((*nodesIt).GetVisiblePixels())
497                {
498                        float vis = relativeVisibility ?
499                                (*nodesIt).ComputeRelativeVisibility() : (float)(*nodesIt).GetVisiblePixels();
500               
501                        averageNodeVis += vis;
502                        ++ nodesSize;
503
504                        std::stringstream d; d << "Node visibility: " << vis;
505                        LogManager::getSingleton().logMessage(d.str());
506                }       
507        }
508
509        InfoContainer<GtpVisibility::PatchInfo>::iterator patchIt, patchIt_end = visiblePatches.end();
510
511        for (patchIt = visiblePatches.begin(); patchIt != patchIt_end; ++ patchIt)
512        {
513                // add if not 0
514                if ((*patchIt).GetVisiblePixels())
515                {
516                        float vis = relativeVisibility ?
517                                (*patchIt).ComputeRelativeVisibility() : (float)(*patchIt).GetVisiblePixels();
518               
519                        averagePatchVis += vis;
520                        ++ patchSize;
521
522                        std::stringstream d; d << "Patch visibility: " << vis;
523                        LogManager::getSingleton().logMessage(d.str());
524                }       
525        }
526
527        if (nodesSize)
528                averageNodeVis /= (float)nodesSize;
529        if (geomSize)
530                averageGeometryVis /= (float)geomSize;
531        if (patchSize)
532                averagePatchVis /= (float)patchSize;
533
534        //-- update visibility queries stats
535    try
536        {
537                char str[100];
538               
539                sprintf(str, ": %s, %s, %s",
540                                msQueryTypeCaptions[fromPoint ?  1 : 0].c_str(),
541                                msQueryRelativeVisCaptions[relativeVisibility ? 1 : 0].c_str(),
542                                msQueryMethodCaptions[useItemBuffer ? 1 : 0].c_str());
543
544                mQueryTypeInfo->setCaption(str);
545
546                sprintf(str, ": %d", (int)nodesSize);
547                mQueryVisibleNodesInfo->setCaption(str);
548       
549                sprintf(str,": %d", (int)geomSize);
550                mQueryVisibleGeometryInfo->setCaption(str);
551               
552                sprintf(str,": %d", (int)patchSize);
553                mQueryVisiblePatchInfo->setCaption(str);
554
555                sprintf(str,": %3.3f", averageNodeVis);
556                mQueryNodeVisibilityInfo->setCaption(str);
557
558                sprintf(str,": %3.3f", averageGeometryVis);
559                mQueryGeometryVisibilityInfo->setCaption(str);
560
561                sprintf(str,": %3.3f", averagePatchVis);
562                mQueryPatchVisibilityInfo->setCaption(str);
563        }
564        catch (...)
565        {
566                // ignore
567        }
568
569        // show the results
570        if (!mShowQueryStats && !mShowHelp)
571        {
572                mQueryOverlay->show();
573                mShowQueryStats = true;
574        }
575
576        delete mQueryManager;
577}
578
579//-----------------------------------------------------------------------
580bool TerrainFrameListener::frameEnded(const FrameEvent& evt)
581{
582        if (mShutdownRequested)
583                return false;
584
585    updateStats();
586
587        //-- IMPORTANT: must be set, otherwise terrain is not rendered correctly
588        mSceneMgr->endFrame();
589
590        if (mTimeDelay <= 0) // approx. one second
591                mTimeDelay = 1.0;
592
593        return true;
594}
595//-----------------------------------------------------------------------
596void TerrainFrameListener::moveCamera()
597{
598        // move node rather than camera so orientation is right in the visualization
599        mCamNode->yaw(mRotX);
600        mCamNode->pitch(mRotY);
601        mCamNode->translate(mCamNode->getLocalAxes(), mTranslateVector);
602}
603//-----------------------------------------------------------------------
604void TerrainFrameListener::writeFrames()
605{
606        std::ofstream ofstr(frames_out_filename);
607       
608        std::vector<frame_info>::const_iterator it, it_end;
609
610        it_end = mFrameInfo.end();
611        for (it = mFrameInfo.begin(); it < it_end; ++it)
612        {
613                ofstr << StringConverter::toString((*it).position) << " "
614                          << StringConverter::toString((*it).orientation) << " "
615                          << StringConverter::toString((*it).timeElapsed) << "\n";
616        }
617        ofstr.close();
618}
619//-----------------------------------------------------------------------
620void TerrainFrameListener::loadFrames()
621{
622        std::ifstream ifstr(frames_out_filename);
623        char line[256];
624        frame_info info;
625
626        // reset current values
627        mFrameInfo.clear();
628        mCurrentFrame = 0;
629       
630        while (!ifstr.eof())
631        {
632                ifstr.getline(line, 256);
633                sscanf(line, "%f %f %f %f %f %f %f %f", &info.position.x, &info.position.y, &info.position.z,
634                           &info.orientation.w, &info.orientation.x, &info.orientation.y, &info.orientation.z,
635                           &info.timeElapsed);
636               
637                mFrameInfo.push_back(info);
638               
639                // std::stringstream d; d << StringConverter::toString(info.position) << " " << StringConverter::toString(info.orientation);
640                // LogManager::getSingleton().logMessage(d.str());
641        }
642        ifstr.close();
643}
644//-----------------------------------------------------------------------
645void TerrainFrameListener::nextAppState()
646{
647        mCurrentFrame = 0;
648
649        // if last state was replay state
650        if (mAppState == REPLAY)
651        {
652                // reset debug text and write frame info to file
653                mWindow->setDebugText("");
654                writeFrames();
655               
656                float avgFps = (float)mAvgFps / (float)mFrameCount;
657
658                //-- write out stats for recorded walkthrough
659                std::stringstream d;
660                d << "Algorithm: " << msAlgorithmCaptions[mCurrentAlgorithm] << "\n"
661                  //<< "avg. FPS: " << mWindow->getAverageFPS() << "\n"
662                  << "avg. FPS: " << avgFps << "\n"
663                  << "best FPS: " << mWindow->getBestFPS() << "\n"
664                  << "worst FPS: " << mWindow->getWorstFPS() << "\n"
665                  << "best frame time: " <<     mWindow->getBestFrameTime() << "\n"
666                  << "worst frame time: " << mWindow->getWorstFrameTime();
667               
668                LogManager::getSingleton().logMessage(d.str());
669        }
670       
671        //-- set the next státe
672        mAppState = (mAppState + 1) % STATE_NUM;
673
674        // replay recorded walkthrough
675        if (mAppState == REPLAY)
676        {
677                // no recording during replay
678                mRecord = false;
679
680                // load recorded walkthrough
681                if (mFrameInfo.size() == 0)
682                {
683                        loadFrames();
684                }
685
686                // if there are no recorded frames => set next state
687                if (mFrameInfo.size() == 0)
688                {
689                        nextAppState();
690                }
691                else
692                {
693                        mWindow->setDebugText("Replay");
694                       
695                        // reset, because we measure fps stats during walkthrough (warning: average fps broken)
696                        mWindow->resetStatistics();
697                        resetStats();
698
699                        //-- initialise frame data
700                        mReplayTimeElapsed = 0;
701
702                        mCamNode->setPosition(mFrameInfo[0].position);
703                        mCamNode->setOrientation(mFrameInfo[0].orientation);
704                }
705        }
706
707}
708//-----------------------------------------------------------------------
709void TerrainFrameListener::toggleRecord()
710{
711        mRecord = !mRecord;
712
713        // clear previous camera path
714        if (mRecord)
715                mFrameInfo.clear();
716        else
717                mWindow->setDebugText("");
718}
719//-----------------------------------------------------------------------
720void TerrainFrameListener::changeThreshold(int incr)
721{
722        mVisibilityThreshold += incr;
723        if(mVisibilityThreshold < 0) mVisibilityThreshold = 0;
724       
725        char str[100]; sprintf(str,": %d", mVisibilityThreshold);
726
727        mSceneMgr->setOption("Threshold", &mVisibilityThreshold);
728        mThresholdInfo->setCaption(str);
729}
730//-----------------------------------------------------------------------
731void TerrainFrameListener::changeAssumedVisibility(int incr)
732{
733        mAssumedVisibility += incr;
734        if(mAssumedVisibility < 0) mAssumedVisibility = 0;
735       
736        char str[100]; sprintf(str,": %d", mAssumedVisibility);
737
738        mSceneMgr->setOption("AssumedVisibility", &mAssumedVisibility);
739        mAssumedVisibilityInfo->setCaption(str);
740}
741//-----------------------------------------------------------------------
742void TerrainFrameListener::zoomVizCamera(int zoom)
743{
744        mVizCameraHeight += zoom;
745        if(mVizCameraHeight < 0) mVizCameraHeight = 0;
746}
747//-----------------------------------------------------------------------
748void TerrainFrameListener::nextAlgorithm()
749{
750        mCurrentAlgorithm = (mCurrentAlgorithm + 1) %
751                (GtpVisibility::VisibilityEnvironment::NUM_CULLING_MANAGERS - 1);
752        setAlgorithm(mCurrentAlgorithm);
753}
754//-----------------------------------------------------------------------
755void TerrainFrameListener::setObjectType(int objectType)
756{
757        if (mCurrentObjectType >= 3)
758                mCurrentObjectType = 0;
759
760        // parameters for new object
761        mTerrainContentGenerator->SetOffset(msObjectTerrainOffsets[mCurrentObjectType]);
762        Real scale = msObjectScales[mCurrentObjectType];
763        mTerrainContentGenerator->SetScale(Vector3(scale, scale, scale));
764
765        mCurrentObjectTypeInfo->setCaption(": " + msObjectCaptions[mCurrentObjectType]);
766}
767//-----------------------------------------------------------------------
768void TerrainFrameListener::setAlgorithm(int algorithm)
769{
770        mAlgorithmInfo->setCaption(": " + msAlgorithmCaptions[mCurrentAlgorithm]);
771        mSceneMgr->setOption("Algorithm", &mCurrentAlgorithm);
772}
773//-----------------------------------------------------------------------
774void TerrainFrameListener::resetStats()
775{
776        mAvgFps = 0;
777        mFrameCount = 0;
778}
779//-----------------------------------------------------------------------
780void TerrainFrameListener::updateStats()
781{
782        unsigned int opt = 0;
783        char str[100];
784       
785        static String currFpsString = "Current FPS: ";
786        static String avgFpsString = "Average FPS: ";
787        static String bestFpsString = "Best FPS: ";
788        static String worstFpsString = "Worst FPS: ";
789        static String trisString = "Triangle Count: ";
790
791        // HACK: compute average fps ourselfs, because ogre avg. fps is wrong
792        // TODO: update only once per second
793        mAvgFps += mWindow->getStatistics().lastFPS;
794        ++ mFrameCount;
795       
796        float avgFps = (float)mAvgFps / (float)mFrameCount;
797   
798        // update stats when necessary
799    try
800        {
801                OverlayElement* guiAvg = OverlayManager::getSingleton().getOverlayElement("Core/AverageFps");
802                OverlayElement* guiCurr = OverlayManager::getSingleton().getOverlayElement("Core/CurrFps");
803                OverlayElement* guiBest = OverlayManager::getSingleton().getOverlayElement("Core/BestFps");
804                OverlayElement* guiWorst = OverlayManager::getSingleton().getOverlayElement("Core/WorstFps");
805
806                const RenderTarget::FrameStats& stats = mWindow->getStatistics();
807
808                //guiAvg->setCaption(avgFps + StringConverter::toString(stats.avgFPS));
809                if (mTimeDelay < 0) // only update once per second
810                {               
811                        guiAvg->setCaption(avgFpsString + StringConverter::toString(avgFps) + " ms");
812                }
813
814                guiCurr->setCaption(currFpsString + StringConverter::toString(stats.lastFPS));
815                guiBest->setCaption(bestFpsString + StringConverter::toString(stats.bestFPS)
816                        +" "+StringConverter::toString(stats.bestFrameTime) + " ms");
817                guiWorst->setCaption(worstFpsString + StringConverter::toString(stats.worstFPS)
818                        +" "+StringConverter::toString(stats.worstFrameTime) + " ms");
819
820                OverlayElement* guiTris = OverlayManager::getSingleton().getOverlayElement("Core/NumTris");
821        guiTris->setCaption(trisString + StringConverter::toString(stats.triangleCount));
822
823                OverlayElement* guiDbg = OverlayManager::getSingleton().getOverlayElement("Core/DebugText");
824                guiDbg->setCaption(mWindow->getDebugText());
825
826                //-- culling stats
827                mSceneMgr->getOption("NumFrustumCulledNodes", &opt); sprintf(str,": %d", opt);
828                mFrustumCulledNodesInfo->setCaption(str);
829
830                mSceneMgr->getOption("NumQueryCulledNodes", &opt); sprintf(str,": %d", opt);
831                mQueryCulledNodesInfo->setCaption(str);
832       
833                mSceneMgr->getOption("NumHierarchyNodes", &opt); sprintf(str,": %d", opt);
834                mHierarchyNodesInfo->setCaption(str);
835
836                mSceneMgr->getOption("NumRenderedNodes", &opt); sprintf(str,": %d", opt);
837                mRenderedNodesInfo->setCaption(str);
838
839                sprintf(str,": %d", mTerrainContentGenerator->GetObjectCount());
840                mObjectsCountInfo->setCaption(str);
841
842                // take old value into account in order to create no sudden changes
843                mSceneMgr->getOption("NumQueriesIssued", &opt);
844                mDelayedQueriesIssued = mDelayedQueriesIssued * 0.8 + (float)opt * 0.2;
845                sprintf(str,": %d", (int)mDelayedQueriesIssued);
846                mQueriesIssuedInfo->setCaption(str);
847
848                mSceneMgr->getOption("NumTraversedNodes", &opt);
849                mDelayedTraversedNodes = mDelayedTraversedNodes * 0.8 + (float)opt * 0.2;
850                sprintf(str,": %d", (int)mDelayedTraversedNodes);
851                mTraversedNodesInfo->setCaption(str);
852
853        }
854        catch (...)
855        {
856                // ignore
857        }
858}
859//-----------------------------------------------------------------------
860void TerrainFrameListener::toggleTestGeometryForVisibleLeaves()
861{
862        mTestGeometryForVisibleLeaves = !mTestGeometryForVisibleLeaves;
863        mSceneMgr->setOption("TestGeometryForVisibleLeaves", &mTestGeometryForVisibleLeaves);
864       
865        /* disable optimization which tests geometry instead of aabb
866         * for "delayed" rendering of transparents (i.e., render transparents after all the solids)
867         * because otherwise visible transparents could be skipped
868         */
869        bool delayedRendering = !mTestGeometryForVisibleLeaves;
870
871        mSceneMgr->setOption("DelayRenderTransparents", &delayedRendering);
872
873        if (mTestGeometryForVisibleLeaves)
874        {
875                mTestGeometryForVisibleLeavesInfo->setCaption(": true");
876        }
877        else
878        {
879                mTestGeometryForVisibleLeavesInfo->setCaption(": false");
880        }
881}
882//-----------------------------------------------------------------------
883void TerrainFrameListener::toggleShowOctree()
884{
885        mShowOctree = !mShowOctree;
886
887        mSceneMgr->setOption("ShowOctree", &mShowOctree);
888}
889//-----------------------------------------------------------------------
890void TerrainFrameListener::toggleUseDepthPass()
891{
892        mUseDepthPass = !mUseDepthPass;
893
894        mSceneMgr->setOption("UseDepthPass", &mUseDepthPass);
895       
896        if (mUseDepthPass)
897        {
898                mUseDepthPassInfo->setCaption(": true");
899        }
900        else
901        {
902                mUseDepthPassInfo->setCaption(": false");
903        }
904}
905//-----------------------------------------------------------------------
906void TerrainFrameListener::toggleShowViz()
907{
908        mVisualizeCulledNodes = mShowVisualization = !mShowVisualization;
909       
910        // create viewport with priority VIZ_VIEWPORT_Z_ORDER:
911        // will be rendered over standard viewport
912        if (mShowVisualization)
913        {       
914                Viewport *vizvp = mWindow->addViewport(mVizCamera,
915                        VIZ_VIEWPORT_Z_ORDER, 0.6, 0.6, 0.4, 0.4);
916                               
917                vizvp->setBackgroundColour(ColourValue(0.0, 0.3, 0.2, 1));
918
919                vizvp->setOverlaysEnabled(false);
920                // Alter the camera aspect ratio to match the viewport
921        mVizCamera->setAspectRatio(Real(vizvp->getActualWidth()) /
922                                                                   Real(vizvp->getActualHeight()));
923               
924                mSceneMgr->setOption("VisualizeCulledNodes", &mVisualizeCulledNodes);
925                //vizvp->setClearEveryFrame(false);
926
927                // Create a skyplane (for visualization background)
928                /*
929                Plane plane;
930                plane.d = -1000;
931                plane.normal = Vector3::UNIT_Y;
932                mSceneMgr->setSkyPlane(true, plane, "Examples/TransparentTest", 4000, 75, false);
933                */
934        }
935        else
936        {
937                // remove visualization viewport
938                mWindow->removeViewport(VIZ_VIEWPORT_Z_ORDER);
939
940                // octree bounding boxes are shown for visualization purpose, reset now
941                mSceneMgr->setOption("ShowOctree", &mShowOctree);
942        }
943}
944//-----------------------------------------------------------------------
945void TerrainFrameListener::toggleShowShadows()
946{
947        mShowShadows = !mShowShadows;
948
949        mSunLight->setCastShadows(mShowShadows);
950
951        if (mShowShadows)
952        {
953                mSceneMgr->setShadowTechnique(SHADOWTYPE_TEXTURE_MODULATIVE);
954                //mSceneMgr->setShadowTechnique(SHADOWTYPE_STENCIL_MODULATIVE);
955                //mSceneMgr->setShadowTechnique(SHADOWTYPE_STENCIL_ADDITIVE);           
956        }
957        else
958        {
959                mSceneMgr->setShadowTechnique(SHADOWTYPE_NONE);
960        }
961
962}
963//-----------------------------------------------------------------------
964void TerrainFrameListener::nextNodeVizMode()
965{
966        mNodeVizMode = (mNodeVizMode + 1) % NODEVIZ_MODES_NUM;
967
968        bool renderNodesForViz = (mNodeVizMode == NODEVIZ_RENDER_NODES) ||
969                (mNodeVizMode == NODEVIZ_RENDER_NODES_AND_CONTENT);
970        bool renderNodesContentForViz = (mNodeVizMode == NODEVIZ_RENDER_NODES_AND_CONTENT);
971        //bool renderNodesContentForViz = mNodeVizMode == NODEVIZ_RENDER_GEOMETRY;
972
973        mSceneMgr->setOption("RenderNodesForViz", &renderNodesForViz);
974        mSceneMgr->setOption("RenderNodesContentForViz", &renderNodesContentForViz);
975}
976//-----------------------------------------------------------------------
977void TerrainFrameListener::keyPressed(KeyEvent* e)
978{
979        // hide exact visibility query overlay
980        if (mShowQueryStats)
981        {
982                mQueryOverlay->hide();
983                mShowQueryStats = false;
984        }
985
986        switch(e->getKey())
987        {
988        case KC_ESCAPE:
989                mShutdownRequested = true;
990                e->consume();
991                return;
992
993        case KC_SPACE:
994                nextAlgorithm();
995                break;
996       
997    case KC_F:
998                nextFilter();
999                break;
1000        case KC_R:
1001                nextSceneDetailLevel();
1002                break;
1003        case KC_P:
1004                toggleDisplayCameraDetails();
1005                break;
1006        case KC_G:
1007                toggleTestGeometryForVisibleLeaves();
1008                break;
1009        case KC_T:
1010                toggleShowOctree();
1011                break;
1012        case KC_X:
1013                toggleUseDepthPass();
1014                break;
1015        case KC_S:
1016                toggleShowShadows();
1017                break;
1018
1019        case KC_I:
1020                mUseItemBuffer = !mUseItemBuffer;
1021                break;
1022
1023        case KC_C:
1024
1025                if (mItemBufferMode != GtpVisibility::QueryManager::GEOMETRY_VISIBILITY)
1026                        mItemBufferMode = GtpVisibility::QueryManager::GEOMETRY_VISIBILITY;
1027                else
1028                        mItemBufferMode = GtpVisibility::QueryManager::PATCH_VISIBILITY;
1029
1030                break;
1031
1032        case KC_SUBTRACT:
1033                changeThreshold(-10);
1034                break;
1035        case KC_ADD:
1036                changeThreshold(10);
1037                break;
1038
1039        //-- visualization
1040        case KC_1:
1041                toggleShowViz();
1042                break;
1043        case KC_2:
1044                nextNodeVizMode();
1045                break;
1046
1047        case KC_F1:
1048                toggleShowHelp();
1049                break;
1050        case KC_F2:
1051                toggleShowStats();
1052                break;
1053        case KC_F3:
1054                nextAppState();
1055                break;
1056        case KC_F4:
1057                toggleRecord();
1058                break;
1059        case KC_F5:
1060                applyVisibilityQuery(false, mShiftPressed, mUseItemBuffer);
1061                break;
1062        case KC_F6:
1063                applyVisibilityQuery(true, mShiftPressed, mUseItemBuffer);
1064                break;
1065       
1066        case KC_F7:
1067                setObjectType(++mCurrentObjectType);
1068                break;
1069        case KC_F8:
1070                mApplication->generateScene(500, mCurrentObjectType);
1071                break;
1072        case KC_F9:
1073                mUseAnimation = !mUseAnimation;
1074                break;
1075        case KC_F11:
1076                takeScreenshot();
1077                break;
1078        case KC_F12:
1079                mTerrainContentGenerator->WriteObjects(objects_out_filename);
1080                break;
1081
1082        case KC_8:
1083                changeAssumedVisibility(-1);
1084                break;
1085        case KC_9:
1086                changeAssumedVisibility(1);
1087                break;
1088        case KC_LSHIFT:
1089                mShiftPressed = true;
1090                break;
1091        case KC_DELETE:
1092                mDeleteObjects = true;
1093                break;
1094        //KEY_PRESSED(KC_F3, 0.3, writeFrames());
1095        //KEY_PRESSED(KC_F4, 0.3, loadFrames());
1096        default:
1097                break;
1098        }
1099
1100        CEGUI::System::getSingleton().injectKeyDown(e->getKey());
1101        CEGUI::System::getSingleton().injectChar(e->getKeyChar());
1102        e->consume();
1103}
1104//-----------------------------------------------------------------------
1105void TerrainFrameListener::keyReleased(KeyEvent* e)
1106{
1107        if (e->getKey() == KC_LSHIFT)
1108        {
1109                mShiftPressed = false;
1110        }
1111       
1112        CEGUI::System::getSingleton().injectKeyUp(e->getKey());
1113        e->consume();
1114}
1115//-----------------------------------------------------------------------
1116void TerrainFrameListener::keyClicked(KeyEvent* e)
1117{
1118        // Do nothing
1119        e->consume();
1120}
1121//-----------------------------------------------------------------------
1122void TerrainFrameListener::addFrameInfo(SceneNode *camNode, Real timeElapsed)
1123{
1124        frame_info info;
1125        info.orientation = mCamNode->getOrientation();
1126        info.position = mCamNode->getPosition();
1127        info.timeElapsed = timeElapsed;
1128
1129        mFrameInfo.push_back(info);
1130}
1131//-----------------------------------------------------------------------
1132void TerrainFrameListener::setCurrentFrameInfo(Real timeElapsed)
1133{
1134        //-- find current frame relative to elapsed frame time         
1135        mReplayTimeElapsed -= timeElapsed;
1136
1137        while ((mReplayTimeElapsed <= 0) && (mCurrentFrame < (int)mFrameInfo.size() - 1))
1138        {
1139                mReplayTimeElapsed += mFrameInfo[mCurrentFrame ++].timeElapsed;
1140        }
1141
1142        frame_info new_frame = mFrameInfo[mCurrentFrame];
1143        frame_info old_frame = mFrameInfo[mCurrentFrame - 1];
1144               
1145        //-- interpolate frames
1146        Real factor = 1;
1147
1148        if (old_frame.timeElapsed > 0)
1149        {
1150                factor = mReplayTimeElapsed / old_frame.timeElapsed;
1151        }
1152
1153        Vector3 camPos = old_frame.position + factor
1154                * (new_frame.position - old_frame.position);
1155        Quaternion camOrienation = Quaternion::Slerp(factor, old_frame.orientation,
1156                new_frame.orientation, true);
1157
1158        mCamNode->setPosition(camPos);
1159        mCamNode->setOrientation(camOrienation);
1160       
1161        // stop replay after a full walkthrough
1162        if (mCurrentFrame == (int)mFrameInfo.size() - 1)
1163        {
1164                nextAppState();
1165        }
1166}
1167//-----------------------------------------------------------------------   
1168bool TerrainFrameListener::processUnbufferedKeyInput(const FrameEvent& evt)
1169{
1170        bool cursorPressed = false;
1171       
1172        /* Move camera forward by keypress. */
1173    if (mInputDevice->isKeyDown(KC_UP))
1174        {
1175                mTranslateVector.z = -mMoveScale;
1176                cursorPressed = true;
1177        }
1178    /* Move camera backward by keypress. */
1179    if (mInputDevice->isKeyDown(KC_DOWN))
1180    {
1181                mTranslateVector.z = mMoveScale;
1182                cursorPressed = true;
1183    }
1184
1185    if (mInputDevice->isKeyDown(KC_RIGHT))
1186    {
1187        mCamNode->yaw(-mRotScale);
1188                cursorPressed = true;
1189    }
1190       
1191    if (mInputDevice->isKeyDown(KC_LEFT))
1192    {
1193        mCamNode->yaw(mRotScale);
1194                cursorPressed = true;
1195    }
1196        // visualization camera
1197        if (mInputDevice->isKeyDown(KC_3))
1198        {
1199                zoomVizCamera(50);
1200        }
1201        if (mInputDevice->isKeyDown(KC_4))
1202        {
1203                zoomVizCamera(-50);
1204        }
1205
1206        // show the results
1207        if (cursorPressed && mShowQueryStats)
1208        {
1209                mQueryOverlay->hide();
1210                mShowQueryStats = false;
1211        }
1212
1213    // Return true to continue rendering
1214    return true;
1215}
1216//-----------------------------------------------------------------------
1217void TerrainFrameListener::nextFilter()
1218{
1219        switch (mFiltering)
1220        {
1221        case TFO_BILINEAR:
1222                mFiltering = TFO_TRILINEAR;
1223                mAniso = 1;
1224                break;
1225        case TFO_TRILINEAR:
1226                mFiltering = TFO_ANISOTROPIC;
1227                mAniso = 8;
1228                break;
1229        case TFO_ANISOTROPIC:
1230                mFiltering = TFO_BILINEAR;
1231                mAniso = 1;
1232                break;
1233        default:
1234                break;
1235        }
1236
1237    MaterialManager::getSingleton().setDefaultTextureFiltering(mFiltering);
1238    MaterialManager::getSingleton().setDefaultAnisotropy(mAniso);
1239
1240        // reload stats
1241    showStats(mStatsOn);
1242}
1243//-----------------------------------------------------------------------
1244void TerrainFrameListener::nextSceneDetailLevel()
1245{
1246        mSceneDetailIndex = (mSceneDetailIndex + 1) % 3;
1247        switch (mSceneDetailIndex)
1248        {
1249                case 0:
1250                        mCamera->setDetailLevel(SDL_SOLID);
1251                        break;
1252                case 1:
1253                        mCamera->setDetailLevel(SDL_WIREFRAME);
1254                        break;
1255                case 2:
1256                        mCamera->setDetailLevel(SDL_POINTS);
1257                        break;
1258        }
1259}
1260//-----------------------------------------------------------------------
1261void TerrainFrameListener::takeScreenshot()
1262{
1263        char tmp[20];
1264        sprintf(tmp, "screenshot_%d.png", ++mNumScreenShots);
1265    mWindow->writeContentsToFile(tmp);
1266    mWindow->setDebugText(String("Wrote ") + tmp);
1267}
1268//-----------------------------------------------------------------------
1269void TerrainFrameListener::toggleDisplayCameraDetails()
1270{
1271        mDisplayCameraDetails = !mDisplayCameraDetails;
1272       
1273    if (!mDisplayCameraDetails)
1274        {
1275                mWindow->setDebugText("");
1276        }
1277}
1278//-----------------------------------------------------------------------
1279void TerrainFrameListener::showStats(bool show)
1280{
1281        if (mDebugOverlay && mCullStatsOverlay)
1282        {
1283                if (show)
1284                {
1285                        mDebugOverlay->show();
1286                        mCullStatsOverlay->show();
1287                }
1288                else
1289                {
1290                        mDebugOverlay->hide();
1291                        mCullStatsOverlay->hide();
1292                }
1293        }
1294}
1295//-----------------------------------------------------------------------
1296void TerrainFrameListener::toggleShowStats()
1297{
1298        mStatsOn = !mStatsOn;
1299
1300        showStats(mStatsOn);
1301}
1302//-----------------------------------------------------------------------
1303void TerrainFrameListener::toggleShowHelp()
1304{
1305        mShowHelp = !mShowHelp;
1306
1307        if (mShowHelp)
1308        {
1309                mHelpOverlay->show();
1310        }
1311        else
1312        {
1313                mHelpOverlay->hide();
1314        }
1315}
1316//-----------------------------------------------------------------------
1317void TerrainFrameListener::initOverlayElement(OverlayElement **elInfo, String ext,
1318                                                                                          String name, int top, String caption)
1319{
1320        OverlayElement *el =
1321                OverlayManager::getSingleton().getOverlayElement(ext + name);
1322
1323        (*elInfo) = OverlayManager::getSingleton().getOverlayElement(ext + name + "Info");
1324        (*elInfo)->setCaption(caption);
1325
1326        el->setTop(top);
1327        (*elInfo)->setTop(top);
1328}
1329//-----------------------------------------------------------------------
1330void TerrainFrameListener::initHelpOverlayElement(String name, int top)
1331{
1332        OverlayElement *el = OverlayManager::getSingleton().getOverlayElement(
1333                "Example/Visibility/Help/" + name);
1334
1335        el->setTop(top);
1336}
1337//-----------------------------------------------------------------------
1338void TerrainFrameListener::initHelpOverlay()
1339{
1340        const int vert_space = 15;
1341        int top = 30;
1342
1343        initHelpOverlayElement("ShowHelp", top); top += vert_space;
1344        initHelpOverlayElement("Stats", top); top += vert_space;
1345        initHelpOverlayElement("AppState", top); top += vert_space;
1346        initHelpOverlayElement("Recorded", top); top += vert_space;
1347        initHelpOverlayElement("Animation", top); top += vert_space;
1348        initHelpOverlayElement("Screenshots", top); top += vert_space;
1349        initHelpOverlayElement("WriteOut", top); top += vert_space;
1350
1351        top +=vert_space;
1352        initHelpOverlayElement("SceneDetail", top); top += vert_space;
1353        initHelpOverlayElement("DisplayCameraDetails", top); top += vert_space;
1354        initHelpOverlayElement("DisplayOctree", top); top += vert_space;
1355        initHelpOverlayElement("UseShadows", top); top += vert_space;
1356        initHelpOverlayElement("Filter", top); top += vert_space;
1357
1358        //-- visualization
1359        top += vert_space;
1360        initHelpOverlayElement("VizSection", top); top += vert_space;
1361        initHelpOverlayElement("Viz", top); top += vert_space;
1362        initHelpOverlayElement("NextVizMode", top); top += vert_space;
1363        initHelpOverlayElement("ZoomViz", top); top += vert_space;
1364
1365
1366        //-- visibility queries
1367        top += vert_space;
1368        initHelpOverlayElement("VisQuery", top); top += vert_space;
1369        initHelpOverlayElement("FromCameraQuery", top); top += vert_space;
1370        initHelpOverlayElement("FromPointQuery", top); top += vert_space;
1371        initHelpOverlayElement("QueryType", top); top += vert_space;
1372        initHelpOverlayElement("QueryTarget", top); top += vert_space;
1373
1374        //-- object generation
1375        top += vert_space;
1376        initHelpOverlayElement("SceneObjects", top); top += vert_space;
1377        initHelpOverlayElement("GenerateObjects", top); top += vert_space;
1378        initHelpOverlayElement("RemoveObjects", top); top += vert_space;
1379        initHelpOverlayElement("DropObject", top); top += vert_space;
1380
1381        OverlayElement *helpPanel = OverlayManager::getSingleton().getOverlayElement(
1382                "Example/Visibility/Help/HelpPanel");
1383
1384        helpPanel->setHeight(top + 10);
1385}
1386//-----------------------------------------------------------------------
1387void TerrainFrameListener::initVisStatsOverlay()
1388{
1389        const int border_height = 10;
1390        const int vert_space = 15;
1391
1392        //-- visibility culling stats overlay
1393        int top = border_height;
1394
1395        String ext = "Example/Visibility/";
1396       
1397        initOverlayElement(&mAlgorithmInfo, ext, "Algorithm", top,
1398                ": " + msAlgorithmCaptions[mCurrentAlgorithm]); top += vert_space;
1399
1400        initOverlayElement(&mThresholdInfo, ext, "Threshold", top, ": 0"); top += vert_space;
1401        initOverlayElement(&mTestGeometryForVisibleLeavesInfo, ext,
1402                "TestGeometryForVisibleLeaves", top, ": true"); top += vert_space;
1403        initOverlayElement(&mUseDepthPassInfo, ext, "UseDepthPass", top, ": false"); top += vert_space;
1404        initOverlayElement(&mAssumedVisibilityInfo, ext, "AssumedVisibility", top, ": 0"); top += vert_space;
1405        initOverlayElement(&mCurrentObjectTypeInfo, ext, "CurrentObjectType", top, ": "); top += vert_space;
1406        //initOverlayElement(&mHelpInfo, ext, "Help", top, ": "); top += vert_space;
1407
1408        OverlayElement *optionsPanel = OverlayManager::getSingleton().
1409                getOverlayElement("Example/Visibility/VisibilityPanel");
1410
1411        optionsPanel->setHeight(top + border_height);
1412
1413        top = border_height;
1414        //ext = "Example/Visibility/";
1415        initOverlayElement(&mFrustumCulledNodesInfo, ext, "FrustumCulledNodes", top, ": 0"); top += vert_space;
1416        initOverlayElement(&mQueryCulledNodesInfo, ext, "QueryCulledNodes", top, ": 0"); top += vert_space;
1417        initOverlayElement(&mTraversedNodesInfo, ext, "TraversedNodes", top, ": 0"); top += vert_space;
1418        initOverlayElement(&mHierarchyNodesInfo, ext, "HierarchyNodes", top, ": 0"); top += vert_space;
1419        initOverlayElement(&mRenderedNodesInfo, ext, "RenderedNodes", top, ": 0"); top += vert_space;
1420        initOverlayElement(&mObjectsCountInfo, ext, "ObjectsCount", top, ": 0"); top += vert_space;
1421        initOverlayElement(&mQueriesIssuedInfo, ext, "QueriesIssued", top, ": 0"); top += vert_space;
1422
1423        OverlayElement *visPanel = OverlayManager::getSingleton().
1424                getOverlayElement("Example/Visibility/VisibilityStatsPanel");
1425
1426        visPanel->setHeight(top + border_height);
1427}
1428//-----------------------------------------------------------------------
1429void TerrainFrameListener::initQueryOverlay()
1430{
1431        const int border_height = 10;
1432        const int vert_space = 15;
1433
1434        //-- visibility culling stats overlay
1435        int top = border_height + 25;
1436
1437        String ext = "Example/Visibility/Query/";
1438           
1439        initOverlayElement(&mQueryTypeInfo , ext, "QueryType", top,     ": 0"); top += vert_space;
1440       
1441        initOverlayElement(&mQueryVisibleNodesInfo , ext, "VisibleNodes", top,  ": 0"); top += vert_space;
1442        initOverlayElement(&mQueryVisibleGeometryInfo , ext, "VisibleGeometry", top,    ": 0"); top += vert_space;
1443        initOverlayElement(&mQueryVisiblePatchInfo , ext, "VisiblePatches", top,        ": 0"); top += vert_space;
1444       
1445        initOverlayElement(&mQueryNodeVisibilityInfo , ext, "NodeVisibility", top,      ": 0"); top += vert_space;
1446        initOverlayElement(&mQueryGeometryVisibilityInfo , ext, "GeometryVisibility", top,      ": 0"); top += vert_space;
1447        initOverlayElement(&mQueryPatchVisibilityInfo , ext, "PatchVisibility", top,    ": 0"); top += vert_space;
1448
1449
1450        OverlayElement *queryPanel = OverlayManager::getSingleton().
1451                getOverlayElement("Example/Visibility/Query/QueryPanel");
1452
1453        queryPanel->setHeight(top + border_height);
1454}
Note: See TracBrowser for help on using the repository browser.