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

Revision 1271, 25.0 KB checked in by mattausch, 18 years ago (diff)

removed the visibility env, now explicitly giving the view cells as argument

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