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

Revision 1285, 31.1 KB checked in by szydlowski, 18 years ago (diff)

saving and loading entities to file

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