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

Revision 1304, 33.4 KB checked in by szydlowski, 18 years ago (diff)

final touches

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