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

Revision 1271, 54.0 KB checked in by mattausch, 18 years ago (diff)

removed the visibility env, now explicitly giving the view cells as argument

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