Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/ogreode/demos/SimpleScenes/src/SimpleScenesApplication.cpp @ 21

Last change on this file since 21 was 21, checked in by nicolasc, 16 years ago

added ogreode and Colladaplugin

File size: 14.4 KB
Line 
1/*
2SimpleScenesApplication.cpp
3--------------------------
4The main applicatin that handles switching between the
5different scenes in this demo, as well as any common
6setup and input handling.
7*/
8#include "SimpleScenesApplication.h"
9
10// The tests we can display
11#include "SimpleScenes_BoxStack.h"
12#include "SimpleScenes_Buggy.h"
13#include "SimpleScenes_Chain.h"
14#include "SimpleScenes_TriMesh.h"
15#include "SimpleScenes_Crash.h"
16#include "SimpleScenes_Joints.h"
17#include "SimpleScenes_Zombie.h"
18
19// Windows stuff
20#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
21#define WIN32_LEAN_AND_MEAN
22#include "windows.h"
23
24/*
25Windows entry point
26*/
27INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR strCmdLine, INT nCmdShow)
28#else
29int main(int argc,char* argv[])
30#endif
31{
32        // Create the application and try to run it
33    SimpleScenesApplication app;
34
35    try
36        {
37                app.go();
38    } 
39        catch(Ogre::Exception& e)
40        {
41#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
42                MessageBox( 0, e.getFullDescription().c_str(), "OgreOde SimpleScenes: Exception", MB_OK | MB_ICONERROR | MB_TASKMODAL);
43#else
44        std::cerr << "An exception has occured: " << e.getFullDescription().c_str() << std::endl;
45#endif
46    }
47    return 0;
48}
49
50using namespace Ogre;
51
52#if !(OGRE_VERSION_MINOR < 4)
53using namespace OIS;
54#endif //OGRE_VERSION not heihort
55
56using namespace OgreOde;
57using namespace OgreOde_Prefab;
58using namespace OgreOde_Loader;
59
60/*
61The frame listener is informed before every frame
62*/
63bool SimpleScenesFrameListener::frameStarted(const FrameEvent& evt)
64{
65
66        // Do the default demo input handling and keep our UI display
67        // in sync with the other stuff (frame rate, logo, etc)
68        bool show = mStatsOn;
69        bool bOK = ExampleFrameListener::frameStarted(evt);
70        if (mStatsOn != show)
71        {
72            Overlay* pOver = (Overlay*)OverlayManager::getSingleton().getByName("OgreOdeDemos/Overlay");   
73                if (pOver)
74                {
75                        if (mStatsOn) 
76                pOver->show();
77                        else 
78                pOver->hide();
79                }
80        }
81    // Tell the demo application that it needs to handle input 
82#if (OGRE_VERSION_MINOR < 4)
83    _demo->frameStarted(evt,mInputDevice);
84#else
85    _demo->frameStarted(evt, mKeyboard, mMouse);
86#endif //OGRE_VERSION not heihort
87
88        // Quit or carry on according to the normal demo input
89        return bOK;
90}
91
92/*
93The frame listener is informed after every frame
94*/
95bool SimpleScenesFrameListener::frameEnded(const FrameEvent& evt)
96{
97        // Tell our demo that the frame's ended before doing default processing
98
99#if (OGRE_VERSION_MINOR < 4)
100    _demo->frameEnded(evt,mInputDevice);
101#else
102    _demo->frameEnded(evt, mKeyboard, mMouse);
103#endif //OGRE_VERSION not heihort
104    return ExampleFrameListener::frameEnded(evt);
105}
106
107/*
108Create the scene from an Ogre point of view
109and create the common OgreOde things we'll need
110*/
111void SimpleScenesApplication::createScene(void)
112{
113        MovableObject::setDefaultQueryFlags (ANY_QUERY_MASK);
114
115#ifndef _DEBUG
116        // Set up shadowing
117        mSceneMgr->setShadowTechnique(SHADOWTYPE_TEXTURE_MODULATIVE);
118    mSceneMgr->setShadowColour(ColourValue(0.5, 0.5, 0.5));
119        mSceneMgr->setShadowFarDistance(30);
120
121        if (StringUtil::startsWith(mRoot->getRenderSystem()->getName(),"direct")) 
122        mSceneMgr->setShadowTextureSettings(1024, 2);
123    else 
124        mSceneMgr->setShadowTextureSettings(512, 2);
125#endif
126
127        // Add some default lighting to the scene
128        mSceneMgr->setAmbientLight(ColourValue(0.25, 0.25, 0.25));
129
130        // Create a directional light to shadow and light the bodies
131        _spot = mSceneMgr->createLight("Spot");
132        _spot->setType(Light::LT_DIRECTIONAL);
133        _spot->setDirection(-0.40824828,-0.81649655,-0.40824828);
134        _spot->setCastShadows(true);
135    _spot->setSpecularColour(1,1,0.8);
136
137        // Give us some sky
138        mSceneMgr->setSkyBox(true,"kk3d/DesertVII",5000,true);
139
140        // Position and orient the camera
141        mCamera->setPosition(13,4.5,0);
142        mCamera->lookAt(0,0.5,0);
143        mCamera->setNearClipDistance(0.5);
144
145        // Create the ODE world
146        _world = new OgreOde::World(mSceneMgr);
147
148        _world->setGravity(Vector3(0,-9.80665,0));
149        _world->setCFM(10e-5);
150        _world->setERP(0.8);
151        _world->setAutoSleep(true);
152    _world->setAutoSleepAverageSamplesCount(10);
153        _world->setContactCorrectionVelocity(1.0);
154
155        // Create something that will step the world, but don't do it automatically
156
157    const int _stepper_mode_choice = 2;
158    const int _stepper_choice = 3;
159    const Ogre::Real time_scale = Ogre::Real(1.7);
160    const Ogre::Real max_frame_time = Ogre::Real(1.0 / 4);
161    const Ogre::Real frame_rate = Ogre::Real(1.0 / 60);
162
163
164    StepHandler::StepModeType stepModeType;
165
166    switch(_stepper_mode_choice)
167    {
168    case 0: stepModeType = StepHandler::BasicStep; break;
169    case 1: stepModeType = StepHandler::FastStep; break;
170    case 2: stepModeType = StepHandler::QuickStep; break;
171
172    default: stepModeType = StepHandler::QuickStep; break;
173    }
174
175    switch (_stepper_choice)
176    {
177    case 0:
178        _stepper = new OgreOde::StepHandler(_world,
179            StepHandler::QuickStep, 
180            _time_step,
181            max_frame_time,
182            time_scale);
183
184        break;
185    case 1:
186        _stepper = new OgreOde::ExactVariableStepHandler(_world, 
187            stepModeType, 
188            _time_step,
189            max_frame_time,
190            time_scale);
191
192        break;
193    case 2:
194        _stepper = new OgreOde::ForwardFixedStepHandler(_world, 
195            stepModeType, 
196            _time_step,
197            max_frame_time,
198            time_scale);
199
200        break;
201    case 3:
202    default:
203        _stepper = new OgreOde::ForwardFixedInterpolatedStepHandler (_world, 
204            stepModeType, 
205            _time_step,
206            frame_rate,
207            max_frame_time,
208            time_scale);
209        break;
210    }
211
212    //_stepper->setAutomatic(OgreOde::StepHandler::AutoMode_PostFrame, mRoot);
213    //_stepper->setAutomatic(OgreOde::Stepper::AutoMode_PreFrame, mRoot);
214
215    Root::getSingleton().setFrameSmoothingPeriod(5.0f);
216    //Root::getSingleton().setFrameSmoothingPeriod(0.0f);
217
218        // Create a default plane to act as the ground
219        _plane = new OgreOde::InfinitePlaneGeometry(Plane(Vector3(0,1,0),0), _world, _world->getDefaultSpace());
220
221        // Use a load of meshes to represent the floor
222    int i = 0;
223    StaticGeometry* s;
224    s = mSceneMgr->createStaticGeometry("StaticFloor");
225    s->setRegionDimensions(Vector3(160.0, 100.0, 160.0));
226    // Set the region origin so the center is at 0 world
227    s->setOrigin(Vector3::ZERO);
228        for (Real z = -80.0;z <= 80.0;z += 20.0)
229        {
230                for (Real x = -80.0;x <= 80.0;x += 20.0)
231                {
232                        String name = String("Plane_") + StringConverter::toString(i++);
233                       
234                        Entity* entity = mSceneMgr->createEntity(name, "plane.mesh");
235            entity->setQueryFlags (STATIC_GEOMETRY_QUERY_MASK);
236            entity->setUserObject(_plane);
237                        entity->setCastShadows(false);
238            s->addEntity(entity, Vector3(x,0,z));
239                }
240    }
241    s->build();
242    //SceneNode* mPlaneNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(name);
243
244        // Load up our UI and display it
245    Overlay* pOver = (Overlay*)OverlayManager::getSingleton().getByName("OgreOdeDemos/Overlay");   
246    pOver->show();
247
248        // Initialise stuff
249        _test = 0;
250    _delay = 1.0;
251}
252
253/*
254The frame listener will notify us when a frame's
255about to be started, so we can update stuff
256*/
257
258#if (OGRE_VERSION_MINOR < 4)
259void SimpleScenesApplication::frameStarted(const FrameEvent& evt,InputReader* mInputDevice)
260#else
261void SimpleScenesApplication::frameStarted(const FrameEvent& evt, OIS::Keyboard* mKeyboard, OIS::Mouse* mMouse)
262#endif //OGRE_VERSION not heihort
263{
264        // If we're looking at something then adjust the camera
265        if (_test && _test->getLastNode())
266        {
267                if (_looking)
268                {
269                        mCamera->lookAt(_test->getLastNode()->getPosition());
270
271                        if (_chasing)
272                        {
273                                // Thanks to Ahmed!
274                                const Ogre::Real followFactor = 0.1; 
275                                const Ogre::Real camHeight = 5.0; 
276                                const Ogre::Real camDistance = 7.0; 
277                               
278                                Quaternion q = _test->getLastNode()->getOrientation(); 
279                                Vector3 toCam = _test->getLastNode()->getPosition(); 
280
281                                toCam.y += camHeight; 
282                                toCam.z -= camDistance * q.zAxis().z; 
283                                toCam.x -= camDistance * q.zAxis().x; 
284     
285                                mCamera->move( (toCam - mCamera->getPosition()) * followFactor ); 
286                        }
287                }
288        }
289
290        // Set the shadow distance according to how far we are from the plane that receives them
291        mSceneMgr->setShadowFarDistance((fabs(mCamera->getPosition().y) + 1.0) * 3.0);
292
293        // If we're running a test, tell it that a frame's ended
294    if ((_test)&&(!_paused))
295    {
296#if (OGRE_VERSION_MINOR < 4)
297        _test->frameStarted(evt.timeSinceLastFrame, mInputDevice);
298#else
299        _test->frameStarted(evt.timeSinceLastFrame, mKeyboard, mMouse);
300#endif //OGRE_VERSION not heihort
301    }
302}
303
304/*
305The frame listener will let us know when a frame's ended. So we
306can do stuff that we can't do in a frame started event
307e.g. delete things that we can't delete at the start of a frame,
308presumably because some processing has already been done, leaving
309things dangling, like particle systems.
310*/
311#if (OGRE_VERSION_MINOR < 4)
312void SimpleScenesApplication::frameEnded(const FrameEvent& evt,InputReader* myInput)
313#else
314void SimpleScenesApplication::frameEnded(const FrameEvent& evt, OIS::Keyboard* myInput, OIS::Mouse* mMouse)
315#endif //OGRE_VERSION not heihort
316{
317        Real time = evt.timeSinceLastFrame;
318
319        // If we're running a test, tell it that a frame's ended
320    // If we're running a test, tell it that a frame's ended
321    if ((_test)&&(!_paused))
322    {
323#if (OGRE_VERSION_MINOR < 4)
324        _test->frameEnded(time, myInput);
325#else
326        _test->frameEnded(time, myInput, mMouse);
327#endif //OGRE_VERSION not heihort
328    }
329
330       
331        // Step the world and then synchronise the scene nodes with it,
332        // we could get this to do this automatically, but we
333        // can't be sure of what order the frame listeners will fire in
334        if (_stepper->step(time))
335    {
336                _world->synchronise(); 
337    }
338
339        _delay += time;
340        if (_delay > 1.0)
341        {
342                bool changed = false;
343
344                // Switch the test we're displaying
345                if (myInput->isKeyDown(KC_F1))
346                {
347                        delete _test;
348                        _test = new SimpleScenes_BoxStack(_world);
349                        changed = true;
350                }
351                else if (myInput->isKeyDown(KC_F2))
352                {
353                        delete _test;
354                        _test = new SimpleScenes_Chain(_world);
355                        changed = true;
356                }
357                else if (myInput->isKeyDown(KC_F3))
358                {
359                        delete _test;
360                        _test = new SimpleScenes_Buggy(_world);
361                        changed = true;
362                }
363                else if (myInput->isKeyDown(KC_F4))
364                {
365                        delete _test;
366                        _test = new SimpleScenes_TriMesh(_world);
367                        changed = true;
368                }
369                else if (myInput->isKeyDown(KC_F5))
370                {
371                        delete _test;
372                        _test = new SimpleScenes_Crash(_world);
373                        changed = true;
374                }
375                else if (myInput->isKeyDown(KC_F6))
376                {
377                        delete _test;
378                        _test = new SimpleScenes_Joints(_world);
379
380                        if (mCamera->getPosition().z < 10.0)
381                        {
382                                Vector3 pos = mCamera->getPosition();
383                                mCamera->setPosition(pos.x,pos.y,10.0);
384                                mCamera->lookAt(0,0,0);
385                        }
386                        changed = true;
387                }
388                else if (myInput->isKeyDown(KC_F7))
389                {
390                        delete _test;
391                        _test = new SimpleScenes_Zombie(_world);
392
393                        changed = true;
394                }
395
396                // If we changed the test...
397                if ((_test)&&(changed))
398                {
399                        // Register it with the stepper, so we can (for example) add forces before each step
400                        _stepper->setStepListener(_test);
401
402                        // Set the UI to show the test's details
403                        OverlayManager::getSingleton().getOverlayElement("OgreOdeDemos/Name")->setCaption("Name: " + _test->getName());
404                        OverlayManager::getSingleton().getOverlayElement("OgreOdeDemos/Keys")->setCaption("Keys: " + _test->getKeys());
405
406                        _delay = 0.0;
407                }
408
409                // Switch shadows
410                if (myInput->isKeyDown(KC_SPACE))
411                {
412            static Ogre::uint shadowtype = 0;
413            shadowtype += 1;
414            if (shadowtype > 5)
415                shadowtype = 0;
416            switch (shadowtype)
417            {
418            case 0:
419                mSceneMgr->setShadowTechnique (SHADOWTYPE_NONE);       
420                break;
421            case 1:
422                mSceneMgr->setShadowTechnique(SHADOWTYPE_TEXTURE_MODULATIVE);
423                mSceneMgr->setShadowColour(ColourValue(0.5, 0.5, 0.5));
424                mSceneMgr->setShadowFarDistance(30);
425                if (StringUtil::startsWith(mRoot->getRenderSystem()->getName(),"direct")) 
426                    mSceneMgr->setShadowTextureSettings(1024, 2);
427                else 
428                    mSceneMgr->setShadowTextureSettings(512, 2);
429                break;
430            case 2:
431                mSceneMgr->setShadowTechnique (SHADOWTYPE_STENCIL_ADDITIVE);   
432                break;
433            case 3:
434                mSceneMgr->setShadowTechnique (SHADOWTYPE_STENCIL_MODULATIVE ); 
435                break;
436            case 4:
437                mSceneMgr->setShadowTechnique (SHADOWTYPE_TEXTURE_ADDITIVE );   
438                mSceneMgr->setShadowColour(ColourValue(0.5, 0.5, 0.5));
439                mSceneMgr->setShadowFarDistance(30);
440                if (StringUtil::startsWith(mRoot->getRenderSystem()->getName(),"direct")) 
441                    mSceneMgr->setShadowTextureSettings(1024, 2);
442                else 
443                    mSceneMgr->setShadowTextureSettings(512, 2);
444                break;
445            default:
446                mSceneMgr->setShadowTechnique (SHADOWTYPE_NONE);       
447                break;
448            }
449                        _delay = 0.0;
450                }
451
452                // Look at the last object, chase it, or not
453                if (myInput->isKeyDown(KC_M))
454                {
455                        if (_looking)
456            {
457                if (_chasing) 
458                {
459                    _looking = _chasing = false;
460                }
461                else
462                {
463                    _chasing = true;
464                }
465            }
466                        else 
467            {
468                _looking = true;
469            }
470                        _delay = 0.0;
471                }
472
473                // Switch debugging objects on or off
474                if (myInput->isKeyDown(KC_E))
475                {
476                        _world->setShowDebugGeometries(!_world->getShowDebugGeometries());
477                        _delay = 0.0;
478                }
479
480        // Switch debugging Contacts on or off
481        if (myInput->isKeyDown(KC_B))
482        {
483            _world->setShowDebugContact(!_world->getShowDebugContact());
484            _delay = 0.5;
485        }
486
487                // Pause or Run the simulation
488                if (myInput->isKeyDown(KC_P))
489                {
490                        _paused = !_paused;
491                        _delay = 0.0;
492
493                        _stepper->pause(_paused);
494
495            const Ogre::Real timeSet = (_paused)? 0.0 : 1.0;
496
497            Ogre::SceneManager::MovableObjectIterator it = 
498                mSceneMgr->getMovableObjectIterator(ParticleSystemFactory::FACTORY_TYPE_NAME);
499            while(it.hasMoreElements())
500            {
501                ParticleSystem* p = static_cast<ParticleSystem*>(it.getNext());
502                p->setSpeedFactor(timeSet);
503            }
504                }
505        }
506}
507
508/*
509Destructor, delete stuff we created
510*/
511SimpleScenesApplication::~SimpleScenesApplication(void)
512{
513        delete _test;
514        delete _plane;
515        delete _stepper;       
516        delete _world;
517}
Note: See TracBrowser for help on using the repository browser.