Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

added ogreode and Colladaplugin

File size: 11.0 KB
Line 
1/*
2SimpleScenes.cpp
3---------------
4Code for the base scene class from which the specific scenes are derived
5*/
6#include "SimpleScenes.h"
7
8using namespace Ogre;
9using namespace OgreOde;
10using namespace OgreOde_Prefab;
11using namespace OgreOde_Loader;
12
13const Ogre::Real SimpleScenes::KEY_DELAY = 1.0;
14const Ogre::Real SimpleScenes::STEP_RATE = 0.01;
15
16/*
17Constructor; initailise stuff
18*/
19SimpleScenes::SimpleScenes(OgreOde::World *world)
20{
21        _world = world;
22        _mgr = _world->getSceneManager();
23        _world->setCollisionListener(this);
24        _space = _world->getDefaultSpace();
25        _key_delay = SimpleScenes::KEY_DELAY;
26    _last_node = 0;
27
28    dotOgreOdeLoader = new  OgreOde_Loader::DotLoader (world);
29
30    _ragdollFactory = new OgreOde_Prefab::RagdollFactory();
31    Ogre::Root::getSingletonPtr()->addMovableObjectFactory(_ragdollFactory); 
32    setInfoText(StringUtil::BLANK);
33}
34
35/*
36Called by OgreOde whenever a collision occurs, so
37that we can modify the contact parameters
38*/
39bool SimpleScenes::collision(OgreOde::Contact* contact) 
40{
41        // Check for collisions between things that are connected and ignore them
42        OgreOde::Geometry * const g1 = contact->getFirstGeometry();
43        OgreOde::Geometry * const g2 = contact->getSecondGeometry();
44
45        if (g1 && g2)
46        {
47                const OgreOde::Body * const b1 = g1->getBody();
48                const OgreOde::Body * const  b2 = g2->getBody();
49                if (b1 && b2 && OgreOde::Joint::areConnected(b1, b2)) 
50           return false; 
51        }
52
53        // Set the friction at the contact
54        contact->setCoulombFriction(OgreOde::Utility::Infinity);
55
56    contact->setBouncyness(0.1);
57
58    //contact->setCoulombFriction(5.0);
59    //contact->setFrictionMode(OgreOde::Contact::Flag_SurfaceIsBouncy);
60
61    //contact->setCoulombFriction(OgreOde::Utility::Infinity);
62
63        // Yes, this collision is valid
64        return true;
65}
66
67/*
68Handle key presses
69*/
70#if (OGRE_VERSION_MINOR < 4)
71void SimpleScenes::frameEnded(Real time, InputReader* input)
72#else
73void SimpleScenes::frameEnded(Real time, OIS::Keyboard* input, OIS::Mouse* mouse)
74#endif //OGRE_VERSION not heihort
75{
76        _key_delay += time;
77
78    std::for_each (RagdollList.begin(), RagdollList.end(), 
79        std::mem_fun (&OgreOde_Prefab::Ragdoll::update)); 
80}
81
82/*
83Utility method to set the information string in the UI
84*/
85void SimpleScenes::setInfoText(const String& text)
86{
87        OverlayManager::getSingleton().getOverlayElement("OgreOdeDemos/Info")->setCaption(String("Info: ") + text);
88}
89
90static const String xmlNames[] = {
91    "zombie",
92    "zombie",
93    "ninja",
94    "robot"
95};
96static const String meshNames[] = {
97    "zombie_small.mesh",
98    "zombie_small.mesh",
99    "ninja.mesh",
100    "robot.mesh"
101};
102static const String meshAnimation [] = {
103    "Walk1",
104    "Walk1",
105    "Walk",
106    "Walk"
107};
108static const Ogre::Vector3 meshScale [] = {
109    Ogre::Vector3(1.0, 1.0, 1.0),
110    Ogre::Vector3(1.0, 1.0, 1.0),
111    Ogre::Vector3(1.0, 1.0, 1.0),
112    Ogre::Vector3(1.0, 1.0, 1.0)
113};
114static const String ragdollFile [] = {
115    "zombie.ogreode",
116    "zombie_auto.ogreode",
117    "ninja.ogreode",
118    "robot.ogreode"
119};
120static int sSelectedMesh = 0;
121static int _ragdoll_count = 0;
122
123/*
124Create a ragdoll
125*/
126void SimpleScenes::createRagDoll()
127{
128    if (_key_delay < SimpleScenes::KEY_DELAY) 
129        return;
130 
131    _key_delay = 0.0;
132
133
134    OgreOde_Prefab::Ragdoll *_ragdoll = static_cast <OgreOde_Prefab::Ragdoll *> (dotOgreOdeLoader->loadObject (ragdollFile[sSelectedMesh], 
135                                                                           xmlNames[sSelectedMesh], 
136                                                                            "zombie" + StringConverter::toString(_ragdoll_count++)));
137
138
139    _ragdoll->setCastShadows(true);
140
141    SceneNode *_ragdoll_node = _mgr->getRootSceneNode()->createChildSceneNode(_ragdoll->getName() + "Node");
142    _ragdoll_node->attachObject(_ragdoll);
143
144    //_ragdoll_node->yaw(Degree(rand() % 360));
145    //_ragdoll_node->pitch(Degree(rand() % 360));
146
147
148    _ragdoll_node->setOrientation(Quaternion(Radian(OgreOde::Utility::randomReal() * 10.0 - 5.0),
149                                    Ogre::Vector3(OgreOde::Utility::randomReal() * 2.0 - 1.0,
150                                    OgreOde::Utility::randomReal() * 2.0 - 1.0,
151                                    OgreOde::Utility::randomReal() * 2.0 - 1.0)));
152
153    _ragdoll_node->setPosition(Vector3((OgreOde::Utility::randomReal() * 10.0) - 5.0,
154                                OgreOde::Utility::randomReal() + 5,
155                                (OgreOde::Utility::randomReal() * 10.0) - 5.0));
156
157
158    _ragdoll_node->setScale( meshScale[sSelectedMesh]);
159
160
161    _ragdoll->getAnimationState(meshAnimation[sSelectedMesh])->setEnabled(false);
162
163
164    // Create the ragdoll
165    _ragdoll->takePhysicalControl(_world, _space, false);
166    _ragdoll->setSelfCollisions(false);
167
168    RagdollList.push_back(_ragdoll);
169
170}
171/*
172Create a randomly sized box, sphere or capsule for dropping on things
173*/ 
174OgreOde::Body* SimpleScenes::createRandomObject(OgreOde::Geometry::Class objectClass)
175{
176        if (_key_delay < SimpleScenes::KEY_DELAY) 
177        return 0;
178
179        String typeName = (objectClass == OgreOde::Geometry::Class_Box)?"crate":
180                                      (objectClass == OgreOde::Geometry::Class_Sphere)?"ball":
181                                          (objectClass == OgreOde::Geometry::Class_Capsule)?"capsule":
182                      (objectClass == OgreOde::Geometry::Class_TriangleMesh)?"gun":
183                      "unknown";
184
185        // Create the visual representation (the Ogre entity and scene node)
186        String name = typeName + StringConverter::toString((unsigned int)_bodies.size());
187        Entity* entity = _mgr->createEntity(name, typeName + ".mesh");
188    entity->setQueryFlags (GEOMETRY_QUERY_MASK);
189
190        SceneNode* node = _mgr->getRootSceneNode()->createChildSceneNode(name);
191        node->attachObject(entity);
192        entity->setNormaliseNormals(true);
193        entity->setCastShadows(true);
194
195        // Pick a size
196        Vector3 size((OgreOde::Utility::randomReal() * 0.5 + 0.1) * 2.0,
197                (OgreOde::Utility::randomReal() * 0.5 + 0.1) * 2.0,
198                (OgreOde::Utility::randomReal() * 0.5 + 0.1) * 2.0);
199
200        // Create a body associated with the node we created
201    OgreOde::Body* body = new OgreOde::Body(_world);
202        node->attachObject(body);
203
204        // Set the mass and geometry to match the visual representation
205        OgreOde::Geometry* geom = 0;
206        switch (objectClass)
207        {
208                case OgreOde::Geometry::Class_Box:
209                {
210                        size *= 1.75;
211
212                        OgreOde::BoxMass mass(1.0,size);
213                        mass.setDensity(5.0,size);
214                       
215            geom = (OgreOde::Geometry*)new OgreOde::BoxGeometry(size, _world, _space); 
216                        node->setScale(size.x * 0.1,size.y * 0.1,size.z * 0.1);
217                        body->setMass(mass);
218                }
219                break;
220
221                case OgreOde::Geometry::Class_Sphere:
222                {
223                        OgreOde::SphereMass mass(1.0,size.x);
224                        mass.setDensity(5.0,size.x);
225
226            geom = (OgreOde::Geometry*)new OgreOde::SphereGeometry(size.x, _world, _space);
227                        node->setScale(size.x * 0.2,size.x * 0.2,size.x * 0.2);
228                        body->setMass(mass);
229                }
230                break;
231
232                case OgreOde::Geometry::Class_Capsule:
233                {
234                        size.x *= 0.5;
235
236                        OgreOde::CapsuleMass mass(1.0,size.x,Vector3::UNIT_Z,size.y);
237                        mass.setDensity(5.0,size.x,Vector3::UNIT_Z,size.y);
238                       
239                        geom = (OgreOde::Geometry*)new OgreOde::CapsuleGeometry(size.x,size.y, _world, _space);
240                        node->setScale(size.x,size.x,(size.y + (size.x * 2.0)) * 0.25);
241                        body->setMass(mass);
242                }
243        break;
244
245        case OgreOde::Geometry::Class_TriangleMesh:
246        {
247                OgreOde::EntityInformer ei(entity, node->_getFullTransform());
248                geom = ei.createStaticTriangleMesh( _world, _space);
249
250            OgreOde::BoxMass mass(1.0, ei.getSize());
251            mass.setDensity(5.0, ei.getSize());
252
253            //node->setScale(size.x,size.x,(size.y + (size.x * 2.0)) * 0.25);
254            body->setMass(mass);
255        }
256        break;
257        }
258
259        // Tie the collision geometry to the physical body
260    geom->setBody(body);
261    entity->setUserObject(geom);
262
263        // Keep track of the body
264        _bodies.push_back(body);
265        _geoms.push_back(geom);
266       
267        _key_delay = 0.0;
268
269        // If we created something position and orient it randomly
270        if (body)
271        {
272                body->setOrientation(Quaternion(Radian(OgreOde::Utility::randomReal() * 10.0 - 5.0),
273                                Ogre::Vector3(OgreOde::Utility::randomReal() * 2.0 - 1.0,
274                                        OgreOde::Utility::randomReal() * 2.0 - 1.0,
275                                        OgreOde::Utility::randomReal() * 2.0 - 1.0)));
276                body->setPosition(Vector3((OgreOde::Utility::randomReal() * 10.0) - 5.0,
277                                    OgreOde::Utility::randomReal() + 5,
278                                    (OgreOde::Utility::randomReal() * 10.0) - 5.0));
279
280                // Set the last body we created to be looked at
281                _last_node = static_cast<SceneNode*>(body->getParentNode());
282        }
283
284        return body;
285}
286
287/*
288Destructor, delete everything we're keeping track of
289*/
290SimpleScenes::~SimpleScenes(void)
291{
292        // Stop listening for collisions
293        if (_world->getCollisionListener() == this) 
294        _world->setCollisionListener(0);
295
296        // Delete all the joints
297        for (std::vector<OgreOde::Joint*>::iterator i = _joints.begin();i != _joints.end();++i)
298        {
299                delete (*i);
300        }
301
302        // Run through the list of bodies we're monitoring
303        for (std::vector<OgreOde::Body*>::iterator i = _bodies.begin();i != _bodies.end();++i)
304        {
305                // Get the node this body controls
306                SceneNode* node = static_cast<SceneNode*>((*i)->getParentNode());
307                if (node)
308                {
309                        // Get its name and remember all the things attached to it
310                        String name = node->getName();
311                        int num = node->numAttachedObjects();
312                        for (int cur = 0;cur < num; cur++)
313                        {
314                                MovableObject* obj = node->getAttachedObject(cur);
315                                if (obj->getMovableType() != OgreOde::Body::MovableType) 
316                    clearList.push_back(obj);
317                        }
318
319                        // Destroy the node by name
320                        _mgr->getRootSceneNode()->removeAndDestroyChild(name);
321                }
322
323                // Delete the body
324                delete (*i);
325        }
326
327        // Remove all the entities we found attached to scene nodes we're controlling
328        for (std::vector<MovableObject*>::iterator i = clearList.begin();i != clearList.end();++i)
329        {
330        if ((*i)->getMovableType() == "Entity") 
331        {
332            MovableObject* m = static_cast<MovableObject*>(*i);
333            //_mgr->destroyMovableObject(m->getName(), m->);
334            _mgr->destroyMovableObject(m);
335        }
336                else  if ((*i)->getMovableType() == "ParticleSystem") 
337        {
338            _mgr->destroyParticleSystem(static_cast<ParticleSystem*>(*i));
339        }
340        }
341
342        // Delete all the collision geometries
343        for (std::vector<OgreOde::Geometry*>::iterator i = _geoms.begin();i != _geoms.end();++i)
344        {
345                delete (*i);
346        }
347    // Remove all the entities we found attached to scene nodes we're controlling
348    for (std::vector<OgreOde_Prefab::Ragdoll *>::iterator i = RagdollList.begin();i != RagdollList.end();++i)
349    {
350
351        assert ((*i)->getParentNode ());
352        assert ((*i)->getParentNode ()->getParent());
353        (static_cast<SceneNode*> ((*i)->getParentNode ()->getParent()))->removeAndDestroyChild(
354            (*i)->getParentNode ()->getName ());
355
356        _mgr->destroyMovableObject((*i)->getName(), OgreOde_Prefab::RagdollFactory::FACTORY_TYPE_NAME);
357        //_mgr->destroyMovableObject(m);
358    }
359        Ogre::Root::getSingletonPtr()->removeMovableObjectFactory(_ragdollFactory);
360        delete _ragdollFactory; 
361}
Note: See TracBrowser for help on using the repository browser.