source: trunk/VUT/work/TestCullingDotScene/TestCullingDotSceneApplication.cpp @ 61

Revision 61, 19.4 KB checked in by mattausch, 19 years ago (diff)
Line 
1/**
2    \file
3        TestCullingApplication.cpp
4    \brief
5        Tests the occlusion 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 "OgreLight.h"
17#include "tinyxml.h"
18#include "TestCullingDotSceneApplication.h"
19
20#define WIN32_LEAN_AND_MEAN
21#include "windows.h"
22
23/***********************************************/
24/* TestCullingDotSceneApplication implementation       */
25/***********************************************/
26void TestCullingDotSceneApplication::ParseDotScene( const String &SceneName, const String& groupName )
27{
28        TiXmlDocument   *XMLDoc;
29        TiXmlElement    *XMLRoot, *XMLNodes, *XMLPathFind;
30        try
31        {
32                DataStreamPtr pStream = ResourceGroupManager::getSingleton().openResource( SceneName, groupName );
33
34                String data = pStream->getAsString();
35
36                // Open the .scene File
37                XMLDoc = new TiXmlDocument();
38                XMLDoc->Parse( data.c_str() );
39                pStream->close();
40                pStream.setNull();
41
42                if( XMLDoc->Error() )
43                {
44                        //We'll just log, and continue on gracefully
45                        LogManager::getSingleton().logMessage("Error in dotscene demo app!!!!!");
46                        delete XMLDoc;
47                        return;
48                }
49        }
50        catch(...)
51        {
52                //We'll just log, and continue on gracefully
53                LogManager::getSingleton().logMessage("Error in dotscene demo app!!!!!");
54                delete XMLDoc;
55                return;
56        }
57
58        // Validate the File
59        XMLRoot = XMLDoc->RootElement();
60        if( String( XMLRoot->Value()) != "scene"  ) {
61                LogManager::getSingleton().logMessage( "Error: Invalid .scene File. Missing <scene>" );
62                delete XMLDoc;         
63                return;
64        }
65               
66        XMLNodes = XMLRoot->FirstChildElement( "nodes" );
67       
68        // Read in the scene nodes
69        if( XMLNodes )
70        {
71                TiXmlElement *XMLNode, *XMLPosition, *XMLRotation, *XMLScale,  *XMLEntity, *XMLBillboardSet,  *XMLLight;
72
73                XMLNode = XMLNodes->FirstChildElement( "node" );
74               
75                while( XMLNode )
76                {
77                        // Process the current node
78                        // Grab the name of the node
79                        String NodeName = XMLNode->Attribute("name");
80                        // First create the new scene node
81                        SceneNode* NewNode = static_cast<SceneNode*>( mSceneMgr->getRootSceneNode()->createChild( NodeName ) );
82
83                        Vector3 TempVec;
84                        String TempValue;
85                               
86                        // Now position it...
87                        XMLPosition = XMLNode->FirstChildElement("position");
88                       
89                        if( XMLPosition )
90                        {
91                                TempValue = XMLPosition->Attribute("x");
92                                TempVec.x = StringConverter::parseReal(TempValue);
93                                TempValue = XMLPosition->Attribute("y");
94                                TempVec.y = StringConverter::parseReal(TempValue);
95                                TempValue = XMLPosition->Attribute("z");
96                                TempVec.z = StringConverter::parseReal(TempValue);
97                                NewNode->setPosition( TempVec );
98                        }
99
100                        // Rotate it...
101                        XMLRotation = XMLNode->FirstChildElement("rotation");
102                        if( XMLRotation )
103                        {
104                                Quaternion TempQuat;
105                                TempValue = XMLRotation->Attribute("qx");
106                                TempQuat.x = StringConverter::parseReal(TempValue);
107                                TempValue = XMLRotation->Attribute("qy");
108                                TempQuat.y = StringConverter::parseReal(TempValue);
109                                TempValue = XMLRotation->Attribute("qz");
110                                TempQuat.z = StringConverter::parseReal(TempValue);
111                                TempValue = XMLRotation->Attribute("qw");
112                                TempQuat.w = StringConverter::parseReal(TempValue);
113                                NewNode->setOrientation( TempQuat );
114                        }
115
116                        // Scale it.
117                        XMLScale = XMLNode->FirstChildElement("scale");
118                       
119                        if( XMLScale )
120                        {
121                                TempValue = XMLScale->Attribute("x");
122                                TempVec.x = StringConverter::parseReal(TempValue);
123                                TempValue = XMLScale->Attribute("y");
124                                TempVec.y = StringConverter::parseReal(TempValue);
125                                TempValue = XMLScale->Attribute("z");
126                                TempVec.z = StringConverter::parseReal(TempValue);
127                                NewNode->setScale( TempVec );
128                        }
129
130                        XMLLight = XMLNode->FirstChildElement( "light" );
131                       
132                        if( XMLLight )
133                                NewNode->attachObject( LoadLight( XMLLight ) );
134
135                        // Check for an Entity
136                        XMLEntity = XMLNode->FirstChildElement("entity");
137                       
138                        if( XMLEntity )
139                        {
140                                if( XMLEntity->Attribute("static") )
141                                {
142                                        if( strcmp( XMLEntity->Attribute("static"), "false" )==0 ){
143                                                String EntityName, EntityMeshFilename;
144                                                EntityName = XMLEntity->Attribute( "name" );
145                                                EntityMeshFilename = XMLEntity->Attribute( "meshFile" );
146
147                                                // Create entity
148                                                Entity* NewEntity = mSceneMgr->createEntity(EntityName, EntityMeshFilename);
149                                                NewNode->attachObject( NewEntity );
150                                        }
151                                }
152                        }
153
154                        XMLBillboardSet = XMLNode->FirstChildElement( "billboardSet" );
155                        if( XMLBillboardSet )
156                        {
157                                String TempValue;
158
159                                BillboardSet* bSet = mSceneMgr->createBillboardSet( NewNode->getName() );
160
161                                BillboardType Type;
162                                TempValue = XMLBillboardSet->Attribute( "type" );
163                                if( TempValue == "orientedCommon" )
164                                        Type = BBT_ORIENTED_COMMON;
165                                else if( TempValue == "orientedSelf" )
166                                        Type = BBT_ORIENTED_SELF;
167                                else Type = BBT_POINT;
168
169                                BillboardOrigin Origin;
170                                TempValue = XMLBillboardSet->Attribute( "type" );
171                                if( TempValue == "bottom_left" )
172                                        Origin = BBO_BOTTOM_LEFT;
173                                else if( TempValue == "bottom_center" )
174                                        Origin = BBO_BOTTOM_CENTER;
175                                else if( TempValue == "bottomRight"  )
176                                        Origin = BBO_BOTTOM_RIGHT;
177                                else if( TempValue == "left" )
178                                        Origin = BBO_CENTER_LEFT;
179                                else if( TempValue == "right" )
180                                        Origin = BBO_CENTER_RIGHT;
181                                else if( TempValue == "topLeft" )
182                                        Origin = BBO_TOP_LEFT;
183                                else if( TempValue == "topCenter" )
184                                        Origin = BBO_TOP_CENTER;
185                                else if( TempValue == "topRight" )
186                                        Origin = BBO_TOP_RIGHT;
187                                else
188                                        Origin = BBO_CENTER;
189
190                                bSet->setBillboardType( Type );
191                                bSet->setBillboardOrigin( Origin );
192
193                                TempValue = XMLBillboardSet->Attribute( "name" );
194                                bSet->setMaterialName( TempValue );
195
196                                int width, height;
197                                width = StringConverter::parseReal( XMLBillboardSet->Attribute( "width" ) );
198                                height = StringConverter::parseReal( XMLBillboardSet->Attribute( "height" ) );
199                                bSet->setDefaultDimensions( width, height );
200                                bSet->setVisible( true );
201                                NewNode->attachObject( bSet );
202
203                                TiXmlElement *XMLBillboard;
204
205                                XMLBillboard = XMLBillboardSet->FirstChildElement( "billboard" );
206
207                                while( XMLBillboard )
208                                {
209                                        Billboard *b;
210                                        TempValue;
211                                        TempVec = Vector3( 0, 0, 0 );
212                                        ColourValue TempColour(1,1,1,1);
213
214                                        XMLPosition = XMLBillboard->FirstChildElement( "position" );
215                                        if( XMLPosition ){
216                                                TempValue = XMLPosition->Attribute("x");
217                                                TempVec.x = StringConverter::parseReal(TempValue);
218                                                TempValue = XMLPosition->Attribute("y");
219                                                TempVec.y = StringConverter::parseReal(TempValue);
220                                                TempValue = XMLPosition->Attribute("z");
221                                                TempVec.z = StringConverter::parseReal(TempValue);
222                                        }
223
224                                        TiXmlElement* XMLColour = XMLBillboard->FirstChildElement( "colourDiffuse" );
225                                        if( XMLColour )
226                                        {
227                                                TempValue = XMLColour->Attribute("r");
228                                                TempColour.r = StringConverter::parseReal(TempValue);
229                                                TempValue = XMLColour->Attribute("g");
230                                                TempColour.g = StringConverter::parseReal(TempValue);
231                                                TempValue = XMLColour->Attribute("b");
232                                                TempColour.b = StringConverter::parseReal(TempValue);
233                                        }
234
235                                        b = bSet->createBillboard( TempVec, TempColour);
236
237                                        XMLBillboard = XMLBillboard->NextSiblingElement( "billboard" );
238                                }
239                        }
240
241                        // Move to the next node
242                        XMLNode = XMLNode->NextSiblingElement( "node" );
243                }
244        }
245
246        // Close the XML File
247        delete XMLDoc;
248}
249
250Light* TestCullingDotSceneApplication::LoadLight( TiXmlElement *XMLLight )
251{
252        TiXmlElement *XMLDiffuse, *XMLSpecular, *XMLAttentuation, *XMLPosition;
253
254        // Create a light (point | directional | spot | radPoint)
255        Light* light = mSceneMgr->createLight( XMLLight->Attribute("name") );
256        if( !XMLLight->Attribute("type") || String(XMLLight->Attribute("type")) == "point" )
257                light->setType( Light::LT_POINT );
258        else if( String(XMLLight->Attribute("type")) == "directional")
259                light->setType( Light::LT_DIRECTIONAL );
260        else if( String(XMLLight->Attribute("type")) == "spot")
261                light->setType( Light::LT_SPOTLIGHT );
262        else if( String(XMLLight->Attribute("type")) == "radPoint")
263                light->setType( Light::LT_POINT );
264
265        XMLDiffuse = XMLLight->FirstChildElement("colourDiffuse");
266        if( XMLDiffuse )
267        {
268                ColourValue Diffuse;
269                Diffuse.r = Ogre::StringConverter::parseReal( XMLDiffuse->Attribute("r") );
270                Diffuse.g = Ogre::StringConverter::parseReal( XMLDiffuse->Attribute("g") );
271                Diffuse.b = Ogre::StringConverter::parseReal( XMLDiffuse->Attribute("b") );
272                Diffuse.a = 1;
273                light->setDiffuseColour(Diffuse);
274        }
275       
276        XMLSpecular = XMLLight->FirstChildElement("colourSpecular");
277       
278        if( XMLSpecular )
279        {
280                ColourValue Specular;
281                Specular.r = Ogre::StringConverter::parseReal( XMLSpecular->Attribute("r") );
282                Specular.g = Ogre::StringConverter::parseReal( XMLSpecular->Attribute("g") );
283                Specular.b = Ogre::StringConverter::parseReal( XMLSpecular->Attribute("b") );
284                Specular.a = 1;
285                light->setSpecularColour(Specular);
286        }
287
288        XMLAttentuation = XMLLight->FirstChildElement("lightAttenuation");
289        if( XMLAttentuation )
290        {
291                //get defaults incase not all values specified
292                Real range, constant, linear, quadratic;
293                range = light->getAttenuationRange();
294                constant = light->getAttenuationConstant();
295                linear = light->getAttenuationLinear();
296                quadratic = light->getAttenuationQuadric();
297                       
298                if( XMLAttentuation->Attribute("range") )
299                        range = StringConverter::parseReal( XMLAttentuation->Attribute("range") );
300                if( XMLAttentuation->Attribute("constant") )
301                        constant = StringConverter::parseReal( XMLAttentuation->Attribute("constant") );
302                if( XMLAttentuation->Attribute("linear") )
303                        linear = StringConverter::parseReal( XMLAttentuation->Attribute("linear") );
304                if( XMLAttentuation->Attribute("quadratic") )
305                        quadratic = StringConverter::parseReal( XMLAttentuation->Attribute("quadratic") );
306                        light->setAttenuation( range, constant, linear, quadratic );
307        }
308
309        XMLPosition = XMLLight->FirstChildElement("position");
310        if( XMLPosition )
311        {
312                Vector3 p = Vector3(0,0,0);
313                if( XMLPosition->Attribute("x") )
314                        p.x = StringConverter::parseReal( XMLPosition->Attribute("x") );
315                if( XMLPosition->Attribute("y") )
316                        p.y = StringConverter::parseReal( XMLPosition->Attribute("y") );
317                if( XMLPosition->Attribute("z") )
318                        p.z = StringConverter::parseReal( XMLPosition->Attribute("z") );
319           
320                light->setPosition( p );
321        }
322
323        //castShadows           (true | false) "true"
324        light->setCastShadows( true );
325        if( XMLLight->Attribute("visible") )
326                if( String(XMLLight->Attribute("visible")) == "false" )
327                                light->setCastShadows( false );
328                       
329        //visible                       (true | false) "true"           
330        light->setVisible( true );
331        if( XMLLight->Attribute("visible") )
332                if( String(XMLLight->Attribute("visible")) == "false" )
333                        light->setVisible( false );
334
335        return light;
336}
337//-----------------------------------------------------------------------
338void TestCullingDotSceneApplication::createScene(void)
339{
340        mSceneMgr->setAmbientLight(ColourValue(0.09f, 0.09f, 0.09f));
341        mSceneMgr->setSkyBox(true, "Examples/MorningSkyBox" );
342               
343        //This is default, though, set it anyway :)
344        ResourceGroupManager::getSingleton().setWorldResourceGroupName("General");
345        mSceneMgr->setWorldGeometry( "MyScene.scene" );
346        //mSceneMgr->SetOctreeVisible( 1 );
347               
348        ParseDotScene( "MyScene.scene", "General" );
349        // CEGUI setup
350        setupGui();
351}
352//-----------------------------------------------------------------------
353void TestCullingDotSceneApplication::setupGui( void )
354{
355         mGUIRenderer = new CEGUI::OgreCEGUIRenderer(mWindow, Ogre::RENDER_QUEUE_OVERLAY, false, 3000, ST_GENERIC);
356     mGUISystem = new CEGUI::System(mGUIRenderer);
357
358         // Mouse
359     CEGUI::SchemeManager::getSingleton().loadScheme((CEGUI::utf8*)"TaharezLook.scheme");
360     CEGUI::MouseCursor::getSingleton().setImage("TaharezLook", "MouseArrow");
361         mGUISystem->setDefaultMouseCursor(
362                (CEGUI::utf8*)"TaharezLook", (CEGUI::utf8*)"MouseArrow");
363
364         CEGUI::MouseCursor::getSingleton().show( );
365     
366        /* CEGUI::Window* sheet =
367            CEGUI::WindowManager::getSingleton().loadWindowLayout(
368                (CEGUI::utf8*)"ogregui.layout");
369
370     mGUISystem->setGUISheet(sheet);*/
371}
372//-----------------------------------------------------------------------
373void TestCullingDotSceneApplication::createFrameListener(void)
374{
375        mFrameListener= new MouseQueryListener(mWindow, mCamera, mSceneMgr, mGUIRenderer);
376        mFrameListener->showDebugOverlay(true);
377        mRoot->addFrameListener(mFrameListener);
378}
379//-----------------------------------------------------------------------
380void TestCullingDotSceneApplication::chooseSceneManager(void)
381{
382        mSceneMgr = mRoot->getSceneManager(ST_GENERIC);
383
384}
385//-----------------------------------------------------------------------
386void TestCullingDotSceneApplication::createViewports(void)
387{
388        // Create one viewport, entire window
389        Viewport* vp = mWindow->addViewport(mCamera);
390        // Look back along -Z
391    mCamera->lookAt(Vector3(0, 0, -300));
392        mCamera->setPosition(0 , 100, 600);
393}
394
395/***********************************************/
396/* MouseQueryListener implementation           */
397/***********************************************/
398
399//-----------------------------------------------------------------------
400MouseQueryListener::MouseQueryListener(RenderWindow* win, Camera* cam, SceneManager *sceneManager, CEGUI::Renderer *renderer)
401        : ExampleFrameListener(win, cam, false, true), mGUIRenderer(renderer),
402                mShutdownRequested(false)
403{
404
405        // Setup default variables
406//      mCurrentObject = NULL;
407        mLMouseDown = false;
408        mRMouseDown = false;
409        mSceneMgr = sceneManager;
410
411    // Reduce move speed
412        mMoveSpeed = 50;
413        mRotateSpeed *= 2;
414
415        mCurrentAlgorithm = 0;//GtpVisibility::VisibilityEnvironment::FRUSTUM_CULLING;
416        mThreshold = 0;
417   
418        // Register this so that we get mouse events.
419        mEventProcessor->addMouseListener(this);
420        mEventProcessor->addMouseMotionListener(this);
421        mEventProcessor->addKeyListener(this);
422
423        // show overlay
424        Overlay* pOver = OverlayManager::getSingleton().getByName("Example/VisibilityDemoOverlay");
425
426        mAlgorithmInfo = OverlayManager::getSingleton().getOverlayElement("Example/Occlusion/AlgorithmInfo");
427        mThresholdInfo = OverlayManager::getSingleton().getOverlayElement("Example/Occlusion/ThresholdInfo");
428        mFrustumCulledNodesInfo = OverlayManager::getSingleton().getOverlayElement("Example/Occlusion/FrustumCulledNodesInfo");
429        mQueryCulledNodesInfo = OverlayManager::getSingleton().getOverlayElement("Example/Occlusion/QueryCulledNodesInfo");
430    mTraversedNodesInfo = OverlayManager::getSingleton().getOverlayElement("Example/Occlusion/TraversedNodesInfo");
431
432        mAlgorithmInfo->setCaption(": " + mCurrentAlgorithmCaptions[mCurrentAlgorithm]);
433        mThresholdInfo->setCaption(": 0");
434        mFrustumCulledNodesInfo->setCaption(": 0");
435        mQueryCulledNodesInfo->setCaption(": 0");
436        mTraversedNodesInfo->setCaption(": 0");
437
438    pOver->show();
439} // MouseQueryListener
440//-----------------------------------------------------------------------
441void MouseQueryListener::mouseMoved (MouseEvent *e)
442{
443        // Update CEGUI with the mouse motion
444    CEGUI::System::getSingleton().injectMouseMove(e->getRelX() * mGUIRenderer->getWidth(), e->getRelY() * mGUIRenderer->getHeight());
445}
446//-----------------------------------------------------------------------
447void MouseQueryListener::mousePressed(MouseEvent* e)
448{
449     // Left mouse button down
450     if (e->getButtonID() & InputEvent::BUTTON0_MASK)
451     {
452                 CEGUI::MouseCursor::getSingleton().hide( );
453                 mLMouseDown = true;
454     } // if
455     // Right mouse button down
456     else if (e->getButtonID() & InputEvent::BUTTON1_MASK)
457     {
458         CEGUI::MouseCursor::getSingleton().hide( );
459         mRMouseDown = true;
460     } // else if
461} // mousePressed
462
463 //-----------------------------------------------------------------------
464void MouseQueryListener::mouseReleased(MouseEvent* e)
465{
466    // Left mouse button up
467    if (e->getButtonID() & InputEvent::BUTTON0_MASK)
468    {
469                CEGUI::MouseCursor::getSingleton().show( );
470        mLMouseDown = false;
471    }
472    // Right mouse button up
473    else if (e->getButtonID() & InputEvent::BUTTON1_MASK)
474    {
475        CEGUI::MouseCursor::getSingleton().show( );
476        mRMouseDown = false;
477    }
478}
479//-----------------------------------------------------------------------
480void MouseQueryListener::mouseDragged (MouseEvent *e)
481 {
482         // If we are dragging the left mouse button.   
483         if ( mLMouseDown )
484         {
485                mCamera->yaw( -e->getRelX() * mRotateSpeed );
486                mCamera->pitch( -e->getRelY() * mRotateSpeed );
487     }
488                 
489         // If we are dragging the right mouse button.
490         if ( mRMouseDown )
491         {
492                 Vector3 translation;
493                 translation.x += -e->getRelX() * 0.13;
494                 translation.y -= -e->getRelY() * 0.13;
495
496                 mCamera->moveRelative(translation);           
497         }
498}
499//-----------------------------------------------------------------------
500bool MouseQueryListener::frameEnded(const FrameEvent& evt)
501{
502        if (mShutdownRequested)
503                return false;
504
505    if (timeDelay >= 0)
506        timeDelay -= evt.timeSinceLastFrame;
507
508    KEY_PRESSED(KC_SPACE, 0.3, changeAlgorithm());
509
510        KEY_PRESSED(KC_SUBTRACT, 0.0, changeThreshold(-10));
511        KEY_PRESSED(KC_ADD, 0, changeThreshold(10));
512        //KEY_PRESSED(KC_T, 1, change);
513     
514        changeStats();
515
516    return ExampleFrameListener::frameStarted(evt) && ExampleFrameListener::frameEnded(evt);       
517}
518//-----------------------------------------------------------------------
519void MouseQueryListener::changeThreshold(int incr)
520{
521        mThreshold += incr; if(mThreshold < 0) mThreshold = 0;
522       
523        char str[100]; sprintf(str,": %d", mThreshold);
524
525        mSceneMgr->setOption("Threshold", &mThreshold);
526        mThresholdInfo->setCaption(str);
527}
528//-----------------------------------------------------------------------
529void MouseQueryListener::changeAlgorithm()
530{
531//    mCurrentAlgorithm = ++mCurrentAlgorithm % VisibilitySceneTraverser::NUM_RENDERMODES;
532
533        mAlgorithmInfo->setCaption(": " + mCurrentAlgorithmCaptions[mCurrentAlgorithm]);
534        mSceneMgr->setOption("Algorithm", &mCurrentAlgorithm);
535}
536//-----------------------------------------------------------------------
537void MouseQueryListener::changeStats()
538{
539        unsigned int opt = 0;
540        char str[100];
541       
542        mSceneMgr->getOption("NumFrustumCulledNodes", &opt); sprintf(str,": %d", opt);
543        mFrustumCulledNodesInfo->setCaption(str);
544       
545        mSceneMgr->getOption("NumQueryCulledNodes", &opt); sprintf(str,": %d", opt);
546        mQueryCulledNodesInfo->setCaption(str);
547       
548        mSceneMgr->getOption("NumTraversedNodes", &opt); sprintf(str,": %d", opt);
549        mTraversedNodesInfo->setCaption(str);
550}
551//-----------------------------------------------------------------------
552void MouseQueryListener::keyPressed(KeyEvent* e)
553{
554        if(e->getKey() == KC_ESCAPE)
555    {
556                mShutdownRequested = true;
557                e->consume();
558                return;
559        }
560
561        CEGUI::System::getSingleton().injectKeyDown(e->getKey());
562        CEGUI::System::getSingleton().injectChar(e->getKeyChar());
563        e->consume();
564}
565//-----------------------------------------------------------------------
566void MouseQueryListener::keyReleased(KeyEvent* e)
567{
568        CEGUI::System::getSingleton().injectKeyUp(e->getKey());
569        e->consume();
570}
571//-----------------------------------------------------------------------
572void MouseQueryListener::keyClicked(KeyEvent* e)
573{
574        // Do nothing
575        e->consume();
576}
577//-----------------------------------------------------------------------
578INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR strCmdLine, INT )
579{
580    // Create application object
581    TestCullingDotSceneApplication app;
582
583        try
584        {
585        app.go();
586    }
587        catch( Ogre::Exception& e )
588        {
589        MessageBox( NULL, e.getFullDescription().c_str(), "An exception has occured!", MB_OK | MB_ICONERROR | MB_TASKMODAL);
590    }   
591
592    return 0;
593}
Note: See TracBrowser for help on using the repository browser.