source: GTP/trunk/App/Demos/Vis/HillyTerrain/OGRE/TestCullingTerrainApplication.cpp @ 1265

Revision 1265, 25.8 KB checked in by mattausch, 18 years ago (diff)
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>
[901]7#include <OgreIteratorWrappers.h>
[100]8#include <Ogre.h>
[61]9#include "TestCullingTerrainApplication.h"
[173]10#include "TerrainFrameListener.h"
[61]11
[1158]12#if COLLADA
13#include "OgreColladaPrerequisites.h"
[999]14#include "OgreColladaDocument.h"
15#include "OgreColladaScene.h"
[1158]16#endif
[999]17
[866]18#include "IVReader.h"
19
[61]20#define WIN32_LEAN_AND_MEAN
[94]21#include <windows.h>
[61]22
[901]23const static bool USE_STATIC_GEOMETRY = false;
[866]24bool TestCullingTerrainApplication::msShowHillyTerrain = false;
[164]25
[924]26
27
[999]28/*************************************************************/
29/*                EntityState implementation                 */
30/*************************************************************/
[173]31
[866]32
[164]33Vector3 EntityState::msMinPos = Vector3::ZERO;
34Vector3 EntityState::msMaxPos = Vector3::ZERO;
35
[161]36EntityState::EntityState(Entity *ent, State entityState, Real speed):
37mEntity(ent), mState(entityState), mAnimationSpeed(speed)
38{
39        switch(entityState)
40        {
41        case MOVING:
42                mAnimationState = mEntity->getAnimationState("Walk");
43                break;
44        case WAITING:
45                mAnimationState = mEntity->getAnimationState("Idle");
46                break;
47        case STOP:
48                mAnimationState = NULL;
49                break;
50        default:
51                break;
52        }
53        // enable animation state
54        if (mAnimationState)
55        {
56                mAnimationState->setLoop(true);
57                mAnimationState->setEnabled(true);
58        }
[901]59
[161]60        mTimeElapsed = Math::RangeRandom(1, 5);
61}
62//-----------------------------------------------------------------------
[164]63EntityState::~EntityState()
64{
65        mAnimationState = NULL;
66        mEntity = NULL;
67}
68//-----------------------------------------------------------------------
[161]69Entity *EntityState::GetEntity()
70{
71        return mEntity;
72}
73//-----------------------------------------------------------------------
74EntityState::State EntityState::GetState()
75{
76        return mState;
77}
78//-----------------------------------------------------------------------
79void EntityState::update(Real timeSinceLastFrame)
80{
81        mTimeElapsed -= timeSinceLastFrame * mAnimationSpeed;
[164]82
83        if (!mEntity || !mAnimationState)
84                return;
[161]85       
86        if (mState == MOVING) // toggle between moving (longer) and waiting (short)
87        {
88                SceneNode *parent = mEntity->getParentSceneNode();
[164]89               
90                if (!parent)
91                        return;
[161]92
93                if (mTimeElapsed <= 0) // toggle animation state
94                {
95                        if (mAnimationState->getAnimationName() == "Idle")
96                        {
97                                SetAnimationState("Walk", true);
[164]98                               
99                                mTimeElapsed = walk_duration; // walk for mTimeElapsed units
[161]100
[164]101                                // choose random rotation
102                                Radian rnd = Radian(Math::UnitRandom() * Math::PI * rotate_factor);
[161]103
104                                //mEntity->getParentSceneNode()->rotate();
105                                parent->yaw(rnd);                                               
106                        }
107                        else
108                        {
109                                SetAnimationState("Idle", true);
[164]110                                mTimeElapsed = wait_duration; // wait for mTimeElapsed seconds
[161]111                        }
112                }
113
[164]114                if (mAnimationState->getAnimationName() == "Walk") // move forward
[161]115                {
[164]116                        // store old position, just in case we get out of bounds
[161]117                        Vector3 oldPos = parent->getPosition();
[164]118                        parent->translate(parent->getLocalAxes(), Vector3(move_factor * mAnimationSpeed, 0, 0));
[161]119
[164]120                        // HACK: if out of bounds => reset to old position and set animationstate to idle
[161]121                        if (OutOfBounds(parent))
122                        {
123                                parent->setPosition(oldPos);
[164]124                                SetAnimationState("Idle", true);
[161]125                               
[164]126                                mTimeElapsed = wait_duration;
[161]127                        }
128                }
129        }
130               
[164]131        // add time to drive animation
132        mAnimationState->addTime(timeSinceLastFrame * mAnimationSpeed);
[161]133}
134//-----------------------------------------------------------------------
135void EntityState::SetAnimationState(String stateStr, bool loop)
136{
[164]137        if (!mEntity)
138                return;
139
[161]140        mAnimationState = mEntity->getAnimationState(stateStr);
141        mAnimationState->setLoop(loop);
142        mAnimationState->setEnabled(true);
143}
144//-----------------------------------------------------------------------
145bool EntityState::OutOfBounds(SceneNode *node)
146{
147        Vector3 pos = node->getPosition();
148
149        if ((pos > msMinPos) && (pos < msMaxPos))
[164]150                return false;
[161]151
[164]152        return true;
[161]153}
[164]154
155
156
[945]157/********************************************************************/
158/*            TestCullingTerrainApplication implementation          */
159/********************************************************************/
[160]160
161
[145]162TestCullingTerrainApplication::TestCullingTerrainApplication():
[901]163mTerrainContentGenerator(NULL),
164mRayQueryExecutor(NULL),
[937]165mIVReader(NULL),
166mFilename("terrain"),
[1238]167mEnvironmentFilename("generate_viewcells.env")
[145]168{
169}
[924]170//-------------------------------------------------------------------------
171void TestCullingTerrainApplication::loadConfig(const String& filename)
172{
173        // TODO matt
174        // Set up the options
175        ConfigFile config;
176        String val;
177
178        config.load(filename);
179
[937]180        std::stringstream d; d << "reading the config file from: " << filename;
[924]181        LogManager::getSingleton().logMessage(d.str());
182
183        val = config.getSetting("Scene");
184
185    if (!val.empty())
186        {
187                 mFilename = val.c_str();
[937]188                 d << "\nloading scene from file: " << mFilename;
[924]189                 LogManager::getSingleton().logMessage(d.str());
190        }
191
[937]192       
[973]193        /*val = config.getSetting("ViewCells");
[924]194        if (!val.empty())
[973]195        {        mViewCellsFilename = val.c_str();}*/
[932]196
[937]197        val = config.getSetting("VisibilityEnvironment");
198
199        if (!val.empty())
200        {
201                 mEnvironmentFilename = val.c_str();
[973]202                 std::stringstream d; d << "loading environment from file: " << mEnvironmentFilename;
[937]203                 LogManager::getSingleton().logMessage(d.str());
204        }
205
[932]206        Vector3 v = Vector3::UNIT_SCALE;
207
208        val = config.getSetting("ViewX");
209
210        if (!val.empty())
211                v.x = atof( val.c_str() );
212
213        val = config.getSetting("ViewY");
214       
215        if (!val.empty())
216                v.y = atof(val.c_str());
217
218        val = config.getSetting("ViewZ");
219       
220        if (!val.empty())
221                v.z = atof( val.c_str());
222
[937]223
224        /////////////////////////
225        // setup scene
226
227        //-- load the scene from specified file
[1247]228
[937]229        if (!LoadScene(mFilename))
230                LogManager::getSingleton().logMessage("error loading scene");
231
232
233        GtpVisibility::VisibilityManager *mVisManager = NULL;
234
235        //-- load the environment from file
236        if (mSceneMgr->getOption("VisibilityManager", &mVisManager))
237        {
238                GtpVisibility::VisibilityEnvironment *visEnv = mVisManager->GetVisibilityEnvironment();
239               
240                if (!visEnv->LoadEnvironment(mEnvironmentFilename))
241                {
242                        std::stringstream d; d << "failed loading environment from " << mEnvironmentFilename;
243                        LogManager::getSingleton().logMessage(d.str());
244                }
245                else //-- load environment options
246                {
[973]247                        //-- get view cells file name, load view cells only on demand
[937]248                        mViewCellsFilename = visEnv->getViewCellsFileName();
249
250                        std::stringstream d; d << "view cells file name: " << mViewCellsFilename;
251                        LogManager::getSingleton().logMessage(d.str());
252                }
253        }
254        else
255        {
[973]256                LogManager::getSingleton().logMessage("error: no visibility scenemanager available");
[937]257        }
[1247]258
[932]259        // set camera position accordingly
260        mCamNode->setPosition(v);
[924]261}
[100]262//-----------------------------------------------------------------------
[61]263TestCullingTerrainApplication::~TestCullingTerrainApplication()
264{
[161]265        OGRE_DELETE(mTerrainContentGenerator);
266        OGRE_DELETE(mRayQueryExecutor);
[866]267        OGRE_DELETE(mIVReader);
[164]268
[657]269        deleteEntityStates();   
[161]270}
271//-----------------------------------------------------------------------
272void TestCullingTerrainApplication::deleteEntityStates()
273{
274        for (int i = 0; i < (int)mEntityStates.size(); ++i)
[122]275        {
[164]276                OGRE_DELETE(mEntityStates[i]);
[122]277        }
[164]278
[161]279        mEntityStates.clear();
[61]280}
281//-----------------------------------------------------------------------
[93]282void TestCullingTerrainApplication::createCamera()
[61]283{
[99]284        // create the camera
[103]285        mCamera = mSceneMgr->createCamera("PlayerCam");
[93]286       
[100]287        /** set a nice viewpoint
288        *       we use a camera node here and apply all transformations on it instead
289        *       of applying all transformations directly to the camera
290        *       because then the camera is displayed correctly in the visualization
291        */
[901]292        mCamNode = mSceneMgr->getRootSceneNode()->
[137]293                createChildSceneNode("CamNode1", Vector3(707, 5000, 528));
[901]294       
[100]295        mCamNode->setOrientation(Quaternion(-0.3486, 0.0122, 0.9365, 0.0329));
296        mCamNode->attachObject(mCamera);
[901]297       
[100]298        //-- create visualization camera
299        mVizCamera = mSceneMgr->createCamera("VizCam");
300        mVizCamera->setPosition(mCamNode->getPosition());
301
302        mVizCamera->setNearClipDistance(1);
[93]303        mCamera->setNearClipDistance(1);
[61]304
[99]305        // infinite far plane?
[93]306        if (mRoot->getRenderSystem()->getCapabilities()->hasCapability(RSC_INFINITE_FAR_PLANE))
307        {
[100]308                mVizCamera->setFarClipDistance(0);
[93]309                mCamera->setFarClipDistance(0);
310        }
311        else
312        {
[104]313                 mVizCamera->setFarClipDistance(20000);
314                 mCamera->setFarClipDistance(20000);
[99]315        }       
[61]316}
[99]317
[61]318//-----------------------------------------------------------------------
[99]319bool TestCullingTerrainApplication::setup()
320{
[145]321        bool carryOn = ExampleApplication::setup();
[99]322
[145]323        if (carryOn)
[144]324                createRenderTargetListener();
[99]325
[145]326        return carryOn;
[99]327}
328//-----------------------------------------------------------------------
329void TestCullingTerrainApplication::createRenderTargetListener()
330{
331        mWindow->addListener(new VisualizationRenderTargetListener(mSceneMgr));
332}
333//-----------------------------------------------------------------------
[1003]334bool TestCullingTerrainApplication::LoadSceneCollada(const String &filename,
335                                                                                                         SceneNode *root,
336                                                                                                         const int index)
[866]337{
[1158]338#if COLLADA
[999]339        // Collada
340        ColladaDocument *daeDoc = new ColladaDocument(mSceneMgr);
341
[1003]342        String daeName = filename;
343        //if (daeName.empty())
344        //      daeName = "City_1500.dae";
[999]345
346        // default directory
[1003]347        //daeName.insert(0, "../../media/models/collada/City");
[999]348        LogManager::getSingleton().logMessage("ColladaDocument - import started");
[1003]349
[999]350        // full import
351        if (daeDoc->doImport(daeName))
352        {
353                LogManager::getSingleton().logMessage("yuppi");
354                /**
355                 * build up scene
356                 * if you only want a specific part of the scene graph, you must fetch a scene node
357                 * by its unique node name and give it as parameter
358                 * e.g.
359                 * ColladaSceneNode *box = mScene->getNode("Box2");
360                 * if (box != NULL) box->createOgreInstance(NULL);
361                 */
362                daeDoc->getScene()->createOgreInstance(NULL);
[1003]363
364                // everything is loaded, we do not need the collada document anymore
365                delete daeDoc;
366
367                return true;
[999]368        }
[1003]369        else
370        {
371                LogManager::getSingleton().logMessage("ColladaDocument - import failed");
372                return false;
373        }
[1158]374#endif
[1003]375        return true;
376}
377//-----------------------------------------------------------------------
378bool TestCullingTerrainApplication::LoadSceneIV(const String &filename,
379                                                                                                SceneNode *root,
380                                                                                                const int index)
381{
[999]382
383
[1003]384
[866]385        mIVReader = new IVReader();
386
[945]387        Timer *timer = PlatformManager::getSingleton().createTimer();
388        timer->reset();
[924]389        if (1)
[901]390        {
[932]391                std::string logFilename = "IVLog" + Ogre::StringConverter().toString(index) + ".log";
392               
[924]393                Log *log = LogManager::getSingleton().createLog(logFilename);
394                mIVReader->setLog(log);
[866]395        }
396       
[901]397        //viennaNode->translate(Vector3(-300, -300, 0));
398
[924]399        if (mIVReader->loadFile(filename.c_str()))
[866]400        {
[924]401                SceneNode *node = root->createChildSceneNode("IVSceneNode" + index);
[866]402
[924]403                mIVReader->buildTree(mSceneMgr, node);
[945]404               
405                mIVReader->collapse();
[926]406                OGRE_DELETE(mIVReader);
[945]407
408
409                std::stringstream d;
410                d << "loaded " << filename << " in " << timer->getMilliseconds() * 1e-3 << " secs";
411                LogManager::getSingleton().logMessage(d.str());
412               
413                PlatformManager::getSingleton().destroyTimer(timer);
414
415                //-- bake into static geometry
416                if (USE_STATIC_GEOMETRY)
417                {
418                        BakeSceneIntoStaticGeometry("staticVienna", "Vienna");
419                }
420       
[924]421                return true;
[866]422        }
423
[924]424        return false;
[901]425}
426//--------------------------------------------------------
427void TestCullingTerrainApplication::BakeSceneIntoStaticGeometry(const String &staticGeomName,
428                                                                                                                                const String &nodeName)
429{
430#if OGRE_103
431        // note: different static geom for roofs, roads, ..., becazse they have same material
432        StaticGeometry *staticGeom = mSceneMgr->createStaticGeometry(staticGeomName);
433
434        // note: looping over entities here. why does scene node not work?
435        SceneManager::EntityIterator it = mSceneMgr->getEntityIterator();
436        while (it.hasMoreElements())
437        {
438                Entity *ent = it.getNext();
439                ent->setVisible(false);
440                staticGeom->addEntity(ent, ent->getParentSceneNode()->getPosition());
441        }
442
443        staticGeom->setRegionDimensions(Vector3(100,100,100));
444        staticGeom->build();
445
446        // cleanup node
447        //wallsNode->detachAllObjects();
448       
449        //roofsNode->detachAllObjects();
[924]450        //roadsNode->detachAllObjects();
[945]451        //planeNode->detachAllObjects();
[901]452       
453        //viennaNode->removeChild("Walls");
454        mSceneMgr->destroySceneNode(nodeName);
[866]455#endif
456}
[901]457//--------------------------------------------------------
[75]458void TestCullingTerrainApplication::createScene()
[61]459{
[924]460        //-- load scene
[937]461        loadConfig("terrainCulling.cfg");
462       
[924]463        /////////////////////////////////////
464
[61]465        // Set ambient light
[417]466        mAmbientLight = ColourValue(0.5, 0.5, 0.5);
[139]467        mSceneMgr->setAmbientLight(mAmbientLight);
[113]468       
[110]469        //-- create light
[111]470        mSunLight = mSceneMgr->createLight("SunLight");
471        mSunLight->setType(Light::LT_DIRECTIONAL);
472        //mSunLight->setType(Light::LT_SPOTLIGHT);
[112]473        //mSunLight->setSpotlightRange(Degree(30), Degree(50));
474
[111]475    mSunLight->setPosition(707, 2000, 500);
476        mSunLight->setCastShadows(true);
477
[173]478        // set light angle not too small over the surface, otherwise shadows textures will be broken
[113]479        Vector3 dir(0.5, 1, 0.5);
[110]480        dir.normalise();
[112]481        mSunLight->setDirection(dir);
482        //mSunLight->setDirection(Vector3::NEGATIVE_UNIT_Y);
[111]483        mSunLight->setDiffuseColour(1, 1, 1);
484        mSunLight->setSpecularColour(1, 1, 1);
[110]485
[137]486        // -- Fog
[61]487        // NB it's VERY important to set this before calling setWorldGeometry
488        // because the vertex program picked will be different
489        ColourValue fadeColour(0.93, 0.86, 0.76);
490        mWindow->getViewport(0)->setBackgroundColour(fadeColour);
491        //mSceneMgr->setFog( FOG_LINEAR, fadeColour, .001, 500, 1000);
[94]492       
[61]493        // Create a skybox
[175]494        mSceneMgr->setSkyBox(true, "Examples/CloudyNoonSkyBox", 5000, true);
[103]495       
[866]496        if (msShowHillyTerrain)
497        {
498                std::string terrain_cfg("terrain.cfg");
[61]499#if OGRE_PLATFORM == OGRE_PLATFORM_APPLE
[866]500                terrain_cfg = mResourcePath + terrain_cfg;
[61]501#endif
[866]502                mSceneMgr->setWorldGeometry(terrain_cfg);
503        }
[75]504       
[161]505
[100]506        //-- CEGUI setup
[61]507        setupGui();
[100]508
[901]509        // occluder plane to test visibility
510        if (0)
511        {
[924]512                Plane plane;
513                plane.normal = Vector3::UNIT_Y;
514                plane.d = -60;
515
[901]516                MeshManager::getSingleton().createPlane("Myplane",
517                        ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, plane,
518                        5000,5000,100,100,true,1,5,5,Vector3::UNIT_Z);
[924]519
[901]520                Entity* pPlaneEnt = mSceneMgr->createEntity( "plane", "Myplane" );
521                pPlaneEnt->setMaterialName("Examples/Rockwall");
522                pPlaneEnt->setCastShadows(true);
523                mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(pPlaneEnt);
524        }
[159]525
[866]526        // Warning: In GL since we can't go higher than the window res
[648]527        mSceneMgr->setShadowTextureSettings(1024, 2);
[173]528
[112]529        mSceneMgr->setShadowColour(ColourValue(0.5, 0.5, 0.5));
[111]530
[100]531        //-- terrain content setup
532
[80]533        // HACK: necessary to call once before the content creation for
534        // terrain initialisation
535        mSceneMgr->_renderScene(mCamera, mWindow->getViewport(0), true);
[74]536
[164]537        // ray query executor: needed to clamp to terrain
538        mRayQueryExecutor = new RayQueryExecutor(mSceneMgr);
539
540        mTerrainMinPos = EntityState::msMinPos = Vector3(0, 0, 0);
[346]541        mTerrainMaxPos = EntityState::msMaxPos = Vector3(5000, 5000, 5000);
[164]542
[82]543        mTerrainContentGenerator = new TerrainContentGenerator(mSceneMgr);
[945]544               
545        if (!msShowHillyTerrain)
546                return;
547
[160]548        // if no objects in file, we generate new objects
[945]549        if (!mTerrainContentGenerator->LoadObjects("objects.out"))
[346]550        {
[160]551                // the objects are generated randomly distributed over the terrain
[937]552                if (1) generateScene(1500, 0); // create robots
[723]553                if (0) generateScene(100, 1); // create trees
554                if (0) generateScene(100, 2); // create ninjas
[346]555        }
[61]556}
557//-----------------------------------------------------------------------
[160]558void  TestCullingTerrainApplication::generateScene(int num, int objectType)
559{
[345]560        float val = TerrainFrameListener::msObjectScales[objectType];
561        Vector3 scale(val, val, val);
[347]562        const float maxHeight = 75;
[417]563       
564        // In order to provide much occlusion,
[347]565        // height is restricted to maxHeight => no objects are created on peaks
[175]566        mTerrainContentGenerator->SetMinPos(Vector3(mTerrainMinPos));
[346]567        mTerrainContentGenerator->SetMaxPos(Vector3(mTerrainMaxPos.x, maxHeight, mTerrainMaxPos.z));
[417]568       
569        //std::stringstream d; d << "objscale: " << scale[0];
570        //Ogre::LogManager::getSingleton().logMessage(d.str());
571       
[173]572        mTerrainContentGenerator->SetScale(scale);
573        mTerrainContentGenerator->SetOffset(TerrainFrameListener::msObjectTerrainOffsets[objectType]);
574        mTerrainContentGenerator->GenerateScene(num, TerrainFrameListener::msObjectCaptions[objectType]);
575
[160]576        if (objectType != 0) // from our objects, only robot has animation phases
577                return;
578
579        EntityList *entList = mTerrainContentGenerator->GetGeneratedEntities();
580
581        //-- add animation state for new robots (located at the end of the list)
[175]582        for (int i = (int)entList->size() - num; i < (int)entList->size(); ++i)
[160]583        {
[161]584                mEntityStates.push_back(new EntityState((*entList)[i],
585                        EntityState::WAITING, Math::RangeRandom(0.5, 1.5)));
[160]586        }
[175]587
[347]588        // release limitations on height => it is possible for the user to put single
589        // objects on peaks of the terrain (will be only few, not relevant for occlusion)
[175]590        mTerrainContentGenerator->SetMaxPos(mTerrainMaxPos);
[160]591}
592//-----------------------------------------------------------------------
[161]593void TestCullingTerrainApplication::updateAnimations(Real timeSinceLastFrame)
[160]594{
[161]595        for (int i = 0; i < (int)mEntityStates.size(); ++i)
596        {
[164]597                SceneNode *sn = mEntityStates[i]->GetEntity()->getParentSceneNode();
[161]598
599                mEntityStates[i]->update(timeSinceLastFrame);
600
601                if (mEntityStates[i]->GetState() == EntityState::MOVING)
602                {
[164]603                        Clamp2Terrain(sn, 0); //sn->setNodeVisible(false);
[161]604                }
605        }
[160]606}
607//-----------------------------------------------------------------------
[161]608EntityStates  &TestCullingTerrainApplication::getEntityStates()
[160]609{
[161]610        return mEntityStates;
[160]611}
612//-----------------------------------------------------------------------
[80]613void TestCullingTerrainApplication::setupGui()
[61]614{
[901]615#if OGRE103
[75]616         mGUIRenderer = new CEGUI::OgreCEGUIRenderer(mWindow, Ogre::RENDER_QUEUE_OVERLAY,
617                 false, 3000, ST_EXTERIOR_CLOSE);
[901]618#else
619          mGUIRenderer = new CEGUI::OgreCEGUIRenderer(mWindow, Ogre::RENDER_QUEUE_OVERLAY,
620                 false, 3000, mSceneMgr);
621#endif
[61]622     mGUISystem = new CEGUI::System(mGUIRenderer);
623
624         // Mouse
625     CEGUI::SchemeManager::getSingleton().loadScheme((CEGUI::utf8*)"TaharezLook.scheme");
626     CEGUI::MouseCursor::getSingleton().setImage("TaharezLook", "MouseArrow");
[133]627         mGUISystem->setDefaultMouseCursor((CEGUI::utf8*)"TaharezLook",
628                                                                           (CEGUI::utf8*)"MouseArrow");
[61]629
[418]630         CEGUI::MouseCursor::getSingleton().hide();
[61]631}
632//-----------------------------------------------------------------------
[80]633void TestCullingTerrainApplication::createFrameListener()
[61]634{
[133]635        mTerrainFrameListener = new TerrainFrameListener(mWindow, mCamera, mSceneMgr,
[160]636                mGUIRenderer, mTerrainContentGenerator, mVizCamera, mCamNode, mSunLight, this);
[120]637       
[115]638        mRoot->addFrameListener(mTerrainFrameListener);
[61]639}
640//-----------------------------------------------------------------------
[80]641void TestCullingTerrainApplication::chooseSceneManager()
[61]642{
[901]643#ifdef OGRE_103
[866]644        if (msShowHillyTerrain)
645        {
646                // Terrain scene manager
647                mSceneMgr = mRoot->getSceneManager(ST_EXTERIOR_CLOSE);
648        }
649        else
650        {       // octree scene manager
651                mSceneMgr = mRoot->getSceneManager(ST_GENERIC);
652        }
[901]653#else
654        if (msShowHillyTerrain)
655        {
[924]656                //mSceneMgr = mRoot->createSceneManager("TerrainSceneManager");
657                mSceneMgr = mRoot->createSceneManager("OcclusionCullingSceneManager");
[999]658                //mSceneMgr = mRoot->createSceneManager("KdTreeSceneManager");
[901]659        }
660        else
[973]661        {       
[901]662                //mSceneMgr = mRoot->createSceneManager("OctreeSceneManager");
[924]663                mSceneMgr = mRoot->createSceneManager("OcclusionCullingSceneManager");
[999]664                //mSceneMgr = mRoot->createSceneManager("KdTreeSceneManager");
[901]665        }
666
667#endif
[61]668}
[161]669//-----------------------------------------------------------------------
670bool TestCullingTerrainApplication::Clamp2Terrain(SceneNode *node, int terrainOffs)
671{
672        // clamp scene node to terrain
673        Vector3 pos = node->getPosition();
674        Vector3 queryResult;
675
676        if (mRayQueryExecutor->executeRayQuery(&queryResult,
677                        Vector3(pos.x, MAX_HEIGHT, pos.z), Vector3::NEGATIVE_UNIT_Y))
678        {
679        node->setPosition(pos.x, queryResult.y + terrainOffs, pos.z);
680                return true;
681        }
682
683        return false;
684}
685
[866]686//-----------------------------------------------------------------------
687bool TestCullingTerrainApplication::Clamp2FloorPlane()
688{
689    // clamp to floor plane
690        RaySceneQuery *raySceneQuery = mSceneMgr->createRayQuery(
691                Ray(mCamNode->getPosition(), Vector3::NEGATIVE_UNIT_Y));
[161]692
[866]693        RaySceneQueryResult& qryResult = raySceneQuery->execute();
694   
695        RaySceneQueryResult::iterator rit = qryResult.begin();
696 
697        while (rit != qryResult.end() && rit->movable)
698        {
699                if (rit->movable->getName() != "PlayerCam")
700                {
701                        mCamNode->setPosition(mCamNode->getPosition().x,
702                                rit->movable->getWorldBoundingBox().getCenter().y + 2,
703                                mCamNode->getPosition().z);
704       
[924]705                        /*
706                        std::stringstream d;
[866]707                        d << "World: " << it->movable->getWorldBoundingBox().getCenter().y <<
708                        ", Object: " << it->movable->getBoundingBox().getCenter().y <<
709                        ", Camera: " << mCamera->getDerivedPosition();
710
711                        LogManager::getSingleton().logMessage(d.str());*/
712
713                        return true;
714                }
715
716                ++ rit;
717        }
718   
719        OGRE_DELETE(raySceneQuery);
720        return false;
721}
722
[924]723//-----------------------------------------------------------------------
724// splits strings containing multiple file names
725static int SplitFilenames(const std::string str, std::vector<std::string> &filenames)
726{
727        int pos = 0;
[866]728
[924]729        while(1)
730        {
731                int npos = (int)str.find(';', pos);
732               
733                if (npos < 0 || npos - pos < 1)
734                        break;
735                filenames.push_back(std::string(str, pos, npos - pos));
736                pos = npos + 1;
737        }
738       
739        filenames.push_back(std::string(str, pos, str.size() - pos));
740        return (int)filenames.size();
741}
[866]742
[924]743//-----------------------------------------------------------------------
[937]744bool TestCullingTerrainApplication::LoadScene(const String &filename)
[924]745{
746        using namespace std;
747        // use leaf nodes of the original spatial hierarchy as occludees
748        vector<string> filenames;
749        int files = SplitFilenames(filename, filenames);
750       
751        std::stringstream d;
752        d << "number of input files: " << files << "\n";
753        LogManager::getSingleton().logMessage(d.str());
754
755        bool result = false;
756        vector<string>::const_iterator fit, fit_end = filenames.end();
757        int i = 0;
758        // root for different files
759        for (fit = filenames.begin(); fit != fit_end; ++ fit, ++ i)
760        {
761                const string fn = *fit;
762
763                if (strstr(fn.c_str(), ".iv") || strstr(fn.c_str(), ".wrl"))
764                {
765                        // hack: set postion manually for vienna
[932]766                        //mCamNode->setPosition(Vector3(830, 300, -540));
767                        //mCamNode->setOrientation(Quaternion(-0.3486, 0.0122, 0.9365, 0.0329));
[924]768
769                        // load iv files
[1247]770                        if (!LoadSceneIV(fn, mSceneMgr->getRootSceneNode(), i))
771                        {
772                                // terrain hack
773                                msShowHillyTerrain = true;
774                                LogManager::getSingleton().logMessage("error loading scene. loading terrain instead");
775                        }
[924]776                }
[1003]777                else if (strstr(filename.c_str(), ".dae"))
[924]778                {
779                        // load collada files
[1003]780                        // load iv files
781                        LoadSceneCollada(fn, mSceneMgr->getRootSceneNode(), i);         
[924]782                }
[1003]783                else //if (filename == "terrain")
[924]784                {
785                        // terrain hack
786                        msShowHillyTerrain = true;
787                        LogManager::getSingleton().logMessage("loading terrain");
788                }
789       
790                result = true;
791        }
792       
793
794        /*
795        if (result)
796        {
797                int intersectables, faces;
798
799          std::stringstream d;
800          d << filename << " parsed successfully.\n"
801                << "#NUM_OBJECTS (Total numner of objects)\n" << intersectables << "\n"
802                << "#NUM_FACES (Total numner of faces)\n" << faces << "\n";
803        }
804        */
805       
806        return result;
807}
808//-----------------------------------------------------------------------
[937]809bool TestCullingTerrainApplication::LoadViewCells(const String &filename)
[924]810{
[937]811        LogManager::getSingleton().logMessage("loading view cells");
[924]812
[937]813        //-- the actual loading happens here
[973]814        return mSceneMgr->setOption("LoadViewCells", filename.c_str());
[924]815}
816
817
[866]818/**********************************************************************/
[901]819/*           VisualizationRenderTargetListener implementation         */
[866]820/**********************************************************************/
821
822
[107]823//-----------------------------------------------------------------------
[99]824VisualizationRenderTargetListener::VisualizationRenderTargetListener(SceneManager *sceneMgr)
825:RenderTargetListener(), mSceneMgr(sceneMgr)
826{
827}
[61]828//-----------------------------------------------------------------------
[99]829void VisualizationRenderTargetListener::preViewportUpdate(const RenderTargetViewportEvent &evt)
830{
[133]831        // visualization viewport
832        const bool showViz = evt.source->getZOrder() == VIZ_VIEWPORT_Z_ORDER;
[100]833        const bool nShowViz = !showViz;
834
[139]835        mSavedShadowTechnique = mSceneMgr->getShadowTechnique();
836        mSavedAmbientLight = mSceneMgr->getAmbientLight();
837
838        // -- ambient light must be full for visualization, shadows disabled
[113]839    if (showViz)
840        {
841                mSceneMgr->setAmbientLight(ColourValue(1, 1, 1));
[139]842                mSceneMgr->setShadowTechnique(SHADOWTYPE_NONE);
[113]843        }
[139]844       
845    mSceneMgr->setOption("PrepareVisualization", &showViz);
[100]846        mSceneMgr->setOption("SkyBoxEnabled", &nShowViz);
847        //mSceneMgr->setOption("SkyPlaneEnabled", &showViz);
[99]848       
849        RenderTargetListener::preViewportUpdate(evt);
850}
851//-----------------------------------------------------------------------
852void VisualizationRenderTargetListener::postRenderTargetUpdate(const RenderTargetEvent &evt)
853{
[139]854        // reset values
855        mSceneMgr->setShadowTechnique(mSavedShadowTechnique);
856        mSceneMgr->setAmbientLight(mSavedAmbientLight);
857       
[99]858        RenderTargetListener::postRenderTargetUpdate(evt);
859}
860//-----------------------------------------------------------------------
[61]861INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR strCmdLine, INT )
862{
863    // Create application object
864    TestCullingTerrainApplication app;
865
866        try
867        {
868        app.go();
869    }
870        catch( Ogre::Exception& e )
871        {
[75]872        MessageBox( NULL, e.getFullDescription().c_str(),
873                        "An exception has occured!", MB_OK | MB_ICONERROR | MB_TASKMODAL);
[61]874    }   
875
876    return 0;
[160]877}
Note: See TracBrowser for help on using the repository browser.