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

Revision 133, 29.5 KB checked in by mattausch, 19 years ago (diff)

fixed some bugs

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