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

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