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

Revision 98, 16.2 KB checked in by mattausch, 19 years ago (diff)
Line 
1/**
2    \file
3        TestCullingTerrainApplication.cpp
4    \brief
5        Tests the visibility culling algorithm
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
19#include <windows.h>
20
21
22/*******************************************************/
23/*     TestCullingTerrainApplication implementation    */
24/*******************************************************/
25TestCullingTerrainApplication::~TestCullingTerrainApplication()
26{
27        if(mTerrainContentGenerator)
28                delete mTerrainContentGenerator;
29}
30//-----------------------------------------------------------------------
31void TestCullingTerrainApplication::createCamera()
32{
33        // Create the camera
34        mCamera = mSceneMgr->createCamera("CullCamera");
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
41        mVisualizationCamera = mSceneMgr->createCamera("VisualizationCamera");
42        mVisualizationCamera->setPosition(707, 2500, 528);
43        mVisualizationCamera->setOrientation(Quaternion(-0.3486, 0.0122, 0.9365, 0.0329));
44
45        mVisualizationCamera->setNearClipDistance(1);
46        mCamera->setNearClipDistance(1);
47
48        // Infinite far plane?
49        if (mRoot->getRenderSystem()->getCapabilities()->hasCapability(RSC_INFINITE_FAR_PLANE))
50        {
51                mVisualizationCamera->setFarClipDistance(0);
52                mCamera->setFarClipDistance(0);
53        }
54        else
55        {
56                 mVisualizationCamera->setFarClipDistance(1000);
57                 mCamera->setFarClipDistance(1000);
58        }
59       
60}
61//-----------------------------------------------------------------------
62void TestCullingTerrainApplication::createScene()
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);
80       
81        // Create a skybox
82    mSceneMgr->setSkyBox(true, "Examples/SpaceSkyBox", 3500, false);
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
89        mSceneMgr->setWorldGeometry(terrain_cfg);
90       
91        // CEGUI setup
92        setupGui();
93        // HACK: necessary to call once before the content creation for
94        // terrain initialisation
95        mSceneMgr->_renderScene(mCamera, mWindow->getViewport(0), true);
96
97        mTerrainContentGenerator = new TerrainContentGenerator(mSceneMgr);
98//      mTerrainContentGenerator->GenerateScene(500, "ninja.mesh");
99        mTerrainContentGenerator->SetMaxPos(Vector3(3000.0f, 5000.0f, 3000.0f));
100        mTerrainContentGenerator->GenerateScene(1500, "robot.mesh");
101
102        // no limitations needed anymore: the user can set
103        // objects also on peaks of terrain
104        mTerrainContentGenerator->SetMaxHeight(5000);
105}
106//-----------------------------------------------------------------------
107void TestCullingTerrainApplication::setupGui()
108{
109         mGUIRenderer = new CEGUI::OgreCEGUIRenderer(mWindow, Ogre::RENDER_QUEUE_OVERLAY,
110                 false, 3000, ST_EXTERIOR_CLOSE);
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
119         CEGUI::MouseCursor::getSingleton().show();
120}
121//-----------------------------------------------------------------------
122void TestCullingTerrainApplication::createFrameListener()
123{
124        mFrameListener= new MouseQueryListener(mWindow, mCamera, mSceneMgr,
125                mGUIRenderer, mTerrainContentGenerator, mVisualizationCamera);
126        mFrameListener->showDebugOverlay(true);
127        mRoot->addFrameListener(mFrameListener);
128}
129//-----------------------------------------------------------------------
130void TestCullingTerrainApplication::chooseSceneManager()
131{
132        mSceneMgr = mRoot->getSceneManager(ST_EXTERIOR_CLOSE);
133}
134/***********************************************/
135/*      MouseQueryListener implementation      */
136/***********************************************/
137//-----------------------------------------------------------------------
138MouseQueryListener::MouseQueryListener(RenderWindow* win, Camera* cam,
139                                                                           SceneManager *sceneManager,
140                                                                           CEGUI::Renderer *renderer,
141                                                                           TerrainContentGenerator *sceneGenerator,
142                                                                           Camera *vizCamera):
143ExampleFrameListener(win, cam, false, true),
144mGUIRenderer(renderer),
145mShutdownRequested(false),
146mLMouseDown(false),
147mRMouseDown(false),
148mSceneMgr(sceneManager),
149mCurrentObject(NULL),
150mTerrainContentGenerator(sceneGenerator),
151mVisibilityThreshold(0),
152mCurrentAlgorithm(GtpVisibility::VisibilityEnvironment::COHERENT_HIERARCHICAL_CULLING),
153mShowOctree(false),
154mUseCulling(true),
155mUseOptimization(true),
156mUseCullCamera(false),
157mVisualizationCamera(vizCamera)
158{
159        // Reduce move speed
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
168        mRayQueryExecutor = new RayQueryExecutor(mSceneMgr);
169       
170        // show overlay
171        Overlay* pOver = OverlayManager::getSingleton().getByName("Example/VisibilityDemoOverlay");
172
173        mAlgorithmInfo = OverlayManager::getSingleton().getOverlayElement("Example/Visibility/AlgorithmInfo");
174        mThresholdInfo = OverlayManager::getSingleton().getOverlayElement("Example/Visibility/ThresholdInfo");
175       
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");
181        mObjectsInfo = OverlayManager::getSingleton().getOverlayElement("Example/Visibility/ObjectsInfo");
182        mUseOptimizationInfo = OverlayManager::getSingleton().getOverlayElement("Example/Visibility/UseOptimizationInfo");
183        mQueriesIssuedInfo = OverlayManager::getSingleton().getOverlayElement("Example/Visibility/QueriesIssuedInfo");
184       
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");
192        mObjectsInfo->setCaption(": 0");
193        mUseOptimizationInfo->setCaption(": true");
194        mQueriesIssuedInfo->setCaption(": 0");
195
196        setAlgorithm(mCurrentAlgorithm);
197
198        mSceneMgr->setOption("UseOptimization", &mUseOptimization);
199        mSceneMgr->setOption("UseCulling", &mUseCulling);
200        mSceneMgr->setOption("CullCamera", &mUseCullCamera);
201        mSceneMgr->setOption("ShowOctree", &mShowOctree);
202
203    pOver->show();
204}
205//-----------------------------------------------------------------------
206MouseQueryListener::~MouseQueryListener( )
207{
208        delete mRayQueryExecutor;
209}
210//-----------------------------------------------------------------------
211void MouseQueryListener::mouseMoved (MouseEvent *e)
212{
213        // Update CEGUI with the mouse motion
214    CEGUI::System::getSingleton().injectMouseMove(e->getRelX() * mGUIRenderer->getWidth(),
215                e->getRelY() * mGUIRenderer->getHeight());
216}
217//-----------------------------------------------------------------------
218void MouseQueryListener::mousePressed(MouseEvent* e)
219{
220     // Left mouse button down
221     if (e->getButtonID() & InputEvent::BUTTON0_MASK)
222     {
223                 CEGUI::MouseCursor::getSingleton().hide();
224
225                 // Setup the ray scene query
226         Ray mouseRay = mCamera->getCameraToViewportRay(e->getX(), e->getY());
227   
228                 Vector3 queryResult;
229                 
230                 // Get results, create a node/entity on the position
231                 mCurrentObject = mTerrainContentGenerator->GenerateSceneObject(
232                         mouseRay.getOrigin(), mouseRay.getDirection(), "robot.mesh");
233               
234         mLMouseDown = true;
235     }
236     // Right mouse button down
237     else if (e->getButtonID() & InputEvent::BUTTON1_MASK)
238     {
239         CEGUI::MouseCursor::getSingleton().hide();
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    {
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 MouseQueryListener::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                                 mCurrentObject->setPosition(queryResult);
273                 }
274     }
275         // If we are dragging the right mouse button.
276         if (mRMouseDown)
277         {
278                 mCamera->yaw( -e->getRelX() * mRotateSpeed );
279                 mCamera->pitch( -e->getRelY() * mRotateSpeed );
280         }
281}
282//-----------------------------------------------------------------------
283bool MouseQueryListener::frameStarted(const FrameEvent &evt)
284{
285        clamp2Terrain(mCamera);
286        clamp2Terrain(mVisualizationCamera);
287
288        return ExampleFrameListener::frameStarted(evt);
289}
290void MouseQueryListener::clamp2Terrain(Camera *cam)
291{
292        // clamp to terrain
293        Vector3 camPos = cam->getPosition();
294        Vector3 queryResult;
295
296        if(mRayQueryExecutor->executeRayQuery(&queryResult,
297                        Vector3(camPos.x, 5000.0f, camPos.z), Vector3::NEGATIVE_UNIT_Y))
298        {
299                cam->setPosition(cam->getPosition().x, queryResult.y + 10,
300                        cam->getPosition().z);
301        }
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
312    KEY_PRESSED(KC_SPACE, 0.3, nextAlgorithm());
313
314        KEY_PRESSED(KC_SUBTRACT, 0, changeThreshold(-10));
315        KEY_PRESSED(KC_ADD, 0, changeThreshold(10));
316        KEY_PRESSED(KC_O, 0.3, toggleUseOptimization());
317        KEY_PRESSED(KC_Y, 0.3, toggleShowOctree());
318        KEY_PRESSED(KC_C, 0.3, toggleUseCulling());
319        KEY_PRESSED(KC_V, 0.3, toggleCullCamera());
320        KEY_PRESSED(KC_X, 0.3, FixVizCamera());
321
322        updateStats();
323        //if(mWindow->getViewport(1))   mWindow->getViewport(1)->update();
324
325    return ExampleFrameListener::frameStarted(evt) && ExampleFrameListener::frameEnded(evt);       
326}
327//-----------------------------------------------------------------------
328void MouseQueryListener::changeThreshold(int incr)
329{
330        mVisibilityThreshold += incr;
331        if(mVisibilityThreshold < 0) mVisibilityThreshold = 0;
332       
333        char str[100]; sprintf(str,": %d", mVisibilityThreshold);
334
335        mSceneMgr->setOption("Threshold", &mVisibilityThreshold);
336        mThresholdInfo->setCaption(str);
337}
338//-----------------------------------------------------------------------
339void MouseQueryListener::nextAlgorithm()
340{
341        mCurrentAlgorithm = ++mCurrentAlgorithm %
342                GtpVisibility::VisibilityEnvironment::NUM_CULLING_MANAGERS,
343
344        setAlgorithm(mCurrentAlgorithm);
345}
346//-----------------------------------------------------------------------
347void MouseQueryListener::setAlgorithm(int algorithm)
348{
349        mAlgorithmInfo->setCaption(": " + mCurrentAlgorithmCaptions[mCurrentAlgorithm]);
350        mSceneMgr->setOption("Algorithm", &mCurrentAlgorithm);
351}
352//-----------------------------------------------------------------------
353void MouseQueryListener::updateStats()
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       
361        mSceneMgr->getOption("NumQueriesIssued", &opt); sprintf(str,": %d", opt);
362        mQueriesIssuedInfo->setCaption(str);
363       
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
370        mSceneMgr->getOption("NumHierarchyNodes", &opt); sprintf(str,": %d", opt);
371        mHierarchyNodesInfo->setCaption(str);
372
373        mSceneMgr->getOption("NumRenderedNodes", &opt); sprintf(str,": %d", opt);
374        mRenderedNodesInfo->setCaption(str);
375
376        sprintf(str,": %d", mTerrainContentGenerator->GetObjectCount());
377        mObjectsInfo->setCaption(str);
378}
379//-----------------------------------------------------------------------
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//-----------------------------------------------------------------------
399void MouseQueryListener::toggleUseCulling()
400{
401        mUseCulling = !mUseCulling;
402
403        mSceneMgr->setOption("UseCulling", &mUseCulling);
404}
405//-----------------------------------------------------------------------
406void MouseQueryListener::toggleCullCamera()
407{
408        mUseCullCamera = !mUseCullCamera;
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
418        mSceneMgr->setOption("CullCamera", &mUseCullCamera);
419}
420//-----------------------------------------------------------------------
421void MouseQueryListener::FixVizCamera()
422{
423        mVisualizationCamera->setPosition(mCamera->getPosition());
424        mVisualizationCamera->setOrientation(mCamera->getOrientation());
425        clamp2Terrain(mVisualizationCamera);
426}
427
428//-----------------------------------------------------------------------
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        {
466        MessageBox( NULL, e.getFullDescription().c_str(),
467                        "An exception has occured!", MB_OK | MB_ICONERROR | MB_TASKMODAL);
468    }   
469
470    return 0;
471}
Note: See TracBrowser for help on using the repository browser.