Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

added ogreode and Colladaplugin

File size: 5.1 KB
Line 
1/*
2SimpleScenes_Chain.h
3----------------------
4A reimplementation of the ODE spherical chain demo
5using Ogre and the OgreOde wrapper.
6*/
7#ifndef _SIMPLESCENESCHAIN_H_
8#define _SIMPLESCENES_CHAIN_H_
9
10/*
11The chain test extends the base test class
12*/
13class SimpleScenes_Chain:public SimpleScenes
14{
15public:
16        // Standard constructor, creates everything in the demo
17    SimpleScenes_Chain(OgreOde::World *world) :
18      SimpleScenes(world)
19        {
20                // Set up the sizes of stuff
21                Real link_size = 0.4,geom_size = 0.4,adjust = 0.1;
22                OgreOde::Body* last_body = 0;
23                int num_links = 10;
24
25                _first_body = 0;
26                _force = 100;
27
28                // Create all the links in the chain
29                for (int i = num_links - 1;i >= 0;i--)
30                {
31                        Real np = (Real)i * (link_size + adjust);
32                        String name = String("Sphere_") + StringConverter::toString(i);
33
34                        // Visuals
35                        Entity* entity = _mgr->createEntity(name,"ball.mesh");
36                        entity->setNormaliseNormals(true);
37                        entity->setCastShadows(true);
38
39                        SceneNode* node = _mgr->getRootSceneNode()->createChildSceneNode(entity->getName());
40                        node->attachObject(entity);
41                        node->setScale(link_size * 0.2,link_size * 0.2,link_size * 0.2);
42                        node->setPosition(Vector3(np,np + 0.4,np));
43
44                        // Physicals
45                        OgreOde::EntityInformer ei(entity,Matrix4::getScale(node->getScale()));
46                        OgreOde::Body* body = ei.createSingleDynamicSphere(1.0,_world, _space);
47                        _bodies.push_back(body);
48                        _geoms.push_back(body->getGeometry(0));
49
50                        // Join the current body to the last one (if there was a last one)
51                        if (!_first_body)
52                        {
53                                _last_node = node;
54                                _first_body = body;
55                        }
56
57                        if (last_body)
58                        {
59                                OgreOde::BallJoint* joint = new OgreOde::BallJoint(_world);
60                                joint->attach(body,last_body);
61                                Real ja = ((Real)i + 0.5) * (link_size + adjust);
62                                joint->setAnchor(Vector3(ja,ja + 0.4,ja));
63
64                                _joints.push_back(joint);
65                        }
66
67                        last_body = body;
68                }
69
70                // Create some static boxes to bump into
71                createBox(0,2,Vector3(4,1,4));
72                createBox(1,2,Vector3(-4,1,4));
73                createBox(2,2,Vector3(-4,1,-4));
74                createBox(3,2,Vector3(4,1,-4));
75        }
76
77      // Let the user throw the chain around
78#if (OGRE_VERSION_MINOR < 4)
79      // Handle the user's key presses 
80      virtual void frameEnded(Real time,InputReader* input)
81      {
82          // Do default key handling
83          SimpleScenes::frameEnded(time,input);
84#else
85
86      virtual void frameEnded(Real time, OIS::Keyboard* input, OIS::Mouse* mouse)
87      {
88          // Do default processing
89          SimpleScenes::frameEnded(time, input, mouse);
90#endif
91                _force_to_apply = Ogre::Vector3::ZERO;
92
93                Vector3 right = _mgr->getCamera("PlayerCam")->getRight();
94                Vector3 forward = right.crossProduct(Vector3::UNIT_Y);
95
96                // Up
97                if (input->isKeyDown(KC_X)) _force_to_apply += Ogre::Vector3::UNIT_Y * _force;
98
99                // Left/right
100                if (input->isKeyDown(KC_J)) _force_to_apply -= right * _force;
101                if (input->isKeyDown(KC_L)) _force_to_apply += right * _force;
102
103                // Forward/back
104                if (input->isKeyDown(KC_K)) _force_to_apply += forward * _force;
105                if (input->isKeyDown(KC_I)) _force_to_apply -= forward * _force;
106
107                _mgr->getCamera("PlayerCam");
108        }
109
110        // Apply the forces before every time step
111        void addForcesAndTorques()
112        {
113                // Apply the force we calculated in the key handler
114                _first_body->addForce(_force_to_apply);
115        }
116
117        // Return our name for the test application to display
118        virtual const String& getName()
119        {
120                static String name = "Test Chain";
121                return name;
122        }
123
124        // Tell the user what keys they can use
125        virtual const String& getKeys()
126        {
127                static String keys = "J/L, I/K, X - Throw the chain around";
128                return keys;
129        }
130
131        // Override the collision callback to set our own parameters
132        bool collision(OgreOde::Contact* contact)
133        {
134                // Set the floor to be a bit slippy
135                contact->setCoulombFriction(10.0);
136                return true;
137        }
138
139        // Use the destructor to delete the crate scene nodes
140        // everything else gets deleted automatically
141        ~SimpleScenes_Chain()
142        {
143                for (int i = 0;i < 4;i++)
144                {
145                        if (i != 2)
146                        {
147                                String name = String("Crate_") + StringConverter::toString(i);
148                                _mgr->destroySceneNode(name);
149                                _mgr->destroyEntity(name);
150                        }
151                }
152        }
153
154protected:
155        // Utility method to create a static box
156        void createBox(int id,Real size,const Ogre::Vector3& position)
157        {
158                // Visual
159                String name = String("Crate_") + StringConverter::toString(id);
160
161                Entity* entity = _mgr->createEntity(name,"crate.mesh");
162                entity->setNormaliseNormals(true);
163                entity->setCastShadows(true);
164
165                SceneNode* node = _mgr->getRootSceneNode()->createChildSceneNode(entity->getName());
166                node->attachObject(entity);
167                node->setScale(size * 0.1,size * 0.1,size * 0.1);
168                node->setPosition(position);
169
170                // Make one of them dynamic, the others are static
171                OgreOde::EntityInformer ei(entity,Matrix4::getScale(node->getScale()));
172                if ((position.x < 0)&&(position.z < 0))
173                {
174                        _box_body = ei.createSingleDynamicBox(2.0, _world, _space); 
175                        _bodies.push_back(_box_body);
176                        _geoms.push_back(_box_body->getGeometry(0));
177                }
178                else
179                {
180                        // Collision geometry
181                        _geoms.push_back(ei.createSingleStaticBox(_world, _space));
182                }
183        } 
184
185protected:
186        // Keep track of the top of the chain so we can throw it around
187        OgreOde::Body *_first_body,*_box_body;
188        Real _force;
189        Vector3 _force_to_apply;
190};
191
192#endif
Note: See TracBrowser for help on using the repository browser.