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

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