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

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

fixed some bugs

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
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//-----------------------------------------------------------------------
[133]27TerrainFrameListener::TerrainFrameListener(RenderWindow* win, Camera* cam,
[115]28                                                                           SceneManager *sceneManager,
29                                                                           CEGUI::Renderer *renderer,
30                                                                           TerrainContentGenerator *sceneGenerator,
31                                                                           Camera *vizCamera,
[121]32                                                                           SceneNode *camNode,
33                                                                           Light *sunLight):
[115]34mCamera(cam),
35mWindow(win),
36mNumScreenShots(0),
[120]37mTimeDelay(0),
[115]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),
[130]49mCurrentAlgorithm(GtpVisibility::VisibilityEnvironment::COHERENT_HIERARCHICAL_CULLING),
50//mCurrentAlgorithm(GtpVisibility::VisibilityEnvironment::FRUSTUM_CULLING),
[115]51mNodeVizMode(NODEVIZ_NONE),
52mVizCameraHeight(Real(2500.0)),
53mCamNode(camNode),
54mAppState(WALKTHROUGH),
55mCurrentFrame(0),
56mTimeElapsed(0),
57mRotateSpeed(72),
[120]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),
[121]73mVisualizeCulledNodes(false),
[133]74mSunLight(sunLight),
75mShiftPressed(false)
[115]76{
[130]77        //mInputDevice = PlatformManager::getSingleton().createInputReader();
78       
79        //mInputDevice->initialise(win, true, true);
80        mEventProcessor = new EventProcessor();
81       
82        mEventProcessor->initialise(win);
83        mEventProcessor->startProcessingEvents();
[120]84        mEventProcessor->addMouseListener(this);
[115]85        mEventProcessor->addMouseMotionListener(this);
[133]86        mEventProcessor->addKeyListener(this);
[115]87
[130]88        mInputDevice = mEventProcessor->getInputReader();
89       
90
[115]91        // create ray query executor, used to place objects in terrain
92        mRayQueryExecutor = new RayQueryExecutor(mSceneMgr);
93       
[120]94        mHelpOverlay = OverlayManager::getSingleton().getByName("Example/Visibility/HelpOverlay");
95        mDebugOverlay = OverlayManager::getSingleton().getByName("Core/DebugOverlay");
[115]96
[120]97
98        //-- visibility culling stats overlay
99        mCullStatsOverlay = OverlayManager::getSingleton().getByName("Example/Visibility/DemoOverlay");
100       
[115]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
[120]126        // show stats overlays
127        showStats(true);
128        //mHelpOverlay->show();
[115]129
130        // set culling algorithm type
131        setAlgorithm(mCurrentAlgorithm);
132
133        // set scene manager options
134        mSceneMgr->setOption("UseOptimization", &mUseOptimization);
[120]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);
[115]141        mSceneMgr->setOption("UseDepthPass", &mUseDepthPass);
[120]142       
[115]143        mSceneMgr->setOption("ShowOctree", &mShowOctree);
144        mSceneMgr->setOption("CullCamera", &mCullCamera);
145        mSceneMgr->setOption("ShowVisualization", &mShowVisualization);
[130]146
[133]147        // TODO: change this
148        mVisibilityManager = dynamic_cast<VisibilityTerrainSceneManager *>(mSceneMgr)->
149                GetVisibilityManager();
[130]150
151        dynamic_cast<PlatformQueryManager *>(mVisibilityManager->GetQueryManager())->
152                SetViewport(mWindow->getViewport(0));
[115]153}
154//-----------------------------------------------------------------------
[133]155TerrainFrameListener::~TerrainFrameListener()
[115]156{
[130]157        //PlatformManager::getSingleton().destroyInputReader(mInputDevice);
[115]158   
159        delete mRayQueryExecutor;
[130]160        delete mEventProcessor;
[115]161}
162//-----------------------------------------------------------------------
[133]163void TerrainFrameListener::mouseMoved(MouseEvent *e)
[115]164{
165        // Update CEGUI with the mouse motion
166    CEGUI::System::getSingleton().injectMouseMove(e->getRelX() *
167                mGUIRenderer->getWidth(), e->getRelY() * mGUIRenderer->getHeight());
168}
169//-----------------------------------------------------------------------
[133]170void TerrainFrameListener::mousePressed(MouseEvent* e)
[115]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                 
[130]180                 //Vector3 queryResult; mRayQueryExecutor->executeRayQuery(&queryResult, mouseRay);
181                 
[115]182                 // Get results, create a node/entity on the position
183                 mCurrentObject = mTerrainContentGenerator->GenerateSceneObject(
[130]184                         mouseRay.getOrigin(), Vector3::ZERO, "robot", false);
[115]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     }
[133]194}
[115]195//-----------------------------------------------------------------------
[133]196void TerrainFrameListener::mouseReleased(MouseEvent* e)
[115]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//-----------------------------------------------------------------------
[133]212void TerrainFrameListener::mouseDragged(MouseEvent *e)
[115]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//-----------------------------------------------------------------------
[133]238bool TerrainFrameListener::frameStarted(const FrameEvent &evt)
[115]239{
240        if (mWindow->isClosed())
[130]241        {
[115]242        return false;
[130]243        }
[115]244
[130]245//      mInputDevice->capture();
[122]246
[130]247        //-- IMPORTANT: must be set, otherwise terrain is not rendered correctly
248        int terrainLevelIdx = 0;
249        mSceneMgr->setOption("TerrainLevelIdx", &terrainLevelIdx);
[115]250
[130]251        //-- setup what is needed for immediate mouse/key movement
252        if (mTimeDelay >= 0)
253        {
254                mTimeDelay -= evt.timeSinceLastFrame;
255        }
[115]256
[130]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        }
[115]271
[130]272        mRotX = 0;
273        mRotY = 0;
274        mTranslateVector = Vector3::ZERO;
[115]275
[130]276        if (!processUnbufferedKeyInput(evt))
277        {
278                return false;
279        }
280/*      if (!processUnbufferedMouseInput(evt))
[133]281        {       return false;   }*/
282
[130]283        // --- set parameters for visualization
284        if (mShowVisualization)
285        {
[115]286                // important for visualization => draw octree bounding boxes
287                mSceneMgr->setOption("ShowOctree", &mShowVisualization);
[130]288               
289                // ---- setup visualization camera
[115]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)));
[130]299
[115]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
[130]308        //-- set application state
[115]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                }       
[133]323                // move camera according to input
[130]324                moveCamera();
[133]325                // clamp camera so we always walk along the terrain
[130]326                Clamp2Terrain();
[133]327                break;
[130]328
[115]329        default:
330                break;
331        };     
[130]332
[115]333        return true;
334}
335//-----------------------------------------------------------------------
[133]336void TerrainFrameListener::ApplyVisibilityQuery(bool fromPoint, bool relativeVisibility)
[130]337{
338        InfoContainer<GtpVisibility::NodeInfo> visibleNodes;
339        InfoContainer<GtpVisibility::MeshInfo> visibleGeometry;
340
[133]341        if (fromPoint)
342        {
343        }
344        else
345        {
346                mVisibilityManager->GetQueryManager()->ComputeCameraVisibility(*mCamera,
347                            &visibleNodes, &visibleGeometry, relativeVisibility);
348        }
[130]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//-----------------------------------------------------------------------
[133]363void TerrainFrameListener::Clamp2Terrain()
[115]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//-----------------------------------------------------------------------
[133]376bool TerrainFrameListener::frameEnded(const FrameEvent& evt)
[115]377{
378        if (mShutdownRequested)
379                return false;
380
[120]381    updateStats();
[115]382
383        return true;
384}
385//-----------------------------------------------------------------------
[133]386void TerrainFrameListener::moveCamera()
[115]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//-----------------------------------------------------------------------
[133]394void TerrainFrameListener::writeFrames()
[115]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) << " "
[130]404                          << StringConverter::toString((*it).orientation) << " "
405                          << StringConverter::toString((*it).timeElapsed) << "\n";
[115]406        }
407        ofstr.close();
408}
409//-----------------------------------------------------------------------
[133]410void TerrainFrameListener::loadFrames()
[115]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               
[130]429                /*      std::stringstream d;
[115]430                d << StringConverter::toString(info.position) << " " << StringConverter::toString(info.orientation);
[130]431                LogManager::getSingleton().logMessage(d.str());         */
[115]432        }
433        ifstr.close();
434}
435//-----------------------------------------------------------------------
[133]436void TerrainFrameListener::nextAppState()
[115]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               
[121]447                //-- write out stats for recorded walkthrough
[115]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//-----------------------------------------------------------------------
[133]496void TerrainFrameListener::toggleRecord()
[115]497{
498        mRecord = !mRecord;
499
500        // clear previous camera path
501        if (mRecord)
502                mFrameInfo.clear();
503        else
504                mWindow->setDebugText("");
505}
506//-----------------------------------------------------------------------
[133]507void TerrainFrameListener::changeThreshold(int incr)
[115]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//-----------------------------------------------------------------------
[133]518void TerrainFrameListener::zoomVizCamera(int zoom)
[115]519{
520        mVizCameraHeight += zoom;
521        if(mVizCameraHeight < 0) mVizCameraHeight = 0;
522}
523//-----------------------------------------------------------------------
[133]524void TerrainFrameListener::nextAlgorithm()
[115]525{
526        mCurrentAlgorithm = (mCurrentAlgorithm + 1) %
527                GtpVisibility::VisibilityEnvironment::NUM_CULLING_MANAGERS,
528
529        setAlgorithm(mCurrentAlgorithm);
530}
531//-----------------------------------------------------------------------
[133]532void TerrainFrameListener::setAlgorithm(int algorithm)
[115]533{
534        mAlgorithmInfo->setCaption(": " + mCurrentAlgorithmCaptions[mCurrentAlgorithm]);
535        mSceneMgr->setOption("Algorithm", &mCurrentAlgorithm);
536}
537//-----------------------------------------------------------------------
[133]538void TerrainFrameListener::updateStats()
[115]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//-----------------------------------------------------------------------
[133]599void TerrainFrameListener::toggleUseOptimization()
[115]600{
601        mUseOptimization = !mUseOptimization;
602        mSceneMgr->setOption("UseOptimization", &mUseOptimization);
[133]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
[115]607        bool delayedRendering = !mUseOptimization;
608        mSceneMgr->setOption("DelayRenderTransparents", &delayedRendering);
609
610        if (mUseOptimization)
[133]611        {
[115]612                mUseOptimizationInfo->setCaption(": true");
[133]613        }
[115]614        else
[133]615        {
[115]616                mUseOptimizationInfo->setCaption(": false");
[133]617        }
[115]618}
619//-----------------------------------------------------------------------
[133]620void TerrainFrameListener::toggleShowOctree()
[115]621{
622        mShowOctree = !mShowOctree;
623
624        mSceneMgr->setOption("ShowOctree", &mShowOctree);
625}
626//-----------------------------------------------------------------------
[133]627void TerrainFrameListener::toggleUseDepthPass()
[115]628{
629        mUseDepthPass = !mUseDepthPass;
630
631        mSceneMgr->setOption("UseDepthPass", &mUseDepthPass);
632       
633        if (mUseDepthPass)
[120]634        {
[115]635                mUseDepthPassInfo->setCaption(": true");
[120]636        }
[115]637        else
[120]638        {
[115]639                mUseDepthPassInfo->setCaption(": false");
[120]640        }
[115]641}
642//-----------------------------------------------------------------------
[133]643void TerrainFrameListener::toggleShowViz()
[115]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//-----------------------------------------------------------------------
[133]682void TerrainFrameListener::toggleUseShadows()
[115]683{
684        mUseShadows = !mUseShadows;
685
[121]686        mSunLight->setCastShadows(mUseShadows);
[115]687
688        if (mUseShadows)
689        {
690                mSceneMgr->setShadowTechnique(SHADOWTYPE_TEXTURE_MODULATIVE);
691        }
692        else
693        {
694                mSceneMgr->setShadowTechnique(SHADOWTYPE_NONE);
695        }
696
697}
698//-----------------------------------------------------------------------
[133]699void TerrainFrameListener::nextNodeVizMode()
[115]700{
701        mNodeVizMode = (mNodeVizMode + 1) % NODEVIZ_MODES_NUM;
702
[120]703        bool renderNodesForViz = (mNodeVizMode == NODEVIZ_RENDER_NODES) ||
704                (mNodeVizMode == NODEVIZ_RENDER_NODES_AND_CONTENT);
[115]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//-----------------------------------------------------------------------
[133]712void TerrainFrameListener::keyPressed(KeyEvent* e)
[115]713{
[133]714        switch(e->getKey())
715        {
716        case KC_ESCAPE:
[115]717                mShutdownRequested = true;
718                e->consume();
719                return;
[133]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;
[115]795        }
796
[133]797        if (mDisplayCameraDetails)
798    {
799        // Print camera details
800        mWindow->setDebugText("P: " + StringConverter::toString(mCamera->getDerivedPosition()) + " " +
801            "O: " + StringConverter::toString(mCamera->getDerivedOrientation()));
802    }
803
[115]804        CEGUI::System::getSingleton().injectKeyDown(e->getKey());
805        CEGUI::System::getSingleton().injectChar(e->getKeyChar());
806        e->consume();
807}
808//-----------------------------------------------------------------------
[133]809void TerrainFrameListener::keyReleased(KeyEvent* e)
[115]810{
811        CEGUI::System::getSingleton().injectKeyUp(e->getKey());
812        e->consume();
813}
814//-----------------------------------------------------------------------
[133]815void TerrainFrameListener::keyClicked(KeyEvent* e)
[115]816{
817        // Do nothing
818        e->consume();
819}
820//-----------------------------------------------------------------------
[133]821void TerrainFrameListener::addFrameInfo(SceneNode *camNode, Real timeElapsed)
[115]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//-----------------------------------------------------------------------
[133]831void TerrainFrameListener::setCurrentFrameInfo(Real timeElapsed)
[115]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)
[133]848        {
[115]849                factor = mTimeElapsed / old_frame.timeElapsed;
[133]850        }
[115]851
[133]852        Vector3 camPos = old_frame.position + factor
853                * (new_frame.position - old_frame.position);
[115]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//-----------------------------------------------------------------------   
[133]867bool TerrainFrameListener::processUnbufferedKeyInput(const FrameEvent& evt)
[115]868{
[133]869        /*if (mInputDevice->isKeyDown(KC_ESCAPE))
[120]870    {           
871        return false;
[133]872    }*/
[115]873
[120]874        /* Move camera forward by keypress. */
875    if (mInputDevice->isKeyDown(KC_UP))
876        {
877                mTranslateVector.z = -mMoveScale;
878        }
[115]879
880    /* Move camera backward by keypress. */
[120]881    if (mInputDevice->isKeyDown(KC_DOWN))
[115]882    {
[120]883                mTranslateVector.z = mMoveScale;
[115]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    }
[133]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        }
[115]904
905
906    // Return true to continue rendering
907    return true;
908}
909//-----------------------------------------------------------------------
[133]910void TerrainFrameListener::nextFilter()
[120]911{
[133]912        switch (mFiltering)
[120]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
[133]933        // reload stats
[120]934    showStats(mStatsOn);
935}
936//-----------------------------------------------------------------------
[133]937void TerrainFrameListener::nextSceneDetailLevel()
[120]938{
[133]939        mSceneDetailIndex = (mSceneDetailIndex + 1) % 3;
940        switch (mSceneDetailIndex)
[120]941        {
[133]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;
[120]951        }
952}
953//-----------------------------------------------------------------------
[133]954void TerrainFrameListener::takeScreenShot()
[120]955{
956        char tmp[20];
957        sprintf(tmp, "screenshot_%d.png", ++mNumScreenShots);
958    mWindow->writeContentsToFile(tmp);
959    mWindow->setDebugText(String("Wrote ") + tmp);
960}
961//-----------------------------------------------------------------------
[133]962void TerrainFrameListener::toggleDisplayCameraDetails()
[120]963{
964        mDisplayCameraDetails = !mDisplayCameraDetails;
965       
966    if (!mDisplayCameraDetails)
[133]967        {
[120]968                mWindow->setDebugText("");
[115]969        }
970}
[120]971//-----------------------------------------------------------------------
[133]972void TerrainFrameListener::showStats(bool show)
[115]973{
[120]974        if (mDebugOverlay && mCullStatsOverlay)
[115]975        {
976                if (show)
977                {
978                        mDebugOverlay->show();
[120]979                        mCullStatsOverlay->show();
[115]980                }
981                else
982                {
983                        mDebugOverlay->hide();
[120]984                        mCullStatsOverlay->hide();
[115]985                }
986        }
987}
[120]988//-----------------------------------------------------------------------
[133]989void TerrainFrameListener::toggleShowStats()
[120]990{
991        mStatsOn = !mStatsOn;
[115]992
[120]993        showStats(mStatsOn);
994}
995//-----------------------------------------------------------------------
[133]996void TerrainFrameListener::toggleShowHelp()
[120]997{
998        mShowHelp = !mShowHelp;
[115]999
[120]1000        if (mShowHelp)
1001        {
1002                mHelpOverlay->show();
1003        }
1004        else
1005        {
1006                mHelpOverlay->hide();
1007        }
[133]1008}
Note: See TracBrowser for help on using the repository browser.