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

Revision 346, 46.8 KB checked in by mattausch, 19 years ago (diff)

updated terrain removed debug messages from chc

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