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

Revision 76, 13.0 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        delete mTerrainContentGenerator;
28}
29//-----------------------------------------------------------------------
30void TestCullingTerrainApplication::createCamera( void )
31{
32        // Create the camera
33        mCamera = mSceneMgr->createCamera("PlayerCam");
34
35        // Position it at 500 in Z direction
36        mCamera->setPosition(Vector3(128,25,128));
37
38        // Look back along -Z
39    mCamera->lookAt(Vector3(0,0,-300));
40    mCamera->setNearClipDistance(1);
41    mCamera->setFarClipDistance(1000);
42}
43//-----------------------------------------------------------------------
44void TestCullingTerrainApplication::createScene()
45{
46        // Set ambient light
47        mSceneMgr->setAmbientLight(ColourValue(0.5, 0.5, 0.5));
48       
49        // Create a light
50        Light* l = mSceneMgr->createLight("MainLight");
51        // Accept default settings: point light, white diffuse, just set position
52        // NB I could attach the light to a SceneNode if I wanted it to move automatically with
53        //  other objects, but I don't
54        l->setPosition(20,80,50);
55
56        // --Fog
57        // NB it's VERY important to set this before calling setWorldGeometry
58        // because the vertex program picked will be different
59        ColourValue fadeColour(0.93, 0.86, 0.76);
60        mWindow->getViewport(0)->setBackgroundColour(fadeColour);
61        //mSceneMgr->setFog( FOG_LINEAR, fadeColour, .001, 500, 1000);
62
63        // Create a skybox
64    //mSceneMgr->setSkyBox(true, "Examples/SpaceSkyBox", 500, false);
65        //mSceneMgr->setSkyDome( true, "Examples/CloudySky", 5, 8, 500, false );
66
67        /*      // Define the required skyplane
68        Plane plane;
69        // 5000 world units from the camera
70        plane.d = 5000;
71        // Above the camera, facing down
72        plane.normal = -Vector3::UNIT_Y;
73        // Create the plane 10000 units wide, tile the texture 3 times
74    mSceneMgr->setSkyPlane(true, plane, "Examples/SpaceSkyPlane",10000,3);*/
75
76        std::string terrain_cfg("terrain.cfg");
77#if OGRE_PLATFORM == OGRE_PLATFORM_APPLE
78        terrain_cfg = mResourcePath + terrain_cfg;
79#endif
80        mSceneMgr->setWorldGeometry(terrain_cfg);
81        // Infinite far plane?
82        if (mRoot->getRenderSystem()->getCapabilities()->hasCapability(RSC_INFINITE_FAR_PLANE))
83        {
84                mCamera->setFarClipDistance(0);
85        }
86
87        // Set a nice viewpoint
88        mCamera->setPosition(707,2500,528);
89        mCamera->setOrientation(Quaternion(-0.3486, 0.0122, 0.9365, 0.0329));
90       
91        // CEGUI setup
92        setupGui();
93
94        mTerrainContentGenerator = new TerrainContentGenerator(mSceneMgr);
95        mTerrainContentGenerator->generateScene(300, "robot.mesh");
96}
97//-----------------------------------------------------------------------
98void TestCullingTerrainApplication::setupGui( void )
99{
100         mGUIRenderer = new CEGUI::OgreCEGUIRenderer(mWindow, Ogre::RENDER_QUEUE_OVERLAY,
101                 false, 3000, ST_EXTERIOR_CLOSE);
102     mGUISystem = new CEGUI::System(mGUIRenderer);
103
104         // Mouse
105     CEGUI::SchemeManager::getSingleton().loadScheme((CEGUI::utf8*)"TaharezLook.scheme");
106     CEGUI::MouseCursor::getSingleton().setImage("TaharezLook", "MouseArrow");
107         mGUISystem->setDefaultMouseCursor(
108                (CEGUI::utf8*)"TaharezLook", (CEGUI::utf8*)"MouseArrow");
109
110         CEGUI::MouseCursor::getSingleton().show();
111}
112//-----------------------------------------------------------------------
113void TestCullingTerrainApplication::createFrameListener(void)
114{
115        mFrameListener= new MouseQueryListener(mWindow, mCamera, mSceneMgr, mGUIRenderer);
116        mFrameListener->showDebugOverlay(true);
117        mRoot->addFrameListener(mFrameListener);
118}
119//-----------------------------------------------------------------------
120void TestCullingTerrainApplication::chooseSceneManager(void)
121{
122        mSceneMgr = mRoot->getSceneManager(ST_EXTERIOR_CLOSE);
123}
124
125/***********************************************/
126/* MouseQueryListener implementation           */
127/***********************************************/
128//-----------------------------------------------------------------------
129MouseQueryListener::MouseQueryListener(RenderWindow* win, Camera* cam,
130                                                                           SceneManager *sceneManager,
131                                                                           CEGUI::Renderer *renderer):
132ExampleFrameListener(win, cam, false, true), mGUIRenderer(renderer),
133mShutdownRequested(false)
134{
135        // Setup default variables
136        mCurrentObject = NULL;
137        mLMouseDown = false;
138        mRMouseDown = false;
139        mSceneMgr = sceneManager;
140
141    // Reduce move speed
142        mMoveSpeed = 50;
143        mRotateSpeed *= 2;
144
145        mCurrentAlgorithm = GtpVisibility::VisibilityEnvironment::COHERENT_HIERARCHICAL_CULLING,
146        mThreshold = 0;
147   
148        // Register this so that we get mouse events.
149        mEventProcessor->addMouseListener(this);
150        mEventProcessor->addMouseMotionListener(this);
151        mEventProcessor->addKeyListener(this);
152
153        mRayQueryExecutor = new RayQueryExecutor(mSceneMgr);
154       
155        // show overlay
156        Overlay* pOver = OverlayManager::getSingleton().getByName("Example/VisibilityDemoOverlay");
157
158        mAlgorithmInfo = OverlayManager::getSingleton().getOverlayElement("Example/Visibility/AlgorithmInfo");
159        mThresholdInfo = OverlayManager::getSingleton().getOverlayElement("Example/Visibility/ThresholdInfo");
160        mFrustumCulledNodesInfo = OverlayManager::getSingleton().getOverlayElement("Example/Visibility/FrustumCulledNodesInfo");
161        mQueryCulledNodesInfo = OverlayManager::getSingleton().getOverlayElement("Example/Visibility/QueryCulledNodesInfo");
162    mTraversedNodesInfo = OverlayManager::getSingleton().getOverlayElement("Example/Visibility/TraversedNodesInfo");
163        mHierarchyNodesInfo = OverlayManager::getSingleton().getOverlayElement("Example/Visibility/HierarchyNodesInfo");
164        mRenderedNodesInfo = OverlayManager::getSingleton().getOverlayElement("Example/Visibility/RenderedNodesInfo");
165
166        mAlgorithmInfo->setCaption(": " + mCurrentAlgorithmCaptions[mCurrentAlgorithm]);
167        mThresholdInfo->setCaption(": 0");
168        mFrustumCulledNodesInfo->setCaption(": 0");
169        mQueryCulledNodesInfo->setCaption(": 0");
170        mTraversedNodesInfo->setCaption(": 0");
171        mHierarchyNodesInfo->setCaption(": 0");
172        mRenderedNodesInfo->setCaption(": 0");
173               
174    pOver->show();
175}
176//-----------------------------------------------------------------------
177MouseQueryListener::~MouseQueryListener( )
178{
179        delete mRayQueryExecutor;
180}
181//-----------------------------------------------------------------------
182void MouseQueryListener::mouseMoved (MouseEvent *e)
183{
184        // Update CEGUI with the mouse motion
185    CEGUI::System::getSingleton().injectMouseMove(e->getRelX() * mGUIRenderer->getWidth(),
186                e->getRelY() * mGUIRenderer->getHeight());
187}
188//-----------------------------------------------------------------------
189void MouseQueryListener::mousePressed(MouseEvent* e)
190{
191     // Left mouse button down
192     if (e->getButtonID() & InputEvent::BUTTON0_MASK)
193     {
194                 CEGUI::MouseCursor::getSingleton().hide();
195
196                 // Setup the ray scene query
197         Ray mouseRay = mCamera->getCameraToViewportRay( e->getX(), e->getY() );
198   
199                 Vector3 queryResult;
200         // Get results, create a node/entity on the position
201                 if(mRayQueryExecutor->executeRayQuery(&queryResult, mouseRay))
202         {
203                         char name[16];
204             sprintf(name, "Robot%d", mCount++);
205
206             Entity *ent = mSceneMgr->createEntity(name, "robot.mesh");
207             mCurrentObject = mSceneMgr->getRootSceneNode()->
208                                 createChildSceneNode(String(name) + "Node", queryResult);
209             mCurrentObject->attachObject(ent);
210             mCurrentObject->setScale(0.1f, 0.1f, 0.1f);
211                         
212         }
213
214         mLMouseDown = true;
215     }
216     // Right mouse button down
217     else if (e->getButtonID() & InputEvent::BUTTON1_MASK)
218     {
219         CEGUI::MouseCursor::getSingleton().hide();
220         mRMouseDown = true;
221     } // else if
222} // mousePressed
223
224 //-----------------------------------------------------------------------
225void MouseQueryListener::mouseReleased(MouseEvent* e)
226{
227    // Left mouse button up
228    if (e->getButtonID() & InputEvent::BUTTON0_MASK)
229    {
230                CEGUI::MouseCursor::getSingleton().show();
231        mLMouseDown = false;
232    }
233    // Right mouse button up
234    else if (e->getButtonID() & InputEvent::BUTTON1_MASK)
235    {
236        CEGUI::MouseCursor::getSingleton().show();
237        mRMouseDown = false;
238    }
239}
240//-----------------------------------------------------------------------
241void MouseQueryListener::mouseDragged(MouseEvent *e)
242 {
243         // If we are dragging the left mouse button.           
244         if (mLMouseDown)
245     {
246                 Vector3 queryResult;
247                 Ray mouseRay = mCamera->getCameraToViewportRay(e->getX(), e->getY());
248
249                 if(mRayQueryExecutor->executeRayQuery(&queryResult, mouseRay))
250                 {
251                         mCurrentObject->setPosition(queryResult);
252                 }
253     }
254         // If we are dragging the right mouse button.
255         if (mRMouseDown)
256         {
257                 mCamera->yaw( -e->getRelX() * mRotateSpeed );
258                 mCamera->pitch( -e->getRelY() * mRotateSpeed );
259         }
260}
261//-----------------------------------------------------------------------
262bool MouseQueryListener::frameStarted(const FrameEvent &evt)
263{
264        // clamp to terrain
265        Vector3 camPos = mCamera->getPosition();
266        Vector3 queryResult;
267
268    if(mRayQueryExecutor->executeRayQuery(&queryResult,
269                Vector3(camPos.x, 5000.0f, camPos.z), Vector3::NEGATIVE_UNIT_Y))
270        {
271                mCamera->setPosition(mCamera->getPosition().x, queryResult.y + 10,
272                        mCamera->getPosition().z);
273        }
274       
275        return ExampleFrameListener::frameStarted(evt);
276}
277//-----------------------------------------------------------------------
278bool MouseQueryListener::frameEnded(const FrameEvent& evt)
279{
280        if (mShutdownRequested)
281                return false;
282
283    if (timeDelay >= 0)
284        timeDelay -= evt.timeSinceLastFrame;
285
286    KEY_PRESSED(KC_SPACE, 0.3, changeAlgorithm());
287
288        KEY_PRESSED(KC_SUBTRACT, 0, changeThreshold(-10));
289        KEY_PRESSED(KC_ADD, 0, changeThreshold(10));
290        //KEY_PRESSED(KC_T, 1, change);
291     
292        changeStats();
293
294    return ExampleFrameListener::frameStarted(evt) && ExampleFrameListener::frameEnded(evt);       
295}
296//-----------------------------------------------------------------------
297void MouseQueryListener::changeThreshold(int incr)
298{
299        mThreshold += incr; if(mThreshold < 0) mThreshold = 0;
300       
301        char str[100]; sprintf(str,": %d", mThreshold);
302
303        mSceneMgr->setOption("Threshold", &mThreshold);
304        mThresholdInfo->setCaption(str);
305}
306//-----------------------------------------------------------------------
307void MouseQueryListener::changeAlgorithm()
308{
309        mCurrentAlgorithm = ++mCurrentAlgorithm %
310                GtpVisibility::VisibilityEnvironment::NUM_CULLING_MANAGERS,
311
312        mAlgorithmInfo->setCaption(": " + mCurrentAlgorithmCaptions[mCurrentAlgorithm]);
313        mSceneMgr->setOption("Algorithm", &mCurrentAlgorithm);
314}
315//-----------------------------------------------------------------------
316void MouseQueryListener::changeStats()
317{
318        unsigned int opt = 0;
319        char str[100];
320       
321        mSceneMgr->getOption("NumFrustumCulledNodes", &opt); sprintf(str,": %d", opt);
322        mFrustumCulledNodesInfo->setCaption(str);
323       
324        mSceneMgr->getOption("NumQueryCulledNodes", &opt); sprintf(str,": %d", opt);
325        mQueryCulledNodesInfo->setCaption(str);
326       
327        mSceneMgr->getOption("NumTraversedNodes", &opt); sprintf(str,": %d", opt);
328        mTraversedNodesInfo->setCaption(str);
329
330        mSceneMgr->getOption("NumHierarchyNodes", &opt); sprintf(str,": %d", opt);
331        mHierarchyNodesInfo->setCaption(str);
332
333        mSceneMgr->getOption("NumRenderedNodes", &opt); sprintf(str,": %d", opt);
334        mRenderedNodesInfo->setCaption(str);
335}
336//-----------------------------------------------------------------------
337void MouseQueryListener::keyPressed(KeyEvent* e)
338{
339        if(e->getKey() == KC_ESCAPE)
340    {
341                mShutdownRequested = true;
342                e->consume();
343                return;
344        }
345
346        CEGUI::System::getSingleton().injectKeyDown(e->getKey());
347        CEGUI::System::getSingleton().injectChar(e->getKeyChar());
348        e->consume();
349}
350//-----------------------------------------------------------------------
351void MouseQueryListener::keyReleased(KeyEvent* e)
352{
353        CEGUI::System::getSingleton().injectKeyUp(e->getKey());
354        e->consume();
355}
356//-----------------------------------------------------------------------
357void MouseQueryListener::keyClicked(KeyEvent* e)
358{
359        // Do nothing
360        e->consume();
361}
362//-----------------------------------------------------------------------
363INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR strCmdLine, INT )
364{
365    // Create application object
366    TestCullingTerrainApplication app;
367
368        try
369        {
370        app.go();
371    }
372        catch( Ogre::Exception& e )
373        {
374        MessageBox( NULL, e.getFullDescription().c_str(),
375                        "An exception has occured!", MB_OK | MB_ICONERROR | MB_TASKMODAL);
376    }   
377
378    return 0;
379}
Note: See TracBrowser for help on using the repository browser.