Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

added ogreode and Colladaplugin

File size: 10.5 KB
Line 
1/*
2SimpleScenes_RagDoll.h
3---------------------
4A demo RagDoll shooting demo, showing ragdolls and ray intersections.
5*/
6#ifndef _SIMPLESCENES_ZOMBIE_H_
7#define _SIMPLESCENES_ZOMBIE_H_
8
9static const String xmlNames[] = {
10    "zombie",
11    "zombie",
12    "ninja",
13    "robot",
14        "GingerBreadMan"
15};
16static const String meshNames[] = {
17    "zombie_small.mesh",
18    "zombie_small.mesh",
19    "ninja.mesh",
20        "robot.mesh",
21        "GingerBreadMan.mesh"
22};
23static const String meshAnimation [] = {
24    "Walk1",
25    "Walk1",
26    "Walk",
27        "Walk",
28        "Walk1"
29};
30static const Ogre::Vector3 meshScale [] = {
31    Ogre::Vector3(1.0, 1.0, 1.0),
32    Ogre::Vector3(1.0, 1.0, 1.0),
33    Ogre::Vector3(0.02, 0.02, 0.02),
34        Ogre::Vector3(0.05, 0.05, 0.05),
35        Ogre::Vector3(1.0, 1.0, 1.0),
36};
37static const String ragdollFile [] = {
38    "zombie.ogreode",
39    "zombie_auto.ogreode",
40    "ninja.ogreode",
41    "robot.ogreode",
42        "gingerbreadman.ogreode"
43};
44static size_t sSelectedMesh = 4;
45
46#ifdef _DEBUG
47        static size_t sMaxRagdoll = 10;
48#else //_DEBUG
49        static size_t sMaxRagdoll = 30;
50#endif //_DEBUG
51
52/*
53The zombie demo extends the base test class
54*/
55class SimpleScenes_Zombie:public SimpleScenes
56{
57private:
58    typedef std::list<OgreOde_Prefab::Ragdoll *> RagDollList;
59
60    struct ragDollData
61    {
62       int  sSelectedMesh;
63      Ogre::Real timeSinceBirth;
64          Ogre::Real timeSincePhysical;
65    };
66
67public:
68        void createRagDoll()
69    {
70
71                _last_ragdoll = 0.0;
72       
73        OgreOde_Prefab::Ragdoll *ragdoll = static_cast <OgreOde_Prefab::Ragdoll *> (dotOgreOdeLoader->loadObject(ragdollFile[sSelectedMesh],
74                                                                             xmlNames[sSelectedMesh],
75                                                                             "zombie" + StringConverter::toString(_ragdoll_count++)));
76
77
78
79                ragdoll->setCastShadows(true);         
80                ragdoll->setQueryFlags (ZOMBIE_QUERY_MASK);
81
82        Any a = ragdoll->getUserAny ();
83        assert (a.isEmpty ());
84        {
85            ragDollData *= new ragDollData ();
86
87            b->timeSinceBirth = 0.0f;
88            b->timeSincePhysical = 0.0f;
89            b->sSelectedMesh = sSelectedMesh;
90                       
91
92            Any *newA = new Any(b);                       
93            ragdoll->setUserAny (*newA);
94        }
95
96
97                // Add entity to the scene node
98                SceneNode *ragdoll_node = _mgr->getRootSceneNode()->createChildSceneNode(ragdoll->getName() + "Node");
99                ragdoll_node->attachObject(ragdoll);
100                ragdoll_node->yaw(Degree(rand() % 360));
101                ragdoll_node->setPosition(0.0,0.0,0);
102        ragdoll_node->setScale( meshScale[sSelectedMesh]);
103
104                _last_node = ragdoll_node;
105
106       
107                ragdoll->getAnimationState(meshAnimation[sSelectedMesh])->setEnabled(true);
108
109        myRagDolls.push_back (ragdoll);
110
111
112        //sSelectedMesh = (sSelectedMesh + 1) % 4;
113        }
114
115        // Constructor
116    SimpleScenes_Zombie(OgreOde::World *world) :
117        SimpleScenes(world)
118        {
119                _over = (Overlay*)OverlayManager::getSingleton().getByName("OgreOdeDemos/Target");   
120                _over->show();
121
122                _gun = _mgr->createEntity("gun","gun.mesh");
123                _gun->setCastShadows(false);
124
125                _gun_node = _mgr->getRootSceneNode()->createChildSceneNode("gun");
126                _gun_node->attachObject(_gun);
127
128                _camera = _mgr->getCamera("PlayerCam");
129
130                _animation_speed = 1.0;
131                _ragdoll_count = 0;
132                createRagDoll();
133
134                _shot_time = 0.0;
135
136                myOdeRay = new OgreOde::RayGeometry(1000.0, _world, _space);
137                mRayQuery = _mgr->createRayQuery(Ray());
138                mRayQuery->setQueryMask (ZOMBIE_QUERY_MASK);
139                mRayQuery->setQueryTypeMask(SceneManager::ENTITY_TYPE_MASK);
140        }
141       
142        // Destructor
143        virtual ~SimpleScenes_Zombie()
144    {   
145        for ( RagDollList::iterator zE = myRagDolls.begin();
146            zE != myRagDolls.end(); ++zE)
147        {
148            assert ((*zE)->getParentNode ());
149            assert ((*zE)->getParentNode ()->getParent());
150            (static_cast<SceneNode*> ((*zE)->getParentNode ()->getParent()))->removeAndDestroyChild(
151                (*zE)->getParentNode ()->getName ());
152            _mgr->destroyMovableObject((*zE)->getName(), OgreOde_Prefab::RagdollFactory::FACTORY_TYPE_NAME);
153               
154                }   
155                delete myOdeRay;
156
157                _over->hide();
158                _mgr->destroySceneNode("gun");
159                _mgr->destroyEntity("gun");
160                _mgr->destroyQuery (mRayQuery);
161        }
162
163        // Return our name for the test application to display
164        virtual const String& getName()
165        {
166                static String name = "RagDoll Shooting Gallery";
167                return name;
168        }
169
170        // Return a description of the keys that the user can use in this test
171        virtual const String& getKeys()
172        {
173                static String keys = "X - Shoot";
174                return keys;
175        }
176
177   
178#if (OGRE_VERSION_MINOR < 4)
179    virtual void frameStarted(Real time, InputReader* input)
180#else
181    virtual void frameStarted(Real time, OIS::Keyboard* input, OIS::Mouse* mouse)
182#endif //OGRE_VERSION not heihort
183        {
184                _last_ragdoll += time;
185
186        // Do default key handling
187#if (OGRE_VERSION_MINOR < 4)
188        SimpleScenes::frameEnded(time, input);
189#else
190        SimpleScenes::frameEnded(time, input, mouse);
191#endif //OGRE_VERSION not heihort
192
193                _gun_node->setOrientation(_camera->getOrientation());
194                _gun_node->setPosition(_camera->getPosition() + (_camera->getOrientation() * Ogre::Vector3(0.3,-0.15,-1.1)));
195
196        for ( RagDollList::iterator zE = myRagDolls.begin();
197            zE != myRagDolls.end(); 
198            ++zE)
199        {   
200            ragDollData *b = any_cast<ragDollData *> ((*zE)->getUserAny());
201            if ((*zE)->isPhysical())
202            {
203                if (!(*zE)->isStatic())
204                {
205
206                    b->timeSincePhysical += time;
207                    (*zE)->update();// RagDoll Activated
208                }
209            }
210            else
211            {
212                (*zE)->getAnimationState(meshAnimation[b->sSelectedMesh])->addTime(time * _animation_speed);
213
214                (*zE)->getParentNode ()->translate(
215                    (*zE)->getParentNode ()->getOrientation() * (Vector3::UNIT_Z * time * 2.5));
216               
217            }
218        }
219
220        }
221
222
223#if (OGRE_VERSION_MINOR < 4)
224    // Handle the user's key presses   
225    virtual void frameEnded(Real time,InputReader* input)
226    {
227        // Do default key handling
228        SimpleScenes::frameEnded(time,input);
229#else
230
231    virtual void frameEnded(Real time, OIS::Keyboard* input, OIS::Mouse* mouse)
232    {
233        // Do default processing
234        SimpleScenes::frameEnded(time, input, mouse);
235#endif
236                _shot_time -= time;
237
238                if (_key_delay > 0 &&
239            input->isKeyDown(KC_C))
240        { 
241            for ( RagDollList::iterator zE = myRagDolls.begin();
242                zE != myRagDolls.end(); 
243                ++zE)
244            {
245                if ((*zE)->isPhysical())
246                {
247                    (*zE)->releasePhysicalControl();
248                    ragDollData *b = any_cast<ragDollData *> ((*zE)->getUserAny());
249                    (*zE)->getAnimationState(meshAnimation[b->sSelectedMesh])->setEnabled(true);
250                }
251            }
252
253            _key_delay = SimpleScenes::KEY_DELAY;
254                }
255
256
257
258        if (_shot_time <= 0.0 &&             
259#if (OGRE_VERSION_MINOR < 4)
260             (input->isKeyDown(KC_X) || input->getMouseButton (0)))
261#else
262            ( input->isKeyDown(KC_X) || mouse->getMouseState().buttonDown(OIS::MB_Left)))
263#endif
264                {
265
266                        Ray pickRay = _camera->getCameraToViewportRay(0.5, 0.5);
267                        myOdeRay->setDefinition(pickRay.getOrigin(), pickRay.getDirection());
268
269                        _shot_time = 0.2;
270
271                        mRayQuery->setRay (pickRay);
272                        const RaySceneQueryResult& result = mRayQuery->execute();
273                        if (!result.empty())
274                        {
275                                RaySceneQueryResult::const_iterator i = result.begin();
276               
277                                //mRayQuery->setSortByDistance (true, 1);//only one hit
278                                myOdeRay->enable ();
279                                while((i != result.end()))
280                                {
281
282                                        _last_ragdoll = 5.0;
283
284                                        OgreOde_Prefab::Ragdoll * const radgoll =
285                                                static_cast<OgreOde_Prefab::Ragdoll *> (i->movable);
286
287                                   // uncomment to see nice debug mesh of animated mesh
288//#define _TESTTRIMESH
289#ifdef _TESTTRIMESH
290
291                                        // ray cast could be tested against that instead of ragdoll.
292                                        // depending on complexity of mesh could be simpler
293                                        OgreOde::EntityInformer ei((*zE), (*zE)->getParentNode ()->_getFullTransform());
294                                        _geoms.push_back(ei.createStaticTriangleMesh(_space));
295#else //_TESTTRIMESH
296                                        bool wasPhysical = radgoll->isPhysical ();
297                                        if (!wasPhysical)
298                                        {
299                                                ragDollData * const b = any_cast<ragDollData *> (radgoll->getUserAny());
300                                                radgoll->getAnimationState(meshAnimation[b->sSelectedMesh])->setEnabled(false);
301
302                                               
303                                                // Create the ragdoll
304                                                radgoll->takePhysicalControl(_world, _space, false);
305                                                radgoll->setSelfCollisions(false);
306
307                                        }
308
309
310                    OgreOde::Body *hit_body;
311                    Ogre::Vector3 hit_point;
312
313                                        bool is_hit = false;
314                                        if (radgoll->pick(myOdeRay, hit_body, hit_point))
315                                        {
316                                                if (hit_body)
317                                                {
318                                                        hit_body->addForceAt(pickRay.getDirection() * 250000, hit_point);
319                                                        is_hit = true;
320                                                        ragDollData *b = any_cast<ragDollData *> (radgoll->getUserAny());
321                                                        b->timeSincePhysical = 0.0f;
322                                                }
323                                        }
324
325                                        if (!is_hit&& !wasPhysical)
326                                        {
327                                                radgoll->releasePhysicalControl();
328                                                ragDollData *b = any_cast<ragDollData *> (radgoll->getUserAny());
329                                                radgoll->getAnimationState(meshAnimation[b->sSelectedMesh])->setEnabled(true);
330                                        }
331#endif //_TESTTRIMESH   
332
333                                        ++i;
334                                }       // if results. 
335                        }
336                        myOdeRay->disable ();
337        }
338                       
339                   
340                for ( RagDollList::iterator zE = myRagDolls.begin();
341                        zE != myRagDolls.end(); )
342                {
343
344                        OgreOde_Prefab::Ragdoll * const radgoll = (*zE);
345                        ragDollData *b = any_cast<ragDollData *> (radgoll->getUserAny());
346                        b->timeSinceBirth += time;
347
348                        // turn to stone to improve fps,
349                        // better way to do that would be to tweak
350                        // simulation parameters to be less jitty.
351                        // better auto sleep
352                        if (radgoll->isPhysical() 
353                                && !radgoll->isStatic() 
354                                && radgoll->isAwake()
355                                && b->timeSincePhysical > 5.0)
356                        {
357                                //radgoll->turnToStone();
358                                radgoll->sleep();
359                        }
360                       
361           
362                        if ( b->timeSinceBirth > sMaxRagdoll)
363                        {
364                                (static_cast<SceneNode*> (radgoll->getParentNode ()->getParent()))->removeAndDestroyChild(
365                                        radgoll->getParentNode ()->getName ());
366                                _mgr->destroyMovableObject(radgoll->getName(), OgreOde_Prefab::RagdollFactory::FACTORY_TYPE_NAME);
367                                zE = myRagDolls.erase(zE);
368                        }
369                        else
370                        {
371                                ++zE;
372                        }
373                }
374        if (_last_ragdoll > 5.0 && 
375            myRagDolls.size() < static_cast<size_t>(sMaxRagdoll))
376            createRagDoll();
377               
378        }
379
380protected:
381        RagDollList myRagDolls;
382        RaySceneQuery *mRayQuery;
383
384        Real _animation_speed;
385
386        Entity *_gun;
387        SceneNode *_gun_node;
388
389        OgreOde::RayGeometry *myOdeRay;
390
391        Camera* _camera;
392        Overlay* _over;
393
394        Real _shot_time;
395
396        Real _last_ragdoll;
397        int _ragdoll_count;
398};
399
400#endif
Note: See TracBrowser for help on using the repository browser.