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

Revision 159, 36.9 KB checked in by mattausch, 19 years ago (diff)

added flags for switching on/off transparents for item buffer and vertex programs for depth pass / item buffer

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