source: trunk/VUT/work/TestCullingTerrain/TestCullingTerrainApplication.cpp @ 98

Revision 98, 16.2 KB checked in by mattausch, 19 years ago (diff)
RevLine 
[61]1/**
2    \file
3        TestCullingTerrainApplication.cpp
4    \brief
[74]5        Tests the visibility culling algorithm
[61]6*/
7
8#include <OgreNoMemoryMacros.h>
9#include <CEGUI/CEGUI.h>
10#include <../CEGUIRenderer/include/OgreCEGUIRenderer.h>
11#include <../CEGUIRenderer/include/OgreCEGUIResourceProvider.h>
12#include <../CEGUIRenderer/include/OgreCEGUITexture.h>
13#include <OgreMemoryMacros.h>
14
15#include "Ogre.h"
16#include "TestCullingTerrainApplication.h"
17
18#define WIN32_LEAN_AND_MEAN
[94]19#include <windows.h>
[61]20
21
[80]22/*******************************************************/
23/*     TestCullingTerrainApplication implementation    */
24/*******************************************************/
[61]25TestCullingTerrainApplication::~TestCullingTerrainApplication()
26{
[93]27        if(mTerrainContentGenerator)
28                delete mTerrainContentGenerator;
[61]29}
30//-----------------------------------------------------------------------
[93]31void TestCullingTerrainApplication::createCamera()
[61]32{
33        // Create the camera
[94]34        mCamera = mSceneMgr->createCamera("CullCamera");
[93]35       
36        // Set a nice viewpoint
37        mCamera->setPosition(707, 2500, 528);
38        mCamera->setOrientation(Quaternion(-0.3486, 0.0122, 0.9365, 0.0329));
39       
40        //--create cull camera
[94]41        mVisualizationCamera = mSceneMgr->createCamera("VisualizationCamera");
42        mVisualizationCamera->setPosition(707, 2500, 528);
43        mVisualizationCamera->setOrientation(Quaternion(-0.3486, 0.0122, 0.9365, 0.0329));
[61]44
[94]45        mVisualizationCamera->setNearClipDistance(1);
[93]46        mCamera->setNearClipDistance(1);
[61]47
[93]48        // Infinite far plane?
49        if (mRoot->getRenderSystem()->getCapabilities()->hasCapability(RSC_INFINITE_FAR_PLANE))
50        {
[94]51                mVisualizationCamera->setFarClipDistance(0);
[93]52                mCamera->setFarClipDistance(0);
53        }
54        else
55        {
[94]56                 mVisualizationCamera->setFarClipDistance(1000);
[93]57                 mCamera->setFarClipDistance(1000);
58        }
59       
[61]60}
61//-----------------------------------------------------------------------
[75]62void TestCullingTerrainApplication::createScene()
[61]63{
64        // Set ambient light
65        mSceneMgr->setAmbientLight(ColourValue(0.5, 0.5, 0.5));
66       
67        // Create a light
68        Light* l = mSceneMgr->createLight("MainLight");
69        // Accept default settings: point light, white diffuse, just set position
70        // NB I could attach the light to a SceneNode if I wanted it to move automatically with
71        //  other objects, but I don't
72        l->setPosition(20,80,50);
73
74        // --Fog
75        // NB it's VERY important to set this before calling setWorldGeometry
76        // because the vertex program picked will be different
77        ColourValue fadeColour(0.93, 0.86, 0.76);
78        mWindow->getViewport(0)->setBackgroundColour(fadeColour);
79        //mSceneMgr->setFog( FOG_LINEAR, fadeColour, .001, 500, 1000);
[94]80       
[61]81        // Create a skybox
[98]82    mSceneMgr->setSkyBox(true, "Examples/SpaceSkyBox", 3500, false);
[61]83        //mSceneMgr->setSkyDome( true, "Examples/CloudySky", 5, 8, 500, false );
84
85        std::string terrain_cfg("terrain.cfg");
86#if OGRE_PLATFORM == OGRE_PLATFORM_APPLE
87        terrain_cfg = mResourcePath + terrain_cfg;
88#endif
[74]89        mSceneMgr->setWorldGeometry(terrain_cfg);
[75]90       
[61]91        // CEGUI setup
92        setupGui();
[80]93        // HACK: necessary to call once before the content creation for
94        // terrain initialisation
95        mSceneMgr->_renderScene(mCamera, mWindow->getViewport(0), true);
[74]96
[82]97        mTerrainContentGenerator = new TerrainContentGenerator(mSceneMgr);
[87]98//      mTerrainContentGenerator->GenerateScene(500, "ninja.mesh");
[98]99        mTerrainContentGenerator->SetMaxPos(Vector3(3000.0f, 5000.0f, 3000.0f));
100        mTerrainContentGenerator->GenerateScene(1500, "robot.mesh");
[86]101
[84]102        // no limitations needed anymore: the user can set
103        // objects also on peaks of terrain
[82]104        mTerrainContentGenerator->SetMaxHeight(5000);
[61]105}
106//-----------------------------------------------------------------------
[80]107void TestCullingTerrainApplication::setupGui()
[61]108{
[75]109         mGUIRenderer = new CEGUI::OgreCEGUIRenderer(mWindow, Ogre::RENDER_QUEUE_OVERLAY,
110                 false, 3000, ST_EXTERIOR_CLOSE);
[61]111     mGUISystem = new CEGUI::System(mGUIRenderer);
112
113         // Mouse
114     CEGUI::SchemeManager::getSingleton().loadScheme((CEGUI::utf8*)"TaharezLook.scheme");
115     CEGUI::MouseCursor::getSingleton().setImage("TaharezLook", "MouseArrow");
116         mGUISystem->setDefaultMouseCursor(
117                (CEGUI::utf8*)"TaharezLook", (CEGUI::utf8*)"MouseArrow");
118
[75]119         CEGUI::MouseCursor::getSingleton().show();
[61]120}
121//-----------------------------------------------------------------------
[80]122void TestCullingTerrainApplication::createFrameListener()
[61]123{
[80]124        mFrameListener= new MouseQueryListener(mWindow, mCamera, mSceneMgr,
[94]125                mGUIRenderer, mTerrainContentGenerator, mVisualizationCamera);
[61]126        mFrameListener->showDebugOverlay(true);
127        mRoot->addFrameListener(mFrameListener);
128}
129//-----------------------------------------------------------------------
[80]130void TestCullingTerrainApplication::chooseSceneManager()
[61]131{
132        mSceneMgr = mRoot->getSceneManager(ST_EXTERIOR_CLOSE);
133}
134/***********************************************/
[80]135/*      MouseQueryListener implementation      */
[61]136/***********************************************/
137//-----------------------------------------------------------------------
[75]138MouseQueryListener::MouseQueryListener(RenderWindow* win, Camera* cam,
139                                                                           SceneManager *sceneManager,
[80]140                                                                           CEGUI::Renderer *renderer,
[93]141                                                                           TerrainContentGenerator *sceneGenerator,
[94]142                                                                           Camera *vizCamera):
[86]143ExampleFrameListener(win, cam, false, true),
144mGUIRenderer(renderer),
145mShutdownRequested(false),
146mLMouseDown(false),
147mRMouseDown(false),
148mSceneMgr(sceneManager),
149mCurrentObject(NULL),
150mTerrainContentGenerator(sceneGenerator),
151mVisibilityThreshold(0),
[87]152mCurrentAlgorithm(GtpVisibility::VisibilityEnvironment::COHERENT_HIERARCHICAL_CULLING),
[93]153mShowOctree(false),
154mUseCulling(true),
[94]155mUseOptimization(true),
[93]156mUseCullCamera(false),
[94]157mVisualizationCamera(vizCamera)
[61]158{
[86]159        // Reduce move speed
[61]160        mMoveSpeed = 50;
161        mRotateSpeed *= 2;
162   
163        // Register this so that we get mouse events.
164        mEventProcessor->addMouseListener(this);
165        mEventProcessor->addMouseMotionListener(this);
166        mEventProcessor->addKeyListener(this);
167
[74]168        mRayQueryExecutor = new RayQueryExecutor(mSceneMgr);
[75]169       
[61]170        // show overlay
171        Overlay* pOver = OverlayManager::getSingleton().getByName("Example/VisibilityDemoOverlay");
172
[74]173        mAlgorithmInfo = OverlayManager::getSingleton().getOverlayElement("Example/Visibility/AlgorithmInfo");
174        mThresholdInfo = OverlayManager::getSingleton().getOverlayElement("Example/Visibility/ThresholdInfo");
[84]175       
[74]176        mFrustumCulledNodesInfo = OverlayManager::getSingleton().getOverlayElement("Example/Visibility/FrustumCulledNodesInfo");
177        mQueryCulledNodesInfo = OverlayManager::getSingleton().getOverlayElement("Example/Visibility/QueryCulledNodesInfo");
178    mTraversedNodesInfo = OverlayManager::getSingleton().getOverlayElement("Example/Visibility/TraversedNodesInfo");
179        mHierarchyNodesInfo = OverlayManager::getSingleton().getOverlayElement("Example/Visibility/HierarchyNodesInfo");
180        mRenderedNodesInfo = OverlayManager::getSingleton().getOverlayElement("Example/Visibility/RenderedNodesInfo");
[87]181        mObjectsInfo = OverlayManager::getSingleton().getOverlayElement("Example/Visibility/ObjectsInfo");
[86]182        mUseOptimizationInfo = OverlayManager::getSingleton().getOverlayElement("Example/Visibility/UseOptimizationInfo");
[87]183        mQueriesIssuedInfo = OverlayManager::getSingleton().getOverlayElement("Example/Visibility/QueriesIssuedInfo");
184       
[61]185        mAlgorithmInfo->setCaption(": " + mCurrentAlgorithmCaptions[mCurrentAlgorithm]);
186        mThresholdInfo->setCaption(": 0");
187        mFrustumCulledNodesInfo->setCaption(": 0");
188        mQueryCulledNodesInfo->setCaption(": 0");
189        mTraversedNodesInfo->setCaption(": 0");
190        mHierarchyNodesInfo->setCaption(": 0");
191        mRenderedNodesInfo->setCaption(": 0");
[87]192        mObjectsInfo->setCaption(": 0");
[86]193        mUseOptimizationInfo->setCaption(": true");
[87]194        mQueriesIssuedInfo->setCaption(": 0");
[84]195
[85]196        setAlgorithm(mCurrentAlgorithm);
197
[93]198        mSceneMgr->setOption("UseOptimization", &mUseOptimization);
199        mSceneMgr->setOption("UseCulling", &mUseCulling);
200        mSceneMgr->setOption("CullCamera", &mUseCullCamera);
201        mSceneMgr->setOption("ShowOctree", &mShowOctree);
202
[61]203    pOver->show();
204}
205//-----------------------------------------------------------------------
206MouseQueryListener::~MouseQueryListener( )
207{
[74]208        delete mRayQueryExecutor;
[61]209}
210//-----------------------------------------------------------------------
211void MouseQueryListener::mouseMoved (MouseEvent *e)
212{
213        // Update CEGUI with the mouse motion
[75]214    CEGUI::System::getSingleton().injectMouseMove(e->getRelX() * mGUIRenderer->getWidth(),
215                e->getRelY() * mGUIRenderer->getHeight());
[61]216}
217//-----------------------------------------------------------------------
218void MouseQueryListener::mousePressed(MouseEvent* e)
219{
220     // Left mouse button down
221     if (e->getButtonID() & InputEvent::BUTTON0_MASK)
222     {
[76]223                 CEGUI::MouseCursor::getSingleton().hide();
[61]224
225                 // Setup the ray scene query
[80]226         Ray mouseRay = mCamera->getCameraToViewportRay(e->getX(), e->getY());
[74]227   
228                 Vector3 queryResult;
[80]229                 
230                 // Get results, create a node/entity on the position
[82]231                 mCurrentObject = mTerrainContentGenerator->GenerateSceneObject(
[80]232                         mouseRay.getOrigin(), mouseRay.getDirection(), "robot.mesh");
233               
[61]234         mLMouseDown = true;
235     }
236     // Right mouse button down
237     else if (e->getButtonID() & InputEvent::BUTTON1_MASK)
238     {
[75]239         CEGUI::MouseCursor::getSingleton().hide();
[61]240         mRMouseDown = true;
241     } // else if
242} // mousePressed
243
244 //-----------------------------------------------------------------------
245void MouseQueryListener::mouseReleased(MouseEvent* e)
246{
247    // Left mouse button up
248    if (e->getButtonID() & InputEvent::BUTTON0_MASK)
249    {
[75]250                CEGUI::MouseCursor::getSingleton().show();
[61]251        mLMouseDown = false;
252    }
253    // Right mouse button up
254    else if (e->getButtonID() & InputEvent::BUTTON1_MASK)
255    {
[75]256        CEGUI::MouseCursor::getSingleton().show();
[61]257        mRMouseDown = false;
258    }
259}
260//-----------------------------------------------------------------------
[75]261void MouseQueryListener::mouseDragged(MouseEvent *e)
[61]262 {
263         // If we are dragging the left mouse button.           
[75]264         if (mLMouseDown)
[61]265     {
[74]266                 Vector3 queryResult;
267                 Ray mouseRay = mCamera->getCameraToViewportRay(e->getX(), e->getY());
[61]268
[74]269                 if(mRayQueryExecutor->executeRayQuery(&queryResult, mouseRay))
[61]270                 {
[80]271                         if(mCurrentObject)
272                                 mCurrentObject->setPosition(queryResult);
[74]273                 }
[61]274     }
275         // If we are dragging the right mouse button.
[75]276         if (mRMouseDown)
[61]277         {
278                 mCamera->yaw( -e->getRelX() * mRotateSpeed );
279                 mCamera->pitch( -e->getRelY() * mRotateSpeed );
280         }
281}
282//-----------------------------------------------------------------------
283bool MouseQueryListener::frameStarted(const FrameEvent &evt)
284{
[94]285        clamp2Terrain(mCamera);
286        clamp2Terrain(mVisualizationCamera);
287
288        return ExampleFrameListener::frameStarted(evt);
289}
290void MouseQueryListener::clamp2Terrain(Camera *cam)
291{
[61]292        // clamp to terrain
[94]293        Vector3 camPos = cam->getPosition();
[74]294        Vector3 queryResult;
[61]295
[93]296        if(mRayQueryExecutor->executeRayQuery(&queryResult,
[94]297                        Vector3(camPos.x, 5000.0f, camPos.z), Vector3::NEGATIVE_UNIT_Y))
[93]298        {
[94]299                cam->setPosition(cam->getPosition().x, queryResult.y + 10,
300                        cam->getPosition().z);
[93]301        }
[61]302}
303//-----------------------------------------------------------------------
304bool MouseQueryListener::frameEnded(const FrameEvent& evt)
305{
306        if (mShutdownRequested)
307                return false;
308
309    if (timeDelay >= 0)
310        timeDelay -= evt.timeSinceLastFrame;
311
[85]312    KEY_PRESSED(KC_SPACE, 0.3, nextAlgorithm());
[61]313
314        KEY_PRESSED(KC_SUBTRACT, 0, changeThreshold(-10));
315        KEY_PRESSED(KC_ADD, 0, changeThreshold(10));
[86]316        KEY_PRESSED(KC_O, 0.3, toggleUseOptimization());
[98]317        KEY_PRESSED(KC_Y, 0.3, toggleShowOctree());
[87]318        KEY_PRESSED(KC_C, 0.3, toggleUseCulling());
[93]319        KEY_PRESSED(KC_V, 0.3, toggleCullCamera());
[94]320        KEY_PRESSED(KC_X, 0.3, FixVizCamera());
[93]321
[87]322        updateStats();
[94]323        //if(mWindow->getViewport(1))   mWindow->getViewport(1)->update();
[61]324
325    return ExampleFrameListener::frameStarted(evt) && ExampleFrameListener::frameEnded(evt);       
326}
327//-----------------------------------------------------------------------
328void MouseQueryListener::changeThreshold(int incr)
329{
[85]330        mVisibilityThreshold += incr;
331        if(mVisibilityThreshold < 0) mVisibilityThreshold = 0;
[61]332       
[85]333        char str[100]; sprintf(str,": %d", mVisibilityThreshold);
[61]334
[85]335        mSceneMgr->setOption("Threshold", &mVisibilityThreshold);
[61]336        mThresholdInfo->setCaption(str);
337}
338//-----------------------------------------------------------------------
[85]339void MouseQueryListener::nextAlgorithm()
[61]340{
[74]341        mCurrentAlgorithm = ++mCurrentAlgorithm %
342                GtpVisibility::VisibilityEnvironment::NUM_CULLING_MANAGERS,
[61]343
[85]344        setAlgorithm(mCurrentAlgorithm);
345}
346//-----------------------------------------------------------------------
347void MouseQueryListener::setAlgorithm(int algorithm)
348{
[61]349        mAlgorithmInfo->setCaption(": " + mCurrentAlgorithmCaptions[mCurrentAlgorithm]);
350        mSceneMgr->setOption("Algorithm", &mCurrentAlgorithm);
351}
352//-----------------------------------------------------------------------
[87]353void MouseQueryListener::updateStats()
[61]354{
355        unsigned int opt = 0;
356        char str[100];
357       
358        mSceneMgr->getOption("NumFrustumCulledNodes", &opt); sprintf(str,": %d", opt);
359        mFrustumCulledNodesInfo->setCaption(str);
360       
[87]361        mSceneMgr->getOption("NumQueriesIssued", &opt); sprintf(str,": %d", opt);
362        mQueriesIssuedInfo->setCaption(str);
363       
[61]364        mSceneMgr->getOption("NumQueryCulledNodes", &opt); sprintf(str,": %d", opt);
365        mQueryCulledNodesInfo->setCaption(str);
366       
367        mSceneMgr->getOption("NumTraversedNodes", &opt); sprintf(str,": %d", opt);
368        mTraversedNodesInfo->setCaption(str);
369
[74]370        mSceneMgr->getOption("NumHierarchyNodes", &opt); sprintf(str,": %d", opt);
[61]371        mHierarchyNodesInfo->setCaption(str);
372
373        mSceneMgr->getOption("NumRenderedNodes", &opt); sprintf(str,": %d", opt);
374        mRenderedNodesInfo->setCaption(str);
[84]375
376        sprintf(str,": %d", mTerrainContentGenerator->GetObjectCount());
[87]377        mObjectsInfo->setCaption(str);
[61]378}
379//-----------------------------------------------------------------------
[86]380void MouseQueryListener::toggleUseOptimization()
381{
382        mUseOptimization = !mUseOptimization;
383
384        mSceneMgr->setOption("UseOptimization", &mUseOptimization);
385
386        if(mUseOptimization)
387                mUseOptimizationInfo->setCaption(": true");
388        else
389                mUseOptimizationInfo->setCaption(": false");
390}
391//-----------------------------------------------------------------------
392void MouseQueryListener::toggleShowOctree()
393{
394        mShowOctree = !mShowOctree;
395
396        mSceneMgr->setOption("ShowOctree", &mShowOctree);
397}
398//-----------------------------------------------------------------------
[87]399void MouseQueryListener::toggleUseCulling()
400{
401        mUseCulling = !mUseCulling;
402
403        mSceneMgr->setOption("UseCulling", &mUseCulling);
404}
405//-----------------------------------------------------------------------
[93]406void MouseQueryListener::toggleCullCamera()
407{
408        mUseCullCamera = !mUseCullCamera;
[94]409
410        if(mUseCullCamera)
411        {       
412                mWindow->addViewport(mVisualizationCamera, 10, 0.5, 0.5, 1, 1);
413                mWindow->getViewport(1)->setClearEveryFrame(true);
414        }
415        else
416                mWindow->removeViewport(10);
417
[93]418        mSceneMgr->setOption("CullCamera", &mUseCullCamera);
419}
420//-----------------------------------------------------------------------
[94]421void MouseQueryListener::FixVizCamera()
[93]422{
[94]423        mVisualizationCamera->setPosition(mCamera->getPosition());
424        mVisualizationCamera->setOrientation(mCamera->getOrientation());
425        clamp2Terrain(mVisualizationCamera);
[93]426}
427
428//-----------------------------------------------------------------------
[61]429void MouseQueryListener::keyPressed(KeyEvent* e)
430{
431        if(e->getKey() == KC_ESCAPE)
432    {
433                mShutdownRequested = true;
434                e->consume();
435                return;
436        }
437
438        CEGUI::System::getSingleton().injectKeyDown(e->getKey());
439        CEGUI::System::getSingleton().injectChar(e->getKeyChar());
440        e->consume();
441}
442//-----------------------------------------------------------------------
443void MouseQueryListener::keyReleased(KeyEvent* e)
444{
445        CEGUI::System::getSingleton().injectKeyUp(e->getKey());
446        e->consume();
447}
448//-----------------------------------------------------------------------
449void MouseQueryListener::keyClicked(KeyEvent* e)
450{
451        // Do nothing
452        e->consume();
453}
454//-----------------------------------------------------------------------
455INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR strCmdLine, INT )
456{
457    // Create application object
458    TestCullingTerrainApplication app;
459
460        try
461        {
462        app.go();
463    }
464        catch( Ogre::Exception& e )
465        {
[75]466        MessageBox( NULL, e.getFullDescription().c_str(),
467                        "An exception has occured!", MB_OK | MB_ICONERROR | MB_TASKMODAL);
[61]468    }   
469
470    return 0;
471}
Note: See TracBrowser for help on using the repository browser.