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

Revision 135, 31.8 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
12// output file for frame info
13const char* frames_out_filename = "frame.out";
14// output file for object positions / orientations
15const char* objects_out_filename = "objects.out";
16
17
18String currentAlgorithmCaptions[GtpVisibility::VisibilityEnvironment::NUM_CULLING_MANAGERS] =
19{
20        "View Frustum Culling",
21        "Stop and Wait Culling",
22        "Coherent Hierarchical Culling"
23};
24
25String queryTypeCaptions[4] =
26{
27        "from camera, visible pixels",
28        "from viewpoint, visible pixels",
29        "from camera, relative visibility",
30        "from viewpoint, relative visibility"
31};
32
33//-----------------------------------------------------------------------
34TerrainFrameListener::TerrainFrameListener(RenderWindow* win, Camera* cam,
35                                                                           SceneManager *sceneManager,
36                                                                           CEGUI::Renderer *renderer,
37                                                                           TerrainContentGenerator *sceneGenerator,
38                                                                           Camera *vizCamera,
39                                                                           SceneNode *camNode,
40                                                                           Light *sunLight):
41mCamera(cam),
42mWindow(win),
43mNumScreenShots(0),
44mTimeDelay(0),
45mSceneDetailIndex(0),
46mMoveScale(0.0f),
47mRotScale(0.0f),
48mTranslateVector(Vector3::ZERO),
49mAniso(1),
50mFiltering(TFO_BILINEAR),
51mGUIRenderer(renderer),
52mSceneMgr(sceneManager),
53mCurrentObject(NULL),
54mTerrainContentGenerator(sceneGenerator),
55mVisibilityThreshold(0),
56mCurrentAlgorithm(GtpVisibility::VisibilityEnvironment::COHERENT_HIERARCHICAL_CULLING),
57//mCurrentAlgorithm(GtpVisibility::VisibilityEnvironment::FRUSTUM_CULLING),
58mNodeVizMode(NODEVIZ_NONE),
59mVizCameraHeight(Real(2500.0)),
60mCamNode(camNode),
61mAppState(WALKTHROUGH),
62mCurrentFrame(0),
63mTimeElapsed(0),
64mRotateSpeed(72),
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),
80mVisualizeCulledNodes(false),
81mSunLight(sunLight),
82mShiftPressed(false),
83mShowQueryStats(false)
84{
85        //mInputDevice = PlatformManager::getSingleton().createInputReader();
86        //mInputDevice->initialise(win, true, true);
87
88        mEventProcessor = new EventProcessor();
89       
90        mEventProcessor->initialise(win);
91        mEventProcessor->startProcessingEvents();
92        mEventProcessor->addMouseListener(this);
93        mEventProcessor->addMouseMotionListener(this);
94        mEventProcessor->addKeyListener(this);
95
96        mInputDevice = mEventProcessor->getInputReader();
97       
98
99        // create ray query executor, used to place objects in terrain
100        mRayQueryExecutor = new RayQueryExecutor(mSceneMgr);
101       
102        mHelpOverlay = OverlayManager::getSingleton().getByName("Example/Visibility/HelpOverlay");
103        mDebugOverlay = OverlayManager::getSingleton().getByName("Core/DebugOverlay");
104        mQueryOverlay = OverlayManager::getSingleton().getByName("Example/Visibility/QueryOverlay");
105
106        //-- visibility culling stats overlay
107        mCullStatsOverlay = OverlayManager::getSingleton().getByName("Example/Visibility/DemoOverlay");
108       
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       
122        mAlgorithmInfo->setCaption(": " + currentAlgorithmCaptions[mCurrentAlgorithm]);
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
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
142        // show stats overlays
143        showStats(true);
144        //mHelpOverlay->show();
145
146        // set culling algorithm type
147        setAlgorithm(mCurrentAlgorithm);
148
149        // set scene manager options
150        mSceneMgr->setOption("UseOptimization", &mUseOptimization);
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);
157        mSceneMgr->setOption("UseDepthPass", &mUseDepthPass);
158       
159        mSceneMgr->setOption("ShowOctree", &mShowOctree);
160        mSceneMgr->setOption("CullCamera", &mCullCamera);
161        mSceneMgr->setOption("ShowVisualization", &mShowVisualization);
162
163        // TODO: change this (does not work with other scene manager plugins)
164        mVisibilityManager = dynamic_cast<VisibilityTerrainSceneManager *>(mSceneMgr)->
165                GetVisibilityManager();
166
167        dynamic_cast<PlatformQueryManager *>(mVisibilityManager->GetQueryManager())->
168                SetViewport(mWindow->getViewport(0));
169}
170//-----------------------------------------------------------------------
171TerrainFrameListener::~TerrainFrameListener()
172{
173        delete mRayQueryExecutor;
174        delete mEventProcessor;
175}
176//-----------------------------------------------------------------------
177void TerrainFrameListener::mouseMoved(MouseEvent *e)
178{
179        // Update CEGUI with the mouse motion
180    CEGUI::System::getSingleton().injectMouseMove(e->getRelX() *
181                mGUIRenderer->getWidth(), e->getRelY() * mGUIRenderer->getHeight());
182}
183//-----------------------------------------------------------------------
184void TerrainFrameListener::mousePressed(MouseEvent* e)
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                 
194                 //Vector3 queryResult; mRayQueryExecutor->executeRayQuery(&queryResult, mouseRay);
195                 
196                 // Get results, create a node/entity on the position
197                 mCurrentObject = mTerrainContentGenerator->GenerateSceneObject(
198                         mouseRay.getOrigin(), Vector3::ZERO, "robot");
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     }
208}
209//-----------------------------------------------------------------------
210void TerrainFrameListener::mouseReleased(MouseEvent* e)
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//-----------------------------------------------------------------------
226void TerrainFrameListener::mouseDragged(MouseEvent *e)
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//-----------------------------------------------------------------------
252bool TerrainFrameListener::frameStarted(const FrameEvent &evt)
253{
254        if (mWindow->isClosed())
255        {
256        return false;
257        }
258
259//      mInputDevice->capture();
260
261        //-- IMPORTANT: must be set, otherwise terrain is not rendered correctly
262        int terrainLevelIdx = 0;
263        mSceneMgr->setOption("TerrainLevelIdx", &terrainLevelIdx);
264
265        //-- setup what is needed for immediate mouse/key movement
266        if (mTimeDelay >= 0)
267        {
268                mTimeDelay -= evt.timeSinceLastFrame;
269        }
270
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        }
285
286        mRotX = 0;
287        mRotY = 0;
288        mTranslateVector = Vector3::ZERO;
289
290        if (!processUnbufferedKeyInput(evt))
291        {
292                return false;
293        }
294/*      if (!processUnbufferedMouseInput(evt))
295        {       return false;   }*/
296
297        // --- set parameters for visualization
298        if (mShowVisualization)
299        {
300                // important for visualization => draw octree bounding boxes
301                mSceneMgr->setOption("ShowOctree", &mShowVisualization);
302               
303                // ---- setup visualization camera
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)));
313
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
322        //-- set application state
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                }       
337                // move camera according to input
338                moveCamera();
339                // clamp camera so we always walk along the terrain
340                Clamp2Terrain();
341                break;
342
343        default:
344                break;
345        };     
346
347        return true;
348}
349//-----------------------------------------------------------------------
350void TerrainFrameListener::ApplyVisibilityQuery(bool fromPoint, bool relativeVisibility)
351{
352        InfoContainer<GtpVisibility::NodeInfo> visibleNodes;
353        InfoContainer<GtpVisibility::MeshInfo> visibleGeometry;
354
355        if (fromPoint)
356        {
357                Vector3 point;
358                mVisibilityManager->GetQueryManager()->
359                ComputeFromPointVisibility(point, &visibleNodes, &visibleGeometry, relativeVisibility);
360        }
361        else
362        {
363                mVisibilityManager->GetQueryManager()->ComputeCameraVisibility(*mCamera,
364                            &visibleNodes, &visibleGeometry, relativeVisibility);
365        }
366
367        float averageNodeVis = 0;
368        float averageGeometryVis = 0;
369
370        for (int i=0; i < visibleGeometry.size(); ++i)
371        {
372                averageGeometryVis += visibleGeometry[i].GetVisibility();
373
374                std::stringstream d; d << "Geometry visibility: " << visibleGeometry[i].GetVisibility();
375                LogManager::getSingleton().logMessage(d.str());
376        }
377        for (int i=0; i < visibleNodes.size(); ++i)
378        {
379                averageNodeVis += visibleNodes[i].GetVisibility();
380
381                std::stringstream d; d << "Node visibility: " << visibleNodes[i].GetVisibility();
382                LogManager::getSingleton().logMessage(d.str());
383        }
384
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        }
423}
424//-----------------------------------------------------------------------
425void TerrainFrameListener::Clamp2Terrain()
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//-----------------------------------------------------------------------
438bool TerrainFrameListener::frameEnded(const FrameEvent& evt)
439{
440        if (mShutdownRequested)
441                return false;
442
443    updateStats();
444
445        return true;
446}
447//-----------------------------------------------------------------------
448void TerrainFrameListener::moveCamera()
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//-----------------------------------------------------------------------
456void TerrainFrameListener::writeFrames()
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();
463        for (it = mFrameInfo.begin(); it < it_end; ++it)
464        {
465                ofstr << StringConverter::toString((*it).position) << " "
466                          << StringConverter::toString((*it).orientation) << " "
467                          << StringConverter::toString((*it).timeElapsed) << "\n";
468        }
469        ofstr.close();
470}
471//-----------------------------------------------------------------------
472void TerrainFrameListener::loadFrames()
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,
486                           &info.orientation.w, &info.orientation.x, &info.orientation.y, &info.orientation.z,
487                           &info.timeElapsed);
488               
489                mFrameInfo.push_back(info);
490               
491                /*      std::stringstream d;
492                d << StringConverter::toString(info.position) << " " << StringConverter::toString(info.orientation);
493                LogManager::getSingleton().logMessage(d.str());         */
494        }
495        ifstr.close();
496}
497//-----------------------------------------------------------------------
498void TerrainFrameListener::nextAppState()
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               
509                //-- write out stats for recorded walkthrough
510                std::stringstream d;
511                d << "Algorithm: " << currentAlgorithmCaptions[mCurrentAlgorithm] << "\n"
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//-----------------------------------------------------------------------
558void TerrainFrameListener::toggleRecord()
559{
560        mRecord = !mRecord;
561
562        // clear previous camera path
563        if (mRecord)
564                mFrameInfo.clear();
565        else
566                mWindow->setDebugText("");
567}
568//-----------------------------------------------------------------------
569void TerrainFrameListener::changeThreshold(int incr)
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//-----------------------------------------------------------------------
580void TerrainFrameListener::zoomVizCamera(int zoom)
581{
582        mVizCameraHeight += zoom;
583        if(mVizCameraHeight < 0) mVizCameraHeight = 0;
584}
585//-----------------------------------------------------------------------
586void TerrainFrameListener::nextAlgorithm()
587{
588        mCurrentAlgorithm = (mCurrentAlgorithm + 1) %
589                GtpVisibility::VisibilityEnvironment::NUM_CULLING_MANAGERS,
590
591        setAlgorithm(mCurrentAlgorithm);
592}
593//-----------------------------------------------------------------------
594void TerrainFrameListener::setAlgorithm(int algorithm)
595{
596        mAlgorithmInfo->setCaption(": " + currentAlgorithmCaptions[mCurrentAlgorithm]);
597        mSceneMgr->setOption("Algorithm", &mCurrentAlgorithm);
598}
599//-----------------------------------------------------------------------
600void TerrainFrameListener::updateStats()
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
612    try
613        {
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        }
656        catch (...)
657        {
658                // ignore
659        }
660}
661//-----------------------------------------------------------------------
662void TerrainFrameListener::toggleUseOptimization()
663{
664        mUseOptimization = !mUseOptimization;
665        mSceneMgr->setOption("UseOptimization", &mUseOptimization);
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
670        bool delayedRendering = !mUseOptimization;
671        mSceneMgr->setOption("DelayRenderTransparents", &delayedRendering);
672
673        if (mUseOptimization)
674        {
675                mUseOptimizationInfo->setCaption(": true");
676        }
677        else
678        {
679                mUseOptimizationInfo->setCaption(": false");
680        }
681}
682//-----------------------------------------------------------------------
683void TerrainFrameListener::toggleShowOctree()
684{
685        mShowOctree = !mShowOctree;
686
687        mSceneMgr->setOption("ShowOctree", &mShowOctree);
688}
689//-----------------------------------------------------------------------
690void TerrainFrameListener::toggleUseDepthPass()
691{
692        mUseDepthPass = !mUseDepthPass;
693
694        mSceneMgr->setOption("UseDepthPass", &mUseDepthPass);
695       
696        if (mUseDepthPass)
697        {
698                mUseDepthPassInfo->setCaption(": true");
699        }
700        else
701        {
702                mUseDepthPassInfo->setCaption(": false");
703        }
704}
705//-----------------------------------------------------------------------
706void TerrainFrameListener::toggleShowViz()
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//-----------------------------------------------------------------------
745void TerrainFrameListener::toggleUseShadows()
746{
747        mUseShadows = !mUseShadows;
748
749        mSunLight->setCastShadows(mUseShadows);
750
751        if (mUseShadows)
752        {
753                mSceneMgr->setShadowTechnique(SHADOWTYPE_TEXTURE_MODULATIVE);
754        }
755        else
756        {
757                mSceneMgr->setShadowTechnique(SHADOWTYPE_NONE);
758        }
759
760}
761//-----------------------------------------------------------------------
762void TerrainFrameListener::nextNodeVizMode()
763{
764        mNodeVizMode = (mNodeVizMode + 1) % NODEVIZ_MODES_NUM;
765
766        bool renderNodesForViz = (mNodeVizMode == NODEVIZ_RENDER_NODES) ||
767                (mNodeVizMode == NODEVIZ_RENDER_NODES_AND_CONTENT);
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//-----------------------------------------------------------------------
775void TerrainFrameListener::keyPressed(KeyEvent* e)
776{
777        switch(e->getKey())
778        {
779        case KC_ESCAPE:
780                mShutdownRequested = true;
781                e->consume();
782                return;
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:
852                mShiftPressed = true;
853                break;
854        //KEY_PRESSED(KC_F3, 0.3, writeFrames());
855        //KEY_PRESSED(KC_F4, 0.3, loadFrames());
856        default:
857                break;
858        }
859
860        if (mDisplayCameraDetails)
861    {
862        // Print camera details
863        mWindow->setDebugText("P: " + StringConverter::toString(mCamera->getDerivedPosition()) +
864                        " " + "O: " + StringConverter::toString(mCamera->getDerivedOrientation()));
865    }
866
867        CEGUI::System::getSingleton().injectKeyDown(e->getKey());
868        CEGUI::System::getSingleton().injectChar(e->getKeyChar());
869        e->consume();
870}
871//-----------------------------------------------------------------------
872void TerrainFrameListener::keyReleased(KeyEvent* e)
873{
874        if (e->getKey() == KC_LSHIFT)
875        {
876                mShiftPressed = false;
877        }
878       
879        CEGUI::System::getSingleton().injectKeyUp(e->getKey());
880        e->consume();
881}
882//-----------------------------------------------------------------------
883void TerrainFrameListener::keyClicked(KeyEvent* e)
884{
885        // Do nothing
886        e->consume();
887}
888//-----------------------------------------------------------------------
889void TerrainFrameListener::addFrameInfo(SceneNode *camNode, Real timeElapsed)
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//-----------------------------------------------------------------------
899void TerrainFrameListener::setCurrentFrameInfo(Real timeElapsed)
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)
916        {
917                factor = mTimeElapsed / old_frame.timeElapsed;
918        }
919
920        Vector3 camPos = old_frame.position + factor
921                * (new_frame.position - old_frame.position);
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//-----------------------------------------------------------------------   
935bool TerrainFrameListener::processUnbufferedKeyInput(const FrameEvent& evt)
936{
937        bool cursorPressed = false;
938       
939        /* Move camera forward by keypress. */
940    if (mInputDevice->isKeyDown(KC_UP))
941        {
942                mTranslateVector.z = -mMoveScale;
943                cursorPressed = true;
944        }
945    /* Move camera backward by keypress. */
946    if (mInputDevice->isKeyDown(KC_DOWN))
947    {
948                mTranslateVector.z = mMoveScale;
949                cursorPressed = true;
950    }
951
952    if (mInputDevice->isKeyDown(KC_RIGHT))
953    {
954        mCamNode->yaw(-mRotScale);
955                cursorPressed = true;
956    }
957       
958    if (mInputDevice->isKeyDown(KC_LEFT))
959    {
960        mCamNode->yaw(mRotScale);
961                cursorPressed = true;
962    }
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        }
972
973        // show the results
974        if (cursorPressed && mShowQueryStats)
975        {
976                mQueryOverlay->hide();
977                mShowQueryStats = false;
978        }
979
980    // Return true to continue rendering
981    return true;
982}
983//-----------------------------------------------------------------------
984void TerrainFrameListener::nextFilter()
985{
986        switch (mFiltering)
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
1007        // reload stats
1008    showStats(mStatsOn);
1009}
1010//-----------------------------------------------------------------------
1011void TerrainFrameListener::nextSceneDetailLevel()
1012{
1013        mSceneDetailIndex = (mSceneDetailIndex + 1) % 3;
1014        switch (mSceneDetailIndex)
1015        {
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;
1025        }
1026}
1027//-----------------------------------------------------------------------
1028void TerrainFrameListener::takeScreenShot()
1029{
1030        char tmp[20];
1031        sprintf(tmp, "screenshot_%d.png", ++mNumScreenShots);
1032    mWindow->writeContentsToFile(tmp);
1033    mWindow->setDebugText(String("Wrote ") + tmp);
1034}
1035//-----------------------------------------------------------------------
1036void TerrainFrameListener::toggleDisplayCameraDetails()
1037{
1038        mDisplayCameraDetails = !mDisplayCameraDetails;
1039       
1040    if (!mDisplayCameraDetails)
1041        {
1042                mWindow->setDebugText("");
1043        }
1044}
1045//-----------------------------------------------------------------------
1046void TerrainFrameListener::showStats(bool show)
1047{
1048        if (mDebugOverlay && mCullStatsOverlay)
1049        {
1050                if (show)
1051                {
1052                        mDebugOverlay->show();
1053                        mCullStatsOverlay->show();
1054                }
1055                else
1056                {
1057                        mDebugOverlay->hide();
1058                        mCullStatsOverlay->hide();
1059                }
1060        }
1061}
1062//-----------------------------------------------------------------------
1063void TerrainFrameListener::toggleShowStats()
1064{
1065        mStatsOn = !mStatsOn;
1066
1067        showStats(mStatsOn);
1068}
1069//-----------------------------------------------------------------------
1070void TerrainFrameListener::toggleShowHelp()
1071{
1072        mShowHelp = !mShowHelp;
1073
1074        if (mShowHelp)
1075        {
1076                mHelpOverlay->show();
1077        }
1078        else
1079        {
1080                mHelpOverlay->hide();
1081        }
1082}
Note: See TracBrowser for help on using the repository browser.