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

Revision 154, 34.6 KB checked in by mattausch, 19 years ago (diff)

added item buffer queries.

Line 
1#include <OgreNoMemoryMacros.h>
2#include <CEGUI/CEGUI.h>
3#include <../CEGUIRenderer/include/OgreCEGUIRenderer.h>
4#include <../CEGUIRenderer/include/OgreCEGUIResourceProvider.h>
5#include <../CEGUIRenderer/include/OgreCEGUITexture.h>
6#include <OgreMemoryMacros.h>
7#include "TerrainFrameListener.h"
8#include "OgrePlatformQueryManager.h"
9#include "OgreVisibilityTerrainSceneManager.h"
10#include "VisibilityInfo.h"
11#include "OgreItemBufferQueryManager.h"
12#include "OgreOcclusionQueriesQueryManager.h"
13
14
15
16
17// output file for frame info
18const char* frames_out_filename = "frame.out";
19// output file for object positions / orientations
20const char* objects_out_filename = "objects.out";
21
22
23// --- captions for overlays
24
25String currentAlgorithmCaptions[GtpVisibility::VisibilityEnvironment::NUM_CULLING_MANAGERS] =
26{
27        "View Frustum Culling",
28        "Stop and Wait Culling",
29        "Coherent Hierarchical Culling"
30};
31
32String queryTypeCaptions[] =
33{
34        "from camera",
35        "from viewpoint"
36};
37
38String queryRelativeVisCaptions[] =
39{
40        "visible pixels",
41        "relative visibility"
42};
43
44String queryMethodCaptions[] =
45{
46        "occlusion queries",
47        "item buffer"
48};
49
50//-----------------------------------------------------------------------
51TerrainFrameListener::TerrainFrameListener(RenderWindow* win, Camera* cam,
52                                                                           SceneManager *sceneManager,
53                                                                           CEGUI::Renderer *renderer,
54                                                                           TerrainContentGenerator *sceneGenerator,
55                                                                           Camera *vizCamera,
56                                                                           SceneNode *camNode,
57                                                                           Light *sunLight):
58mCamera(cam),
59mWindow(win),
60mNumScreenShots(0),
61mTimeDelay(0),
62mSceneDetailIndex(0),
63mMoveScale(0.0f),
64mRotScale(0.0f),
65mTranslateVector(Vector3::ZERO),
66mAniso(1),
67mFiltering(TFO_BILINEAR),
68mGUIRenderer(renderer),
69mSceneMgr(sceneManager),
70mCurrentObject(NULL),
71mTerrainContentGenerator(sceneGenerator),
72mVisibilityThreshold(0),
73mAssumedVisibility(0),
74mCurrentAlgorithm(GtpVisibility::VisibilityEnvironment::COHERENT_HIERARCHICAL_CULLING),
75//mCurrentAlgorithm(GtpVisibility::VisibilityEnvironment::FRUSTUM_CULLING),
76mNodeVizMode(NODEVIZ_NONE),
77mVizCameraHeight(Real(2500.0)),
78mCamNode(camNode),
79mAppState(WALKTHROUGH),
80mCurrentFrame(0),
81mTimeElapsed(0),
82mRotateSpeed(72),
83mMoveSpeed(50),
84mVizCamera(vizCamera),
85mStatsOn(true),
86mShutdownRequested(false),
87mLMouseDown(false),
88mRMouseDown(false),
89mShowOctree(false),
90mUseDepthPass(false),
91mUseOptimization(true),
92mShowVisualization(false),
93mCullCamera(false),
94mRecord(false),
95mShowShadows(false),
96mShowHelp(false),
97mDisplayCameraDetails(false),
98mVisualizeCulledNodes(false),
99mSunLight(sunLight),
100mShiftPressed(false),
101mShowQueryStats(false),
102mQueryManager(NULL),
103mVisibilityManager(NULL)
104{
105        //mInputDevice = PlatformManager::getSingleton().createInputReader();
106        //mInputDevice->initialise(win, true, true);
107
108        mEventProcessor = new EventProcessor();
109       
110        mEventProcessor->initialise(win);
111        mEventProcessor->startProcessingEvents();
112        mEventProcessor->addMouseListener(this);
113        mEventProcessor->addMouseMotionListener(this);
114        mEventProcessor->addKeyListener(this);
115
116        mInputDevice = mEventProcessor->getInputReader();
117       
118
119        // create ray query executor, used to place objects in terrain
120        mRayQueryExecutor = new RayQueryExecutor(mSceneMgr);
121       
122        mHelpOverlay = OverlayManager::getSingleton().getByName("Example/Visibility/HelpOverlay");
123        mDebugOverlay = OverlayManager::getSingleton().getByName("Core/DebugOverlay");
124        mQueryOverlay = OverlayManager::getSingleton().getByName("Example/Visibility/QueryOverlay");
125
126        //-- visibility culling stats overlay
127        mCullStatsOverlay = OverlayManager::getSingleton().getByName("Example/Visibility/DemoOverlay");
128       
129        mAlgorithmInfo = OverlayManager::getSingleton().getOverlayElement("Example/Visibility/AlgorithmInfo");
130        mThresholdInfo = OverlayManager::getSingleton().getOverlayElement("Example/Visibility/ThresholdInfo");
131        mUseOptimizationInfo = OverlayManager::getSingleton().getOverlayElement("Example/Visibility/UseOptimizationInfo");
132        mUseDepthPassInfo = OverlayManager::getSingleton().getOverlayElement("Example/Visibility/UseDepthPassInfo");
133        mAssumedVisibilityInfo = OverlayManager::getSingleton().getOverlayElement("Example/Visibility/AssumedVisibilityInfo");
134
135        mFrustumCulledNodesInfo = OverlayManager::getSingleton().getOverlayElement("Example/Visibility/FrustumCulledNodesInfo");
136        mQueryCulledNodesInfo = OverlayManager::getSingleton().getOverlayElement("Example/Visibility/QueryCulledNodesInfo");
137    mTraversedNodesInfo = OverlayManager::getSingleton().getOverlayElement("Example/Visibility/TraversedNodesInfo");
138        mHierarchyNodesInfo = OverlayManager::getSingleton().getOverlayElement("Example/Visibility/HierarchyNodesInfo");
139        mRenderedNodesInfo = OverlayManager::getSingleton().getOverlayElement("Example/Visibility/RenderedNodesInfo");
140        mObjectsInfo = OverlayManager::getSingleton().getOverlayElement("Example/Visibility/ObjectsInfo");
141        mQueriesIssuedInfo = OverlayManager::getSingleton().getOverlayElement("Example/Visibility/QueriesIssuedInfo");
142       
143        mAlgorithmInfo->setCaption(": " + currentAlgorithmCaptions[mCurrentAlgorithm]);
144        mThresholdInfo->setCaption(": 0");
145        mFrustumCulledNodesInfo->setCaption(": 0");
146        mQueryCulledNodesInfo->setCaption(": 0");
147        mTraversedNodesInfo->setCaption(": 0");
148        mHierarchyNodesInfo->setCaption(": 0");
149        mRenderedNodesInfo->setCaption(": 0");
150        mObjectsInfo->setCaption(": 0");
151        mUseOptimizationInfo->setCaption(": true");
152        mUseDepthPassInfo->setCaption(": false");
153        mQueriesIssuedInfo->setCaption(": 0");
154        mAssumedVisibilityInfo->setCaption(": 0");
155
156
157        //-- visibility query stats overlay
158        mQueryTypeInfo = OverlayManager::getSingleton().getOverlayElement("Example/Visibility/Query/QueryTypeInfo");
159        mQueryVisibleNodesInfo = OverlayManager::getSingleton().getOverlayElement("Example/Visibility/Query/VisibleNodesInfo");
160    mQueryVisibleGeometryInfo = OverlayManager::getSingleton().getOverlayElement("Example/Visibility/Query/VisibleGeometryInfo");
161        mQueryNodeVisibilityInfo = OverlayManager::getSingleton().getOverlayElement("Example/Visibility/Query/NodeVisibilityInfo");
162        mQueryGeometryVisibilityInfo = OverlayManager::getSingleton().getOverlayElement("Example/Visibility/Query/GeometryVisibilityInfo");
163
164        // show stats overlays
165        showStats(true);
166        //mHelpOverlay->show();
167
168        // set culling algorithm type
169        setAlgorithm(mCurrentAlgorithm);
170
171        // set scene manager options
172        mSceneMgr->setOption("UseOptimization", &mUseOptimization);
173
174        // apply delayed rendering (i.e., transparents after hierarchical culling pass)
175        // only if optimization is not used
176        bool delayRenderTransparents = !mUseOptimization;
177
178        mSceneMgr->setOption("DelayRenderTransparents", &delayRenderTransparents);
179        mSceneMgr->setOption("UseDepthPass", &mUseDepthPass);
180       
181        mSceneMgr->setOption("ShowOctree", &mShowOctree);
182        mSceneMgr->setOption("CullCamera", &mCullCamera);
183        mSceneMgr->setOption("PrepareVisualization", &mShowVisualization);
184
185        // reset statistics
186        resetStats();
187}
188//-----------------------------------------------------------------------
189TerrainFrameListener::~TerrainFrameListener()
190{
191        delete mRayQueryExecutor;
192        delete mEventProcessor;
193
194        if (mQueryManager)
195        {
196                delete mQueryManager;
197                mQueryManager = NULL;
198        }
199}
200//-----------------------------------------------------------------------
201void TerrainFrameListener::mouseMoved(MouseEvent *e)
202{
203        // Update CEGUI with the mouse motion
204    CEGUI::System::getSingleton().injectMouseMove(e->getRelX() *
205                mGUIRenderer->getWidth(), e->getRelY() * mGUIRenderer->getHeight());
206}
207//-----------------------------------------------------------------------
208void TerrainFrameListener::mousePressed(MouseEvent* e)
209{
210     // Left mouse button down
211     if (e->getButtonID() & InputEvent::BUTTON0_MASK)
212     {
213                 CEGUI::MouseCursor::getSingleton().hide();
214
215                 // Setup the ray scene query
216         Ray mouseRay = mCamera->getCameraToViewportRay(e->getX(), e->getY());
217                 
218                 //Vector3 queryResult; mRayQueryExecutor->executeRayQuery(&queryResult, mouseRay);
219                 
220                 // Get results, create a node/entity on the position
221                 mCurrentObject = mTerrainContentGenerator->GenerateSceneObject(
222                         mouseRay.getOrigin()/*queryResult*/, Vector3::ZERO, "robot");
223               
224         mLMouseDown = true;
225     }
226     // Right mouse button down
227     else if (e->getButtonID() & InputEvent::BUTTON1_MASK)
228     {
229         CEGUI::MouseCursor::getSingleton().hide();
230         mRMouseDown = true;
231     }
232}
233//-----------------------------------------------------------------------
234void TerrainFrameListener::mouseReleased(MouseEvent* e)
235{
236    // Left mouse button up
237    if (e->getButtonID() & InputEvent::BUTTON0_MASK)
238    {
239                CEGUI::MouseCursor::getSingleton().show();
240        mLMouseDown = false;
241    }
242    // Right mouse button up
243    else if (e->getButtonID() & InputEvent::BUTTON1_MASK)
244    {
245        CEGUI::MouseCursor::getSingleton().show();
246        mRMouseDown = false;
247    }
248}
249//-----------------------------------------------------------------------
250void TerrainFrameListener::mouseDragged(MouseEvent *e)
251 {
252         // If we are dragging the left mouse button.           
253         if (mLMouseDown)
254     {
255                 Vector3 queryResult;
256                 Ray mouseRay = mCamera->getCameraToViewportRay(e->getX(), e->getY());
257
258                 if (mRayQueryExecutor->executeRayQuery(&queryResult, mouseRay))
259                 {
260                         if (mCurrentObject)
261                         {
262                                 mCurrentObject->setPosition(queryResult);
263                         }
264                 }
265     }
266         // If we are dragging the right mouse button.
267         if (mRMouseDown)
268         {
269                 //mCamera->yaw(-e->getRelX() * mRotateSpeed);
270                 //mCamera->pitch(-e->getRelY() * mRotateSpeed);
271                 mCamNode->yaw(-e->getRelX() * mRotateSpeed);
272                 mCamNode->pitch(-e->getRelY() * mRotateSpeed);
273         }
274}
275//-----------------------------------------------------------------------
276bool TerrainFrameListener::frameStarted(const FrameEvent &evt)
277{
278        if (mWindow->isClosed())
279        {
280        return false;
281        }
282
283        if (mDisplayCameraDetails)
284    {
285        // Print camera details
286        mWindow->setDebugText("P: " + StringConverter::toString(mCamera->getDerivedPosition()) +
287                        " " + "O: " + StringConverter::toString(mCamera->getDerivedOrientation()));
288    }
289
290        //-- IMPORTANT: must be set, otherwise terrain is not rendered correctly
291        int terrainLevelIdx = 0;
292        mSceneMgr->setOption("TerrainLevelIdx", &terrainLevelIdx);
293
294        //-- setup what is needed for immediate mouse/key movement
295        if (mTimeDelay >= 0)
296        {
297                mTimeDelay -= evt.timeSinceLastFrame;
298        }
299
300        // If this is the first frame, pick a speed
301        if (evt.timeSinceLastFrame == 0)
302        {
303                mMoveScale = 1;
304                mRotScale = 0.1;
305        }
306        // Otherwise scale movement units by time passed since last frame
307        else
308        {
309                // Move about 100 units per second,
310                mMoveScale = mMoveSpeed * evt.timeSinceLastFrame;
311                // Take about 10 seconds for full rotation
312                mRotScale = mRotateSpeed * evt.timeSinceLastFrame;
313        }
314
315        mRotX = 0;
316        mRotY = 0;
317        mTranslateVector = Vector3::ZERO;
318
319        if (!processUnbufferedKeyInput(evt))
320        {
321                return false;
322        }
323/*      if (!processUnbufferedMouseInput(evt))
324        {       return false;   }*/
325
326        // --- set parameters for visualization
327        if (mShowVisualization)
328        {
329                // important for visualization => draw octree bounding boxes
330                mSceneMgr->setOption("ShowOctree", &mShowVisualization);
331               
332                // ---- setup visualization camera
333
334                mVizCamera->setPosition(0, 0, 0);
335                mVizCamera->setOrientation(Quaternion::IDENTITY);
336
337                Vector3 camPos = mCamNode->getPosition();
338                mVizCamera->setPosition(camPos.x, mVizCameraHeight, camPos.z);
339
340                // point down -Z axis
341                mVizCamera->pitch(Radian(Degree(270.0)));
342
343                // rotation arounnd X axis
344                mVizCamera->yaw(Math::ATan2(-mCamera->getDerivedDirection().x,
345                        -mCamera->getDerivedDirection().z));
346               
347                // move by a constant so view plane is on bottom of viewport
348                mVizCamera->moveRelative(Vector3(0, 800, 0));
349        }
350
351        //-- set application state
352        switch (mAppState)
353        {
354        case REPLAY:
355                setCurrentFrameInfo(evt.timeSinceLastFrame);
356                break;
357        case WALKTHROUGH:
358                //-- if we are recording camera status per frame
359                if (mRecord)
360                {
361                        addFrameInfo(mCamNode, evt.timeSinceLastFrame);
362                        // print recording message
363                        mWindow->setDebugText("Recording frame " +
364                                StringConverter::toString(mFrameInfo.size() - 1));
365                }       
366                // move camera according to input
367                moveCamera();
368                // clamp camera so we always walk along the terrain
369                Clamp2Terrain();
370                break;
371
372        default:
373                break;
374        };     
375
376        return true;
377}
378//-----------------------------------------------------------------------
379void TerrainFrameListener::ApplyVisibilityQuery(bool fromPoint, bool relativeVisibility,
380                                                                                                bool useItemBuffer)
381{
382        // TODO: change this (does not work with other scene manager plugins)
383        VisibilityTerrainSceneManager *sm =
384                dynamic_cast<VisibilityTerrainSceneManager *>(mSceneMgr);
385
386        if (useItemBuffer)
387        {
388                mQueryManager = new ItemBufferQueryManager(sm->GetHierarchyInterface(),
389                        mWindow->getViewport(0));
390        }
391        else
392        {
393                mQueryManager = new OcclusionQueriesQueryManager(sm->GetHierarchyInterface(),
394                        mWindow->getViewport(0));
395        }
396
397        sm->GetVisibilityManager()->SetQueryManager(mQueryManager);
398
399        InfoContainer<GtpVisibility::NodeInfo> visibleNodes;
400        InfoContainer<GtpVisibility::MeshInfo> visibleGeometry;
401
402        if (fromPoint)
403        {
404                mQueryManager->
405                        ComputeFromPointVisibility(mCamNode->getPosition(), &visibleNodes,
406                                                                           &visibleGeometry, relativeVisibility);
407        }
408        else
409        {
410                mQueryManager->ComputeCameraVisibility(*mCamera,
411                            &visibleNodes, &visibleGeometry, relativeVisibility);
412        }
413
414        float averageNodeVis = 0;
415        float averageGeometryVis = 0;
416        int geomSize = 0;
417        int nodesSize = 0;
418
419        InfoContainer<GtpVisibility::MeshInfo>::iterator geomIt, geomIt_end = visibleGeometry.end();
420
421        for (geomIt = visibleGeometry.begin(); geomIt != geomIt_end; ++geomIt)
422        {
423                // add if not 0
424                if ((*geomIt).GetVisiblePixels())
425                {
426                        float vis = relativeVisibility ?
427                                (*geomIt).ComputeRelativeVisibility() : (float)(*geomIt).GetVisiblePixels();
428       
429                        averageGeometryVis += vis;
430                        ++geomSize;
431                       
432                        std::stringstream d; d << "Geometry " << geomSize << " visibility: " << vis;
433                        LogManager::getSingleton().logMessage(d.str());
434                }
435        }
436
437        InfoContainer<GtpVisibility::NodeInfo>::iterator nodesIt, nodesIt_end = visibleNodes.end();
438
439        for (nodesIt = visibleNodes.begin(); nodesIt != nodesIt_end; ++nodesIt)
440        {
441                // add if not 0
442                if ((*nodesIt).GetVisiblePixels())
443                {
444                        float vis = relativeVisibility ?
445                                (*nodesIt).ComputeRelativeVisibility() : (float)(*nodesIt).GetVisiblePixels();
446               
447                        averageNodeVis += vis;
448                        ++nodesSize;
449
450                        std::stringstream d; d << "Node visibility: " << vis;
451                        LogManager::getSingleton().logMessage(d.str());
452                }       
453        }
454
455        if (nodesSize)
456                averageNodeVis /= (float)nodesSize;
457        if (geomSize)
458                averageGeometryVis /= (float)geomSize;
459
460        //-- update visibility queries stats
461    try
462        {
463                char str[100];
464               
465                sprintf(str, ": %s, %s, %s",
466                                queryTypeCaptions[fromPoint ?  1 : 0].c_str(),
467                                queryRelativeVisCaptions[relativeVisibility ? 1 : 0].c_str(),
468                                queryMethodCaptions[useItemBuffer ? 1 : 0].c_str());
469
470                mQueryTypeInfo->setCaption(str);
471
472                sprintf(str, ": %d", (int)nodesSize);
473                mQueryVisibleNodesInfo->setCaption(str);
474       
475                sprintf(str,": %d", (int)geomSize);
476                mQueryVisibleGeometryInfo->setCaption(str);
477               
478                sprintf(str,": %3.3f", averageNodeVis);
479                mQueryNodeVisibilityInfo->setCaption(str);
480
481                sprintf(str,": %3.3f", averageGeometryVis);
482                mQueryGeometryVisibilityInfo->setCaption(str);
483        }
484        catch (...)
485        {
486                // ignore
487        }
488
489        // show the results
490        if (!mShowQueryStats)
491        {
492                mQueryOverlay->show();
493                mShowQueryStats = true;
494        }
495
496        delete mQueryManager;
497}
498//-----------------------------------------------------------------------
499void TerrainFrameListener::Clamp2Terrain()
500{
501        // clamp camera to terrain
502        Vector3 camPos = mCamNode->getPosition();
503        Vector3 queryResult;
504
505        if (mRayQueryExecutor->executeRayQuery(&queryResult,
506                        Vector3(camPos.x, 5000.0f, camPos.z), Vector3::NEGATIVE_UNIT_Y))
507        {
508                const int terrainOffs = 10;
509                mCamNode->setPosition(camPos.x, queryResult.y + terrainOffs, camPos.z);
510        }
511}
512//-----------------------------------------------------------------------
513bool TerrainFrameListener::frameEnded(const FrameEvent& evt)
514{
515        if (mShutdownRequested)
516                return false;
517
518    updateStats();
519
520        return true;
521}
522//-----------------------------------------------------------------------
523void TerrainFrameListener::moveCamera()
524{
525        // move node rather than camera so orientation is right in the visualization
526        mCamNode->yaw(mRotX);
527        mCamNode->pitch(mRotY);
528        mCamNode->translate(mCamNode->getLocalAxes(), mTranslateVector);
529}
530//-----------------------------------------------------------------------
531void TerrainFrameListener::writeFrames()
532{
533        std::ofstream ofstr(frames_out_filename);
534       
535        std::vector<frame_info>::const_iterator it, it_end;
536
537        it_end = mFrameInfo.end();
538        for (it = mFrameInfo.begin(); it < it_end; ++it)
539        {
540                ofstr << StringConverter::toString((*it).position) << " "
541                          << StringConverter::toString((*it).orientation) << " "
542                          << StringConverter::toString((*it).timeElapsed) << "\n";
543        }
544        ofstr.close();
545}
546//-----------------------------------------------------------------------
547void TerrainFrameListener::loadFrames()
548{
549        std::ifstream ifstr(frames_out_filename);
550        char line[256];
551        frame_info info;
552
553        // reset current values
554        mFrameInfo.clear();
555        mCurrentFrame = 0;
556       
557        while (!ifstr.eof())
558        {
559                ifstr.getline(line, 256);
560                sscanf(line, "%f %f %f %f %f %f %f %f", &info.position.x, &info.position.y, &info.position.z,
561                           &info.orientation.w, &info.orientation.x, &info.orientation.y, &info.orientation.z,
562                           &info.timeElapsed);
563               
564                mFrameInfo.push_back(info);
565               
566                // std::stringstream d; d << StringConverter::toString(info.position) << " " << StringConverter::toString(info.orientation);
567                // LogManager::getSingleton().logMessage(d.str());
568        }
569        ifstr.close();
570}
571//-----------------------------------------------------------------------
572void TerrainFrameListener::nextAppState()
573{
574        mCurrentFrame = 0;
575
576        // if last state was replay state
577        if (mAppState == REPLAY)
578        {
579                // reset debug text and write frame info to file
580                mWindow->setDebugText("");
581                writeFrames();
582               
583                float avgFps = (float)mAvgFps / (float)mFrameCount;
584
585                //-- write out stats for recorded walkthrough
586                std::stringstream d;
587                d << "Algorithm: " << currentAlgorithmCaptions[mCurrentAlgorithm] << "\n"
588                  //<< "avg. FPS: " << mWindow->getAverageFPS() << "\n"
589                  << "avg. FPS: " << avgFps << "\n"
590                  << "best FPS: " << mWindow->getBestFPS() << "\n"
591                  << "worst FPS: " << mWindow->getWorstFPS() << "\n"
592                  << "best frame time: " <<     mWindow->getBestFrameTime() << "\n"
593                  << "worst frame time: " << mWindow->getWorstFrameTime();
594               
595                LogManager::getSingleton().logMessage(d.str());
596        }
597       
598        //-- set the next státe
599        mAppState = (mAppState + 1) % STATE_NUM;
600
601        // replay recorded walkthrough
602        if (mAppState == REPLAY)
603        {
604                // no recording during replay
605                mRecord = false;
606
607                // load recorded walkthrough
608                if (mFrameInfo.size() == 0)
609                {
610                        loadFrames();
611                }
612
613                // if there are no recorded frames => set next state
614                if (mFrameInfo.size() == 0)
615                {
616                        nextAppState();
617                }
618                else
619                {
620                        mWindow->setDebugText("Replay");
621                       
622                        // reset, because we measure fps stats during walkthrough (warning: average fps broken)
623                        mWindow->resetStatistics();
624                        resetStats();
625
626                        //-- initialise frame data
627                        mTimeElapsed = 0;
628
629                        mCamNode->setPosition(mFrameInfo[0].position);
630                        mCamNode->setOrientation(mFrameInfo[0].orientation);
631                }
632        }
633
634}
635//-----------------------------------------------------------------------
636void TerrainFrameListener::toggleRecord()
637{
638        mRecord = !mRecord;
639
640        // clear previous camera path
641        if (mRecord)
642                mFrameInfo.clear();
643        else
644                mWindow->setDebugText("");
645}
646//-----------------------------------------------------------------------
647void TerrainFrameListener::changeThreshold(int incr)
648{
649        mVisibilityThreshold += incr;
650        if(mVisibilityThreshold < 0) mVisibilityThreshold = 0;
651       
652        char str[100]; sprintf(str,": %d", mVisibilityThreshold);
653
654        mSceneMgr->setOption("Threshold", &mVisibilityThreshold);
655        mThresholdInfo->setCaption(str);
656}
657//-----------------------------------------------------------------------
658void TerrainFrameListener::changeAssumedVisibility(int incr)
659{
660        mAssumedVisibility += incr;
661        if(mAssumedVisibility < 0) mAssumedVisibility = 0;
662       
663        char str[100]; sprintf(str,": %d", mAssumedVisibility);
664
665        mSceneMgr->setOption("AssumedVisibility", &mAssumedVisibility);
666        mAssumedVisibilityInfo->setCaption(str);
667}
668//-----------------------------------------------------------------------
669void TerrainFrameListener::zoomVizCamera(int zoom)
670{
671        mVizCameraHeight += zoom;
672        if(mVizCameraHeight < 0) mVizCameraHeight = 0;
673}
674//-----------------------------------------------------------------------
675void TerrainFrameListener::nextAlgorithm()
676{
677        mCurrentAlgorithm = (mCurrentAlgorithm + 1) %
678                GtpVisibility::VisibilityEnvironment::NUM_CULLING_MANAGERS,
679
680        setAlgorithm(mCurrentAlgorithm);
681}
682//-----------------------------------------------------------------------
683void TerrainFrameListener::setAlgorithm(int algorithm)
684{
685        mAlgorithmInfo->setCaption(": " + currentAlgorithmCaptions[mCurrentAlgorithm]);
686        mSceneMgr->setOption("Algorithm", &mCurrentAlgorithm);
687}
688//-----------------------------------------------------------------------
689void TerrainFrameListener::resetStats()
690{
691        mAvgFps = 0;
692        mFrameCount = 0;
693}
694//-----------------------------------------------------------------------
695void TerrainFrameListener::updateStats()
696{
697        unsigned int opt = 0;
698        char str[100];
699       
700        static String currFpsString = "Current FPS: ";
701        static String avgFpsString = "Average FPS: ";
702        static String bestFpsString = "Best FPS: ";
703        static String worstFpsString = "Worst FPS: ";
704        static String trisString = "Triangle Count: ";
705
706        mAvgFps += mWindow->getStatistics().lastFPS;
707        ++ mFrameCount;
708       
709        float avgFps = (float)mAvgFps / (float)mFrameCount;
710   
711        // update stats when necessary
712    try
713        {
714                OverlayElement* guiAvg = OverlayManager::getSingleton().getOverlayElement("Core/AverageFps");
715                OverlayElement* guiCurr = OverlayManager::getSingleton().getOverlayElement("Core/CurrFps");
716                OverlayElement* guiBest = OverlayManager::getSingleton().getOverlayElement("Core/BestFps");
717                OverlayElement* guiWorst = OverlayManager::getSingleton().getOverlayElement("Core/WorstFps");
718
719                const RenderTarget::FrameStats& stats = mWindow->getStatistics();
720
721                //guiAvg->setCaption(avgFps + StringConverter::toString(stats.avgFPS));
722                guiAvg->setCaption(avgFpsString + StringConverter::toString(avgFps));
723                guiCurr->setCaption(currFpsString + StringConverter::toString(stats.lastFPS));
724                guiBest->setCaption(bestFpsString + StringConverter::toString(stats.bestFPS)
725                        +" "+StringConverter::toString(stats.bestFrameTime)+" ms");
726                guiWorst->setCaption(worstFpsString + StringConverter::toString(stats.worstFPS)
727                        +" "+StringConverter::toString(stats.worstFrameTime)+" ms");
728
729                OverlayElement* guiTris = OverlayManager::getSingleton().getOverlayElement("Core/NumTris");
730        guiTris->setCaption(trisString + StringConverter::toString(stats.triangleCount));
731
732                OverlayElement* guiDbg = OverlayManager::getSingleton().getOverlayElement("Core/DebugText");
733                guiDbg->setCaption(mWindow->getDebugText());
734
735                //-- culling stats
736                mSceneMgr->getOption("NumFrustumCulledNodes", &opt); sprintf(str,": %d", opt);
737                mFrustumCulledNodesInfo->setCaption(str);
738       
739                mSceneMgr->getOption("NumQueriesIssued", &opt); sprintf(str,": %d", opt);
740                mQueriesIssuedInfo->setCaption(str);
741
742                mSceneMgr->getOption("NumQueryCulledNodes", &opt); sprintf(str,": %d", opt);
743                mQueryCulledNodesInfo->setCaption(str);
744       
745                mSceneMgr->getOption("NumTraversedNodes", &opt); sprintf(str,": %d", opt);
746                mTraversedNodesInfo->setCaption(str);
747
748                mSceneMgr->getOption("NumHierarchyNodes", &opt); sprintf(str,": %d", opt);
749                mHierarchyNodesInfo->setCaption(str);
750
751                mSceneMgr->getOption("NumRenderedNodes", &opt); sprintf(str,": %d", opt);
752                mRenderedNodesInfo->setCaption(str);
753
754                sprintf(str,": %d", mTerrainContentGenerator->GetObjectCount());
755                mObjectsInfo->setCaption(str);
756        }
757        catch (...)
758        {
759                // ignore
760        }
761}
762//-----------------------------------------------------------------------
763void TerrainFrameListener::toggleUseOptimization()
764{
765        mUseOptimization = !mUseOptimization;
766        mSceneMgr->setOption("UseOptimization", &mUseOptimization);
767       
768        // disable optimization which tests geometry instead of aabb
769        // for delayed rendering (i.e., render transparents after all the solids)
770        // because otherwise visible transparents could be skipped
771        bool delayedRendering = !mUseOptimization;
772        mSceneMgr->setOption("DelayRenderTransparents", &delayedRendering);
773
774        if (mUseOptimization)
775        {
776                mUseOptimizationInfo->setCaption(": true");
777        }
778        else
779        {
780                mUseOptimizationInfo->setCaption(": false");
781        }
782}
783//-----------------------------------------------------------------------
784void TerrainFrameListener::toggleShowOctree()
785{
786        mShowOctree = !mShowOctree;
787
788        mSceneMgr->setOption("ShowOctree", &mShowOctree);
789}
790//-----------------------------------------------------------------------
791void TerrainFrameListener::toggleUseDepthPass()
792{
793        mUseDepthPass = !mUseDepthPass;
794
795        mSceneMgr->setOption("UseDepthPass", &mUseDepthPass);
796       
797        if (mUseDepthPass)
798        {
799                mUseDepthPassInfo->setCaption(": true");
800        }
801        else
802        {
803                mUseDepthPassInfo->setCaption(": false");
804        }
805}
806//-----------------------------------------------------------------------
807void TerrainFrameListener::toggleShowViz()
808{
809        mVisualizeCulledNodes = mShowVisualization = !mShowVisualization;
810       
811        // create viewport with priority VIZ_VIEWPORT_Z_ORDER:
812        // will be rendered over standard viewport
813        if (mShowVisualization)
814        {       
815                Viewport *vizvp = mWindow->addViewport(mVizCamera,
816                        VIZ_VIEWPORT_Z_ORDER, 0.6, 0.6, 0.4, 0.4);
817                               
818                vizvp->setBackgroundColour(ColourValue(0.0, 0.3, 0.2, 1));
819
820                vizvp->setOverlaysEnabled(false);
821                // Alter the camera aspect ratio to match the viewport
822        mVizCamera->setAspectRatio(Real(vizvp->getActualWidth()) /
823                                                                   Real(vizvp->getActualHeight()));
824               
825                mSceneMgr->setOption("VisualizeCulledNodes", &mVisualizeCulledNodes);
826                //vizvp->setClearEveryFrame(false);
827
828                // Create a skyplane (for visualization background)
829                /*
830                Plane plane;
831                plane.d = -1000;
832                plane.normal = Vector3::UNIT_Y;
833                mSceneMgr->setSkyPlane(true, plane, "Examples/TransparentTest", 4000, 75, false);
834                */
835        }
836        else
837        {
838                // remove visualization viewport
839                mWindow->removeViewport(VIZ_VIEWPORT_Z_ORDER);
840
841                // octree bounding boxes are shown for visualization purpose, reset now
842                mSceneMgr->setOption("ShowOctree", &mShowOctree);
843        }
844}
845//-----------------------------------------------------------------------
846void TerrainFrameListener::toggleShowShadows()
847{
848        mShowShadows = !mShowShadows;
849
850        mSunLight->setCastShadows(mShowShadows);
851
852        if (mShowShadows)
853        {
854                mSceneMgr->setShadowTechnique(SHADOWTYPE_TEXTURE_MODULATIVE);
855                //mSceneMgr->setShadowTechnique(SHADOWTYPE_STENCIL_MODULATIVE);
856                //mSceneMgr->setShadowTechnique(SHADOWTYPE_STENCIL_ADDITIVE);           
857        }
858        else
859        {
860                mSceneMgr->setShadowTechnique(SHADOWTYPE_NONE);
861        }
862
863}
864//-----------------------------------------------------------------------
865void TerrainFrameListener::nextNodeVizMode()
866{
867        mNodeVizMode = (mNodeVizMode + 1) % NODEVIZ_MODES_NUM;
868
869        bool renderNodesForViz = (mNodeVizMode == NODEVIZ_RENDER_NODES) ||
870                (mNodeVizMode == NODEVIZ_RENDER_NODES_AND_CONTENT);
871        bool renderNodesContentForViz = (mNodeVizMode == NODEVIZ_RENDER_NODES_AND_CONTENT);
872        //bool renderNodesContentForViz = mNodeVizMode == NODEVIZ_RENDER_GEOMETRY;
873
874        mSceneMgr->setOption("RenderNodesForViz", &renderNodesForViz);
875        mSceneMgr->setOption("RenderNodesContentForViz", &renderNodesContentForViz);
876}
877//-----------------------------------------------------------------------
878void TerrainFrameListener::keyPressed(KeyEvent* e)
879{
880        switch(e->getKey())
881        {
882        case KC_ESCAPE:
883                mShutdownRequested = true;
884                e->consume();
885                return;
886
887        case KC_SPACE:
888                nextAlgorithm();
889                break;
890       
891        case KC_F:
892                nextFilter();
893                break;
894        case KC_R:
895                nextSceneDetailLevel();
896                break;
897        case KC_P:
898                toggleDisplayCameraDetails();
899                break;
900        case KC_O:
901                toggleUseOptimization();
902                break;
903        case KC_T:
904                toggleShowOctree();
905                break;
906        case KC_X:
907                toggleUseDepthPass();
908                break;
909        case KC_S:
910                toggleShowShadows();
911                break;
912
913        case KC_SUBTRACT:
914                changeThreshold(-10);
915                break;
916        case KC_ADD:
917                changeThreshold(10);
918                break;
919
920        //-- visualization
921        case KC_1:
922                toggleShowViz();
923                break;
924        case KC_2:
925                nextNodeVizMode();
926                break;
927
928        case KC_F1:
929                toggleShowHelp();
930                break;
931        case KC_F2:
932                toggleShowStats();
933                break;
934        case KC_F3:
935                nextAppState();
936                break;
937        case KC_F4:
938                toggleRecord();
939                break;
940        case KC_F5:
941                ApplyVisibilityQuery(false, mShiftPressed, false);
942                break;
943        case KC_F6:
944                ApplyVisibilityQuery(true, mShiftPressed, false);
945                break;
946        case KC_F7:
947                ApplyVisibilityQuery(false, mShiftPressed, true);
948                break;
949        case KC_F8:
950                ApplyVisibilityQuery(true, mShiftPressed, true);
951                break;
952        case KC_F11:
953                takeScreenShot();
954                break;
955        case KC_F12:
956                mTerrainContentGenerator->WriteObjects(objects_out_filename);
957                break;
958
959        case KC_8:
960                changeAssumedVisibility(-1);
961                break;
962        case KC_9:
963                changeAssumedVisibility(1);
964                break;
965        case KC_LSHIFT:
966                mShiftPressed = true;
967                break;
968        //KEY_PRESSED(KC_F3, 0.3, writeFrames());
969        //KEY_PRESSED(KC_F4, 0.3, loadFrames());
970        default:
971                break;
972        }
973
974        CEGUI::System::getSingleton().injectKeyDown(e->getKey());
975        CEGUI::System::getSingleton().injectChar(e->getKeyChar());
976        e->consume();
977}
978//-----------------------------------------------------------------------
979void TerrainFrameListener::keyReleased(KeyEvent* e)
980{
981        if (e->getKey() == KC_LSHIFT)
982        {
983                mShiftPressed = false;
984        }
985       
986        CEGUI::System::getSingleton().injectKeyUp(e->getKey());
987        e->consume();
988}
989//-----------------------------------------------------------------------
990void TerrainFrameListener::keyClicked(KeyEvent* e)
991{
992        // Do nothing
993        e->consume();
994}
995//-----------------------------------------------------------------------
996void TerrainFrameListener::addFrameInfo(SceneNode *camNode, Real timeElapsed)
997{
998        frame_info info;
999        info.orientation = mCamNode->getOrientation();
1000        info.position = mCamNode->getPosition();
1001        info.timeElapsed = timeElapsed;
1002
1003        mFrameInfo.push_back(info);
1004}
1005//-----------------------------------------------------------------------
1006void TerrainFrameListener::setCurrentFrameInfo(Real timeElapsed)
1007{
1008        //-- find current frame relative to elapsed frame time         
1009        mTimeElapsed -= timeElapsed;
1010
1011        while ((mTimeElapsed <= 0) && (mCurrentFrame < (int)mFrameInfo.size() - 1))
1012        {
1013                mTimeElapsed += mFrameInfo[mCurrentFrame ++].timeElapsed;
1014        }
1015
1016        frame_info new_frame = mFrameInfo[mCurrentFrame];
1017        frame_info old_frame = mFrameInfo[mCurrentFrame - 1];
1018               
1019        //-- interpolate frames
1020        Real factor = 1;
1021
1022        if (old_frame.timeElapsed > 0)
1023        {
1024                factor = mTimeElapsed / old_frame.timeElapsed;
1025        }
1026
1027        Vector3 camPos = old_frame.position + factor
1028                * (new_frame.position - old_frame.position);
1029        Quaternion camOrienation = Quaternion::Slerp(factor, old_frame.orientation,
1030                new_frame.orientation, true);
1031
1032        mCamNode->setPosition(camPos);
1033        mCamNode->setOrientation(camOrienation);
1034       
1035        // stop replay after a full walkthrough
1036        if (mCurrentFrame == (int)mFrameInfo.size() - 1)
1037        {
1038                nextAppState();
1039        }
1040}
1041//-----------------------------------------------------------------------   
1042bool TerrainFrameListener::processUnbufferedKeyInput(const FrameEvent& evt)
1043{
1044        bool cursorPressed = false;
1045       
1046        /* Move camera forward by keypress. */
1047    if (mInputDevice->isKeyDown(KC_UP))
1048        {
1049                mTranslateVector.z = -mMoveScale;
1050                cursorPressed = true;
1051        }
1052    /* Move camera backward by keypress. */
1053    if (mInputDevice->isKeyDown(KC_DOWN))
1054    {
1055                mTranslateVector.z = mMoveScale;
1056                cursorPressed = true;
1057    }
1058
1059    if (mInputDevice->isKeyDown(KC_RIGHT))
1060    {
1061        mCamNode->yaw(-mRotScale);
1062                cursorPressed = true;
1063    }
1064       
1065    if (mInputDevice->isKeyDown(KC_LEFT))
1066    {
1067        mCamNode->yaw(mRotScale);
1068                cursorPressed = true;
1069    }
1070        // visualization camera
1071        if (mInputDevice->isKeyDown(KC_3))
1072        {
1073                zoomVizCamera(50);
1074        }
1075        if (mInputDevice->isKeyDown(KC_4))
1076        {
1077                zoomVizCamera(-50);
1078        }
1079
1080        // show the results
1081        if (cursorPressed && mShowQueryStats)
1082        {
1083                mQueryOverlay->hide();
1084                mShowQueryStats = false;
1085        }
1086
1087    // Return true to continue rendering
1088    return true;
1089}
1090//-----------------------------------------------------------------------
1091void TerrainFrameListener::nextFilter()
1092{
1093        switch (mFiltering)
1094        {
1095        case TFO_BILINEAR:
1096                mFiltering = TFO_TRILINEAR;
1097                mAniso = 1;
1098                break;
1099        case TFO_TRILINEAR:
1100                mFiltering = TFO_ANISOTROPIC;
1101                mAniso = 8;
1102                break;
1103        case TFO_ANISOTROPIC:
1104                mFiltering = TFO_BILINEAR;
1105                mAniso = 1;
1106                break;
1107        default:
1108                break;
1109        }
1110
1111    MaterialManager::getSingleton().setDefaultTextureFiltering(mFiltering);
1112    MaterialManager::getSingleton().setDefaultAnisotropy(mAniso);
1113
1114        // reload stats
1115    showStats(mStatsOn);
1116}
1117//-----------------------------------------------------------------------
1118void TerrainFrameListener::nextSceneDetailLevel()
1119{
1120        mSceneDetailIndex = (mSceneDetailIndex + 1) % 3;
1121        switch (mSceneDetailIndex)
1122        {
1123                case 0:
1124                        mCamera->setDetailLevel(SDL_SOLID);
1125                        break;
1126                case 1:
1127                        mCamera->setDetailLevel(SDL_WIREFRAME);
1128                        break;
1129                case 2:
1130                        mCamera->setDetailLevel(SDL_POINTS);
1131                        break;
1132        }
1133}
1134//-----------------------------------------------------------------------
1135void TerrainFrameListener::takeScreenShot()
1136{
1137        char tmp[20];
1138        sprintf(tmp, "screenshot_%d.png", ++mNumScreenShots);
1139    mWindow->writeContentsToFile(tmp);
1140    mWindow->setDebugText(String("Wrote ") + tmp);
1141}
1142//-----------------------------------------------------------------------
1143void TerrainFrameListener::toggleDisplayCameraDetails()
1144{
1145        mDisplayCameraDetails = !mDisplayCameraDetails;
1146       
1147    if (!mDisplayCameraDetails)
1148        {
1149                mWindow->setDebugText("");
1150        }
1151}
1152//-----------------------------------------------------------------------
1153void TerrainFrameListener::showStats(bool show)
1154{
1155        if (mDebugOverlay && mCullStatsOverlay)
1156        {
1157                if (show)
1158                {
1159                        mDebugOverlay->show();
1160                        mCullStatsOverlay->show();
1161                }
1162                else
1163                {
1164                        mDebugOverlay->hide();
1165                        mCullStatsOverlay->hide();
1166                }
1167        }
1168}
1169//-----------------------------------------------------------------------
1170void TerrainFrameListener::toggleShowStats()
1171{
1172        mStatsOn = !mStatsOn;
1173
1174        showStats(mStatsOn);
1175}
1176//-----------------------------------------------------------------------
1177void TerrainFrameListener::toggleShowHelp()
1178{
1179        mShowHelp = !mShowHelp;
1180
1181        if (mShowHelp)
1182        {
1183                mHelpOverlay->show();
1184        }
1185        else
1186        {
1187                mHelpOverlay->hide();
1188        }
1189}
Note: See TracBrowser for help on using the repository browser.