source: GTP/trunk/App/Demos/Vis/HillyTerrain/OGRE/TerrainFrameListener.cpp @ 1617

Revision 1617, 55.3 KB checked in by mattausch, 18 years ago (diff)

s shit

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