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

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