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

Revision 139, 32.0 KB checked in by mattausch, 19 years ago (diff)

fixed bug with tight octree boxes
added more flexible renderqueue (can delete per flag)
reordered functions in visibility terrain scene manager

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),
77mShowShadows(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("PrepareVisualization", &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()/*queryResult*/, 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        if (mDisplayCameraDetails)
260    {
261        // Print camera details
262        mWindow->setDebugText("P: " + StringConverter::toString(mCamera->getDerivedPosition()) +
263                        " " + "O: " + StringConverter::toString(mCamera->getDerivedOrientation()));
264    }
265
266        //-- IMPORTANT: must be set, otherwise terrain is not rendered correctly
267        int terrainLevelIdx = 0;
268        mSceneMgr->setOption("TerrainLevelIdx", &terrainLevelIdx);
269
270        //-- setup what is needed for immediate mouse/key movement
271        if (mTimeDelay >= 0)
272        {
273                mTimeDelay -= evt.timeSinceLastFrame;
274        }
275
276        // If this is the first frame, pick a speed
277        if (evt.timeSinceLastFrame == 0)
278        {
279                mMoveScale = 1;
280                mRotScale = 0.1;
281        }
282        // Otherwise scale movement units by time passed since last frame
283        else
284        {
285                // Move about 100 units per second,
286                mMoveScale = mMoveSpeed * evt.timeSinceLastFrame;
287                // Take about 10 seconds for full rotation
288                mRotScale = mRotateSpeed * evt.timeSinceLastFrame;
289        }
290
291        mRotX = 0;
292        mRotY = 0;
293        mTranslateVector = Vector3::ZERO;
294
295        if (!processUnbufferedKeyInput(evt))
296        {
297                return false;
298        }
299/*      if (!processUnbufferedMouseInput(evt))
300        {       return false;   }*/
301
302        // --- set parameters for visualization
303        if (mShowVisualization)
304        {
305                // important for visualization => draw octree bounding boxes
306                mSceneMgr->setOption("ShowOctree", &mShowVisualization);
307               
308                // ---- setup visualization camera
309
310                mVizCamera->setPosition(0, 0, 0);
311                mVizCamera->setOrientation(Quaternion::IDENTITY);
312
313                Vector3 camPos = mCamNode->getPosition();
314                mVizCamera->setPosition(camPos.x, mVizCameraHeight, camPos.z);
315
316                // point down -Z axis
317                mVizCamera->pitch(Radian(Degree(270.0)));
318
319                // rotation arounnd X axis
320                mVizCamera->yaw(Math::ATan2(-mCamera->getDerivedDirection().x,
321                        -mCamera->getDerivedDirection().z));
322               
323                // move by a constant so view plane is on bottom of viewport
324                mVizCamera->moveRelative(Vector3(0, 800, 0));
325        }
326
327        //-- set application state
328        switch (mAppState)
329        {
330        case REPLAY:
331                setCurrentFrameInfo(evt.timeSinceLastFrame);
332                break;
333        case WALKTHROUGH:
334                //-- if we are recording camera status per frame
335                if (mRecord)
336                {
337                        addFrameInfo(mCamNode, evt.timeSinceLastFrame);
338                        // print recording message
339                        mWindow->setDebugText("Recording frame " +
340                                StringConverter::toString(mFrameInfo.size() - 1));
341                }       
342                // move camera according to input
343                moveCamera();
344                // clamp camera so we always walk along the terrain
345                Clamp2Terrain();
346                break;
347
348        default:
349                break;
350        };     
351
352        return true;
353}
354//-----------------------------------------------------------------------
355void TerrainFrameListener::ApplyVisibilityQuery(bool fromPoint, bool relativeVisibility)
356{
357        InfoContainer<GtpVisibility::NodeInfo> visibleNodes;
358        InfoContainer<GtpVisibility::MeshInfo> visibleGeometry;
359
360        if (fromPoint)
361        {
362                Vector3 point;
363                mVisibilityManager->GetQueryManager()->
364                ComputeFromPointVisibility(point, &visibleNodes, &visibleGeometry, relativeVisibility);
365        }
366        else
367        {
368                mVisibilityManager->GetQueryManager()->ComputeCameraVisibility(*mCamera,
369                            &visibleNodes, &visibleGeometry, relativeVisibility);
370        }
371
372        float averageNodeVis = 0;
373        float averageGeometryVis = 0;
374
375        for (int i=0; i < visibleGeometry.size(); ++i)
376        {
377                averageGeometryVis += visibleGeometry[i].GetVisibility();
378
379                std::stringstream d; d << "Geometry visibility: " << visibleGeometry[i].GetVisibility();
380                LogManager::getSingleton().logMessage(d.str());
381        }
382        for (int i=0; i < visibleNodes.size(); ++i)
383        {
384                averageNodeVis += visibleNodes[i].GetVisibility();
385
386                std::stringstream d; d << "Node visibility: " << visibleNodes[i].GetVisibility();
387                LogManager::getSingleton().logMessage(d.str());
388        }
389
390        averageNodeVis /= (float)visibleNodes.size();
391        averageGeometryVis /= (float)visibleGeometry.size();
392
393        char str[100];
394
395        //-- update visibility queries stats
396    try
397        {
398                //-- visibility queries stats
399                int idx = fromPoint ?  1 : 0;
400                idx += relativeVisibility ? 2 : 0;
401
402                sprintf(str, ": %s", queryTypeCaptions[idx].c_str());
403                mQueryTypeInfo->setCaption(str);
404
405                sprintf(str, ": %d", (int)visibleNodes.size());
406                mQueryVisibleNodesInfo->setCaption(str);
407       
408                sprintf(str,": %d", (int)visibleGeometry.size());
409                mQueryVisibleGeometryInfo->setCaption(str);
410               
411                sprintf(str,": %3.3f", averageNodeVis);
412                mQueryNodeVisibilityInfo->setCaption(str);
413
414                sprintf(str,": %3.3f", averageGeometryVis);
415                mQueryGeometryVisibilityInfo->setCaption(str);
416        }
417        catch (...)
418        {
419                // ignore
420        }
421
422        // show the results
423        if (!mShowQueryStats)
424        {
425                mQueryOverlay->show();
426                mShowQueryStats = true;
427        }
428}
429//-----------------------------------------------------------------------
430void TerrainFrameListener::Clamp2Terrain()
431{
432        // clamp to terrain
433        Vector3 camPos = mCamNode->getPosition();
434        Vector3 queryResult;
435
436        if (mRayQueryExecutor->executeRayQuery(&queryResult,
437                        Vector3(camPos.x, 5000.0f, camPos.z), Vector3::NEGATIVE_UNIT_Y))
438        {
439                mCamNode->setPosition(camPos.x, queryResult.y + 10, camPos.z);
440        }
441}
442//-----------------------------------------------------------------------
443bool TerrainFrameListener::frameEnded(const FrameEvent& evt)
444{
445        if (mShutdownRequested)
446                return false;
447
448    updateStats();
449
450        return true;
451}
452//-----------------------------------------------------------------------
453void TerrainFrameListener::moveCamera()
454{
455        // move node rather than camera so orientation is right in the visualization
456        mCamNode->yaw(mRotX);
457        mCamNode->pitch(mRotY);
458        mCamNode->translate(mCamNode->getLocalAxes(), mTranslateVector);
459}
460//-----------------------------------------------------------------------
461void TerrainFrameListener::writeFrames()
462{
463        std::ofstream ofstr(frames_out_filename);
464       
465        std::vector<frame_info>::const_iterator it, it_end;
466
467        it_end = mFrameInfo.end();
468        for (it = mFrameInfo.begin(); it < it_end; ++it)
469        {
470                ofstr << StringConverter::toString((*it).position) << " "
471                          << StringConverter::toString((*it).orientation) << " "
472                          << StringConverter::toString((*it).timeElapsed) << "\n";
473        }
474        ofstr.close();
475}
476//-----------------------------------------------------------------------
477void TerrainFrameListener::loadFrames()
478{
479        std::ifstream ifstr(frames_out_filename);
480        char line[256];
481        frame_info info;
482
483        // reset current values
484        mFrameInfo.clear();
485        mCurrentFrame = 0;
486       
487        while (!ifstr.eof())
488        {
489                ifstr.getline(line, 256);
490                sscanf(line, "%f %f %f %f %f %f %f %f", &info.position.x, &info.position.y, &info.position.z,
491                           &info.orientation.w, &info.orientation.x, &info.orientation.y, &info.orientation.z,
492                           &info.timeElapsed);
493               
494                mFrameInfo.push_back(info);
495               
496                /*      std::stringstream d;
497                d << StringConverter::toString(info.position) << " " << StringConverter::toString(info.orientation);
498                LogManager::getSingleton().logMessage(d.str());         */
499        }
500        ifstr.close();
501}
502//-----------------------------------------------------------------------
503void TerrainFrameListener::nextAppState()
504{
505        mCurrentFrame = 0;
506
507        // if last state was replay state
508        if (mAppState == REPLAY)
509        {
510                // reset debug text and write frame info to file
511                mWindow->setDebugText("");
512                writeFrames();
513               
514                //-- write out stats for recorded walkthrough
515                std::stringstream d;
516                d << "Algorithm: " << currentAlgorithmCaptions[mCurrentAlgorithm] << "\n"
517                  << "avg. FPS: " << mWindow->getAverageFPS() << "\n"
518                  << "best FPS: " << mWindow->getBestFPS() << "\n"
519                  << "worst FPS: " << mWindow->getWorstFPS() << "\n"
520                  << "best frame time: " <<     mWindow->getBestFrameTime() << "\n"
521                  << "worst frame time: " << mWindow->getWorstFrameTime();
522               
523                LogManager::getSingleton().logMessage(d.str());
524        }
525       
526        //-- set the next státe
527        mAppState = (mAppState + 1) % STATE_NUM;
528
529        // replay recorded walkthrough
530        if (mAppState == REPLAY)
531        {
532                // no recording during replay
533                mRecord = false;
534
535                // load recorded walkthrough
536                if (mFrameInfo.size() == 0)
537                {
538                        loadFrames();
539                }
540
541                // if there are no recorded frames => set next state
542                if (mFrameInfo.size() == 0)
543                {
544                        nextAppState();
545                }
546                else
547                {
548                        mWindow->setDebugText("Replay");
549                       
550                        // reset, because we measure fps stats during walkthrough
551                        mWindow->resetStatistics();
552
553                        //-- initialise frame data
554                        mTimeElapsed = 0;
555
556                        mCamNode->setPosition(mFrameInfo[0].position);
557                        mCamNode->setOrientation(mFrameInfo[0].orientation);
558                }
559        }
560
561}
562//-----------------------------------------------------------------------
563void TerrainFrameListener::toggleRecord()
564{
565        mRecord = !mRecord;
566
567        // clear previous camera path
568        if (mRecord)
569                mFrameInfo.clear();
570        else
571                mWindow->setDebugText("");
572}
573//-----------------------------------------------------------------------
574void TerrainFrameListener::changeThreshold(int incr)
575{
576        mVisibilityThreshold += incr;
577        if(mVisibilityThreshold < 0) mVisibilityThreshold = 0;
578       
579        char str[100]; sprintf(str,": %d", mVisibilityThreshold);
580
581        mSceneMgr->setOption("Threshold", &mVisibilityThreshold);
582        mThresholdInfo->setCaption(str);
583}
584//-----------------------------------------------------------------------
585void TerrainFrameListener::zoomVizCamera(int zoom)
586{
587        mVizCameraHeight += zoom;
588        if(mVizCameraHeight < 0) mVizCameraHeight = 0;
589}
590//-----------------------------------------------------------------------
591void TerrainFrameListener::nextAlgorithm()
592{
593        mCurrentAlgorithm = (mCurrentAlgorithm + 1) %
594                GtpVisibility::VisibilityEnvironment::NUM_CULLING_MANAGERS,
595
596        setAlgorithm(mCurrentAlgorithm);
597}
598//-----------------------------------------------------------------------
599void TerrainFrameListener::setAlgorithm(int algorithm)
600{
601        mAlgorithmInfo->setCaption(": " + currentAlgorithmCaptions[mCurrentAlgorithm]);
602        mSceneMgr->setOption("Algorithm", &mCurrentAlgorithm);
603}
604//-----------------------------------------------------------------------
605void TerrainFrameListener::updateStats()
606{
607        unsigned int opt = 0;
608        char str[100];
609       
610        static String currFps = "Current FPS: ";
611        static String avgFps = "Average FPS: ";
612        static String bestFps = "Best FPS: ";
613        static String worstFps = "Worst FPS: ";
614        static String tris = "Triangle Count: ";
615
616        // update stats when necessary
617    try
618        {
619                OverlayElement* guiAvg = OverlayManager::getSingleton().getOverlayElement("Core/AverageFps");
620                OverlayElement* guiCurr = OverlayManager::getSingleton().getOverlayElement("Core/CurrFps");
621                OverlayElement* guiBest = OverlayManager::getSingleton().getOverlayElement("Core/BestFps");
622                OverlayElement* guiWorst = OverlayManager::getSingleton().getOverlayElement("Core/WorstFps");
623
624                const RenderTarget::FrameStats& stats = mWindow->getStatistics();
625
626                guiAvg->setCaption(avgFps + StringConverter::toString(stats.avgFPS));
627                guiCurr->setCaption(currFps + StringConverter::toString(stats.lastFPS));
628                guiBest->setCaption(bestFps + StringConverter::toString(stats.bestFPS)
629                        +" "+StringConverter::toString(stats.bestFrameTime)+" ms");
630                guiWorst->setCaption(worstFps + StringConverter::toString(stats.worstFPS)
631                        +" "+StringConverter::toString(stats.worstFrameTime)+" ms");
632
633                OverlayElement* guiTris = OverlayManager::getSingleton().getOverlayElement("Core/NumTris");
634        guiTris->setCaption(tris + StringConverter::toString(stats.triangleCount));
635
636                OverlayElement* guiDbg = OverlayManager::getSingleton().getOverlayElement("Core/DebugText");
637                guiDbg->setCaption(mWindow->getDebugText());
638
639                //-- culling stats
640                mSceneMgr->getOption("NumFrustumCulledNodes", &opt); sprintf(str,": %d", opt);
641                mFrustumCulledNodesInfo->setCaption(str);
642       
643                mSceneMgr->getOption("NumQueriesIssued", &opt); sprintf(str,": %d", opt);
644                mQueriesIssuedInfo->setCaption(str);
645
646                mSceneMgr->getOption("NumQueryCulledNodes", &opt); sprintf(str,": %d", opt);
647                mQueryCulledNodesInfo->setCaption(str);
648       
649                mSceneMgr->getOption("NumTraversedNodes", &opt); sprintf(str,": %d", opt);
650                mTraversedNodesInfo->setCaption(str);
651
652                mSceneMgr->getOption("NumHierarchyNodes", &opt); sprintf(str,": %d", opt);
653                mHierarchyNodesInfo->setCaption(str);
654
655                mSceneMgr->getOption("NumRenderedNodes", &opt); sprintf(str,": %d", opt);
656                mRenderedNodesInfo->setCaption(str);
657
658                sprintf(str,": %d", mTerrainContentGenerator->GetObjectCount());
659                mObjectsInfo->setCaption(str);
660        }
661        catch (...)
662        {
663                // ignore
664        }
665}
666//-----------------------------------------------------------------------
667void TerrainFrameListener::toggleUseOptimization()
668{
669        mUseOptimization = !mUseOptimization;
670        mSceneMgr->setOption("UseOptimization", &mUseOptimization);
671       
672        // disable optimization which tests geometry instead of aabb
673        // for delayed rendering (i.e., render transparents after all the solids)
674        // because otherwise visible transparents could be skipped
675        bool delayedRendering = !mUseOptimization;
676        mSceneMgr->setOption("DelayRenderTransparents", &delayedRendering);
677
678        if (mUseOptimization)
679        {
680                mUseOptimizationInfo->setCaption(": true");
681        }
682        else
683        {
684                mUseOptimizationInfo->setCaption(": false");
685        }
686}
687//-----------------------------------------------------------------------
688void TerrainFrameListener::toggleShowOctree()
689{
690        mShowOctree = !mShowOctree;
691
692        mSceneMgr->setOption("ShowOctree", &mShowOctree);
693}
694//-----------------------------------------------------------------------
695void TerrainFrameListener::toggleUseDepthPass()
696{
697        mUseDepthPass = !mUseDepthPass;
698
699        mSceneMgr->setOption("UseDepthPass", &mUseDepthPass);
700       
701        if (mUseDepthPass)
702        {
703                mUseDepthPassInfo->setCaption(": true");
704        }
705        else
706        {
707                mUseDepthPassInfo->setCaption(": false");
708        }
709}
710//-----------------------------------------------------------------------
711void TerrainFrameListener::toggleShowViz()
712{
713        mVisualizeCulledNodes = mShowVisualization = !mShowVisualization;
714       
715        // create viewport with priority VIZ_VIEWPORT_Z_ORDER:
716        // will be rendered over standard viewport
717        if (mShowVisualization)
718        {       
719                Viewport *vizvp = mWindow->addViewport(mVizCamera,
720                        VIZ_VIEWPORT_Z_ORDER, 0.6, 0.6, 0.4, 0.4);
721                               
722                vizvp->setBackgroundColour(ColourValue(0.0, 0.3, 0.2, 1));
723
724                vizvp->setOverlaysEnabled(false);
725                // Alter the camera aspect ratio to match the viewport
726        mVizCamera->setAspectRatio(Real(vizvp->getActualWidth()) /
727                                                                   Real(vizvp->getActualHeight()));
728               
729                mSceneMgr->setOption("VisualizeCulledNodes", &mVisualizeCulledNodes);
730                //vizvp->setClearEveryFrame(false);
731
732                // Create a skyplane (for visualization background)
733                /*
734                Plane plane;
735                plane.d = -1000;
736                plane.normal = Vector3::UNIT_Y;
737                mSceneMgr->setSkyPlane(true, plane, "Examples/TransparentTest", 4000, 75, false);
738                */
739        }
740        else
741        {
742                // remove visualization viewport
743                mWindow->removeViewport(VIZ_VIEWPORT_Z_ORDER);
744
745                // octree bounding boxes are shown for visualization purpose, reset now
746                mSceneMgr->setOption("ShowOctree", &mShowOctree);
747        }
748}
749//-----------------------------------------------------------------------
750void TerrainFrameListener::toggleShowShadows()
751{
752        mShowShadows = !mShowShadows;
753
754        mSunLight->setCastShadows(mShowShadows);
755
756        if (mShowShadows)
757        {
758                mSceneMgr->setShadowTechnique(SHADOWTYPE_TEXTURE_MODULATIVE);
759                //mSceneMgr->setShadowTechnique(SHADOWTYPE_STENCIL_MODULATIVE);
760                //mSceneMgr->setShadowTechnique(SHADOWTYPE_STENCIL_ADDITIVE);           
761        }
762        else
763        {
764                mSceneMgr->setShadowTechnique(SHADOWTYPE_NONE);
765        }
766
767}
768//-----------------------------------------------------------------------
769void TerrainFrameListener::nextNodeVizMode()
770{
771        mNodeVizMode = (mNodeVizMode + 1) % NODEVIZ_MODES_NUM;
772
773        bool renderNodesForViz = (mNodeVizMode == NODEVIZ_RENDER_NODES) ||
774                (mNodeVizMode == NODEVIZ_RENDER_NODES_AND_CONTENT);
775        bool renderNodesContentForViz = (mNodeVizMode == NODEVIZ_RENDER_NODES_AND_CONTENT);
776        //bool renderNodesContentForViz = mNodeVizMode == NODEVIZ_RENDER_GEOMETRY;
777
778        mSceneMgr->setOption("RenderNodesForViz", &renderNodesForViz);
779        mSceneMgr->setOption("RenderNodesContentForViz", &renderNodesContentForViz);
780}
781//-----------------------------------------------------------------------
782void TerrainFrameListener::keyPressed(KeyEvent* e)
783{
784        switch(e->getKey())
785        {
786        case KC_ESCAPE:
787                mShutdownRequested = true;
788                e->consume();
789                return;
790
791        case KC_SPACE:
792                nextAlgorithm();
793                break;
794       
795        case KC_F:
796                nextFilter();
797                break;
798        case KC_R:
799                nextSceneDetailLevel();
800                break;
801        case KC_P:
802                toggleDisplayCameraDetails();
803                break;
804        case KC_O:
805                toggleUseOptimization();
806                break;
807        case KC_T:
808                toggleShowOctree();
809                break;
810        case KC_X:
811                toggleUseDepthPass();
812                break;
813        case KC_S:
814                toggleShowShadows();
815                break;
816
817        case KC_SUBTRACT:
818                changeThreshold(-10);
819                break;
820        case KC_ADD:
821                changeThreshold(10);
822                break;
823
824        //-- visualization
825        case KC_1:
826                toggleShowViz();
827                break;
828        case KC_2:
829                nextNodeVizMode();
830                break;
831
832        case KC_F1:
833                toggleShowHelp();
834                break;
835        case KC_F2:
836                toggleShowStats();
837                break;
838        case KC_F3:
839                nextAppState();
840                break;
841        case KC_F4:
842                toggleRecord();
843                break;
844        case KC_F5:
845                ApplyVisibilityQuery(false, mShiftPressed);
846                break;
847        case KC_F6:
848                ApplyVisibilityQuery(true, mShiftPressed);
849                break;
850
851        case KC_F11:
852                takeScreenShot();
853                break;
854        case KC_F12:
855                mTerrainContentGenerator->WriteObjects(objects_out_filename);
856                break;
857
858        case KC_LSHIFT:
859                mShiftPressed = true;
860                break;
861        //KEY_PRESSED(KC_F3, 0.3, writeFrames());
862        //KEY_PRESSED(KC_F4, 0.3, loadFrames());
863        default:
864                break;
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.