Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/ogreode/demos/SimpleScenes/include/SimpleScenes_Crash.h @ 21

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

added ogreode and Colladaplugin

File size: 23.4 KB
Line 
1/*
2SimpleScenes_Crash.h
3----------------------
4A reimplementation of the ODE "crashing into a wall" demo
5using Ogre and the OgreOde wrapper.
6*/
7#ifndef _SIMPLESCENES_CRASH_H_
8#define _SIMPLESCENES_CRASH_H_
9
10/*
11The crash test extends the base test class
12*/
13class SimpleScenes_Crash:public SimpleScenes
14{
15public:
16        // Standard constructor/destructor
17    SimpleScenes_Crash(OgreOde::World *world) :
18      SimpleScenes(world)
19      {
20          _rocket_node_explosion = _mgr->getRootSceneNode ()->createChildSceneNode ("rocket_node_explosion_node");
21
22          _rocketParticles_explosion = _mgr->createParticleSystem ("rocket_node_explosion", "myExplosionTemplate");
23          _rocketParticles_smoke_white = _mgr->createParticleSystem ("rocketParticles_smoke_white", "myExplosionSmokewhiteTemplate");
24          _rocketParticles_smoke = _mgr->createParticleSystem ("rocketParticles_smoke", "myExplosionSmokeTemplate");
25
26          _rocket_node_explosion->attachObject(_rocketParticles_explosion);
27          _rocket_node_explosion->attachObject(_rocketParticles_smoke_white);
28          _rocket_node_explosion->attachObject(_rocketParticles_smoke);
29
30          _rocketParticles_explosion->setSpeedFactor(0.0);
31          _rocketParticles_smoke_white->setSpeedFactor(0.0);
32          _rocketParticles_smoke->setSpeedFactor(0.0);
33
34
35
36          _rocket_node_explosion->setVisible(false);
37
38        // create helicopter
39        {
40                    // Main bit of the helicopter
41                    _apache_body = _mgr->createEntity("Apache Body", "apache_body.mesh");
42
43            _apache_body->setQueryFlags(VEHICLE_QUERY_MASK);
44
45                    _apache_body->setCastShadows(true);
46
47                    _apache_body_node = _mgr->getRootSceneNode()->createChildSceneNode("Apache Body");
48                    _apache_body_node->attachObject(_apache_body);
49                    _apache_body_node->setPosition(0,1.2,0);
50
51                    // Main rotor
52                    _main_rotor = _mgr->createEntity("Main Rotor", "main_rotor.mesh");
53            _main_rotor->setCastShadows(true);
54
55                    _main_rotor_node = _apache_body_node->createChildSceneNode("Main Rotor");
56                    _main_rotor_node->attachObject(_main_rotor);
57                    _main_rotor_node->setPosition(0,0.987322,0.573885);
58
59                    // Tail rotor
60                    _tail_rotor = _mgr->createEntity("Tail Rotor", "tail_rotor.mesh");
61            _tail_rotor->setCastShadows(true);
62
63                    _tail_rotor_node = _apache_body_node->createChildSceneNode("Tail Rotor");
64                    _tail_rotor_node->attachObject(_tail_rotor);
65                    _tail_rotor_node->setPosition(0.174927,0.173132,-3.50708);
66
67                    // Set up the parameters for the main rotor
68                    _main_min = 2.0;
69                    _main_max = 90.0;
70                    _main_spd = _main_min;
71                    _main_response = 40.0;
72                    _main_scale = 1.0;
73
74                    // Set up the parameters for the tail rotor
75                    _tail_min = -80.0;
76                    _tail_max = 80.0;
77                    _tail_response = 90.0;
78                    _tail_scale = 0.5;
79                    _tail_spd = 0.0;
80
81                    // Other simulation parameters
82                    _rotate_scale = 20.0;
83                    _thrust = 50.0;
84                    _linear_damp = 12.5;
85                    _angular_damp = 25.0;
86                    _thrust_offs = Ogre::Vector3(0,0.1,0);
87                    _fire_rate = 0.5;
88                    _fire_time = _fire_rate;
89                    _fire_force = 250.0;
90                    _fire_mass = 0.1;
91                    _fire_size = 0.25;
92                    _rockets = 0;
93
94
95                    // Create a space for the helicopter to live in
96                    _apache_space = new OgreOde::SimpleSpace(_world, _space);
97                    _apache_space->setInternalCollisions(false);
98                    _apache_space->setAutoCleanup(false);       
99
100                    // Create the physical body of the helicopter
101                    OgreOde::BoxMass apache_mass(1.5,Vector3(1.4,1.46,4.24));
102                    _apache = new OgreOde::Body(_world);
103                    _apache_body_node->attachObject(_apache);
104                    _apache->setMass(apache_mass);
105
106            _apache->setDamping(_linear_damp, _angular_damp);
107
108                    _bodies.push_back(_apache);
109                    _last_node = _apache_body_node;
110
111                    // Create the geometry of the helicopter from several bits
112
113                    // Main body
114                    OgreOde::TransformGeometry* trans = new OgreOde::TransformGeometry(_world, _apache_space);
115            trans->setBody(_apache);
116
117            _apache_body->setUserObject(trans);
118
119            OgreOde::BoxGeometry* geom = new OgreOde::BoxGeometry(Vector3(1.4,1.46,4.24), world, 0);           
120                    trans->setEncapsulatedGeometry(geom);
121                    geom->setPosition(Vector3(0.013,0.014,1.052));
122                    _geoms.push_back(geom);
123                    _geoms.push_back(trans);
124
125
126
127                    // Left wing
128                    trans = new OgreOde::TransformGeometry(_world, _apache_space);
129                    geom = new OgreOde::BoxGeometry(Vector3(0.75,0.55,1.05), world, 0);         
130                    trans->setBody(_apache);
131                    trans->setEncapsulatedGeometry(geom);
132                    geom->setPosition(Vector3(-1.089,-0.486,0.446));           
133                    _geoms.push_back(geom);
134                    _geoms.push_back(trans);
135
136                    // Right wing
137                    trans = new OgreOde::TransformGeometry(_world, _apache_space);
138                    geom = new OgreOde::BoxGeometry(Vector3(0.75,0.55,1.05), world, 0);         
139                    trans->setBody(_apache);
140                    trans->setEncapsulatedGeometry(geom);
141                    geom->setPosition(Vector3(1.089,-0.505,0.446));             
142                    _geoms.push_back(geom);
143                    _geoms.push_back(trans);
144
145                    // Tail boom
146                    trans = new OgreOde::TransformGeometry(_world, _apache_space);
147                    geom = new OgreOde::BoxGeometry(Vector3(0.73,0.66,3.28), world, 0);         
148                    trans->setBody(_apache);
149                    trans->setEncapsulatedGeometry(geom);
150                    geom->setPosition(Vector3(0,-0.533,-2.104));               
151                    _geoms.push_back(geom);
152                    _geoms.push_back(trans);
153
154                    // Tail flipper (probably not the technically correct name!)
155                    trans = new OgreOde::TransformGeometry(_world, _apache_space);
156                    geom = new OgreOde::BoxGeometry(Vector3(1.61,0.30,0.45), world, 0);         
157                    trans->setBody(_apache);
158                    trans->setEncapsulatedGeometry(geom);
159                    geom->setPosition(Vector3(-0.014,-0.622,-3.778));           
160                    _geoms.push_back(geom);
161                    _geoms.push_back(trans);
162
163                    // Tail fin
164                    trans = new OgreOde::TransformGeometry(_world, _apache_space);
165                    geom = new OgreOde::BoxGeometry(Vector3(0.30,1.27,0.96), world, 0);         
166                    trans->setBody(_apache);
167                    trans->setEncapsulatedGeometry(geom);
168                    geom->setPosition(Vector3(0,-0.042,-3.491));       
169                    _geoms.push_back(geom);
170                    _geoms.push_back(trans);
171
172                    // Rear wheel - a separate body connected by a ball joint, doesn't have a SceneNode
173                    OgreOde::SphereMass wheel_mass(0.02,0.06);
174                    _rear_wheel = new OgreOde::Body(_world);
175                    _rear_wheel->setMass(wheel_mass);
176                    _rear_wheel->setPosition(Vector3(0.0,0.068,-3.937));
177                    OgreOde::BallJoint* ball_joint = new OgreOde::BallJoint(_world);
178                    ball_joint->attach(_apache,_rear_wheel);
179                    ball_joint->setAnchor(_rear_wheel->getPosition());
180                    OgreOde::SphereGeometry* sphere = new OgreOde::SphereGeometry(0.06, _world, _apache_space);
181                    sphere->setBody(_rear_wheel);
182                    _geoms.push_back(sphere);
183                    _bodies.push_back(_rear_wheel);
184                    _joints.push_back(ball_joint);
185
186                    // Left front wheel - connected by a hinge joint so it can only roll forward
187                    OgreOde::SphereMass front_wheel_mass(0.03,0.17);
188                    _left_front = new OgreOde::Body(_world);
189                    _left_front->setMass(front_wheel_mass);
190                    _left_front->setPosition(Vector3(-0.699,0.199,1.163));
191                    OgreOde::HingeJoint* hinge_joint = new OgreOde::HingeJoint(_world);
192                    hinge_joint->attach(_apache,_left_front);
193                    hinge_joint->setAnchor(_left_front->getPosition());
194                    hinge_joint->setAxis(Vector3::UNIT_X);
195                    sphere = new OgreOde::SphereGeometry(0.17, _world, _apache_space);
196                    sphere->setBody(_left_front);
197                    _geoms.push_back(sphere);
198                    _bodies.push_back(_left_front);
199                    _joints.push_back(hinge_joint);
200
201                    // Right front wheel - connected by a hinge joint, doesn't have a SceneNode
202                    _right_front = new OgreOde::Body(_world);
203                    _right_front->setMass(front_wheel_mass);
204                    _right_front->setPosition(Vector3(0.699,0.185,1.163));
205                    hinge_joint = new OgreOde::HingeJoint(_world);
206                    hinge_joint->attach(_apache,_right_front);
207                    hinge_joint->setAnchor(_right_front->getPosition());
208                    hinge_joint->setAxis(Vector3::UNIT_X);
209                    sphere = new OgreOde::SphereGeometry(0.17, _world, _apache_space);
210                    sphere->setBody(_right_front);
211
212                    _geoms.push_back(sphere);
213                    _bodies.push_back(_right_front);
214                    _joints.push_back(hinge_joint);
215        }
216
217
218                // Create the wall of boxes to crash into, make it
219                // smaller in Debug mode for performance reasons
220                int i = 0;
221#ifndef _DEBUG
222                for (Real y = 0.0;y <= 5.0;y += 1.0)
223                {
224                        for (Real x = -6.0 + (y * 0.5);x <= 6.0 - (y * 0.5);x += 1.0)
225                        {
226#else
227                for (Real y = 0.0;y <= 1.0;y += 1.0)
228                {
229                        for (Real x = -2.0 + (y * 0.5);x <= 2.0 - (y * 0.5);x += 1.0)
230                        {
231#endif
232                                // Create the Ogre box
233                                String name = String("Box_") + StringConverter::toString(i);
234                Entity* box = _mgr->createEntity(name,"crate.mesh");
235                box->setQueryFlags (GEOMETRY_QUERY_MASK);
236                                box->setCastShadows(true);
237
238                                SceneNode* node = _mgr->getRootSceneNode()->createChildSceneNode(name);
239                                node->attachObject(box);
240                                node->setScale(0.1,0.1,0.1);
241
242                                // Set the position and rotate that, then rotate the box by the same amount
243                                Quaternion q;
244                                q.FromAngleAxis(Degree(45),Vector3::UNIT_Y);
245                                Vector3 pos(x,y + 0.5,-10.0);
246                                node->setPosition(q * pos);
247                                node->setOrientation(q);
248
249                                // Create a box for ODE and attach it to the Ogre version
250                                OgreOde::Body* body = new OgreOde::Body(_world, name + "Body");
251                                node->attachObject(body);
252                                body->setMass(OgreOde::BoxMass(0.01,Vector3(1,1,1)));
253                body->setDamping (0.005, 0.005);
254
255                                OgreOde::BoxGeometry* geom = new OgreOde::BoxGeometry(Vector3(1.0,1.0,1.0),_world, _space);
256                // Tie the collision geometry to the physical body
257                geom->setBody(body);
258                box->setUserObject(geom);
259
260                                // Keep track of the ODE objects for house keeping
261                                _bodies.push_back(body);
262                                _geoms.push_back(geom);
263
264                                i++;
265                        }
266                }
267        }
268        virtual ~SimpleScenes_Crash()
269        {
270                // Destroy the non-standard scene nodes that make up the helicopter
271                _apache_body_node->removeAndDestroyChild("Main Rotor");
272                _apache_body_node->removeAndDestroyChild("Tail Rotor");
273               
274                // Remove the entities that represent the scene nodes we destroyed
275                _mgr->destroyEntity("Main Rotor");
276                _mgr->destroyEntity("Tail Rotor");
277       
278                // Delete the space in which the helicopter lived
279                delete _apache_space;
280        }
281
282        // Return our name for the test application to display
283        virtual const String& getName()
284        {
285                static String name = "Test Crash";
286                return name;
287        }
288
289        // Return a description of the keys that the user can use in this test
290        virtual const String& getKeys()
291        {
292                static String keys = "I/K - Throttle, J/L - Turn, G/B/V/N - Thrust, X - Fire";
293                return keys;
294        }
295
296#if (OGRE_VERSION_MINOR < 4)
297    // Handle the user's key presses   
298    virtual void frameEnded(Real time,InputReader* input)
299    {
300        // Do default key handling
301        SimpleScenes::frameEnded(time,input);
302#else
303
304    virtual void frameEnded(Real time, OIS::Keyboard* input, OIS::Mouse* mouse)
305    {
306        // Do default processing
307        SimpleScenes::frameEnded(time, input, mouse);
308#endif
309
310                // Throttle up or down
311                if (input->isKeyDown(KC_I)) _main_spd += (_main_response * time);
312                else if (input->isKeyDown(KC_K)) _main_spd -= (_main_response * time);
313
314                // Thrust left, right, forward, or back
315                _thrust_force = Ogre::Vector3::ZERO;
316                if (input->isKeyDown(KC_G)) _thrust_force.z += _thrust;
317                if (input->isKeyDown(KC_B)) _thrust_force.z -= _thrust;
318                if (input->isKeyDown(KC_V)) _thrust_force.x += _thrust;
319                if (input->isKeyDown(KC_N)) _thrust_force.x -= _thrust;
320
321                // Clamp the main rotor speed
322                _main_spd = std::max(_main_min,std::min(_main_max,_main_spd));
323
324                // Turn left or right or automatically stop the tail rotor
325                if (input->isKeyDown(KC_J)) _tail_spd += (_tail_response * time);
326                else if (input->isKeyDown(KC_L)) _tail_spd -= (_tail_response * time);
327                else
328                {
329                        if (_tail_spd < 0.0)
330                        {
331                                _tail_spd += (_tail_response * time);
332                                if (_tail_spd > 0.0) _tail_spd = 0.0;
333                        }
334                        else if (_tail_spd > 0.0)
335                        {
336                                _tail_spd -= (_tail_response * time);
337                                if (_tail_spd < 0.0) _tail_spd = 0.0;
338                        }
339                }
340               
341                // Clamp the tail rotor speed
342                _tail_spd = std::max(_tail_min,std::min(_tail_max,_tail_spd));
343
344                // Rotate the tail rotor scene node
345                _tail_rotor_node->rotate(Vector3::UNIT_X,Radian(_tail_spd * time * _rotate_scale));
346
347                // If there's some power being applied to the main rotor then...
348                if ((_main_spd > _main_min)||(!input->isKeyDown(KC_K)))
349                {
350                        // Rotate the main rotor scene node
351                        _main_rotor_node->rotate(Vector3::UNIT_Y,Radian(_main_spd * time * _rotate_scale));
352                }
353
354                // Fire rockets. Woo!
355                _fire_time += time;
356                if ((_fire_time > _fire_rate)&&(input->isKeyDown(KC_X)))
357                {
358                        _fire_time = 0.0;
359                        _rockets++;
360
361                        // Create a rocket node and attach a particle system to it
362                        const String name (String("Rocket_") + StringConverter::toString(_rockets));
363                        ParticleSystem * rocketParticles = _mgr->createParticleSystem (name, "OgreOdeDemos/Rocket");
364                        SceneNode * rocket_node = _mgr->getRootSceneNode ()->createChildSceneNode (name);
365                        rocket_node->attachObject(rocketParticles);
366                       
367                        // Alternate firing between the left and right pods and
368                        // convert it from body coordinates to world
369                        // Do the same with the firing "force" vector
370                        const Vector3 pos (_apache->getPointWorldPosition (Vector3 (1.35 * ((_rockets & 1)?-1.0:1.0),-0.55,0.95)));
371                        const Vector3 force (_apache->getVectorToWorld (Vector3 (0,0,_fire_force)));
372
373                        rocket_node->setPosition (pos);
374
375                        // Create a sphere for the physical body
376                        OgreOde::Body* rocket_body = new OgreOde::Body (_world);
377                        OgreOde::SphereGeometry* rocket_geom = 
378                new OgreOde::SphereGeometry (_fire_size, _world, _space);
379
380                        rocket_body->setMass (OgreOde::SphereMass (_fire_mass,_fire_size));
381                        rocket_body->setAffectedByGravity (false);
382                        rocket_geom->setBody (rocket_body);
383
384                        rocket_node->attachObject (rocket_body);
385                       
386                        _bodies.push_back (rocket_body);
387                        _geoms.push_back (rocket_geom);
388
389                        // Fire it off by applying an initial force
390                        rocket_body->addForce (force);
391
392                        // Initialise the rocket's life span to zero
393                        _rocket_list[rocket_geom] = 0.0f;
394                }
395
396                // Check all the rockets
397                for (std::map<OgreOde::SphereGeometry*,Real>::iterator i = _rocket_list.begin();
398            i != _rocket_list.end();)
399                {
400            // Increase the time it's lived
401            float *rocketTime = &(i->second);
402                        *rocketTime += time;
403
404                        // If it had it's emitter disabled (see below) more than 2 seconds ago then kill it
405                        if ((*rocketTime < 0.0))
406                        {
407                                // Get the geometry's body and kill any particle system attached to the same node
408                                killParticleSystem (i->first);
409
410                OgreOde::Body * const body = i->first->getBody ();
411                                // Manually remove the body from the list of managed bodies
412                                for (std::vector<OgreOde::Body*>::iterator bi = _bodies.begin();
413                    bi != _bodies.end();)
414                                {
415                                        if ((*bi) == body) 
416                        bi = _bodies.erase(bi);
417                                        else 
418                        ++bi;
419                                }               
420                                       
421                                // Manually delete the geometry from the list of managed geometries
422                                for (std::vector<OgreOde::Geometry*>::iterator gi = _geoms.begin();
423                    gi != _geoms.end();)
424                                {
425                                        if ((*gi) == i->first)
426                        gi = _geoms.erase(gi);
427                                        else 
428                        ++gi;
429                                }                       
430                                       
431                                // Delete the actual body and geometry
432                                delete body;                                           
433                                delete i->first;
434
435                                // Erase the rocket from the hash map
436                                _rocket_list.erase(i++);
437                        }
438                        else 
439                        {
440                                // If the rocket has been alive for more than 2 seconds then kill its emitters (so it fades away)
441                                if (*rocketTime > 3.0)
442                {
443                    OgreOde::SphereGeometry* sphereGeom = i->first;
444                                        killEmitters(sphereGeom, rocketTime);
445                                }
446                                ++i;
447                        }
448                }
449        }
450       
451        // Override the base collision callback, 'cos we don't want the "if connected" check doing
452        bool collision(OgreOde::Contact* contact)
453    {
454        OgreOde::Geometry* firstGeom = contact->getFirstGeometry();
455        OgreOde::Geometry* secondGeom = contact->getSecondGeometry();
456
457        OgreOde::SphereGeometry* rocketGeom = 0;
458        OgreOde::Geometry* otherGeom = 0;
459        float *time = 0;
460        std::map<OgreOde::SphereGeometry*,Real>::iterator li;
461        if (firstGeom->getClass () == OgreOde::Geometry::Class_Sphere || 
462            secondGeom->getClass () == OgreOde::Geometry::Class_Sphere)
463        {
464
465            // If a rocket's hit something then stop emitting particles
466            // check if it's a sphere (rocket proxy Geom...)
467            if (firstGeom->getClass () == OgreOde::Geometry::Class_Sphere)
468            {
469                li = _rocket_list.find(static_cast<OgreOde::SphereGeometry*>(firstGeom));
470                if (li != _rocket_list.end())
471                {   
472                    rocketGeom = li->first;
473                    time = &(li->second);
474                    otherGeom = secondGeom;
475                }
476            }
477
478            if (secondGeom->getClass () == OgreOde::Geometry::Class_Sphere)
479            {
480                std::map<OgreOde::SphereGeometry*,Real>::iterator li = 
481                    _rocket_list.find(static_cast<OgreOde::SphereGeometry*>(secondGeom));
482                if (li != _rocket_list.end())
483                {
484                    rocketGeom = li->first;
485                    time = &(li->second);
486                    otherGeom = firstGeom;
487                }
488            }
489            if (rocketGeom && *time > 0)
490            {
491                // prevent collision against Apache
492                if (otherGeom->getSpace() == _apache_space)
493                {
494                    return  false;
495                }
496
497                // there, Add an Explosion Effect (could make two sphere, one that destroy, one for the wave effect only.)
498                const Vector3 explosionCenter (contact->getPosition ());
499                Ogre::SphereSceneQuery* explosionAreaQuery =  _mgr->createSphereQuery(Sphere(explosionCenter, 20), 0xFFFFFFFF);
500
501                // asking for movable physic object (no particles system or static geometry (here the plane))
502                explosionAreaQuery->setQueryMask (GEOMETRY_QUERY_MASK | VEHICLE_QUERY_MASK);
503                explosionAreaQuery->setQueryTypeMask(SceneManager::ENTITY_TYPE_MASK);
504
505                const SceneQueryResult& result = explosionAreaQuery->execute ();
506                if (!result.movables.empty())
507                {
508                    SceneQueryResultMovableList::const_iterator i = result.movables.begin();
509                    while(i != result.movables.end())
510                    {
511                        //GEOMETRY_QUERY_MASK
512                        OgreOde::Geometry *affectedGeom = static_cast <OgreOde::Geometry *> ((*i)->getUserObject ());
513                        assert (affectedGeom != rocketGeom);
514                        assert (affectedGeom);
515                        OgreOde::Body *affectedBody = affectedGeom->getBody ();                       
516                        assert (affectedBody);
517                        Vector3 forceAreaDirection = (*i)->getParentNode()->getPosition() - explosionCenter;
518                        const Real forcePower = forceAreaDirection.squaredLength () / 5;
519                        forceAreaDirection.normalise ();
520
521                        // Apply the main rotor force
522                        affectedBody->addForce(forceAreaDirection * forcePower);
523                       
524                        ++i;
525                    }
526                }
527
528                // remove particle and rocket geom
529                killEmitters(rocketGeom, time);
530
531                // add explosion particles
532                _rocket_node_explosion->setPosition(explosionCenter);
533                _rocket_node_explosion->setVisible(true);
534
535                resetParticleSystem(_rocketParticles_explosion, true, 0.1);
536                resetParticleSystem(_rocketParticles_smoke_white, true, 0.3);
537                resetParticleSystem(_rocketParticles_smoke, true, 0.6);
538            }
539           
540        }
541                // Set the friction at the contact
542                contact->setCoulombFriction(5.0);
543
544                // Yes, this collision is valid
545                return true;
546        }
547
548        // Will get called just before each time step, since a timestep zeros the force accumulators
549        void addForcesAndTorques()
550        {
551                // Apply the main rotor force
552                _apache->addForce(Vector3(0,_main_spd * _main_scale,0));
553
554                // Apply the tail rotor torque
555                _apache->addRelativeTorque(Vector3(0,_tail_spd * _tail_scale,0));
556
557                // Apply the thrust force
558                _apache->addRelativeForceAtRelative(_thrust_force,_thrust_offs);
559
560       
561        }
562
563protected:
564
565        // Kill the emitters for any particle systems attached to the same node
566        // as the body with which the specified geometry is associated (if that makes sense!)
567        void killEmitters(OgreOde::SphereGeometry* geom, Real* time = 0)
568        {
569                // Find the body
570                OgreOde::Body* body = geom->getBody();
571                if (body)
572                {
573                        // Find the associated scene node
574                        SceneNode* node = static_cast<SceneNode*>(body->getParentNode());
575                        if (node)
576                        {
577                                // Kill the emitters of any attached particle systems
578                                for (int i = 0;i < node->numAttachedObjects();i++)
579                                {
580                                        MovableObject* obj = node->getAttachedObject(i);
581                                        if (obj->getMovableType() == "ParticleSystem")
582                                        { 
583                                                static_cast<ParticleSystem*>(obj)->removeAllEmitters();
584                                        }
585                                }
586                        }
587
588                        // Set the life span value so that we can easily tell
589                        // that its had its emitters deleted
590                        if (time) 
591                *time = -100.0;
592                }
593        }
594
595
596    void resetParticleSystem(Ogre::ParticleSystem *ps, bool enable, const Ogre::Real delay)
597    {
598       const unsigned short numEmitters = ps->getNumEmitters();
599       for (unsigned short i = 0; i < numEmitters; i++)
600       {
601           Ogre::ParticleEmitter *pe = ps->getEmitter(i);
602           pe->setEnabled(enable);
603           pe->setStartTime (delay);
604       }
605
606       ps->setSpeedFactor(enable ? 1.0 : 0.0);
607    }
608        // Kill the particle system and scene node associated with this geometry
609        void killParticleSystem(OgreOde::SphereGeometry* geom)
610        {
611                // Find the body
612                OgreOde::Body* body = geom->getBody();
613                if (body)
614                {
615                        // Find the scene node
616                        SceneNode* node = static_cast<SceneNode*>(body->getParentNode());
617                        if (node)
618                        {                                                       
619                                MovableObject* obj = 0;                         
620                                for (int i = 0;i < node->numAttachedObjects();i++)
621                                {
622                                        // If this object isn't an OgreOde::Body then it must be
623                                        // (in our demo) a particle system that we need to delete
624                                        MovableObject* can_obj = node->getAttachedObject(i);
625                                        if (can_obj->getMovableType() != "OgreOde::Body") 
626                        obj = can_obj;
627                                }
628
629                                // Delete the node
630                                _mgr->getRootSceneNode()->removeAndDestroyChild(node->getName());
631
632                                // If we found a particle system then delete it
633                                if (obj) 
634                    _mgr->destroyParticleSystem(obj->getName());
635                        }
636                }
637        }
638
639protected:
640        // Things we'll control and delete manually
641        Entity *_apache_body,*_main_rotor,*_tail_rotor;
642        SceneNode *_apache_body_node,*_main_rotor_node,*_tail_rotor_node;
643
644        Real _rotate_scale;
645       
646        // Physical things we'll need to apply forces to and delete manually
647        OgreOde::Body *_apache,*_rear_wheel,*_left_front,*_right_front;
648        OgreOde::SimpleSpace* _apache_space;
649
650
651        // The worst helicopter flight model in the world!
652        Real _main_spd,_main_response,_main_scale,_main_min,_main_max;
653        Real _tail_spd,_tail_response,_tail_scale,_tail_min,_tail_max;
654        Real _thrust,_linear_damp,_angular_damp;
655        Vector3 _thrust_offs,_thrust_force;
656
657        // Stuff to help us shoot things
658        Real _fire_rate,_fire_time,_fire_force,_fire_mass,_fire_size;
659        std::map<OgreOde::SphereGeometry*,Real> _rocket_list;
660        int _rockets; 
661
662
663    SceneNode * _rocket_node_explosion;
664    ParticleSystem * _rocketParticles_explosion;
665    ParticleSystem * _rocketParticles_smoke_white;
666    ParticleSystem * _rocketParticles_smoke;
667};
668
669#endif
Note: See TracBrowser for help on using the repository browser.