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

Revision 1816, 25.2 KB checked in by mattausch, 17 years ago (diff)

changed scenemanager: options are directly given to it

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