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

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