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

Revision 1296, 32.6 KB checked in by szydlowski, 18 years ago (diff)

Implemented PVS support in kdtree scene manager - not complete, defunct
modified BoundingBoxConverter? to work with KdTreeSceneManager?

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