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

Revision 187, 43.0 KB checked in by mattausch, 19 years ago (diff)

added animationbug fix (deleting while animation)fixed visibilityQueriesadditive shadow volumes fixed for octree
hack to fully empty queue after traversal
added demo for vienna model

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