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

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

per-frame-stats with internal rendering - use depth pass issue unresolved

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