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

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