source: GTP/trunk/App/Demos/Vis/HillyTerrain/OGRE/TerrainFrameListener.cpp @ 639

Revision 639, 48.0 KB checked in by mattausch, 18 years ago (diff)
Line 
1#include <OgreNoMemoryMacros.h>
2#include <CEGUI/CEGUI.h>
3#include <../CEGUIRenderer/include/OgreCEGUIRenderer.h>
4#include <../CEGUIRenderer/include/OgreCEGUIResourceProvider.h>
5#include <../CEGUIRenderer/include/OgreCEGUITexture.h>
6#include <OgreMemoryMacros.h>
7#include "TerrainFrameListener.h"
8#include "OgrePlatformQueryManager.h"
9#include "OgreVisibilityTerrainSceneManager.h"
10#include "VisibilityInfo.h"
11#include "OgreOcclusionQueriesQueryManager.h"
12#include "TestCullingTerrainApplication.h"
13
14
15//-- captions for overlays
16String TerrainFrameListener::msAlgorithmCaptions[] =
17{
18        "Coherent Hierarchical Culling",
19        "View Frustum Culling",
20        "Stop and Wait Culling"
21};
22
23String TerrainFrameListener::msQueryTypeCaptions[] =
24{
25        "from camera",
26        "from viewpoint"
27};
28
29String TerrainFrameListener::msQueryRelativeVisCaptions[] =
30{
31        "visible pixels",
32        "relative visibility"
33};
34
35String TerrainFrameListener::msQueryMethodCaptions[] =
36{
37        "occlusion queries",
38        "item buffer"
39};
40
41Real TerrainFrameListener::msObjectTerrainOffsets[] =
42{
43        0,
44        -0.1,
45        //7,
46        0
47};
48
49Real TerrainFrameListener::msObjectScales[] =
50{
51        0.07,
52        0.03,
53        //0.1,
54        0.03
55};
56
57String TerrainFrameListener::msObjectCaptions[] =
58{
59        "robot",
60        //"athene",
61        "natFX_Tree1_LOD2",
62        //"tree2",
63        //"HongKong_Tower",
64        "ninja"
65        //"ogrehead"
66};
67
68// output file for frame info
69const char* frames_out_filename = "frame.out";
70// output file for object positions / orientations
71const char* objects_out_filename = "objects.out";
72       
73std::ofstream video_out("video.lst");
74
75//-----------------------------------------------------------------------
76TerrainFrameListener::TerrainFrameListener(RenderWindow* win, Camera* cam,
77                                                                           SceneManager *sceneManager,
78                                                                           CEGUI::Renderer *renderer,
79                                                                           TerrainContentGenerator *sceneGenerator,
80                                                                           Camera *vizCamera,
81                                                                           SceneNode *camNode,
82                                                                           Light *sunLight,
83                                                                           TestCullingTerrainApplication *app):
84mCamera(cam),
85mWindow(win),
86mNumScreenShots(0),
87mTimeDelay(0),
88mSceneDetailIndex(0),
89mMoveScale(0.0f),
90mRotScale(0.0f),
91mTranslateVector(Vector3::ZERO),
92mAniso(1),
93mFiltering(TFO_BILINEAR),
94mGUIRenderer(renderer),
95mSceneMgr(sceneManager),
96mCurrentObject(NULL),
97mTerrainContentGenerator(sceneGenerator),
98mVisibilityThreshold(0),
99mAssumedVisibility(0),
100mCurrentAlgorithm(GtpVisibility::VisibilityEnvironment::COHERENT_HIERARCHICAL_CULLING),
101//mCurrentAlgorithm(GtpVisibility::VisibilityEnvironment::FRUSTUM_CULLING),
102mNodeVizMode(NODEVIZ_NONE),
103mVizCameraHeight(Real(2500.0)),
104mCamNode(camNode),
105mAppState(WALKTHROUGH),
106mCurrentFrame(0),
107mReplayTimeElapsed(0),
108mRotateSpeed(72),
109mMoveSpeed(50),
110mVizCamera(vizCamera),
111mStatsOn(true),
112mShutdownRequested(false),
113mLMouseDown(false),
114mRMouseDown(false),
115mShowOctree(false),
116mUseDepthPass(false),
117mTestGeometryForVisibleLeaves(false),
118mShowVisualization(false),
119mCullCamera(false),
120mRecordFrames(false),
121mShowShadows(false),
122mShowHelp(false),
123mDisplayCameraDetails(false),
124mVisualizeCulledNodes(false),
125mSunLight(sunLight),
126mShiftPressed(false),
127mShowQueryStats(false),
128mQueryManager(NULL),
129mVisibilityManager(NULL),
130mDelayedQueriesIssued(0.0),
131mDelayedTraversedNodes(0.0),
132mCurrentObjectType(0),
133mApplication(app),
134mUseAnimation(false),
135mDeleteObjects(false),
136mUseItemBuffer(false),
137mItemBufferMode(GtpVisibility::QueryManager::PATCH_VISIBILITY),
138mRecordVideo(false),
139mPureRenderTimeFps(0.0),
140mNumVideoFrames(0),
141mDemoFps(0),
142mUseDemoFps(false),
143mUseArbQueries(false),
144mUseBufferedInputMouse(false)
145{
146        //mInputDevice = PlatformManager::getSingleton().createInputReader();
147        //mInputDevice->initialise(win, true, true);
148
149        mEventProcessor = new EventProcessor();
150       
151        mEventProcessor->initialise(win);
152        mEventProcessor->startProcessingEvents();
153        mEventProcessor->addMouseListener(this);
154        mEventProcessor->addMouseMotionListener(this);
155        mEventProcessor->addKeyListener(this);
156
157        mInputDevice = mEventProcessor->getInputReader();       
158
159        mInputDevice->setBufferedInput(true, mUseBufferedInputMouse);
160
161        // create ray query executor, used to place objects in terrain
162        mRayQueryExecutor = new RayQueryExecutor(mSceneMgr);
163       
164        //-- overlays
165        mDebugOverlay = OverlayManager::getSingleton().getByName("Core/DebugOverlay");
166        mHelpOverlay = OverlayManager::getSingleton().getByName("Example/Visibility/HelpOverlay");
167        mQueryOverlay = OverlayManager::getSingleton().getByName("Example/Visibility/QueryOverlay");
168        mCullStatsOverlay = OverlayManager::getSingleton().getByName("Example/Visibility/CullStatsOverlay");
169
170        initVisStatsOverlay(); // visibility stats overlay
171        initHelpOverlay();     // help overlay
172        initQueryOverlay();    // visibility query stats overlay
173
174        // show stats overlays
175        showStats(true);
176       
177        // set culling algorithm type
178        setAlgorithm(mCurrentAlgorithm);
179
180        // set scene manager options
181        setTestGeometryForVisibleLeaves(mTestGeometryForVisibleLeaves);
182
183        mSceneMgr->setOption("UseDepthPass", &mUseDepthPass);
184       
185        mSceneMgr->setOption("ShowOctree", &mShowOctree);
186        mSceneMgr->setOption("CullCamera", &mCullCamera);
187        mSceneMgr->setOption("PrepareVisualization", &mShowVisualization);
188
189        setObjectType(mCurrentObjectType);
190
191        // initialise timer
192        mTimer = Root::getSingleton().getTimer();
193        mTimeFrameEnded = mTimeFrameStarted = mTimer->getMilliseconds();
194               
195        //if (mSceneMgr->getSceneNode("robot Entity1Node")->getAttachedObject(0)->getMovableType() == "Entity")
196        //      Ogre::LogManager::getSingleton().logMessage("found entity");
197       
198        // arb or nv queries
199        //mSceneMgr->setOption("UseArbQueries", &mUseArbQueries);
200       
201        // reset statistics
202        mWalkthroughStats.Reset();
203}
204//-----------------------------------------------------------------------
205TerrainFrameListener::~TerrainFrameListener()
206{
207        OGRE_DELETE(mRayQueryExecutor);
208        OGRE_DELETE(mEventProcessor);
209        OGRE_DELETE(mQueryManager);
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                Real val = Math::RangeRandom(0, 360); // random rotation
231
232                // get results, create a node/entity on the position
233                mCurrentObject =
234                        mTerrainContentGenerator->GenerateSceneObject(mouseRay.getOrigin(),
235                                                                                                                  Vector3(val, 0, 0),
236                                                                                                                  msObjectCaptions[mCurrentObjectType]);
237               
238                mLMouseDown = true;
239        }
240        // Right mouse button down
241        /*else if (e->getButtonID() & InputEvent::BUTTON1_MASK)
242        {
243         CEGUI::MouseCursor::getSingleton().hide();
244         mRMouseDown = true;
245        }*/
246}
247//-----------------------------------------------------------------------
248void TerrainFrameListener::mouseDragDropped(MouseEvent* e)
249{
250        // Left mouse button up
251    if (e->getButtonID() & InputEvent::BUTTON0_MASK)
252    {
253                CEGUI::MouseCursor::getSingleton().show();
254               
255            mLMouseDown = false;
256    }
257    // Right mouse button up
258    else if (e->getButtonID() & InputEvent::BUTTON1_MASK)
259    {
260        CEGUI::MouseCursor::getSingleton().show();
261
262                mRMouseDown = false;
263    }
264}
265//-----------------------------------------------------------------------
266void TerrainFrameListener::mouseReleased(MouseEvent* e)
267{
268    // Left mouse button up
269    if (e->getButtonID() & InputEvent::BUTTON0_MASK)
270    {
271                CEGUI::MouseCursor::getSingleton().show();
272               
273                // start animation: only robot has animation phases
274                if (mCurrentObject && (mCurrentObjectType == TestCullingTerrainApplication::ROBOT))
275                {
276                        // HACK: not neccesary the last element
277                        Entity *ent = mTerrainContentGenerator->GetGeneratedEntities()->back();
278                        EntityState *entState = new EntityState(ent, EntityState::MOVING, Math::RangeRandom(0.5, 1.5));
279                        mApplication->getEntityStates().push_back(entState);
280                }
281
282            mLMouseDown = false;
283    }
284    // Right mouse button up
285    else if (e->getButtonID() & InputEvent::BUTTON1_MASK)
286    {
287        CEGUI::MouseCursor::getSingleton().show();
288
289        mRMouseDown = false;
290    }
291}
292//-----------------------------------------------------------------------
293void TerrainFrameListener::mouseDragged(MouseEvent *e)
294{
295        // If we are dragging the left mouse button.             
296        if (mLMouseDown)
297    {
298                if (!mCurrentObject)
299                        return;
300
301                Vector3 queryResult;
302                Ray mouseRay = mCamera->getCameraToViewportRay(e->getX(), e->getY());
303
304                if (mRayQueryExecutor->executeRayQuery(&queryResult, mouseRay))
305                {
306                        // apply offset so object is ON terrain
307                        queryResult.y += msObjectTerrainOffsets[mCurrentObjectType];
308                        mCurrentObject->setPosition(queryResult);
309                }
310        }
311}
312//-----------------------------------------------------------------------
313bool TerrainFrameListener::frameStarted(const FrameEvent &evt)
314{
315        if (mWindow->isClosed())
316        {
317        return false;
318        }
319       
320        if (mDeleteObjects)
321        {
322                mApplication->deleteEntityStates();
323                mTerrainContentGenerator->RemoveGeneratedObjects();
324                mDeleteObjects = false;
325        }
326
327        if (mUseAnimation) // update animations
328        {
329                mApplication->updateAnimations(evt.timeSinceLastFrame);
330        }
331
332        if (mDisplayCameraDetails)  // Print camera details
333    {       
334        mWindow->setDebugText("P: " + StringConverter::toString(mCamera->getDerivedPosition()) +
335                        " " + "O: " + StringConverter::toString(mCamera->getDerivedOrientation()));
336    }
337
338        //-- setup what is needed for immediate mouse/key movement
339        if (mTimeDelay >= 0)
340        {
341                mTimeDelay -= evt.timeSinceLastFrame;
342        }
343       
344        // If this is the first frame, pick a speed
345        if (evt.timeSinceLastFrame == 0)
346        {
347                mMoveScale = 1;
348                mRotScale = 0.1;
349        }
350        // Otherwise scale movement units by time passed since last frame
351        else
352        {
353                // Move about 100 units per second,
354                mMoveScale = mMoveSpeed * evt.timeSinceLastFrame;
355                // Take about 10 seconds for full rotation
356                mRotScale = mRotateSpeed * evt.timeSinceLastFrame;
357        }
358
359        mRotX = 0;
360        mRotY = 0;
361        mTranslateVector = Vector3::ZERO;
362
363        if (!processUnbufferedKeyInput(evt))
364        {
365                return false;
366        }
367        if (!mUseBufferedInputMouse)
368        {
369                if (!processUnbufferedMouseInput(evt))
370                {       
371                        return false;   
372                }
373        }
374
375        //-- set parameters for visualization
376        if (mShowVisualization)
377        {
378                // important for visualization => draw octree bounding boxes
379                mSceneMgr->setOption("ShowOctree", &mShowVisualization);
380               
381                //-- setup visualization camera
382
383                mVizCamera->setPosition(0, 0, 0);
384                mVizCamera->setOrientation(Quaternion::IDENTITY);
385
386                Vector3 camPos = mCamNode->getPosition();
387                mVizCamera->setPosition(camPos.x, mVizCameraHeight, camPos.z);
388
389                // point down -Z axis
390                mVizCamera->pitch(Radian(Degree(270.0)));
391
392                // rotation arounnd X axis
393                mVizCamera->yaw(Math::ATan2(-mCamera->getDerivedDirection().x,
394                        -mCamera->getDerivedDirection().z));
395               
396                // move by a constant so view plane is on bottom of viewport
397                mVizCamera->moveRelative(Vector3(0, 800, 0));
398        }
399        else
400        {
401                // frame start time
402                mTimeFrameStarted = mTimer->getMilliseconds();
403                //Ogre::LogManager::getSingleton().logMessage("Frame started");
404        }
405
406        //-- set application state
407        switch (mAppState)
408        {
409        case REPLAY:
410                /// set the current camera data to loaded frame information
411                setCurrentFrameInfo(evt.timeSinceLastFrame);
412                // HACK for demo
413                //addFrameInfo(mSavedFrameInfo, mCamNode, evt.timeSinceLastFrame);
414                break;
415        case WALKTHROUGH:
416                //-- recording the camera settings per frame
417                if (mRecordFrames)
418                {
419                        addFrameInfo(mFrameInfo, mCamNode, evt.timeSinceLastFrame);
420                        // print recording message
421                        mWindow->setDebugText("Recording frame " +
422                                StringConverter::toString(mFrameInfo.size() - 1));
423                }       
424                // move camera according to input
425                moveCamera();
426
427                // clamp camera so we always walk along the terrain
428                mApplication->Clamp2Terrain(mCamNode, 5);
429                break;
430
431        default:
432                break;
433        };     
434
435        return true;
436}
437//-----------------------------------------------------------------------
438void TerrainFrameListener::applyVisibilityQuery(bool fromPoint, bool relativeVisibility,
439                                                                                                bool useItemBuffer)
440{
441        // TODO: change this (does not work with other scene manager plugins)
442        VisibilityTerrainSceneManager *sm =
443                dynamic_cast<VisibilityTerrainSceneManager *>(mSceneMgr);
444
445        int itemBufferMode = useItemBuffer ? mItemBufferMode : 0;
446       
447        int queryModes = 0;
448        queryModes |= GtpVisibility::QueryManager::PATCH_VISIBILITY;
449        queryModes |= GtpVisibility::QueryManager::GEOMETRY_VISIBILITY;
450        queryModes |= GtpVisibility::QueryManager::NODE_VISIBILITY;
451       
452        mQueryManager = new OcclusionQueriesQueryManager(sm->GetHierarchyInterface(),
453                        mWindow->getViewport(0), queryModes, itemBufferMode);
454
455        //mQueryManager = new PlatformQueryManager(sm->GetHierarchyInterface(), mWindow->getViewport(0), false);
456       
457        sm->GetVisibilityManager()->SetQueryManager(mQueryManager);
458
459        GtpVisibility::NodeInfoContainer visibleNodes;
460        GtpVisibility::MeshInfoContainer visibleGeometry;
461        GtpVisibility::PatchInfoContainer visiblePatches;
462
463
464        if (fromPoint)
465        {
466                mQueryManager->
467                        ComputeFromPointVisibility(mCamNode->getPosition(), &visibleNodes,
468                                                                           &visibleGeometry, &visiblePatches, relativeVisibility);
469        }
470        else
471        {
472                mQueryManager->ComputeCameraVisibility(*mCamera,
473                            &visibleNodes, &visibleGeometry, &visiblePatches, relativeVisibility);
474        }
475               
476        std::stringstream d;
477        d << "Query mode: " << queryModes << ", "
478          << msQueryTypeCaptions[fromPoint ?  1 : 0].c_str() << " "
479          << msQueryRelativeVisCaptions[relativeVisibility ? 1 : 0].c_str() << " "
480      << msQueryMethodCaptions[useItemBuffer ? 1 : 0].c_str();
481        LogManager::getSingleton().logMessage(d.str());
482
483
484        float averageNodeVis = 0, averageGeometryVis = 0, averagePatchVis = 0;
485        int geomSize = 0, nodesSize = 0, patchSize = 0;
486
487        GtpVisibility::MeshInfoContainer::iterator geomIt, geomIt_end = visibleGeometry.end();
488
489        for (geomIt = visibleGeometry.begin(); geomIt != geomIt_end; ++geomIt)
490        {
491                // add if not 0
492                if ((*geomIt).GetVisiblePixels())
493                {
494                        float vis = relativeVisibility ?
495                                (*geomIt).ComputeRelativeVisibility() : (float)(*geomIt).GetVisiblePixels();
496       
497                        averageGeometryVis += vis;
498                        ++ geomSize;
499                       
500                        std::stringstream d;
501                        d << "Geometry " << geomSize << " id: " << (*geomIt).GetSource()->getSubEntity(0)->getId()
502                          << " visibility: "  << (*geomIt).GetVisiblePixels() << ", " << (*geomIt).GetProjectedPixels();
503                        LogManager::getSingleton().logMessage(d.str());
504                }
505        }
506
507        GtpVisibility::NodeInfoContainer::iterator nodesIt, nodesIt_end = visibleNodes.end();
508
509        for (nodesIt = visibleNodes.begin(); nodesIt != nodesIt_end; ++nodesIt)
510        {
511                // add if not 0
512                if ((*nodesIt).GetVisiblePixels())
513                {
514                        float vis = relativeVisibility ?
515                                (*nodesIt).ComputeRelativeVisibility() : (float)(*nodesIt).GetVisiblePixels();
516               
517                        averageNodeVis += vis;
518                        ++ nodesSize;
519
520                        std::stringstream d; d << "Node visibility: " << vis;
521                        LogManager::getSingleton().logMessage(d.str());
522                }       
523        }
524
525        GtpVisibility::PatchInfoContainer::iterator patchIt, patchIt_end = visiblePatches.end();
526
527        for (patchIt = visiblePatches.begin(); patchIt != patchIt_end; ++ patchIt)
528        {
529                // add if not 0
530                if ((*patchIt).GetVisiblePixels())
531                {
532                        float vis = relativeVisibility ?
533                                (*patchIt).ComputeRelativeVisibility() : (float)(*patchIt).GetVisiblePixels();
534               
535                        averagePatchVis += vis;
536                        ++ patchSize;
537
538                        std::stringstream d; d << "Patch visibility: " << vis;
539                        LogManager::getSingleton().logMessage(d.str());
540                }       
541        }
542
543        if (nodesSize)
544                averageNodeVis /= (float)nodesSize;
545        if (geomSize)
546                averageGeometryVis /= (float)geomSize;
547        if (patchSize)
548                averagePatchVis /= (float)patchSize;
549
550        //-- update visibility queries stats
551    try
552        {
553                char str[100];
554               
555                sprintf(str, ": %s, %s, %s",
556                                msQueryTypeCaptions[fromPoint ?  1 : 0].c_str(),
557                                msQueryRelativeVisCaptions[relativeVisibility ? 1 : 0].c_str(),
558                                msQueryMethodCaptions[useItemBuffer ? 1 : 0].c_str());
559
560                mQueryTypeInfo->setCaption(str);
561
562                sprintf(str, ": %d", (int)nodesSize);
563                mQueryVisibleNodesInfo->setCaption(str);
564       
565                sprintf(str,": %d", (int)geomSize);
566                mQueryVisibleGeometryInfo->setCaption(str);
567               
568                sprintf(str,": %d", (int)patchSize);
569                mQueryVisiblePatchInfo->setCaption(str);
570
571                sprintf(str,": %3.3f", averageNodeVis);
572                mQueryNodeVisibilityInfo->setCaption(str);
573
574                sprintf(str,": %3.3f", averageGeometryVis);
575                mQueryGeometryVisibilityInfo->setCaption(str);
576
577                sprintf(str,": %3.3f", averagePatchVis);
578                mQueryPatchVisibilityInfo->setCaption(str);
579        }
580        catch (...)
581        {
582                // ignore
583        }
584
585        // show the results
586        if (!mShowQueryStats && !mShowHelp)
587        {
588                mQueryOverlay->show();
589                mShowQueryStats = true;
590        }
591
592        delete mQueryManager;
593}
594
595
596bool TerrainFrameListener::processUnbufferedMouseInput(const FrameEvent& evt)
597{
598        /* Rotation factors, may not be used if the second mouse button is pressed. */
599
600    /* If the second mouse button is pressed, then the mouse movement results in
601       sliding the camera, otherwise we rotate. */
602    if (mInputDevice->getMouseButton(1))
603    {
604                mTranslateVector.x += mInputDevice->getMouseRelativeX() * 0.13;
605                mTranslateVector.y -= mInputDevice->getMouseRelativeY() * 0.13;
606        }
607        else
608        {
609                mRotX = Degree(-mInputDevice->getMouseRelativeX() * 0.13);
610                mRotY = Degree(-mInputDevice->getMouseRelativeY() * 0.13);
611        }
612
613        return true;
614}
615//-----------------------------------------------------------------------
616bool TerrainFrameListener::frameEnded(const FrameEvent& evt)
617{
618        if (mShutdownRequested)
619                return false;
620
621        // timer end time
622        if (!mShowVisualization)
623        {
624                mTimeFrameEnded = mTimer->getMilliseconds();
625                //Ogre::LogManager::getSingleton().logMessage("Frame ended");
626        }
627
628    updateStats();
629
630        if (mRecordVideo) // record current frame
631        {
632                //Ogre::LogManager::getSingleton().logMessage("taking video frame");
633                takeVideoFrame(video_out);
634                //Ogre::LogManager::getSingleton().logMessage("finished");
635        }
636        //-- IMPORTANT: must be set, otherwise terrain is not rendered correctly
637        mSceneMgr->endFrame();
638
639        if (mTimeDelay <= 0) // simulates approx. one second
640                mTimeDelay = 1.0;
641
642        return true;
643}
644//-----------------------------------------------------------------------
645void TerrainFrameListener::moveCamera()
646{
647        // move node rather than camera so orientation is right in the visualization
648        mCamNode->yaw(mRotX, Ogre::Node::TS_WORLD);
649        //mCamNode->rotate(Vector3(0,1,0), mRotX, Ogre::Node::TS_WORLD);
650        mCamNode->pitch(mRotY);
651
652        mCamNode->translate(mCamNode->getLocalAxes(), mTranslateVector);
653}
654//-----------------------------------------------------------------------
655void TerrainFrameListener::writeFrames()
656{
657        std::ofstream ofstr(frames_out_filename);
658       
659        std::vector<frame_info>::const_iterator it, it_end;
660
661        it_end = mFrameInfo.end();
662        for (it = mFrameInfo.begin(); it < it_end; ++it)
663        {
664                ofstr << StringConverter::toString((*it).position) << " "
665                          << StringConverter::toString((*it).orientation) << " "
666                          << StringConverter::toString((*it).timeElapsed) << " "
667                          << StringConverter::toString((*it).fps) << "\n";
668        }
669        ofstr.close();
670}
671// quick hack
672void TerrainFrameListener::writeNewFrameInfo()
673{
674        std::ofstream ofstr("newframe.out");
675       
676        std::vector<frame_info>::const_iterator it, it_end;
677
678        it_end = mSavedFrameInfo.end();
679        for (it = mSavedFrameInfo.begin(); it < it_end; ++it)
680        {
681                ofstr << StringConverter::toString((*it).position) << " "
682                          << StringConverter::toString((*it).orientation) << " "
683                          << StringConverter::toString((*it).timeElapsed) << " "
684                          << StringConverter::toString((*it).fps) << "\n";
685        }
686        ofstr.close();
687}
688//-----------------------------------------------------------------------
689void TerrainFrameListener::loadFrames()
690{
691        std::ifstream ifstr(frames_out_filename);
692        char line[256];
693        frame_info info;
694
695        // reset current values
696        mFrameInfo.clear();
697        mCurrentFrame = 0;
698       
699        while (!ifstr.eof())
700        {
701                ifstr.getline(line, 256);
702                sscanf(line, "%f %f %f %f %f %f %f %f %f", &info.position.x, &info.position.y, &info.position.z,
703                           &info.orientation.w, &info.orientation.x, &info.orientation.y, &info.orientation.z,
704                           &info.timeElapsed, &info.fps);
705               
706                mFrameInfo.push_back(info);
707               
708                // std::stringstream d; d << StringConverter::toString(info.position) << " " << StringConverter::toString(info.orientation);
709                // LogManager::getSingleton().logMessage(d.str());
710        }
711        ifstr.close();
712}
713//-----------------------------------------------------------------------
714void TerrainFrameListener::nextAppState()
715{
716        mCurrentFrame = 0;
717        int lastState = mAppState;
718
719        // transition to the next state
720        mAppState = (mAppState + 1) % STATE_NUM;
721
722        // if last state was replay state
723        if (lastState == REPLAY)
724        {
725        // reset debug text
726                mWindow->setDebugText("");
727                               
728                // hack for producing demo
729                writeNewFrameInfo();
730                mSavedFrameInfo.clear();
731
732                std::stringstream d;
733                mWalkthroughStats.Print(d, msAlgorithmCaptions[mCurrentAlgorithm]);
734               
735                LogManager::getSingleton().logMessage(d.str());
736        }
737       
738        // replay recorded walkthrough
739        if (mAppState == REPLAY)
740        {
741                // no recording during replay
742                mRecordFrames = false; mWindow->setDebugText("");
743
744                // load recorded walkthrough from disk
745                if (mFrameInfo.size() == 0)
746                {
747                        loadFrames();
748                }
749               
750                // if there are no recorded frames => set next state
751                if (mFrameInfo.size() == 0)
752                {
753                        nextAppState();
754                }
755                else // replay
756                {
757                        mWindow->setDebugText("Replay");
758                       
759                        // reset, because we measure fps stats during walkthrough (warning: average fps broken)
760                        mWindow->resetStatistics();
761                        mWalkthroughStats.Reset();
762
763                        //-- initialise frame data
764                        mReplayTimeElapsed = 0;
765
766                        mCamNode->setPosition(mFrameInfo[0].position);
767                        mCamNode->setOrientation(mFrameInfo[0].orientation);
768                }
769        }
770
771}
772//-----------------------------------------------------------------------
773void TerrainFrameListener::toggleRecord()
774{
775        mRecordFrames = !mRecordFrames;
776
777        if (mRecordFrames)
778        {
779                // starting new recording => clear old frame info
780                mFrameInfo.clear();
781        }
782        else
783        {
784                writeFrames(); // write frame info to file
785                mWindow->setDebugText("");
786        }
787}
788//-----------------------------------------------------------------------
789void TerrainFrameListener::changeThreshold(int incr)
790{
791        mVisibilityThreshold += incr;
792
793        if (mVisibilityThreshold < 0)
794        {
795                mVisibilityThreshold = 0;
796        }
797
798        char str[100]; sprintf(str,": %d", mVisibilityThreshold);
799
800        mSceneMgr->setOption("Threshold", &mVisibilityThreshold);
801        mThresholdInfo->setCaption(str);
802}
803//-----------------------------------------------------------------------
804void TerrainFrameListener::changeAssumedVisibility(int incr)
805{
806        mAssumedVisibility += incr;
807
808        if (mAssumedVisibility < 0)
809        {       
810                mAssumedVisibility = 0;
811        }
812
813        char str[100]; sprintf(str,": %d", mAssumedVisibility);
814
815        mSceneMgr->setOption("AssumedVisibility", &mAssumedVisibility);
816        mAssumedVisibilityInfo->setCaption(str);
817}
818//-----------------------------------------------------------------------
819void TerrainFrameListener::zoomVizCamera(int zoom)
820{
821        mVizCameraHeight += zoom;
822        if(mVizCameraHeight < 0) mVizCameraHeight = 0;
823}
824//-----------------------------------------------------------------------
825void TerrainFrameListener::nextAlgorithm()
826{
827        mCurrentAlgorithm = (mCurrentAlgorithm + 1) %
828                GtpVisibility::VisibilityEnvironment::NUM_CULLING_MANAGERS;
829        setAlgorithm(mCurrentAlgorithm);
830}
831//-----------------------------------------------------------------------
832void TerrainFrameListener::setObjectType(int objectType)
833{
834        if (mCurrentObjectType >= 3) // TODO: define a constant
835                mCurrentObjectType = 0;
836
837        // parameters for new object
838        mTerrainContentGenerator->SetOffset(msObjectTerrainOffsets[mCurrentObjectType]);
839        Real scale = msObjectScales[mCurrentObjectType];
840        mTerrainContentGenerator->SetScale(Vector3(scale, scale, scale));
841
842        mCurrentObjectTypeInfo->setCaption(": " + msObjectCaptions[mCurrentObjectType]);
843}
844//-----------------------------------------------------------------------
845void TerrainFrameListener::setAlgorithm(int algorithm)
846{
847        mAlgorithmInfo->setCaption(": " + msAlgorithmCaptions[mCurrentAlgorithm]);
848        mSceneMgr->setOption("Algorithm", &mCurrentAlgorithm);
849}
850//-----------------------------------------------------------------------
851void TerrainFrameListener::updateStats()
852{
853        unsigned int opt = 0;
854        char str[100];
855       
856        static String currFpsString = "Current FPS: ";
857        static String avgFpsString = "Average FPS: ";
858        static String bestFpsString = "Best FPS: ";
859        static String worstFpsString = "Worst FPS: ";
860        static String trisString = "Triangle Count: ";
861
862        int currentFps = mWindow->getStatistics().lastFPS;
863       
864        // HACK for demo: use precomputed FPS
865        if (mUseDemoFps)
866                currentFps = mDemoFps;
867#if 0
868        // HACK: take pure rendering time, only measures the render call
869        long pureRenderTime = mTimeFrameEnded - mTimeFrameStarted;
870
871        if (pureRenderTime)
872        {
873                mPureRenderTimeFps = 1000.0 / (float) pureRenderTime;
874        }
875        currentFps = mPureRenderRenderTimeFps;
876        //std::stringstream d; d << "Pure render time fps: " << mPureRenderTimeFps << "\n";
877        //Ogre::LogManager::getSingleton().logMessage(d.str());
878#endif
879       
880        unsigned int nodeInfo[3];
881    mSceneMgr->getOption("NumRenderedNodes", nodeInfo);
882        mSceneMgr->getOption("NumQueryCulledNodes", nodeInfo+1);
883        mSceneMgr->getOption("NumFrustumCulledNodes", nodeInfo+2);
884
885
886        mWalkthroughStats.UpdateFrame(currentFps, mWindow->getBestFPS(), mWindow->getWorstFPS(),
887                                                                  (int)mWindow->getTriangleCount(), nodeInfo[0], nodeInfo[1], nodeInfo[2]);
888
889        // HACK: compute average fps ourselfs, because ogre avg. fps is wrong
890        // TODO: update only once per second
891        float avgFps = (float)mWalkthroughStats.mAccFps / (float)(mWalkthroughStats.mFrameCount);
892       
893
894        // update stats when necessary
895    try
896        {
897                OverlayElement* guiAvg = OverlayManager::getSingleton().getOverlayElement("Core/AverageFps");
898                OverlayElement* guiCurr = OverlayManager::getSingleton().getOverlayElement("Core/CurrFps");
899                OverlayElement* guiBest = OverlayManager::getSingleton().getOverlayElement("Core/BestFps");
900                OverlayElement* guiWorst = OverlayManager::getSingleton().getOverlayElement("Core/WorstFps");
901
902                const RenderTarget::FrameStats& stats = mWindow->getStatistics();
903
904                // HACK: take newly computed avg. fps instead of Ogre avg fps and update only once per second
905                if (mTimeDelay < 0)
906                {               
907                        guiAvg->setCaption(avgFpsString + StringConverter::toString(avgFps) + " ms");
908                        //guiCurr->setCaption(currFpsString + StringConverter::toString(currentFps));
909                }
910                //guiAvg->setCaption(avgFps + StringConverter::toString(stats.avgFPS));
911                guiCurr->setCaption(currFpsString + StringConverter::toString(currentFps));
912               
913                //std::stringstream d; d << "frame rate :" << stats.lastFPS;
914                //Ogre::LogManager::getSingleton().logMessage(d.str());
915
916                guiBest->setCaption(bestFpsString + StringConverter::toString(stats.bestFPS)
917                        +" "+StringConverter::toString(stats.bestFrameTime) + " ms");
918                guiWorst->setCaption(worstFpsString + StringConverter::toString(stats.worstFPS)
919                        +" "+StringConverter::toString(stats.worstFrameTime) + " ms");
920
921                OverlayElement* guiTris = OverlayManager::getSingleton().getOverlayElement("Core/NumTris");
922        guiTris->setCaption(trisString + StringConverter::toString(stats.triangleCount));
923               
924                //LogManager::getSingleton().logMessage(StringConverter::toString(stats.triangleCount));
925
926                OverlayElement* guiDbg = OverlayManager::getSingleton().getOverlayElement("Core/DebugText");
927                guiDbg->setCaption(mWindow->getDebugText());
928
929
930                //-- culling stats
931                mSceneMgr->getOption("NumFrustumCulledNodes", &opt); sprintf(str,": %d", opt);
932                mFrustumCulledNodesInfo->setCaption(str);
933
934                mSceneMgr->getOption("NumQueryCulledNodes", &opt); sprintf(str,": %d", opt);
935                mQueryCulledNodesInfo->setCaption(str);
936       
937                mSceneMgr->getOption("NumHierarchyNodes", &opt); sprintf(str,": %d", opt);
938                mHierarchyNodesInfo->setCaption(str);
939
940                mSceneMgr->getOption("NumRenderedNodes", &opt); sprintf(str,": %d", opt);
941                mRenderedNodesInfo->setCaption(str);
942
943                sprintf(str,": %d", mTerrainContentGenerator->GetObjectCount());
944                mObjectsCountInfo->setCaption(str);
945
946                // take old value into account in order to create no sudden changes
947                mSceneMgr->getOption("NumQueriesIssued", &opt);
948                mDelayedQueriesIssued = mDelayedQueriesIssued * 0.8 + (float)opt * 0.2;
949                sprintf(str,": %d", (int)mDelayedQueriesIssued);
950                mQueriesIssuedInfo->setCaption(str);
951
952                mSceneMgr->getOption("NumTraversedNodes", &opt);
953                mDelayedTraversedNodes = mDelayedTraversedNodes * 0.8 + (float)opt * 0.2;
954                sprintf(str,": %d", (int)mDelayedTraversedNodes);
955                mTraversedNodesInfo->setCaption(str);
956
957        }
958        catch (...)
959        {
960                // ignore
961        }
962}
963//-----------------------------------------------------------------------
964void TerrainFrameListener::setTestGeometryForVisibleLeaves(bool testGeometryForVisibleLeaves)
965{
966        mSceneMgr->setOption("TestGeometryForVisibleLeaves", &mTestGeometryForVisibleLeaves);
967       
968        /* disable optimization which tests geometry instead of aabb
969         * for "delayed" rendering of transparents (i.e., render transparents after all the solids)
970         * because otherwise visible transparents could be skipped
971         */
972        bool delayedRendering = !mTestGeometryForVisibleLeaves;
973
974        mSceneMgr->setOption("DelayRenderTransparents", &delayedRendering);
975
976        if (mTestGeometryForVisibleLeaves)
977        {
978                mTestGeometryForVisibleLeavesInfo->setCaption(": true");
979        }
980        else
981        {
982                mTestGeometryForVisibleLeavesInfo->setCaption(": false");
983        }
984}
985//-----------------------------------------------------------------------
986void TerrainFrameListener::toggleShowOctree()
987{
988        mShowOctree = !mShowOctree;
989
990        mSceneMgr->setOption("ShowOctree", &mShowOctree);
991}
992//-----------------------------------------------------------------------
993void TerrainFrameListener::toggleUseDepthPass()
994{
995        mUseDepthPass = !mUseDepthPass;
996
997        mSceneMgr->setOption("UseDepthPass", &mUseDepthPass);
998       
999        if (mUseDepthPass)
1000        {
1001                mUseDepthPassInfo->setCaption(": true");
1002        }
1003        else
1004        {
1005                mUseDepthPassInfo->setCaption(": false");
1006        }
1007}
1008//-----------------------------------------------------------------------
1009void TerrainFrameListener::toggleUseArbQueries()
1010{
1011        mUseArbQueries = !mUseArbQueries;
1012
1013        mSceneMgr->setOption("UseArbQueries", &mUseArbQueries);
1014       
1015        if (mUseArbQueries)
1016        {
1017                mUseArbQueriesInfo->setCaption(": ARB");
1018        }
1019        else
1020        {
1021                mUseArbQueriesInfo->setCaption(": NV");
1022        }
1023}
1024//-----------------------------------------------------------------------
1025void TerrainFrameListener::toggleShowViz()
1026{
1027        mVisualizeCulledNodes = mShowVisualization = !mShowVisualization;
1028       
1029        // create viewport with priority VIZ_VIEWPORT_Z_ORDER:
1030        // will be rendered over standard viewport
1031        if (mShowVisualization)
1032        {       
1033                Viewport *vizvp = mWindow->addViewport(mVizCamera,
1034                        VIZ_VIEWPORT_Z_ORDER, 0.6, 0.6, 0.4, 0.4);
1035                               
1036                vizvp->setBackgroundColour(ColourValue(0.0, 0.3, 0.2, 1));
1037
1038                vizvp->setOverlaysEnabled(false);
1039                // Alter the camera aspect ratio to match the viewport
1040        mVizCamera->setAspectRatio(Real(vizvp->getActualWidth()) /
1041                                                                   Real(vizvp->getActualHeight()));
1042               
1043                mSceneMgr->setOption("VisualizeCulledNodes", &mVisualizeCulledNodes);
1044                //vizvp->setClearEveryFrame(false);
1045
1046                // Create a skyplane (for visualization background)
1047                /*
1048                Plane plane;
1049                plane.d = -1000;
1050                plane.normal = Vector3::UNIT_Y;
1051                mSceneMgr->setSkyPlane(true, plane, "Examples/TransparentTest", 4000, 75, false);
1052                */
1053        }
1054        else
1055        {
1056                // remove visualization viewport
1057                mWindow->removeViewport(VIZ_VIEWPORT_Z_ORDER);
1058
1059                // octree bounding boxes are shown for visualization purpose, reset now
1060                mSceneMgr->setOption("ShowOctree", &mShowOctree);
1061        }
1062}
1063//-----------------------------------------------------------------------
1064void TerrainFrameListener::toggleShowShadows()
1065{
1066        mShowShadows = !mShowShadows;
1067
1068        mSunLight->setCastShadows(mShowShadows);
1069
1070        if (mShowShadows)
1071        {
1072                mSceneMgr->setShadowTechnique(SHADOWTYPE_TEXTURE_MODULATIVE);
1073                //mSceneMgr->setShadowTechnique(SHADOWTYPE_STENCIL_MODULATIVE);
1074                //mSceneMgr->setShadowTechnique(SHADOWTYPE_STENCIL_ADDITIVE);           
1075        }
1076        else
1077        {
1078                mSceneMgr->setShadowTechnique(SHADOWTYPE_NONE);
1079        }
1080
1081}
1082//-----------------------------------------------------------------------
1083void TerrainFrameListener::nextNodeVizMode()
1084{
1085        mNodeVizMode = (mNodeVizMode + 1) % NODEVIZ_MODES_NUM;
1086
1087        bool renderNodesForViz = (mNodeVizMode == NODEVIZ_RENDER_NODES) ||
1088                (mNodeVizMode == NODEVIZ_RENDER_NODES_AND_CONTENT);
1089        bool renderNodesContentForViz = (mNodeVizMode == NODEVIZ_RENDER_NODES_AND_CONTENT);
1090        //bool renderNodesContentForViz = mNodeVizMode == NODEVIZ_RENDER_GEOMETRY;
1091
1092        mSceneMgr->setOption("RenderNodesForViz", &renderNodesForViz);
1093        mSceneMgr->setOption("RenderNodesContentForViz", &renderNodesContentForViz);
1094}
1095//-----------------------------------------------------------------------
1096void TerrainFrameListener::keyPressed(KeyEvent* e)
1097{
1098        // hide exact visibility query overlay
1099        if (mShowQueryStats)
1100        {
1101                mQueryOverlay->hide();
1102                mShowQueryStats = false;
1103        }
1104
1105        switch(e->getKey())
1106        {
1107        case KC_ESCAPE:
1108                mShutdownRequested = true;
1109                e->consume();
1110                return;
1111
1112        case KC_SPACE:
1113                nextAlgorithm();
1114                break;
1115       
1116    case KC_F:
1117                nextFilter();
1118                break;
1119        case KC_R:
1120                nextSceneDetailLevel();
1121                break;
1122        case KC_P:
1123                toggleDisplayCameraDetails();
1124                break;
1125        case KC_G:
1126                mTestGeometryForVisibleLeaves = !mTestGeometryForVisibleLeaves;
1127                setTestGeometryForVisibleLeaves(mTestGeometryForVisibleLeaves);
1128                break;
1129        case KC_T:
1130                toggleShowOctree();
1131                break;
1132        case KC_X:
1133                toggleUseDepthPass();
1134                break;
1135        case KC_H:
1136                toggleShowShadows();
1137                break;
1138
1139        case KC_I:
1140                mUseItemBuffer = !mUseItemBuffer;
1141                break;
1142
1143        case KC_C:
1144
1145                if (mItemBufferMode != GtpVisibility::QueryManager::GEOMETRY_VISIBILITY)
1146                        mItemBufferMode = GtpVisibility::QueryManager::GEOMETRY_VISIBILITY;
1147                else
1148                        mItemBufferMode = GtpVisibility::QueryManager::PATCH_VISIBILITY;
1149
1150                break;
1151
1152        case KC_SUBTRACT:
1153                changeThreshold(-10);
1154                break;
1155        case KC_ADD:
1156                changeThreshold(10);
1157                break;
1158
1159        //-- visualization
1160        case KC_1:
1161                toggleShowViz();
1162                break;
1163        case KC_2:
1164                nextNodeVizMode();
1165                break;
1166
1167        case KC_F1:
1168                toggleShowHelp();
1169                break;
1170        case KC_F2:
1171                mStatsOn = !mStatsOn;
1172                showStats(mStatsOn);
1173                break;
1174        case KC_F3:
1175                nextAppState();
1176                break;
1177        case KC_F4:
1178                toggleRecord();
1179                break;
1180        case KC_F5:
1181                applyVisibilityQuery(false, mShiftPressed, mUseItemBuffer);
1182                break;
1183        case KC_F6:
1184                applyVisibilityQuery(true, mShiftPressed, mUseItemBuffer);
1185                break;
1186       
1187        case KC_F7:
1188                setObjectType(++mCurrentObjectType);
1189                break;
1190        case KC_F8:
1191                mApplication->generateScene(500, mCurrentObjectType);
1192                break;
1193        case KC_F9:
1194                mUseAnimation = !mUseAnimation;
1195                break;
1196
1197        case KC_F10:
1198                mRecordVideo = !mRecordVideo;
1199                       
1200        case KC_F11:
1201                takeScreenshot();
1202                break;
1203        case KC_F12:
1204                mTerrainContentGenerator->WriteObjects(objects_out_filename);
1205                break;
1206
1207        case KC_8:
1208                changeAssumedVisibility(-1);
1209                break;
1210        case KC_9:
1211                changeAssumedVisibility(1);
1212                break;
1213        case KC_LSHIFT:
1214                mShiftPressed = true;
1215                break;
1216        case KC_DELETE:
1217                mDeleteObjects = true;
1218                break;
1219        case KC_M: // hack
1220                mUseDemoFps = !mUseDemoFps;
1221                break;
1222        case KC_Q:
1223                toggleUseArbQueries();
1224                break;
1225        case KC_O:
1226                switchMouseMode();
1227                break;
1228        //KEY_PRESSED(KC_F3, 0.3, writeFrames());
1229        //KEY_PRESSED(KC_F4, 0.3, loadFrames());
1230        default:
1231                break;
1232        }
1233
1234        CEGUI::System::getSingleton().injectKeyDown(e->getKey());
1235        CEGUI::System::getSingleton().injectChar(e->getKeyChar());
1236        e->consume();
1237}
1238//-----------------------------------------------------------------------
1239void TerrainFrameListener::keyReleased(KeyEvent* e)
1240{
1241        if (e->getKey() == KC_LSHIFT)
1242        {
1243                mShiftPressed = false;
1244        }
1245       
1246        CEGUI::System::getSingleton().injectKeyUp(e->getKey());
1247        e->consume();
1248}
1249//-----------------------------------------------------------------------
1250void TerrainFrameListener::keyClicked(KeyEvent* e)
1251{
1252        // Do nothing
1253        e->consume();
1254}
1255//-----------------------------------------------------------------------
1256void TerrainFrameListener::addFrameInfo(FrameInfoContainer &frameInfos, SceneNode *camNode, Real timeElapsed)
1257{
1258        frame_info info;
1259
1260        info.orientation = mCamNode->getOrientation();
1261        info.position = mCamNode->getPosition();
1262        info.timeElapsed = timeElapsed;
1263        info.fps = mWindow->getStatistics().lastFPS;
1264
1265        frameInfos.push_back(info);
1266}
1267//-----------------------------------------------------------------------
1268void TerrainFrameListener::setCurrentFrameInfo(Real timeElapsed)
1269{
1270        //-- find current frame relative to elapsed frame time         
1271        mReplayTimeElapsed -= timeElapsed;
1272       
1273        while ((mReplayTimeElapsed <= 0) && (mCurrentFrame < (int)mFrameInfo.size() - 1))
1274        {
1275                mReplayTimeElapsed += mFrameInfo[mCurrentFrame ++].timeElapsed;
1276        }
1277
1278
1279        // TODO: crashes here if recording / replaying on the same time!!
1280        frame_info new_frame = mFrameInfo[mCurrentFrame];
1281        frame_info old_frame = mFrameInfo[mCurrentFrame - 1];
1282               
1283        //-- interpolate frames
1284        Real factor = 1;
1285
1286        if (old_frame.timeElapsed > 0)
1287        {
1288                factor = mReplayTimeElapsed / old_frame.timeElapsed;
1289        }
1290
1291        Vector3 camPos = old_frame.position + factor
1292                * (new_frame.position - old_frame.position);
1293
1294        // interpolate the orientation
1295        Quaternion camOrienation = Quaternion::Slerp(factor, old_frame.orientation,
1296                new_frame.orientation, true);
1297
1298        // HACK: interpolate fps
1299        mDemoFps = old_frame.fps + factor * (new_frame.fps -old_frame.fps);
1300
1301        mCamNode->setPosition(camPos);
1302        mCamNode->setOrientation(camOrienation);
1303       
1304        // stop replaying after one full walkthrough
1305        if (mCurrentFrame == (int)mFrameInfo.size() - 1)
1306        {
1307                nextAppState();
1308        }
1309}
1310//-----------------------------------------------------------------------   
1311bool TerrainFrameListener::processUnbufferedKeyInput(const FrameEvent& evt)
1312{
1313        bool cursorPressed = false;
1314       
1315        /* Move camera forward by keypress. */
1316    if (mInputDevice->isKeyDown(KC_UP) || mInputDevice->isKeyDown(KC_W))
1317        {
1318                mTranslateVector.z = -mMoveScale;
1319                cursorPressed = true;
1320        }
1321    /* Move camera backward by keypress. */
1322    if (mInputDevice->isKeyDown(KC_DOWN) || mInputDevice->isKeyDown(KC_S))
1323    {
1324                mTranslateVector.z = mMoveScale;
1325                cursorPressed = true;
1326    }
1327
1328        if (mInputDevice->isKeyDown(KC_A))
1329        {
1330                mTranslateVector.x -= mMoveScale;
1331                mTranslateVector.y += mMoveScale;
1332
1333                cursorPressed = true;
1334        }
1335
1336        if (mInputDevice->isKeyDown(KC_D))
1337        {
1338                mTranslateVector.x += mMoveScale;
1339                mTranslateVector.y -= mMoveScale;
1340
1341                cursorPressed = true;
1342        }
1343
1344    if (mInputDevice->isKeyDown(KC_RIGHT))
1345    {
1346        mCamNode->yaw(-mRotScale);
1347                cursorPressed = true;
1348    }
1349
1350    if (mInputDevice->isKeyDown(KC_LEFT))
1351    {
1352        mCamNode->yaw(mRotScale);
1353                cursorPressed = true;
1354    }
1355        // visualization camera
1356        if (mInputDevice->isKeyDown(KC_3))
1357        {
1358                zoomVizCamera(50);
1359        }
1360        if (mInputDevice->isKeyDown(KC_4))
1361        {
1362                zoomVizCamera(-50);
1363        }
1364
1365        // show the results
1366        if (cursorPressed && mShowQueryStats)
1367        {
1368                mQueryOverlay->hide();
1369                mShowQueryStats = false;
1370        }
1371
1372    // Return true to continue rendering
1373    return true;
1374}
1375//-----------------------------------------------------------------------
1376void TerrainFrameListener::nextFilter()
1377{
1378        switch (mFiltering)
1379        {
1380        case TFO_BILINEAR:
1381                mFiltering = TFO_TRILINEAR;
1382                mAniso = 1;
1383                break;
1384        case TFO_TRILINEAR:
1385                mFiltering = TFO_ANISOTROPIC;
1386                mAniso = 8;
1387                break;
1388        case TFO_ANISOTROPIC:
1389                mFiltering = TFO_BILINEAR;
1390                mAniso = 1;
1391                break;
1392        default:
1393                break;
1394        }
1395
1396    MaterialManager::getSingleton().setDefaultTextureFiltering(mFiltering);
1397    MaterialManager::getSingleton().setDefaultAnisotropy(mAniso);
1398
1399        // reload stats
1400    showStats(mStatsOn);
1401}
1402//-----------------------------------------------------------------------
1403void TerrainFrameListener::nextSceneDetailLevel()
1404{
1405        mSceneDetailIndex = (mSceneDetailIndex + 1) % 3;
1406        switch (mSceneDetailIndex)
1407        {
1408                case 0:
1409                        mCamera->setDetailLevel(SDL_SOLID);
1410                        break;
1411                case 1:
1412                        mCamera->setDetailLevel(SDL_WIREFRAME);
1413                        break;
1414                case 2:
1415                        mCamera->setDetailLevel(SDL_POINTS);
1416                        break;
1417        }
1418}
1419//-----------------------------------------------------------------------
1420void TerrainFrameListener::takeVideoFrame(std::ofstream &ofstr)
1421{
1422        char name[50];
1423
1424        sprintf(name, "frame_%05d.tga", ++mNumVideoFrames);
1425    mWindow->writeContentsToFile(name);
1426    //mWindow->setDebugText(String("Wrote ") + name);
1427
1428        ofstr << name << "\n";
1429}
1430//-----------------------------------------------------------------------
1431void TerrainFrameListener::takeScreenshot()
1432{
1433        char name[50];
1434
1435        sprintf(name, "screenshot_%05d.png", ++mNumScreenShots);
1436    mWindow->writeContentsToFile(name);
1437    //mWindow->setDebugText(String("Wrote ") + name);
1438}
1439//-----------------------------------------------------------------------
1440void TerrainFrameListener::toggleDisplayCameraDetails()
1441{
1442        mDisplayCameraDetails = !mDisplayCameraDetails;
1443       
1444    if (!mDisplayCameraDetails)
1445        {
1446                mWindow->setDebugText("");
1447        }
1448}
1449//-----------------------------------------------------------------------
1450void TerrainFrameListener::showStats(bool show)
1451{
1452        if (mDebugOverlay && mCullStatsOverlay)
1453        {
1454                if (show)
1455                {
1456                        mDebugOverlay->show();
1457                        mCullStatsOverlay->show();
1458                }
1459                else
1460                {
1461                        mDebugOverlay->hide();
1462                        mCullStatsOverlay->hide();
1463                }
1464        }
1465}
1466
1467//-----------------------------------------------------------------------
1468void TerrainFrameListener::toggleShowHelp()
1469{
1470        mShowHelp = !mShowHelp;
1471
1472        if (mShowHelp)
1473        {
1474                mHelpOverlay->show();
1475        }
1476        else
1477        {
1478                mHelpOverlay->hide();
1479        }
1480}
1481//-----------------------------------------------------------------------
1482void TerrainFrameListener::initOverlayElement(OverlayElement **elInfo, String ext,
1483                                                                                          String name, int top, String caption)
1484{
1485        OverlayElement *el =
1486                OverlayManager::getSingleton().getOverlayElement(ext + name);
1487
1488        (*elInfo) = OverlayManager::getSingleton().getOverlayElement(ext + name + "Info");
1489        (*elInfo)->setCaption(caption);
1490
1491        el->setTop(top);
1492        (*elInfo)->setTop(top);
1493}
1494//-----------------------------------------------------------------------
1495void TerrainFrameListener::initHelpOverlayElement(String name, int top)
1496{
1497        OverlayElement *el = OverlayManager::getSingleton().getOverlayElement(
1498                "Example/Visibility/Help/" + name);
1499
1500        el->setTop(top);
1501}
1502//-----------------------------------------------------------------------
1503void TerrainFrameListener::initHelpOverlay()
1504{
1505        const int vert_space = 15;
1506        int top = 30;
1507
1508        initHelpOverlayElement("ShowHelp", top); top += vert_space;
1509        initHelpOverlayElement("Stats", top); top += vert_space;
1510        initHelpOverlayElement("AppState", top); top += vert_space;
1511        initHelpOverlayElement("Recorded", top); top += vert_space;
1512        initHelpOverlayElement("Animation", top); top += vert_space;
1513        initHelpOverlayElement("Video", top); top += vert_space;
1514        initHelpOverlayElement("Screenshots", top); top += vert_space;
1515        initHelpOverlayElement("WriteOut", top); top += vert_space;
1516
1517
1518        top +=vert_space;
1519        initHelpOverlayElement("SceneDetail", top); top += vert_space;
1520        initHelpOverlayElement("DisplayCameraDetails", top); top += vert_space;
1521        initHelpOverlayElement("DisplayOctree", top); top += vert_space;
1522        initHelpOverlayElement("UseShadows", top); top += vert_space;
1523        initHelpOverlayElement("Filter", top); top += vert_space;
1524
1525        //-- visualization
1526        top += vert_space;
1527        initHelpOverlayElement("VizSection", top); top += vert_space;
1528        initHelpOverlayElement("Viz", top); top += vert_space;
1529        initHelpOverlayElement("NextVizMode", top); top += vert_space;
1530        initHelpOverlayElement("ZoomViz", top); top += vert_space;
1531
1532
1533        //-- visibility queries
1534        top += vert_space;
1535        initHelpOverlayElement("VisQuery", top); top += vert_space;
1536        initHelpOverlayElement("FromCameraQuery", top); top += vert_space;
1537        initHelpOverlayElement("FromPointQuery", top); top += vert_space;
1538        initHelpOverlayElement("QueryType", top); top += vert_space;
1539        initHelpOverlayElement("QueryTarget", top); top += vert_space;
1540
1541        //-- object generation
1542        top += vert_space;
1543        initHelpOverlayElement("SceneObjects", top); top += vert_space;
1544        initHelpOverlayElement("PlaceObjects", top); top += vert_space;
1545        initHelpOverlayElement("GenerateObjects", top); top += vert_space;
1546        initHelpOverlayElement("RemoveObjects", top); top += vert_space;
1547        initHelpOverlayElement("DropObject", top); top += vert_space;
1548
1549        OverlayElement *helpPanel = OverlayManager::getSingleton().getOverlayElement(
1550                "Example/Visibility/Help/HelpPanel");
1551
1552        helpPanel->setHeight(top + 10);
1553}
1554//-----------------------------------------------------------------------
1555void TerrainFrameListener::initVisStatsOverlay()
1556{
1557        const int border_height = 10;
1558        const int vert_space = 15;
1559
1560        //-- visibility culling stats overlay
1561        int top = border_height;
1562
1563        String ext = "Example/Visibility/";
1564       
1565        initOverlayElement(&mAlgorithmInfo, ext, "Algorithm", top,
1566                ": " + msAlgorithmCaptions[mCurrentAlgorithm]); top += vert_space;
1567
1568        initOverlayElement(&mThresholdInfo, ext, "Threshold", top, ": 0"); top += vert_space;
1569        initOverlayElement(&mTestGeometryForVisibleLeavesInfo, ext,
1570                "TestGeometryForVisibleLeaves", top, ": true"); top += vert_space;
1571        initOverlayElement(&mUseDepthPassInfo, ext, "UseDepthPass", top, ": false"); top += vert_space;
1572        initOverlayElement(&mAssumedVisibilityInfo, ext, "AssumedVisibility", top, ": 0"); top += vert_space;
1573        initOverlayElement(&mCurrentObjectTypeInfo, ext, "CurrentObjectType", top, ": "); top += vert_space;
1574        initOverlayElement(&mUseArbQueriesInfo, ext, "UseArbQueries", top, ": NV"); top += vert_space;
1575        //initOverlayElement(&mHelpInfo, ext, "Help", top, ": "); top += vert_space;
1576
1577        OverlayElement *optionsPanel = OverlayManager::getSingleton().
1578                getOverlayElement("Example/Visibility/VisibilityPanel");
1579
1580        optionsPanel->setHeight(top + border_height);
1581
1582        top = border_height;
1583        //ext = "Example/Visibility/";
1584        initOverlayElement(&mFrustumCulledNodesInfo, ext, "FrustumCulledNodes", top, ": 0"); top += vert_space;
1585        initOverlayElement(&mQueryCulledNodesInfo, ext, "QueryCulledNodes", top, ": 0"); top += vert_space;
1586        initOverlayElement(&mTraversedNodesInfo, ext, "TraversedNodes", top, ": 0"); top += vert_space;
1587        initOverlayElement(&mHierarchyNodesInfo, ext, "HierarchyNodes", top, ": 0"); top += vert_space;
1588        initOverlayElement(&mRenderedNodesInfo, ext, "RenderedNodes", top, ": 0"); top += vert_space;
1589        initOverlayElement(&mObjectsCountInfo, ext, "ObjectsCount", top, ": 0"); top += vert_space;
1590        initOverlayElement(&mQueriesIssuedInfo, ext, "QueriesIssued", top, ": 0"); top += vert_space;
1591
1592        OverlayElement *visPanel = OverlayManager::getSingleton().
1593                getOverlayElement("Example/Visibility/VisibilityStatsPanel");
1594
1595        visPanel->setHeight(top + border_height);
1596}
1597//-----------------------------------------------------------------------
1598void TerrainFrameListener::initQueryOverlay()
1599{
1600        const int border_height = 10;
1601        const int vert_space = 15;
1602
1603        //-- visibility culling stats overlay
1604        int top = border_height + 25;
1605
1606        String ext = "Example/Visibility/Query/";
1607           
1608        initOverlayElement(&mQueryTypeInfo , ext, "QueryType", top,     ": 0"); top += vert_space;
1609       
1610        initOverlayElement(&mQueryVisibleNodesInfo , ext, "VisibleNodes", top,  ": 0"); top += vert_space;
1611        initOverlayElement(&mQueryVisibleGeometryInfo , ext, "VisibleGeometry", top,    ": 0"); top += vert_space;
1612        initOverlayElement(&mQueryVisiblePatchInfo , ext, "VisiblePatches", top,        ": 0"); top += vert_space;
1613       
1614        initOverlayElement(&mQueryNodeVisibilityInfo , ext, "NodeVisibility", top,      ": 0"); top += vert_space;
1615        initOverlayElement(&mQueryGeometryVisibilityInfo , ext, "GeometryVisibility", top,      ": 0"); top += vert_space;
1616        initOverlayElement(&mQueryPatchVisibilityInfo , ext, "PatchVisibility", top,    ": 0"); top += vert_space;
1617
1618
1619        OverlayElement *queryPanel = OverlayManager::getSingleton().
1620                getOverlayElement("Example/Visibility/Query/QueryPanel");
1621
1622        queryPanel->setHeight(top + border_height);
1623}
Note: See TracBrowser for help on using the repository browser.