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

Revision 1609, 25.2 KB checked in by mattausch, 18 years ago (diff)
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       
195        val = config.getSetting("ViewCells");
196
197        if (!val.empty())
198        {
199                 mViewCellsFilename = val.c_str();
200                 std::stringstream d; d << "view cells file name: " << mViewCellsFilename;
201                 LogManager::getSingleton().logMessage(d.str());
202        }
203
204        mInitialPosition = Vector3::UNIT_SCALE;
205
206        val = config.getSetting("ViewX");
207
208        if (!val.empty())
209                mInitialPosition.x = atof( val.c_str() );
210
211        val = config.getSetting("ViewY");
212       
213        if (!val.empty())
214                mInitialPosition.y = atof(val.c_str());
215
216        val = config.getSetting("ViewZ");
217       
218        if (!val.empty())
219                mInitialPosition.z = atof( val.c_str());
220
221
222        val = config.getSetting("OnlineCullingAlgorithm");
223
224        if (!val.empty())
225        {
226                 if (val == "CHC")
227                 {
228                         mAlgorithm =
229                                 GtpVisibility::VisibilityEnvironment::COHERENT_HIERARCHICAL_CULLING;
230                 }
231                 else if (val == "SWC")
232                 {
233                         mAlgorithm =
234                                 GtpVisibility::VisibilityEnvironment::STOP_AND_WAIT_CULLING;
235                 }
236                 else if (val == "VFC")
237                 {
238                         mAlgorithm =
239                                 GtpVisibility::VisibilityEnvironment::FRUSTUM_CULLING;
240                 }
241                 else // default rendering
242                 {
243                         mAlgorithm =
244                                 GtpVisibility::VisibilityEnvironment::NUM_CULLING_MANAGERS;
245                 }
246        }
247
248        /////////////////////////
249        // setup scene
250
251        //-- load the scene from specified file
252        if (!LoadScene(mFilename))
253        {
254        LogManager::getSingleton().logMessage("error loading scene");
255        }
256       
257        // set camera position accordingly
258        mCamNode->setPosition(mInitialPosition);
259}
260//-----------------------------------------------------------------------
261TestCullingTerrainApplication::~TestCullingTerrainApplication()
262{
263        OGRE_DELETE(mTerrainContentGenerator);
264        OGRE_DELETE(mRayQueryExecutor);
265        OGRE_DELETE(mIVReader);
266
267        deleteEntityStates();   
268}
269//-----------------------------------------------------------------------
270void TestCullingTerrainApplication::deleteEntityStates()
271{
272        for (int i = 0; i < (int)mEntityStates.size(); ++i)
273        {
274                OGRE_DELETE(mEntityStates[i]);
275        }
276
277        mEntityStates.clear();
278}
279//-----------------------------------------------------------------------
280void TestCullingTerrainApplication::createCamera()
281{
282        // create the camera
283        mCamera = mSceneMgr->createCamera("PlayerCam");
284       
285        /** set a nice viewpoint
286        *       we use a camera node here and apply all transformations on it instead
287        *       of applying all transformations directly to the camera
288        *       because then the camera is displayed correctly in the visualization
289        */
290        mCamNode = mSceneMgr->getRootSceneNode()->
291                createChildSceneNode("CamNode1", Vector3(707, 5000, 528));
292       
293        mCamNode->setOrientation(Quaternion(-0.3486, 0.0122, 0.9365, 0.0329));
294        mCamNode->attachObject(mCamera);
295       
296        ///////////////////
297        //-- create visualization camera
298
299        mVizCamera = mSceneMgr->createCamera("VizCam");
300        mVizCamera->setPosition(mCamNode->getPosition());
301
302        mVizCamera->setNearClipDistance(1);
303        mCamera->setNearClipDistance(1);
304
305        // infinite far plane?
306        if (mRoot->getRenderSystem()->getCapabilities()->hasCapability(RSC_INFINITE_FAR_PLANE))
307        {
308                mVizCamera->setFarClipDistance(0);
309                mCamera->setFarClipDistance(0);
310        }
311        else
312        {
313                 mVizCamera->setFarClipDistance(20000);
314                 mCamera->setFarClipDistance(20000);
315        }       
316}
317
318//-----------------------------------------------------------------------
319bool TestCullingTerrainApplication::setup()
320{
321        bool carryOn = ExampleApplication::setup();
322
323        if (carryOn)
324                createRenderTargetListener();
325
326        return carryOn;
327}
328//-----------------------------------------------------------------------
329void TestCullingTerrainApplication::createRenderTargetListener()
330{
331        mWindow->addListener(new VisualizationRenderTargetListener(mSceneMgr));
332}
333//-----------------------------------------------------------------------
334bool TestCullingTerrainApplication::LoadSceneCollada(const String &filename,
335                                                                                                         SceneNode *root,
336                                                                                                         const int index)
337{
338#if COLLADA
339        // Collada
340        ColladaDocument *daeDoc = new ColladaDocument(mSceneMgr);
341
342        String daeName = filename;
343        //if (daeName.empty())
344        //      daeName = "City_1500.dae";
345
346        // default directory
347        //daeName.insert(0, "../../media/models/collada/City");
348        LogManager::getSingleton().logMessage("ColladaDocument - import started");
349
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);
363
364                // everything is loaded, we do not need the collada document anymore
365                delete daeDoc;
366
367                return true;
368        }
369        else
370        {
371                LogManager::getSingleton().logMessage("ColladaDocument - import failed");
372                return false;
373        }
374#endif
375        return true;
376}
377//-----------------------------------------------------------------------
378bool TestCullingTerrainApplication::LoadSceneIV(const String &filename,
379                                                                                                SceneNode *root,
380                                                                                                const int index)
381{
382
383
384
385        mIVReader = new IVReader();
386
387        Timer *timer = PlatformManager::getSingleton().createTimer();
388        timer->reset();
389        if (1)
390        {
391                std::string logFilename = "IVLog" + Ogre::StringConverter().toString(index) + ".log";
392               
393                Log *log = LogManager::getSingleton().createLog(logFilename);
394                mIVReader->setLog(log);
395        }
396       
397        //viennaNode->translate(Vector3(-300, -300, 0));
398
399        if (mIVReader->loadFile(filename.c_str()))
400        {
401                SceneNode *node = root->createChildSceneNode("IVSceneNode" + index);
402
403                mIVReader->buildTree(mSceneMgr, node);
404               
405                mIVReader->collapse();
406                OGRE_DELETE(mIVReader);
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       
421                return true;
422        }
423
424        return false;
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();
450        //roadsNode->detachAllObjects();
451        //planeNode->detachAllObjects();
452       
453        //viennaNode->removeChild("Walls");
454        mSceneMgr->destroySceneNode(nodeName);
455#endif
456}
457//--------------------------------------------------------
458void TestCullingTerrainApplication::createScene()
459{
460        //-- load scene
461        loadConfig("terrainCulling.cfg");
462       
463        /////////////////////////////////////
464
465        // Set ambient light
466        mAmbientLight = ColourValue(0.5, 0.5, 0.5);
467        mSceneMgr->setAmbientLight(mAmbientLight);
468       
469        //-- create light
470        mSunLight = mSceneMgr->createLight("SunLight");
471        mSunLight->setType(Light::LT_DIRECTIONAL);
472        //mSunLight->setType(Light::LT_SPOTLIGHT);
473        //mSunLight->setSpotlightRange(Degree(30), Degree(50));
474
475    mSunLight->setPosition(707, 2000, 500);
476        mSunLight->setCastShadows(true);
477
478        // set light angle not too small over the surface,
479        // otherwise shadows textures will be broken
480        Vector3 dir(0.5, 1, 0.5);
481        dir.normalise();
482        mSunLight->setDirection(dir);
483        //mSunLight->setDirection(Vector3::NEGATIVE_UNIT_Y);
484        mSunLight->setDiffuseColour(1, 1, 1);
485        mSunLight->setSpecularColour(1, 1, 1);
486
487        // -- Fog
488        // NB it's VERY important to set this before calling setWorldGeometry
489        // because the vertex program picked will be different
490        ColourValue fadeColour(0.93, 0.86, 0.76);
491        mWindow->getViewport(0)->setBackgroundColour(fadeColour);
492        //mSceneMgr->setFog(FOG_LINEAR, fadeColour, .001, 500, 1000);
493       
494        // Create a skybox
495        mSceneMgr->setSkyBox(true, "Examples/CloudyNoonSkyBox", 5000, true);
496       
497        // terrain creation
498        if (msShowHillyTerrain)
499        {
500                std::string terrain_cfg("terrain.cfg");
501#if OGRE_PLATFORM == OGRE_PLATFORM_APPLE
502                terrain_cfg = mResourcePath + terrain_cfg;
503#endif
504                mSceneMgr->setWorldGeometry(terrain_cfg);
505        }
506       
507
508        setupGui(); //-- CEGUI setup
509
510        // occluder plane to test visibility
511        if (0)
512        {
513                Plane plane;
514                plane.normal = Vector3::UNIT_Y;
515                plane.d = -60;
516
517                MeshManager::getSingleton().createPlane("Myplane",
518                        ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, plane,
519                        5000,5000,100,100,true,1,5,5,Vector3::UNIT_Z);
520
521                Entity* pPlaneEnt = mSceneMgr->createEntity( "plane", "Myplane" );
522                pPlaneEnt->setMaterialName("Examples/Rockwall");
523                pPlaneEnt->setCastShadows(true);
524                mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(pPlaneEnt);
525        }
526
527        // Warning: In GL since we can't go higher than the window res
528        mSceneMgr->setShadowTextureSettings(1024, 2);
529        mSceneMgr->setShadowColour(ColourValue(0.5, 0.5, 0.5));
530
531        //////////////77
532        //-- terrain content setup
533
534        // HACK: necessary to call once here for terrain initialisation
535        mSceneMgr->_renderScene(mCamera, mWindow->getViewport(0), true);
536
537        // ray query executor: needed to clamp to terrain
538        mRayQueryExecutor = new RayQueryExecutor(mSceneMgr);
539
540        mTerrainMinPos = EntityState::msMinPos = Vector3(0, 0, 0);
541        mTerrainMaxPos = EntityState::msMaxPos = Vector3(5000, 5000, 5000);
542
543        mTerrainContentGenerator = new TerrainContentGenerator(mSceneMgr);
544               
545        if (!msShowHillyTerrain)
546                return;
547
548        // if no objects in file, we generate new objects
549        if (!mTerrainContentGenerator->LoadObjects("objects.out"))
550        {
551                // the objects are generated randomly distributed over the terrain
552                if (1) generateScene(1500, 0); // create robots
553                if (0) generateScene(100, 1); // create trees
554                if (0) generateScene(100, 2); // create ninjas
555        }
556}
557//-----------------------------------------------------------------------
558void  TestCullingTerrainApplication::generateScene(int num, int objectType)
559{
560        float val = TerrainFrameListener::msObjectScales[objectType];
561        Vector3 scale(val, val, val);
562        const float maxHeight = 75;
563       
564        // In order to provide much occlusion,
565        // height is restricted to maxHeight => no objects are created on peaks
566        mTerrainContentGenerator->SetMinPos(Vector3(mTerrainMinPos));
567        mTerrainContentGenerator->SetMaxPos(Vector3(mTerrainMaxPos.x, maxHeight, mTerrainMaxPos.z));
568       
569        //std::stringstream d; d << "objscale: " << scale[0];
570        //Ogre::LogManager::getSingleton().logMessage(d.str());
571       
572        mTerrainContentGenerator->SetScale(scale);
573        mTerrainContentGenerator->SetOffset(TerrainFrameListener::msObjectTerrainOffsets[objectType]);
574        mTerrainContentGenerator->GenerateScene(num, TerrainFrameListener::msObjectCaptions[objectType]);
575
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)
582        for (int i = (int)entList->size() - num; i < (int)entList->size(); ++i)
583        {
584                mEntityStates.push_back(new EntityState((*entList)[i],
585                        EntityState::WAITING, Math::RangeRandom(0.5, 1.5)));
586        }
587
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)
590        mTerrainContentGenerator->SetMaxPos(mTerrainMaxPos);
591}
592//-----------------------------------------------------------------------
593void TestCullingTerrainApplication::updateAnimations(Real timeSinceLastFrame)
594{
595        for (int i = 0; i < (int)mEntityStates.size(); ++i)
596        {
597                SceneNode *sn = mEntityStates[i]->GetEntity()->getParentSceneNode();
598
599                mEntityStates[i]->update(timeSinceLastFrame);
600
601                if (mEntityStates[i]->GetState() == EntityState::MOVING)
602                {
603                        Clamp2Terrain(sn, 0); //sn->setNodeVisible(false);
604                }
605        }
606}
607//-----------------------------------------------------------------------
608EntityStates  &TestCullingTerrainApplication::getEntityStates()
609{
610        return mEntityStates;
611}
612//-----------------------------------------------------------------------
613void TestCullingTerrainApplication::setupGui()
614{
615#if OGRE103
616         mGUIRenderer = new CEGUI::OgreCEGUIRenderer(mWindow, Ogre::RENDER_QUEUE_OVERLAY,
617                 false, 3000, ST_EXTERIOR_CLOSE);
618#else
619          mGUIRenderer = new CEGUI::OgreCEGUIRenderer(mWindow, Ogre::RENDER_QUEUE_OVERLAY,
620                 false, 3000, mSceneMgr);
621#endif
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");
627         mGUISystem->setDefaultMouseCursor((CEGUI::utf8*)"TaharezLook",
628                                                                           (CEGUI::utf8*)"MouseArrow");
629
630         CEGUI::MouseCursor::getSingleton().hide();
631}
632//-----------------------------------------------------------------------
633void TestCullingTerrainApplication::createFrameListener()
634{
635        mTerrainFrameListener =
636                new TerrainFrameListener(mWindow,
637                                                                 mCamera,
638                                                                 mSceneMgr,
639                                                                 mGUIRenderer,
640                                                                 mTerrainContentGenerator,
641                                                                 mVizCamera,
642                                                                 mCamNode,
643                                                                 mSunLight,
644                                                                 this);
645       
646        mRoot->addFrameListener(mTerrainFrameListener);
647}
648//-----------------------------------------------------------------------
649void TestCullingTerrainApplication::chooseSceneManager()
650{
651#ifdef OGRE_103
652        if (msShowHillyTerrain)
653        {
654                // Terrain scene manager
655                mSceneMgr = mRoot->getSceneManager(ST_EXTERIOR_CLOSE);
656        }
657        else
658        {       // octree scene manager
659                mSceneMgr = mRoot->getSceneManager(ST_GENERIC);
660        }
661#else
662        if (msShowHillyTerrain)
663        {
664                mSceneMgr = mRoot->createSceneManager("OcclusionCullingSceneManager");
665                //mSceneMgr = mRoot->createSceneManager("TerrainSceneManager");
666                //mSceneMgr = mRoot->createSceneManager("KdTreeSceneManager");
667        }
668        else
669        {       
670                mSceneMgr = mRoot->createSceneManager("OcclusionCullingSceneManager");
671                //mSceneMgr = mRoot->createSceneManager("OctreeSceneManager");
672                //mSceneMgr = mRoot->createSceneManager("KdTreeSceneManager");
673        }
674
675#endif
676}
677//-----------------------------------------------------------------------
678bool TestCullingTerrainApplication::Clamp2Terrain(SceneNode *node, int terrainOffs)
679{
680        // clamp scene node to terrain
681        Vector3 pos = node->getPosition();
682        Vector3 queryResult;
683
684        if (mRayQueryExecutor->executeRayQuery(&queryResult,
685                        Vector3(pos.x, MAX_HEIGHT, pos.z), Vector3::NEGATIVE_UNIT_Y))
686        {
687        node->setPosition(pos.x, queryResult.y + terrainOffs, pos.z);
688                return true;
689        }
690
691        return false;
692}
693
694//-----------------------------------------------------------------------
695bool TestCullingTerrainApplication::Clamp2FloorPlane(const float dist)
696{
697    // clamp to floor plane
698        RaySceneQuery *raySceneQuery = mSceneMgr->createRayQuery(
699                Ray(mCamNode->getPosition(), Vector3::NEGATIVE_UNIT_Y));
700
701        RaySceneQueryResult& qryResult = raySceneQuery->execute();
702   
703        RaySceneQueryResult::iterator rit = qryResult.begin();
704        bool success = false;
705float yVal = 0;
706float minVal = 999999999999;
707
708        while (rit != qryResult.end() && rit->movable)
709        {
710                if (rit->movable->getName() != "PlayerCam")
711                {
712                        // place on the ground object
713                        yVal = rit->movable->getWorldBoundingBox().getCenter().y;
714                                if (yVal < minVal)
715                                        minVal = yVal;
716
717                        //std::stringstream d; d << "dist: " << dist << endl;
718                        //Ogre::LogManager()
719                        success = true;
720                }
721
722                ++ rit;
723        }
724   
725        // place on the ground object
726        if (success)
727                        mCamNode->setPosition(
728                                mCamNode->getPosition().x,
729                                minVal + dist,
730                                mCamNode->getPosition().z);
731
732        OGRE_DELETE(raySceneQuery);
733        return success;
734}
735
736//-----------------------------------------------------------------------
737// splits strings containing multiple file names
738static int SplitFilenames(const std::string str, std::vector<std::string> &filenames)
739{
740        int pos = 0;
741
742        while(1)
743        {
744                int npos = (int)str.find(';', pos);
745               
746                if (npos < 0 || npos - pos < 1)
747                        break;
748                filenames.push_back(std::string(str, pos, npos - pos));
749                pos = npos + 1;
750        }
751       
752        filenames.push_back(std::string(str, pos, str.size() - pos));
753        return (int)filenames.size();
754}
755//-----------------------------------------------------------------------
756bool TestCullingTerrainApplication::LoadScene(const String &filename)
757{
758        using namespace std;
759        // use leaf nodes of the original spatial hierarchy as occludees
760        vector<string> filenames;
761        int files = SplitFilenames(filename, filenames);
762       
763        std::stringstream d;
764        d << "number of input files: " << files << "\n";
765        LogManager::getSingleton().logMessage(d.str());
766
767        bool result = false;
768        vector<string>::const_iterator fit, fit_end = filenames.end();
769        int i = 0;
770
771        for (fit = filenames.begin(); fit != fit_end; ++ fit, ++ i)
772        {
773                const string fn = *fit;
774
775                if (strstr(fn.c_str(), ".iv") || strstr(fn.c_str(), ".wrl"))
776                {
777                        // load iv files
778                        if (!LoadSceneIV(fn, mSceneMgr->getRootSceneNode(), i))
779                        {
780                                // terrain hack
781                                msShowHillyTerrain = true;
782                                LogManager::getSingleton().logMessage("error loading scene => load terrain");
783                        }
784                }
785                else if (strstr(filename.c_str(), ".dae"))
786                {
787                        // load collada files
788                        // load iv files
789                        LoadSceneCollada(fn, mSceneMgr->getRootSceneNode(), i);         
790                }
791                else //if (filename == "terrain")
792                {
793                        // terrain hack
794                        msShowHillyTerrain = true;
795                        LogManager::getSingleton().logMessage("loading terrain");
796                }
797       
798                result = true;
799        }
800       
801        return result;
802}
803//-----------------------------------------------------------------------
804bool TestCullingTerrainApplication::LoadViewCells(const String &filename)
805{
806        LogManager::getSingleton().logMessage("loading view cells");
807
808        //-- the actual loading happens here
809        return mSceneMgr->setOption("LoadViewCells", filename.c_str());
810}
811
812
813/**********************************************************************/
814/*           VisualizationRenderTargetListener implementation         */
815/**********************************************************************/
816
817
818//-----------------------------------------------------------------------
819VisualizationRenderTargetListener::VisualizationRenderTargetListener(SceneManager *sceneMgr)
820:RenderTargetListener(), mSceneMgr(sceneMgr)
821{
822}
823//-----------------------------------------------------------------------
824void VisualizationRenderTargetListener::preViewportUpdate(const RenderTargetViewportEvent &evt)
825{
826        // visualization viewport
827        const bool showViz = evt.source->getZOrder() == VIZ_VIEWPORT_Z_ORDER;
828        const bool nShowViz = !showViz;
829
830        mSavedShadowTechnique = mSceneMgr->getShadowTechnique();
831        mSavedAmbientLight = mSceneMgr->getAmbientLight();
832
833        // -- ambient light must be full for visualization, shadows disabled
834    if (showViz)
835        {
836                mSceneMgr->setAmbientLight(ColourValue(1, 1, 1));
837                mSceneMgr->setShadowTechnique(SHADOWTYPE_NONE);
838        }
839       
840    mSceneMgr->setOption("PrepareVisualization", &showViz);
841        mSceneMgr->setOption("SkyBoxEnabled", &nShowViz);
842       
843        RenderTargetListener::preViewportUpdate(evt);
844}
845//-----------------------------------------------------------------------
846void VisualizationRenderTargetListener::postRenderTargetUpdate(const RenderTargetEvent &evt)
847{
848        // reset values
849        mSceneMgr->setShadowTechnique(mSavedShadowTechnique);
850        mSceneMgr->setAmbientLight(mSavedAmbientLight);
851       
852        RenderTargetListener::postRenderTargetUpdate(evt);
853}
854//-----------------------------------------------------------------------
855INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR strCmdLine, INT )
856{
857    // Create application object
858    TestCullingTerrainApplication app;
859
860        try
861        {
862        app.go();
863    }
864        catch( Ogre::Exception& e )
865        {
866        MessageBox( NULL, e.getFullDescription().c_str(),
867                        "An exception has occured!", MB_OK | MB_ICONERROR | MB_TASKMODAL);
868    }   
869
870    return 0;
871}
Note: See TracBrowser for help on using the repository browser.