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

Revision 161, 13.9 KB checked in by mattausch, 19 years ago (diff)

added moving robots

RevLine 
[61]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
[100]8#include <Ogre.h>
[161]9
[115]10//#include "OgreReferenceAppLayer.h"
[100]11//#include "OgreRefAppWorld.h"
[61]12#include "TestCullingTerrainApplication.h"
13
[115]14
[61]15#define WIN32_LEAN_AND_MEAN
[94]16#include <windows.h>
[61]17
[160]18String currentObjectCaptions[] =
19{
20        "robot",
21        "athene",
22        "ninja"
23        //"ogrehead"
24};
25
[161]26/***************************************/
27/*      EntityState implementation     */
28/***************************************/
29EntityState::EntityState(Entity *ent, State entityState, Real speed):
30mEntity(ent), mState(entityState), mAnimationSpeed(speed)
31{
32        switch(entityState)
33        {
34        case MOVING:
35                mAnimationState = mEntity->getAnimationState("Walk");
36                break;
37        case WAITING:
38                mAnimationState = mEntity->getAnimationState("Idle");
39                break;
40        case STOP:
41                mAnimationState = NULL;
42                break;
43        default:
44                break;
45        }
46        // enable animation state
47        if (mAnimationState)
48        {
49                mAnimationState->setLoop(true);
50                mAnimationState->setEnabled(true);
51        }
52        mTimeElapsed = Math::RangeRandom(1, 5);
53}
54//-----------------------------------------------------------------------
55Entity *EntityState::GetEntity()
56{
57        return mEntity;
58}
59//-----------------------------------------------------------------------
60EntityState::State EntityState::GetState()
61{
62        return mState;
63}
64//-----------------------------------------------------------------------
65void EntityState::update(Real timeSinceLastFrame)
66{
67        mTimeElapsed -= timeSinceLastFrame * mAnimationSpeed;
68       
69        if (mState == MOVING) // toggle between moving (longer) and waiting (short)
70        {
71                SceneNode *parent = mEntity->getParentSceneNode();
72
73                if (mTimeElapsed <= 0) // toggle animation state
74                {
75                        if (mAnimationState->getAnimationName() == "Idle")
76                        {
77                                SetAnimationState("Walk", true);
78                                mTimeElapsed = 10; // walk for mTimeElapsed units
79
80                                // choose random direction between zero and two pi
81                                Radian rnd = Radian(Math::UnitRandom() * Math::HALF_PI);
82
83                                //mEntity->getParentSceneNode()->rotate();
84                                parent->yaw(rnd);                                               
85                        }
86                        else
87                        {
88                                SetAnimationState("Idle", true);
89                                mTimeElapsed = 2; // wait for mTimeElapsed seconds
90                        }
91                }
92
93                if (mAnimationState->getAnimationName() == "Walk")
94                {
95                        Vector3 oldPos = parent->getPosition();
96
97                        parent->translate(parent->getLocalAxes(), Vector3(0.03 * mAnimationSpeed, 0, 0));
98
99                        // HACK: if out of bounds => go back to idle
100                        if (OutOfBounds(parent))
101                        {
102                                parent->setPosition(oldPos);
103                                SetAnimationState("Idle);
104                               
105                                mTimeElapsed = 2;
106                        }
107                }
108        }
109               
110        if (mAnimationState) // add time to drive animation
111        {
112                mAnimationState->addTime(timeSinceLastFrame * mAnimationSpeed);
113        }
114}
115//-----------------------------------------------------------------------
116void EntityState::SetAnimationState(String stateStr, bool loop)
117{
118        mAnimationState = mEntity->getAnimationState(stateStr);
119        mAnimationState->setLoop(loop);
120        mAnimationState->setEnabled(true);
121}
122//-----------------------------------------------------------------------
123bool EntityState::OutOfBounds(SceneNode *node)
124{
125        Vector3 pos = node->getPosition();
126
127        if ((pos > msMinPos) && (pos < msMaxPos))
128                return true;
129
130        return false;
131}
[160]132/*********************************************************/
133/*      TestCullingTerrainApplication implementation     */
134/*********************************************************/
135
136
[145]137TestCullingTerrainApplication::TestCullingTerrainApplication():
138mTerrainContentGenerator(NULL)
139{
140}
[100]141//-----------------------------------------------------------------------
[61]142TestCullingTerrainApplication::~TestCullingTerrainApplication()
143{
[161]144        OGRE_DELETE(mTerrainContentGenerator);
145        OGRE_DELETE(mRayQueryExecutor);
146        deleteEntityStates();
147}
148//-----------------------------------------------------------------------
149void TestCullingTerrainApplication::deleteEntityStates()
150{
151        for (int i = 0; i < (int)mEntityStates.size(); ++i)
[122]152        {
[161]153                delete mEntityStates[i];
154                mEntityStates[i] = NULL;
[122]155        }
[161]156        mEntityStates.clear();
[61]157}
158//-----------------------------------------------------------------------
[93]159void TestCullingTerrainApplication::createCamera()
[61]160{
[99]161        // create the camera
[103]162        mCamera = mSceneMgr->createCamera("PlayerCam");
[93]163       
[100]164        /** set a nice viewpoint
165        *       we use a camera node here and apply all transformations on it instead
166        *       of applying all transformations directly to the camera
167        *       because then the camera is displayed correctly in the visualization
168        */
[137]169        mCamNode = mSceneMgr->getRootSceneNode()->
170                createChildSceneNode("CamNode1", Vector3(707, 5000, 528));
[100]171        //mCamera->setPosition(707, 5000, 528);
172        mCamNode->setOrientation(Quaternion(-0.3486, 0.0122, 0.9365, 0.0329));
173        mCamNode->attachObject(mCamera);
[61]174
[100]175        //-- create visualization camera
176        mVizCamera = mSceneMgr->createCamera("VizCam");
177        mVizCamera->setPosition(mCamNode->getPosition());
178
179        mVizCamera->setNearClipDistance(1);
[93]180        mCamera->setNearClipDistance(1);
[61]181
[99]182        // infinite far plane?
[93]183        if (mRoot->getRenderSystem()->getCapabilities()->hasCapability(RSC_INFINITE_FAR_PLANE))
184        {
[100]185                mVizCamera->setFarClipDistance(0);
[93]186                mCamera->setFarClipDistance(0);
187        }
188        else
189        {
[104]190                 mVizCamera->setFarClipDistance(20000);
191                 mCamera->setFarClipDistance(20000);
[99]192        }       
[61]193}
[99]194
[61]195//-----------------------------------------------------------------------
[99]196bool TestCullingTerrainApplication::setup()
197{
[145]198        bool carryOn = ExampleApplication::setup();
[99]199
[145]200        if (carryOn)
[144]201                createRenderTargetListener();
[99]202
[145]203        return carryOn;
[99]204}
205//-----------------------------------------------------------------------
206void TestCullingTerrainApplication::createRenderTargetListener()
207{
208        mWindow->addListener(new VisualizationRenderTargetListener(mSceneMgr));
209}
210//-----------------------------------------------------------------------
[75]211void TestCullingTerrainApplication::createScene()
[61]212{
213        // Set ambient light
[139]214        mAmbientLight = ColourValue(0.5, 0.5, 0.5);
215        mSceneMgr->setAmbientLight(mAmbientLight);
[113]216       
[110]217        //-- create light
[111]218        mSunLight = mSceneMgr->createLight("SunLight");
219        mSunLight->setType(Light::LT_DIRECTIONAL);
220        //mSunLight->setType(Light::LT_SPOTLIGHT);
[112]221        //mSunLight->setSpotlightRange(Degree(30), Degree(50));
222
[111]223    mSunLight->setPosition(707, 2000, 500);
224        mSunLight->setCastShadows(true);
225
[137]226        // set light angle not too sharp, otherwise shadows textures will be broken
[113]227        Vector3 dir(0.5, 1, 0.5);
[110]228        dir.normalise();
[112]229        mSunLight->setDirection(dir);
230        //mSunLight->setDirection(Vector3::NEGATIVE_UNIT_Y);
[111]231        mSunLight->setDiffuseColour(1, 1, 1);
232        mSunLight->setSpecularColour(1, 1, 1);
[110]233
[137]234        // -- Fog
[61]235        // NB it's VERY important to set this before calling setWorldGeometry
236        // because the vertex program picked will be different
237        ColourValue fadeColour(0.93, 0.86, 0.76);
238        mWindow->getViewport(0)->setBackgroundColour(fadeColour);
239        //mSceneMgr->setFog( FOG_LINEAR, fadeColour, .001, 500, 1000);
[94]240       
[61]241        // Create a skybox
[103]242        mSceneMgr->setSkyBox(true, "Examples/SpaceSkyBox", 5000, false);
243       
[61]244        std::string terrain_cfg("terrain.cfg");
245#if OGRE_PLATFORM == OGRE_PLATFORM_APPLE
246        terrain_cfg = mResourcePath + terrain_cfg;
247#endif
[74]248        mSceneMgr->setWorldGeometry(terrain_cfg);
[75]249       
[161]250        // ray query executor
251        mRayQueryExecutor = new RayQueryExecutor(mSceneMgr);
252
[100]253        //-- CEGUI setup
[61]254        setupGui();
[100]255
[159]256        /* // occluder plane to test visibility
[160]257        Plane plane; plane.normal = Vector3::UNIT_Y;    plane.d = -60;
[111]258        MeshManager::getSingleton().createPlane("Myplane",
259                ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, plane,
260                5000,5000,100,100,true,1,5,5,Vector3::UNIT_Z);
261        Entity* pPlaneEnt = mSceneMgr->createEntity( "plane", "Myplane" );
262        pPlaneEnt->setMaterialName("Examples/Rockwall");
263        pPlaneEnt->setCastShadows(true);
[159]264        mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(pPlaneEnt); */
265
[137]266        mSceneMgr->setShadowTextureSettings(1024, 2);
[112]267        mSceneMgr->setShadowColour(ColourValue(0.5, 0.5, 0.5));
[159]268   
[111]269
[100]270        //-- terrain content setup
271
[80]272        // HACK: necessary to call once before the content creation for
273        // terrain initialisation
274        mSceneMgr->_renderScene(mCamera, mWindow->getViewport(0), true);
[74]275
[82]276        mTerrainContentGenerator = new TerrainContentGenerator(mSceneMgr);
[110]277       
[160]278        // if no objects in file, we generate new objects
[110]279        if (!mTerrainContentGenerator->LoadObjects("objects.out"))
280        {
[135]281                // to provide much occlusion,
[160]282                // height is restricted to 50 => no objects appear on peaks
[107]283                mTerrainContentGenerator->SetMaxPos(Vector3(3000.0f, 50.0f, 3000.0f));
[111]284                mTerrainContentGenerator->SetOffset(0);
[110]285
[160]286                // the objects are generated randomly distributed over the terrain
287                generateScene(1500, 0);
[110]288        }
[86]289
[84]290        // no limitations needed anymore: the user can set
291        // objects also on peaks of terrain
[107]292        mTerrainContentGenerator->SetMaxPos(Vector3(3000.0f, 5000.0f, 3000.0f));
[61]293}
294//-----------------------------------------------------------------------
[160]295void  TestCullingTerrainApplication::generateScene(int num, int objectType)
296{
297        mTerrainContentGenerator->GenerateScene(num, currentObjectCaptions[objectType]);
298
299        if (objectType != 0) // from our objects, only robot has animation phases
300                return;
301
302        EntityList *entList = mTerrainContentGenerator->GetGeneratedEntities();
303
304        //-- add animation state for new robots (located at the end of the list)
[161]305        for (int i = entList->size() - num; i < (int)entList->size(); ++i)
[160]306        {
[161]307                mEntityStates.push_back(new EntityState((*entList)[i],
308                        EntityState::WAITING, Math::RangeRandom(0.5, 1.5)));
[160]309        }
310}
311//-----------------------------------------------------------------------
[161]312void TestCullingTerrainApplication::updateAnimations(Real timeSinceLastFrame)
[160]313{
[161]314        for (int i = 0; i < (int)mEntityStates.size(); ++i)
315        {
316                SceneNode *sm = mEntityStates[i]->GetEntity()->getParentSceneNode();
317
318                mEntityStates[i]->update(timeSinceLastFrame);
319
320                if (mEntityStates[i]->GetState() == EntityState::MOVING)
321                {
322                        Clamp2Terrain(sn, 0);
323                        //sm->setNodeVisible(false);
324                }
325        }
[160]326}
327//-----------------------------------------------------------------------
[161]328EntityStates  &TestCullingTerrainApplication::getEntityStates()
[160]329{
[161]330        return mEntityStates;
[160]331}
332//-----------------------------------------------------------------------
[80]333void TestCullingTerrainApplication::setupGui()
[61]334{
[75]335         mGUIRenderer = new CEGUI::OgreCEGUIRenderer(mWindow, Ogre::RENDER_QUEUE_OVERLAY,
336                 false, 3000, ST_EXTERIOR_CLOSE);
[61]337     mGUISystem = new CEGUI::System(mGUIRenderer);
338
339         // Mouse
340     CEGUI::SchemeManager::getSingleton().loadScheme((CEGUI::utf8*)"TaharezLook.scheme");
341     CEGUI::MouseCursor::getSingleton().setImage("TaharezLook", "MouseArrow");
[133]342         mGUISystem->setDefaultMouseCursor((CEGUI::utf8*)"TaharezLook",
343                                                                           (CEGUI::utf8*)"MouseArrow");
[61]344
[75]345         CEGUI::MouseCursor::getSingleton().show();
[61]346}
347//-----------------------------------------------------------------------
[80]348void TestCullingTerrainApplication::createFrameListener()
[61]349{
[133]350        mTerrainFrameListener = new TerrainFrameListener(mWindow, mCamera, mSceneMgr,
[160]351                mGUIRenderer, mTerrainContentGenerator, mVizCamera, mCamNode, mSunLight, this);
[120]352       
[115]353        mRoot->addFrameListener(mTerrainFrameListener);
[61]354}
355//-----------------------------------------------------------------------
[160]356String TestCullingTerrainApplication::getCurrentObjectCaption(int id)
357{
358        return currentObjectCaptions[id];
359}
360//-----------------------------------------------------------------------
[80]361void TestCullingTerrainApplication::chooseSceneManager()
[61]362{
363        mSceneMgr = mRoot->getSceneManager(ST_EXTERIOR_CLOSE);
364}
[161]365//-----------------------------------------------------------------------
366bool TestCullingTerrainApplication::Clamp2Terrain(SceneNode *node, int terrainOffs)
367{
368        // clamp scene node to terrain
369        Vector3 pos = node->getPosition();
370        Vector3 queryResult;
371
372        if (mRayQueryExecutor->executeRayQuery(&queryResult,
373                        Vector3(pos.x, MAX_HEIGHT, pos.z), Vector3::NEGATIVE_UNIT_Y))
374        {
375        node->setPosition(pos.x, queryResult.y + terrainOffs, pos.z);
376                return true;
377        }
378
379        return false;
380}
381
382
[99]383/**************************************************************/
384/*      VisualizationRenderTargetListener implementation      */
385/**************************************************************/
[107]386//-----------------------------------------------------------------------
[99]387VisualizationRenderTargetListener::VisualizationRenderTargetListener(SceneManager *sceneMgr)
388:RenderTargetListener(), mSceneMgr(sceneMgr)
389{
390}
[61]391//-----------------------------------------------------------------------
[99]392void VisualizationRenderTargetListener::preViewportUpdate(const RenderTargetViewportEvent &evt)
393{
[133]394        // visualization viewport
395        const bool showViz = evt.source->getZOrder() == VIZ_VIEWPORT_Z_ORDER;
[100]396        const bool nShowViz = !showViz;
397
[139]398        mSavedShadowTechnique = mSceneMgr->getShadowTechnique();
399        mSavedAmbientLight = mSceneMgr->getAmbientLight();
400
401        // -- ambient light must be full for visualization, shadows disabled
[113]402    if (showViz)
403        {
404                mSceneMgr->setAmbientLight(ColourValue(1, 1, 1));
[139]405                mSceneMgr->setShadowTechnique(SHADOWTYPE_NONE);
[113]406        }
[139]407       
408    mSceneMgr->setOption("PrepareVisualization", &showViz);
[100]409        mSceneMgr->setOption("SkyBoxEnabled", &nShowViz);
410        //mSceneMgr->setOption("SkyPlaneEnabled", &showViz);
[99]411       
412        RenderTargetListener::preViewportUpdate(evt);
413}
414//-----------------------------------------------------------------------
415void VisualizationRenderTargetListener::postRenderTargetUpdate(const RenderTargetEvent &evt)
416{
[139]417        // reset values
418        mSceneMgr->setShadowTechnique(mSavedShadowTechnique);
419        mSceneMgr->setAmbientLight(mSavedAmbientLight);
420       
[99]421        RenderTargetListener::postRenderTargetUpdate(evt);
422}
423//-----------------------------------------------------------------------
[61]424INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR strCmdLine, INT )
425{
426    // Create application object
427    TestCullingTerrainApplication app;
428
429        try
430        {
431        app.go();
432    }
433        catch( Ogre::Exception& e )
434        {
[75]435        MessageBox( NULL, e.getFullDescription().c_str(),
436                        "An exception has occured!", MB_OK | MB_ICONERROR | MB_TASKMODAL);
[61]437    }   
438
439    return 0;
[160]440}
Note: See TracBrowser for help on using the repository browser.