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

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

Added support for BvHierarchy? Scene Manager to test app

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