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

Revision 1003, 25.8 KB checked in by mattausch, 18 years ago (diff)

added collada importer

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