source: GTP/trunk/App/Demos/Vis/KdTreeDemo/OGRE/src/TestKdTree.cpp @ 1300

Revision 1300, 33.1 KB checked in by szydlowski, 18 years ago (diff)

view cells load/use implemented

Line 
1#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
2#define WIN32_LEAN_AND_MEAN
3#include "windows.h"
4#endif
5
6#include "TestKdTree.h"
7#include "WinCmdLineParser.h"
8#include <cstring>
9
10#ifdef __cplusplus
11extern "C" {
12#endif
13
14#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
15        INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR strCmdLine, INT )
16#else
17        int main(int argc, char *argv[])
18#endif
19        {
20#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
21                // parse windows-style command line
22
23                WinCmdLineParser cmdparser(strCmdLine);
24                KdTreeAppListener::Options options;
25
26                try
27                {
28                        cmdparser
29                                .addOpt("i","infile", ARGUMENT_REQUIRED)
30                                .addOpt("o","outfile", ARGUMENT_REQUIRED)
31                                .addOpt("l","logfile", ARGUMENT_REQUIRED)
32                                .addOpt("d","demomode", ARGUMENT_NONE)
33                                .addOpt("","buildmode", ARGUMENT_REQUIRED)
34                                .addOpt("","maxdepth", ARGUMENT_REQUIRED)
35                                .addOpt("","kt", ARGUMENT_REQUIRED)
36                                .addOpt("","ki", ARGUMENT_REQUIRED)
37                                .addOpt("r","rendermode", ARGUMENT_REQUIRED)
38                                .addOpt("s","scenemgr", ARGUMENT_REQUIRED)
39                                .addOpt("","comment", ARGUMENT_REQUIRED)
40                                .addOpt("e","enhancevis", ARGUMENT_NONE)
41                                .addOpt("","savesceneto", ARGUMENT_REQUIRED)
42                                .addOpt("f","faststart", ARGUMENT_NONE)
43                                .addOpt("b","burnin", ARGUMENT_NONE)
44                                .addOpt("v","viewcells", ARGUMENT_OPTIONAL);
45
46
47                        cmdparser.getOpt("i", options.mDemoInfileName);
48                        cmdparser.getOpt("o", options.mDemoOutfileName);
49                        cmdparser.getOpt("l", options.mDemoLogfileName);
50                        cmdparser.getOpt("comment", options.mComment);
51                        options.mFastStart = cmdparser.getOpt("f");
52                        options.mBurnIn = cmdparser.getOpt("b");
53                        options.mDemoMode = cmdparser.getOpt("d");
54                        options.mEnhancedVisibility = cmdparser.getOpt("e");
55                        cmdparser.getOpt("savesceneto", options.mSceneOutfileName);
56
57                        std::string tmp;
58                        std::stringstream s;
59
60                        if (cmdparser.getOpt("buildmode", tmp))
61                        {
62                                int bm = KdTree::KDBM_NOTSET;
63                                for (int i = 0; i < KdTree::KDBM_SIZE; i ++)
64                                {
65                                        if (tmp == KdTreeAppListener::BUILDMETHOD[i])
66                                                bm = i;
67                                }
68                                if (bm != KdTree::KDBM_NOTSET)
69                                {
70                                        options.mBuildMethod = bm;
71                                }
72                                else
73                                {
74                                        MessageBox(NULL, ("Invalid argument for option --buildmode: " + tmp).c_str(), "Error", MB_OK | MB_ICONERROR );
75                                        return -1;
76                                }
77                        }
78
79                        if (cmdparser.getOpt("maxdepth", tmp))
80                        {
81                                s << tmp;
82                                s >> options.mMaxDepth;
83                                s.clear();
84                        }
85
86                        if (cmdparser.getOpt("kt", tmp))
87                        {
88                                s << tmp;
89                                s >> options.mKT;
90                                s.clear();
91                        }
92
93                        if (cmdparser.getOpt("ki", tmp))
94                        {
95                                s << tmp;
96                                s >> options.mKI;
97                                s.clear();
98                        }
99
100                        if (cmdparser.getOpt("r",tmp))
101                        {
102                                int rm = KdTree::KDRM_NOTSET;
103                                for (int i = 0; i < KdTree::KDRM_SIZE; i ++)
104                                {
105                                        if (tmp == KdTreeAppListener::RENDERMETHOD[i])
106                                                rm = i;
107                                }
108                                if (rm != KdTree::KDRM_NOTSET)
109                                {
110                                        options.mRenderMethod = rm;
111                                }
112                                else
113                                {
114                                        MessageBox(NULL, ("Invalid argument for option --rendermode: " + tmp).c_str(), "Error", MB_OK | MB_ICONERROR );
115                                        return -1;
116                                }
117                        }
118
119                        if (cmdparser.getOpt("s",tmp))
120                        {
121                                int sm = KdTreeAppListener::SM_NOTSET;
122                                for (int i = 0; i < KdTreeAppListener::SM_SIZE; i ++)
123                                {
124                                        if (tmp == KdTreeAppListener::SCENEMANAGER[i])
125                                                sm = i;
126                                }
127                                if (sm != KdTreeAppListener::SM_NOTSET)
128                                {
129                                        options.mSceneManager = sm;
130                                }
131                                else
132                                {
133                                        MessageBox(NULL, ("Invalid argument for option --scenemgr: " + tmp).c_str(), "Error", MB_OK | MB_ICONERROR );
134                                        return -1;
135                                }
136                        }
137
138                        if (cmdparser.getOpt("v",tmp))
139                        {
140                                if (tmp == "0")
141                                        options.mViewCells = KdTreeAppListener::VCM_OFF;
142                                else if (tmp == "" || tmp == "1")
143                                        options.mViewCells = KdTreeAppListener::VCM_ON;
144                                else if (tmp == "2")
145                                        options.mViewCells = KdTreeAppListener::VCM_FILTER;
146                                else
147                                {
148                                        MessageBox(NULL, ("Invalid argument for option --viewcells: " + tmp).c_str(), "Error", MB_OK | MB_ICONERROR );
149                                        return -1;
150                                }
151
152                        }
153                }
154                catch (std::string s)
155                {
156                        MessageBox(NULL, s.c_str(), "Error", MB_OK | MB_ICONERROR );
157                        return -1;
158                }
159
160                // Create application object
161                KdTreeApp app(options);
162#else
163                // TODO: unix-style getopt
164                // Create application object
165                KdTreeApp app;
166#endif
167
168                SET_TERM_HANDLER;
169
170                // init random number generator
171                // srand(time(0));
172
173                try {
174                        app.go();
175                } catch( Ogre::Exception& e ) {
176#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
177                        MessageBox( NULL, e.getFullDescription().c_str(), "An exception has occured!", MB_OK | MB_ICONERROR | MB_TASKMODAL);
178#else
179                        std::cerr << "An exception has occured: " <<
180                                e.getFullDescription().c_str() << std::endl;
181#endif
182                }
183
184                return 0;
185        }
186
187#ifdef __cplusplus
188}
189#endif
190
191#define ENT_GRID        0x01
192#define ENT_RND         0x02
193#define ENT_SPC         0x04
194#define ENT_MOV         0x08
195#define ENT_PLN         0x10
196
197void KdTreeApp::setupResources(void)
198{
199        String tmp;
200        ConfigFile cfDeath;
201        char *errptr;
202        int base = 10;
203
204        cfDeath.load("testKdTree.cfg");
205
206        mSceneFiles = cfDeath.getSetting("scene");
207        mViewCells = cfDeath.getSetting("viewcells");
208
209        tmp = cfDeath.getSetting("shadows");
210        StringUtil::toLowerCase(tmp);
211        if (tmp == "on")
212                mShadowsEnabled = true;
213        else
214                mShadowsEnabled = false;
215
216
217        tmp = cfDeath.getSetting("planedim");
218        mPlaneDim = static_cast<Real>(strtod(tmp.c_str(), &errptr));
219
220        tmp = cfDeath.getSetting("randomcount");
221        mRandomCount = static_cast<int>(strtol(tmp.c_str(), &errptr, base));
222
223        tmp = cfDeath.getSetting("selectentities");
224        mSelectEntities = static_cast<int>(strtol(tmp.c_str(), &errptr, base));
225
226        tmp = cfDeath.getSetting("count");
227        mModelCount = static_cast<int>(strtol(tmp.c_str(), &errptr, base));
228
229        tmp = cfDeath.getSetting("spacing");
230        mModelSpacing = static_cast<int>(strtol(tmp.c_str(), &errptr, base));
231       
232        tmp = cfDeath.getSetting("radius");
233        mRotationRadius = static_cast<Real>(strtod(tmp.c_str(), &errptr));
234       
235        tmp = cfDeath.getSetting("period");
236        mOptions.mRotationPeriod = static_cast<Real>(strtod(tmp.c_str(), &errptr));
237
238        tmp = cfDeath.getSetting("movespeed");
239        mOptions.mMoveSpeed = static_cast<Real>(strtod(tmp.c_str(), &errptr));
240
241        tmp = cfDeath.getSetting("rotatespeed");
242        mOptions.mRotateSpeed = static_cast<Real>(strtod(tmp.c_str(), &errptr));
243
244        // command line has preference over config file
245        if (mOptions.mDemoInfileName.empty())
246                mOptions.mDemoInfileName = cfDeath.getSetting("demoinfile");
247
248        if (mOptions.mDemoOutfileName.empty())
249                mOptions.mDemoOutfileName = cfDeath.getSetting("demooutfile");
250
251        if (mOptions.mDemoLogfileName.empty())
252                mOptions.mDemoLogfileName = cfDeath.getSetting("demologfile");
253
254        ExampleApplication::setupResources();
255}
256
257
258void KdTreeApp::createScene(void)
259{
260        createMaterials();
261
262        // load simple scene (planes & robots)
263        if (mSceneFiles == "")
264        {
265                createSimpleScene();
266                mOptions.mSceneType = KdTreeAppListener::ST_SIMPLE;
267                mCamNode->setPosition(Vector3(1280,600,1666));
268                mCamNode->setOrientation(Quaternion(0.936893, -0.124586, 0.323813, 0.04306));
269        }
270        //// load terrain, but only if terrainscenemanager selected
271        //else if (mSceneFiles == TERRAIN_SCENE)
272        //{
273        //      Plane waterPlane;
274
275        //      // Set ambient light
276        //      mSceneMgr->setAmbientLight(ColourValue(0.5, 0.5, 0.5));
277
278        //      // Create a light
279        //      Light* l = mSceneMgr->createLight("MainLight");
280        //      // Accept default settings: point light, white diffuse, just set position
281        //      // NB I could attach the light to a SceneNode if I wanted it to move automatically with
282        //      //  other objects, but I don't
283        //      l->setPosition(20,80,50);
284
285        //      // Fog
286        //      // NB it's VERY important to set this before calling setWorldGeometry
287        //      // because the vertex program picked will be different
288        //      //ColourValue fadeColour(0.93, 0.86, 0.76);
289        //      //mSceneMgr->setFog( FOG_LINEAR, fadeColour, .001, 500, 1000);
290        //      //mWindow->getViewport(0)->setBackgroundColour(fadeColour);
291        //      mWindow->getViewport(0)->setBackgroundColour(ColourValue::Blue);
292
293        //      std::string terrain_cfg("terrain.cfg");
294
295        //      mSceneMgr -> setWorldGeometry( terrain_cfg );
296
297        //      // Define the required skyplane
298        //      Plane plane;
299        //      // 5000 world units from the camera
300        //      plane.d = 5000;
301        //      // Above the camera, facing down
302        //      plane.normal = -Vector3::UNIT_Y;
303
304        //      // read interesting params from config file
305        //      ConfigFile terrainconf;
306        //      std::stringstream s;
307        //      Real x,y,z;
308        //     
309        //      terrainconf.load(terrain_cfg);
310
311        //      s << terrainconf.getSetting("PageWorldX");
312        //      s >> x;
313        //      s.clear();
314
315        //      s << terrainconf.getSetting("MaxHeight");
316        //      s >> y;
317        //      s.clear();
318
319        //      s << terrainconf.getSetting("PageWorldZ");
320        //      s >> z;
321        //      s.clear();
322
323        //      // add stuff minus gound plane
324        //      createTerrainScene(x, y + 1500, z);
325
326        //      // Set a nice viewpoint
327        //      mCamNode->setPosition(707,2500,528);
328        //      mCamNode->setOrientation(Quaternion(-0.3486, 0.0122, 0.9365, 0.0329));
329        //      //mCamNode->setPosition(1056.59, 467.412, 783.502);
330        //      //mCamNode->setOrientation(Quaternion(-0.281354, 0.0204027, 0.956747, 0.0695345));
331        //}
332        // load scene from file
333        else
334        {
335                // don't load the other stuff
336                loadScene(mSceneFiles);
337
338                if (mOptions.mSceneType == KdTreeAppListener::ST_GEOMETRY)
339                {
340                        // initial position
341                        mCamNode->setPosition(Vector3(827.885, 184.435, -524.984));
342                        mCamNode->setOrientation(Quaternion(0.98935, 0.0348082, -0.141246, 0.00496945));
343                        // initial position for vis camera
344                        mTopCam->setPosition(Vector3(1232, 3990, -1477));
345
346                        //// try loading view cells if specified and if scene manager supports it
347                        //if (!mViewCells.empty())
348                        //      mSceneMgr->setOption("LoadViewCells", mViewCells.c_str());
349
350                        // sky box
351                        mSceneMgr->setSkyBox(true, "Examples/CloudyNoonSkyBox", 5000, true);
352                }
353                else if (mOptions.mSceneType == KdTreeAppListener::ST_TERRAIN)
354                {
355                        // initial position
356                        mCamNode->setPosition(707,2500,528);
357                        mCamNode->setOrientation(Quaternion(-0.3486, 0.0122, 0.9365, 0.0329));
358
359                        // sky box
360                        mSceneMgr->setSkyBox(true, "Examples/SpaceSkyBox", mPlaneDim * 2);
361                }
362        }
363}
364
365// fill terrain with robots, spaceships & whatever
366void KdTreeApp::createTerrainScene(Real max_x, Real max_y, Real max_z)
367{
368        Vector3 scale(0.3, 0.3, 0.3);
369        Entity *deaths;
370        SceneNode *nodes, *anchor;
371        std::string entName;
372        std::string nodeName;
373        int i;
374        Real min_x = 100, min_y = 0, min_z = 100;
375        max_x -= 100; max_z -= 100;
376
377        try
378        {
379                anchor = mSceneMgr->getSceneNode("AnchorNode");
380        }
381        catch (Exception)
382        {
383                anchor = mSceneMgr->getRootSceneNode()->createChildSceneNode("AnchorNode");             
384        }
385
386        if (mSelectEntities & ENT_RND)
387        {
388                entName = "randomdeath";
389                nodeName = "RandomDeathNode";
390                for (i = 0; i < mRandomCount; i++)
391                {
392                        Vector3 pos = clampToGround(Vector3(
393                                Math::RangeRandom(min_x, max_x),
394                                max_y,
395                                Math::RangeRandom(min_z, max_z)), 0, max_y);
396                       
397                        // hack to fill valleys
398                        if (pos == Vector3::ZERO)
399                        {
400                                -- i;
401                                continue;
402                        }
403
404                        deaths = mSceneMgr->createEntity(cat(entName,666,i),"robot.mesh");
405                        if (mShadowsEnabled)
406                                deaths->setCastShadows(true);
407                        nodes = /*mSceneMgr->getRootSceneNode()*/anchor->createChildSceneNode(cat(nodeName,666,i), pos,
408                                Quaternion(Radian(Math::RangeRandom(-Math::PI, Math::PI)), Vector3::UNIT_Y));
409                        nodes->attachObject(deaths);
410                        nodes->setScale(scale);
411                }
412        }
413
414        if (mSelectEntities & ENT_SPC)
415        {
416                entName = "randomspaceship";
417                nodeName = "RandomSpaceshipNode";
418                for (i = 0; i < mRandomCount; i++)
419                {
420                        Vector3 pos = clampToGround(Vector3(
421                                Math::RangeRandom(min_x, max_x),
422                                max_y,
423                                Math::RangeRandom(min_z, max_z)),
424                                Math::RangeRandom(20, 500), max_y);
425
426                        // hack to fill valleys
427                        if (pos == Vector3::ZERO)
428                        {
429                                -- i;
430                                continue;
431                        }
432
433                        deaths = mSceneMgr->createEntity(cat(entName,666,i),"razor.mesh");
434                        if (mShadowsEnabled)
435                                deaths->setCastShadows(true);
436                        nodes = /*mSceneMgr->getRootSceneNode()*/anchor->createChildSceneNode(cat(nodeName,666,i), pos,
437                                Quaternion(Radian(Math::RangeRandom(-Math::PI, Math::PI)), Vector3::UNIT_Y));
438                        nodes->attachObject(deaths);
439                        nodes->setScale(scale);
440                }
441        }
442
443        if (mSelectEntities & ENT_MOV)
444        {
445                Entity *movingDeath = mSceneMgr->createEntity("movingDeath","robot.mesh");
446                if (mShadowsEnabled)
447                        movingDeath->setCastShadows( true );
448
449                SceneNode *deathPivotNode = mSceneMgr->getRootSceneNode()->
450                        createChildSceneNode("deathPivotNode", Vector3((min_x + max_x)/2,0,(min_z + max_z)/2));
451                mMoveNode = deathPivotNode->createChildSceneNode("movingNode", Vector3(0, 0, mRotationRadius)
452                        /*,Quaternion(Radian(Math::HALF_PI), Vector3::UNIT_Y)*/);
453                mMoveNode->attachObject(movingDeath);
454                mMoveNode->setScale(scale);
455
456                Entity *ent_ball = mSceneMgr->createEntity("ball","sphere.mesh");
457                SceneNode *node_pivot = mMoveNode->createChildSceneNode("pivotNode");
458                SceneNode *node_ball = node_pivot->createChildSceneNode("orbitNode", Vector3(120, 40, 0));
459                node_ball->attachObject(ent_ball);
460                node_ball->setScale(scale/10);
461        }
462}
463
464void KdTreeApp::createSimpleScene()
465{
466        Entity *deaths;
467        SceneNode *nodes;
468        std::string entName = "death";
469        std::string nodeName = "DeathNode";
470        int i, j, x, z;
471        Real planeHalf = mPlaneDim / 2;
472        Real planeThreeEights = mPlaneDim * 3 / 8;
473        Real planeSixth = mPlaneDim / 6;
474
475        SceneNode *anchor = mSceneMgr->getRootSceneNode()->createChildSceneNode("AnchorNode");
476        //SceneNode *grndan = anchor->createChildSceneNode("GroundAnchor");
477        SceneNode *grndan = mSceneMgr->getRootSceneNode();
478
479        if (mSelectEntities & ENT_GRID)
480        {
481                for (j = 0, z =  -(mModelCount / 2 * mModelSpacing); j < mModelCount; j++, z += mModelSpacing)
482                {
483                        for (i = 0, x = -(mModelCount / 2 * mModelSpacing); i < mModelCount; i++, x += mModelSpacing)
484                        {
485                                deaths = mSceneMgr->createEntity(cat(entName, i, j).c_str(),"robot.mesh");
486                                if (mShadowsEnabled)
487                                        deaths->setCastShadows(true);
488                                nodes = /*mSceneMgr->getRootSceneNode()*/anchor->createChildSceneNode(cat(nodeName, i, j).c_str(), Vector3(x, 0 , z));
489                                nodes->attachObject(deaths);
490                        }
491                }
492        }
493
494        if (mSelectEntities & ENT_RND)
495        {
496                entName = "randomdeath";
497                nodeName = "RandomDeathNode";
498                for (i = 0; i < mRandomCount; i++)
499                {
500                        Vector3 pos(
501                                Math::RangeRandom(-planeHalf,-planeSixth),
502                                0,
503                                Math::RangeRandom(-planeThreeEights, planeThreeEights));
504                        deaths = mSceneMgr->createEntity(cat(entName,666,i),"robot.mesh");
505                        if (mShadowsEnabled)
506                                deaths->setCastShadows(true);
507                        nodes = /*mSceneMgr->getRootSceneNode()*/anchor->createChildSceneNode(cat(nodeName,666,i), pos,
508                                Quaternion(Radian(Math::RangeRandom(-Math::PI, Math::PI)), Vector3::UNIT_Y));
509                        nodes->attachObject(deaths);
510                }
511        }
512
513        if (mSelectEntities & ENT_SPC)
514        {
515                entName = "randomspaceship";
516                nodeName = "RandomSpaceshipNode";
517                for (i = 0; i < mRandomCount; i++)
518                {
519                        Vector3 pos(
520                                //Math::RangeRandom(-planeHalf,-planeSixth),
521                                Math::RangeRandom(planeSixth,planeHalf),
522                                Math::RangeRandom(planeHalf * 0.1, planeHalf),
523                                Math::RangeRandom(-planeThreeEights, planeThreeEights));
524                        deaths = mSceneMgr->createEntity(cat(entName,666,i),"razor.mesh");
525                        if (mShadowsEnabled)
526                                deaths->setCastShadows(true);
527                        nodes = /*mSceneMgr->getRootSceneNode()*/anchor->createChildSceneNode(cat(nodeName,666,i), pos,
528                                Quaternion(Radian(Math::RangeRandom(-Math::PI, Math::PI)), Vector3::UNIT_Y));
529                        nodes->attachObject(deaths);
530                }
531        }
532
533        if (mSelectEntities & ENT_MOV)
534        {
535                Entity *movingDeath = mSceneMgr->createEntity("movingDeath","robot.mesh");
536                if (mShadowsEnabled)
537                        movingDeath->setCastShadows( true );
538
539                SceneNode *deathPivotNode = mSceneMgr->getRootSceneNode()->createChildSceneNode("deathPivotNode");
540                mMoveNode = deathPivotNode->createChildSceneNode("movingNode", Vector3(0, 0, mRotationRadius)/*,
541                                                                                                                                                                                                         Quaternion(Radian(Math::HALF_PI), Vector3::UNIT_Y)*/);
542                                                                                                                                                                                                         mMoveNode->attachObject(movingDeath);
543
544                Entity *ent_ball = mSceneMgr->createEntity("ball","sphere.mesh");
545                SceneNode *node_pivot = mMoveNode->createChildSceneNode("pivotNode");
546                SceneNode *node_ball = node_pivot->createChildSceneNode("orbitNode", Vector3(120, 40, 0));
547                node_ball->attachObject(ent_ball);
548                node_ball->scale(0.1, 0.1, 0.1);
549
550
551                //mFollowCam->setAutoTracking(true, mMoveNode);
552        }
553
554        if (mSelectEntities & ENT_PLN)
555        {
556                Plane ground(Vector3::UNIT_Y, 0);
557                MeshManager::getSingleton().createPlane("ground", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
558                        ground, mPlaneDim * 4 / 3, mPlaneDim, 20, 20, true, 1, 20, 20, Vector3::UNIT_Z);
559                Entity *ent_ground = mSceneMgr->createEntity("GroundEntity", "ground");
560                ent_ground->setCastShadows(false);
561                ent_ground->setMaterialName("Examples/RustySteel");//("Examples/Rockwall");
562                SceneNode *node_ground = /*mSceneMgr->getRootSceneNode()*/grndan->createChildSceneNode("GroundNode", Vector3(0, 0, 0));
563                node_ground->attachObject(ent_ground);
564
565                //MeshManager::getSingleton().createPlane("ground2", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
566                //      ground, mPlaneDim/2, mPlaneDim, 10, 20, true, 1, 10, 20, Vector3::UNIT_Z);
567                //ent_ground = mSceneMgr->createEntity("GroundEntity2", "ground2");
568                //ent_ground->setCastShadows(false);
569                //ent_ground->setMaterialName("Examples/RustySteel");
570                //node_ground = /*mSceneMgr->getRootSceneNode()*/grndan->createChildSceneNode("GroundNode2", Vector3(-mPlaneDim/4, 0, 0));
571                //node_ground->attachObject(ent_ground);
572        }
573
574        // Lights
575        mSceneMgr->setAmbientLight(ColourValue(0.1,0.1,0.1));
576        Light *light = mSceneMgr->createLight("light");
577        if (mShadowsEnabled)
578        {
579                mSceneMgr->setShadowTechnique(SHADOWTYPE_STENCIL_ADDITIVE);
580                light->setType(Light::LT_POINT);
581                light->setPosition(Vector3(x, 300, z + 200));
582        }
583        else
584        {
585                light->setType(Light::LT_DIRECTIONAL);
586                light->setDirection(-1,-1,-1);
587        }
588        light->setDiffuseColour(ColourValue::White);
589        light->setSpecularColour(ColourValue(1, 1, 0.2));
590
591        // Skybox
592        mSceneMgr->setSkyBox(true, "Examples/SpaceSkyBox", mPlaneDim * 2);
593}
594
595void KdTreeApp::createFrameListener(void)
596{
597        // set pointer to self in options
598        mOptions.myApp = this;
599
600        mFrameListener = new KdTreeAppListener(mWindow, mSceneMgr, mOptions);
601        //mFrameListener->showDebugOverlay( true );
602        mRoot->addFrameListener(mFrameListener);
603        mRenderTargerListener = new KdTreeAppRenderTargetListener(mSceneMgr);
604        mWindow->addListener(mRenderTargerListener);
605}
606
607void KdTreeApp::chooseSceneManager(void)
608{
609        // Get the SceneManager
610        mSceneMgr = mRoot->createSceneManager(
611                KdTreeAppListener::SCENEMANAGERNAME[mOptions.mSceneManager],
612                "MySceneManager");
613        // set params for kdtree scene manager
614        if (mOptions.mSceneManager == KdTreeAppListener::SM_KDT ||
615                mOptions.mSceneManager == KdTreeAppListener::SM_KTE)
616        {
617                mSceneMgr->setOption("BuildMethod", &mOptions.mBuildMethod);
618                mSceneMgr->setOption("KdTreeMaxDepth", &mOptions.mMaxDepth);
619                mSceneMgr->setOption("KT", &mOptions.mKT);
620                mSceneMgr->setOption("KI", &mOptions.mKI);
621                mSceneMgr->setOption("RenderMethod", &mOptions.mRenderMethod);
622                mSceneMgr->setOption("EnhancedVisibility", &mOptions.mEnhancedVisibility);
623                // fix
624                bool depthpass = false;
625                mSceneMgr->setOption("UseDepthPass", &depthpass);
626        }
627        // set algorithm when scene manager is OCM - numbering is different though
628        else if (mOptions.mSceneManager == KdTreeAppListener::SM_OCM)
629        {
630                int alg = CONV_KDT_TO_OCM_ALG(mOptions.mRenderMethod);
631                mSceneMgr->setOption("Algorithm", &alg);
632        }
633
634        // create ray query for ground intersection
635        mRaySceneQuery = mSceneMgr->createRayQuery(
636                Ray(Vector3::ZERO, Vector3::NEGATIVE_UNIT_Y));
637}
638
639void KdTreeApp::createCamera(void)
640{
641    // Create the camera
642    mCamera = mSceneMgr->createCamera("PlayerCam");
643        mCamera->setNearClipDistance(1);
644
645        mCamNode = mSceneMgr->getRootSceneNode()->createChildSceneNode("PlayerCamNode", Vector3(0,0,0));
646        mCamNode->attachObject(mCamera);
647       
648
649    // Position it at 500 in Z direction
650    //mCamera->setPosition(Vector3(0,50,500));
651        //mCamera->setPosition(Vector3(500,256,666));
652        //mCamera->setPosition(Vector3(1280,600,1666));
653    // Look back along -Z
654    //mCamera->lookAt(Vector3(0,50,-300));
655        //mCamera->lookAt(Vector3(-20,30,10));
656
657        //mFollowCam = mSceneMgr->createCamera("FollowCam");
658        //mFollowCam->setPosition(Vector3(800,150,800));
659        //mFollowCam->setNearClipDistance(5);
660        //mFollowCam->setFOVy(Angle(15));
661
662        mTopCam = mSceneMgr->createCamera("TopCam");
663        mTopCam->setPosition(Vector3(0,mPlaneDim * 1.25,0));
664        mTopCam->setDirection(0,0,-1);
665        mTopCam->pitch(Radian(-Math::HALF_PI));
666        mTopCam->setCullingFrustum(mCamera);
667        mTopCam->setNearClipDistance(1);
668
669        // infinite far plane?
670        if (mRoot->getRenderSystem()->getCapabilities()->hasCapability(RSC_INFINITE_FAR_PLANE))
671        {
672                mTopCam->setFarClipDistance(0);
673                mCamera->setFarClipDistance(0);
674        }
675        else
676        {
677                mTopCam->setFarClipDistance(20000);
678                mCamera->setFarClipDistance(20000);
679        }       
680}
681
682void KdTreeApp::createViewports(void)
683{
684    // Create one viewport, entire window
685    Viewport* vp = mWindow->addViewport(mCamera);
686    vp->setBackgroundColour(ColourValue(0,0,100));
687
688    // Alter the camera aspect ratio to match the viewport
689    mCamera->setAspectRatio(
690        Real(vp->getActualWidth()) / Real(vp->getActualHeight()));
691/*
692        Viewport* fvp = mWindow->addViewport(mFollowCam,2,0.75,0.75,0.25,0.25);
693        fvp->setBackgroundColour(ColourValue(100,0,0));
694        fvp->setOverlaysEnabled( false );
695
696        mFollowCam->setAspectRatio(
697                Real(fvp->getActualWidth()) / Real(fvp->getActualHeight()));
698*/
699}
700
701bool KdTreeApp::configure(void)
702{
703    // Show the configuration dialog and initialise the system
704    // You can skip this and use root.restoreConfig() to load configuration
705    // settings if you were sure there are valid ones saved in ogre.cfg
706        bool cont = false;
707
708        if (mOptions.mFastStart)
709                cont = mRoot->restoreConfig();
710        else
711                cont = mRoot->showConfigDialog();
712
713        if (cont)
714    {
715        // If returned true, user clicked OK so initialise
716        // Here we choose to let the system create a default rendering window by passing 'true'
717        mWindow = mRoot->initialise(true);
718        return true;
719    }
720    else
721    {
722        return false;
723    }
724}
725
726void KdTreeApp::createMaterials()
727{
728        MaterialPtr mat;
729        Technique * tech;
730        Pass * pass;
731        TextureUnitState * tex;
732
733        // create play button
734        mat = MaterialManager::getSingleton().getByName("KdTree/DemoPlayButton");
735        if (mat.isNull())
736                mat = MaterialManager::getSingleton().create("KdTree/DemoPlayButton", "General");
737        mat->setLightingEnabled(false);
738        tech = mat->getTechnique(0);
739        tech->setSceneBlending(SBT_TRANSPARENT_ALPHA);
740        tech->setDepthCheckEnabled(false);
741        pass = tech->getPass(0);
742        tex = pass->createTextureUnitState();
743        tex->setTextureName("DemoPlayButton.png");
744
745        // create record button
746        mat = MaterialManager::getSingleton().getByName("KdTree/DemoRecordButton");
747        if (mat.isNull())
748                mat = MaterialManager::getSingleton().create("KdTree/DemoRecordButton", "General");
749        mat->setLightingEnabled(false);
750        tech = mat->getTechnique(0);
751        tech->setSceneBlending(SBT_TRANSPARENT_ALPHA);
752        tech->setDepthCheckEnabled(false);
753        pass = tech->getPass(0);
754        tex = pass->createTextureUnitState();
755        tex->setTextureName("DemoRecordButton.png");
756}
757
758Vector3 KdTreeApp::clampToGround(const Vector3& vect, Real offset, Real cap)
759{
760        static Ray updateRay;
761        static Vector3 result;
762
763        result = vect;
764
765        if (mOptions.mSceneType == KdTreeAppListener::ST_TERRAIN)
766        {
767                updateRay.setOrigin(vect);
768                updateRay.setDirection(Vector3::NEGATIVE_UNIT_Y);
769                mRaySceneQuery->setRay(updateRay);
770                RaySceneQueryResult& qryResult = mRaySceneQuery->execute();
771                RaySceneQueryResult::iterator i = qryResult.begin();
772                if (i != qryResult.end() && i->worldFragment)
773                {
774                        SceneQuery::WorldFragment* wf = i->worldFragment;
775                        result.y = wf->singleIntersection.y;
776                }
777        }
778        else
779        {
780                updateRay.setOrigin(vect);
781                updateRay.setDirection(Vector3::NEGATIVE_UNIT_Y);
782                mRaySceneQuery->setRay(updateRay);
783                RaySceneQueryResult& qryResult = mRaySceneQuery->execute();
784                RaySceneQueryResult::iterator i = qryResult.begin();
785                while (i != qryResult.end() && i->movable)
786                {
787                        if (i->movable->getName() != "PlayerCam")
788                        {
789                                MovableObject *mov = i->movable;
790                                result.y = mov->getWorldBoundingBox().getCenter().y;
791                                break;
792                        }
793                        i++;
794                }
795        }
796
797        // hack to fill the valleys only - make cap lower than max height
798        if (result.y >= cap)
799                return Vector3::ZERO;
800
801        result.y = result.y + offset > cap ? cap : result.y + offset;
802
803        return result;
804}
805
806//-----------------------------------------------------------------------
807// splits strings containing multiple file names
808static int splitFilenames(const std::string str, std::vector<std::string> &filenames)
809{
810        int pos = 0;
811
812        while(1)
813        {
814                int npos = (int)str.find(';', pos);
815
816                if (npos < 0 || npos - pos < 1)
817                        break;
818                filenames.push_back(std::string(str, pos, npos - pos));
819                pos = npos + 1;
820        }
821
822        filenames.push_back(std::string(str, pos, str.size() - pos));
823        return (int)filenames.size();
824}
825
826bool KdTreeApp::loadScene(const String &filename)
827{
828        // use leaf nodes of the original spatial hierarchy as occludees
829        std::vector<std::string> filenames;
830        int files = splitFilenames(filename, filenames);
831
832        std::stringstream d;
833        d << "number of input files: " << files << "\n";
834        LogManager::getSingleton().logMessage(d.str());
835
836        bool loadres = false;
837        bool result = filenames.empty() ? false : true;
838
839        std::vector<std::string>::const_iterator fit, fit_end = filenames.end();
840        int i = 0;
841        // root for different files
842        for (fit = filenames.begin(); fit != fit_end; ++ fit, ++ i)
843        {
844                const std::string fn = *fit;
845
846                if (strstr(fn.c_str(), ".iv") || strstr(fn.c_str(), ".wrl"))
847                {
848                        // load iv files
849                        loadres = loadSceneIV(fn, mSceneMgr->getRootSceneNode(), i);
850                        mOptions.mSceneType = KdTreeAppListener::ST_GEOMETRY;
851                }
852                else if (strstr(fn.c_str(), ".cfg"))
853                {
854                        // load terrain from cfg
855                        loadres = loadSceneCfg(fn, mSceneMgr->getRootSceneNode(), i);
856                        mOptions.mSceneType = KdTreeAppListener::ST_TERRAIN;
857                }
858                else if (strstr(fn.c_str(), ".txt"))
859                {
860                        // load entities form text file
861                        loadres = loadSceneASCII(fn, mSceneMgr->getRootSceneNode(), i);
862                }
863                else
864                {
865                        loadres = false;
866                }
867
868                // result is true only if all files have been succesfully loaded
869                result = result ? loadres : false;
870        }
871
872        return result;
873}
874
875//-----------------------------------------------------------------------
876bool KdTreeApp::loadSceneIV(const String &filename, SceneNode *root, const int index)
877{
878        IVReader * mIVReader = new IVReader();
879
880        if (0)
881        {
882                String logFilename = "IVLog" + Ogre::StringConverter().toString(index) + ".log";
883
884                Log *log = LogManager::getSingleton().createLog(logFilename);
885                mIVReader->setLog(log);
886        }
887
888        //viennaNode->translate(Vector3(-300, -300, 0));
889
890        if (mIVReader->loadFile(filename.c_str()))
891        {
892                SceneNode *node = root->createChildSceneNode("IVSceneNode" + index);
893
894                mIVReader->buildTree(mSceneMgr, node);
895
896                mIVReader->collapse();
897                OGRE_DELETE(mIVReader);
898
899                return true;
900        }
901        else
902        {
903                OGRE_DELETE(mIVReader);
904
905                return false;
906        }
907}
908
909//-----------------------------------------------------------------------
910bool KdTreeApp::loadSceneCfg(const String &filename, SceneNode *root, const int index)
911{
912        // Set ambient light
913        mSceneMgr->setAmbientLight(ColourValue(0.5, 0.5, 0.5));
914        // Create a light
915        Light* l = mSceneMgr->createLight("MainLight");
916        l->setPosition(20,80,50);
917       
918        // try to load world geometry defined in the cfg file
919        mSceneMgr -> setWorldGeometry( filename );
920
921        // return true since we have no feedback from setWorldGeometry
922        return true;
923}
924
925#define MAX_BUF_SIZE 1024
926
927//-----------------------------------------------------------------------
928bool KdTreeApp::loadSceneASCII(const String &filename, SceneNode *root, const int index)
929{
930        typedef std::map<std::string, std::string> EntMeshMap;
931        typedef std::vector<std::string> Line;
932       
933        std::ifstream read;
934        read.open(filename.c_str());
935        if (read.is_open())
936        {
937                char buf[MAX_BUF_SIZE];
938                Line line;
939                std::stringstream s;
940                std::string node, ent, mesh;
941                Vector3 pos;
942                Quaternion or;
943                Vector3 scale;
944                int count;
945                EntMeshMap emm;
946
947                // the node which is parent to all entities
948                SceneNode *anchor = mSceneMgr->getRootSceneNode()->createChildSceneNode("AnchorNode");
949
950                while (!read.eof())
951                {
952                        line.clear();
953                        memset(buf, 0, MAX_BUF_SIZE);
954                        read.getline(buf, MAX_BUF_SIZE);
955                        splitFilenames(std::string(buf), line);
956                        if (line.size() < 5)
957                                continue;
958                        // see if node not empty
959                        s << line[4];
960                        s >> count;
961                        s.clear();
962                        if (count > 0)
963                        {
964                                // read info
965                                node = line[0];
966                                s << line[1];
967                                s >> pos.x >> pos.y >> pos.z;
968                                s.clear();
969                                s << line[2];
970                                s >> or.w >> or.x >> or.y >> or.z;
971                                s.clear();
972                                s << line[3];
973                                s >> scale.x >> scale.y >> scale.z;
974                                s.clear();
975                                for (int i = 5; i < 5 + count; i ++)
976                                {
977                                        s << line[i];
978                                        s >> ent >> mesh;
979                                        s.clear();
980                                        emm[ent] = mesh;
981                                }
982                                // build node
983                                //SceneNode *newnode = anchor->createChildSceneNode(node, pos, or);
984                                SceneNode *newnode = anchor->createChildSceneNode(node);
985                                for (EntMeshMap::iterator emmit = emm.begin(); emmit != emm.end(); emmit ++)
986                                {
987                                        Entity * entity = mSceneMgr->createEntity(emmit->first, emmit->second);
988                                        newnode->attachObject(entity);
989                                }
990                                newnode->setPosition(pos);
991                                newnode->setOrientation(or);
992                                newnode->setScale(scale);
993                                emm.clear();
994                        }
995
996
997                }
998
999                return true;
1000        }
1001        else
1002        {
1003                return false;
1004        }
1005}
1006
1007//-----------------------------------------------------------------------
1008bool KdTreeApp::saveSceneASCII(const String& filename, SceneNode *entityroot)
1009{
1010        // find all entities under node entityroot and store their name, position
1011        //and orientation to a test file
1012        std::ofstream write;
1013        write.open(filename.c_str());
1014        if (write.is_open())
1015        {
1016                NodeList list;
1017                addNodesToList(entityroot, list);
1018
1019                std::string fs = ";", rs = "\n";
1020                std::string entnames;
1021                int entcount;
1022
1023                for (NodeList::iterator it = list.begin(); it != list.end(); it ++)
1024                {
1025                        // fist dump info about node (name, position, orientation, scale)
1026                        SceneNode * node = *it;
1027                        write << node->getName() << fs <<
1028                                StringConverter::toString(node->getPosition()) << fs <<
1029                                StringConverter::toString(node->getOrientation()) << fs <<
1030                                StringConverter::toString(node->getScale()) << fs;
1031
1032                        entcount = 0;
1033                        entnames = "";
1034
1035                        SceneNode::ObjectIterator objIt = node->getAttachedObjectIterator();
1036
1037                        while (objIt.hasMoreElements())
1038                        {
1039                                MovableObject *movable = objIt.getNext();
1040                                if (movable->getMovableType() == "Entity")
1041                                {
1042                                        Entity *ent = static_cast<Entity *>(movable);
1043                                        entcount++;
1044                                        entnames += fs + ent->getName() + " " + ent->getMesh()->getName();
1045
1046                                }
1047                        }
1048
1049                        // now dump entity count and names
1050                        write << entcount << entnames << rs;
1051                }
1052
1053                write.close();
1054                return true;
1055        }
1056        else
1057        {
1058                return false;
1059        }
1060
1061}
1062
1063void KdTreeApp::addNodesToList(SceneNode* node, NodeList& list)
1064{
1065        //// check if node has entities
1066        //bool entfound = false;
1067
1068        //SceneNode::ObjectIterator objIt = node->getAttachedObjectIterator();
1069        //while (objIt.hasMoreElements())
1070        //{
1071        //      MovableObject *movable = objIt.getNext();
1072        //      if (movable->getMovableType() == "Entity")
1073        //              entfound = true;
1074        //}
1075
1076        //// if yes, add to list
1077        //if (entfound)
1078        list.push_back(node);
1079
1080        // check if node has children and add them to list
1081        SceneNode::ChildNodeIterator childIt = node->getChildIterator();
1082        while (childIt.hasMoreElements())
1083        {
1084                SceneNode *child = static_cast<SceneNode *>(childIt.getNext());
1085                addNodesToList(child, list);
1086        }
1087}
1088
1089
1090/**********************************************************************/
1091/*           VisualizationRenderTargetListener implementation         */
1092/**********************************************************************/
1093
1094
1095//-----------------------------------------------------------------------
1096KdTreeAppRenderTargetListener::KdTreeAppRenderTargetListener(SceneManager *sceneMgr)
1097:RenderTargetListener(), mSceneMgr(sceneMgr)
1098{
1099}
1100//-----------------------------------------------------------------------
1101void KdTreeAppRenderTargetListener::preViewportUpdate(const RenderTargetViewportEvent &evt)
1102{
1103        // visualization viewport
1104        const bool showViz = evt.source->getZOrder() == VIZ_VIEWPORT_Z_ORDER;
1105        const bool nShowViz = !showViz;
1106
1107        mSavedShadowTechnique = mSceneMgr->getShadowTechnique();
1108        mSavedAmbientLight = mSceneMgr->getAmbientLight();
1109
1110        // -- ambient light must be full for visualization, shadows disabled
1111        if (showViz)
1112        {
1113                mSceneMgr->setAmbientLight(ColourValue(1, 1, 1));
1114                mSceneMgr->setShadowTechnique(SHADOWTYPE_NONE);
1115        }
1116
1117        mSceneMgr->setOption("PrepareVisualization", &showViz);
1118        SceneNode * skybox = mSceneMgr->getSkyBoxNode();
1119        if (skybox != 0)
1120                mSceneMgr->setOption("SkyBoxEnabled", &nShowViz);
1121        //if ((SceneNode * skyplane = mSceneMgr->getSkyPlaneNode()) != 0)
1122        //      mSceneMgr->setOption("SkyPlaneEnabled", &showViz);
1123
1124        RenderTargetListener::preViewportUpdate(evt);
1125}
1126//-----------------------------------------------------------------------
1127void KdTreeAppRenderTargetListener::postRenderTargetUpdate(const RenderTargetEvent &evt)
1128{
1129        // reset values
1130        mSceneMgr->setShadowTechnique(mSavedShadowTechnique);
1131        mSceneMgr->setAmbientLight(mSavedAmbientLight);
1132
1133        RenderTargetListener::postRenderTargetUpdate(evt);
1134}
Note: See TracBrowser for help on using the repository browser.