Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/ogreode/include/OgreOdeBody.h @ 21

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

added ogreode and Colladaplugin

File size: 12.2 KB
Line 
1#ifndef _OGREODEBODY_H_
2#define _OGREODEBODY_H_
3
4#include "OgreOdePreReqs.h"
5
6namespace OgreOde
7{
8        //-----------------------------------------------------------------------
9        class _OgreOdeExport BodyState
10        {
11        public:
12                BodyState(){};
13                BodyState(const Ogre::Vector3   &position,
14                                  const Ogre::Quaternion &orientation);
15
16        void operator=(const BodyState &other);
17                bool operator==(const BodyState &other) const;
18                bool operator!=(const BodyState &other) const;
19
20                //-----------------------------------------------------------------------
21                /// compare with another physics state for "significant" differences.
22                /// used for detecting position or orientation snaps which need smoothing.
23                bool isDifferent(const BodyState &other, const Ogre::Real threshold = Ogre::Real(0.01)) const;
24
25        void interpolate(const BodyState * const _previous_state, 
26                                const BodyState * const _current_state, 
27                                const Ogre::Real alpha);
28
29                Ogre::Vector3           _position;
30                Ogre::Quaternion        _orientation;
31        };
32
33        //-----------------------------------------------------------------------
34        template <class T>
35        class _OgreOdeExport CircularBuffer
36        {
37        public:
38
39                CircularBuffer() :
40                        head (0),
41                        tail (0)
42                {
43                }
44
45                void resize(const size_t size)
46                {
47                        head = 0;
48                        tail = 0;
49                        buffers.resize(size);
50                }
51
52                size_t size()
53                {
54                        int count = (int)head - (int)tail;
55                        if (count<0)
56                                count += (int) buffers.size();
57                        return (size_t) count;
58                }
59
60                void add(const T &buffer)
61                {
62                        buffers[head] = buffer;
63                        next(head);
64
65                }
66
67                void remove()
68                {
69                        assert(!empty());
70                        next(tail);
71                }
72
73                T& oldest()
74                {
75                        assert(!empty());
76                        return buffers[tail];
77                }
78
79                T& newest()
80                {
81                        assert(!empty());
82                        int index = (int)head - 1;
83                        if (index == -1)
84                                index = (int) buffers.size() - 1;
85                        return buffers[index];
86                }
87
88                T& almostNewest()
89                {
90                        assert(buffers.size() > 1);
91                        int index = (int)head - 2;
92                        if (index == -1)
93                                index = (int) buffers.size() - 1;
94                        return buffers[index];
95                }
96
97                bool empty() const
98                {
99                        return head == tail;
100                }
101
102                void next(size_t &index)
103                {
104                        if (index  == (size_t)buffers.size()) 
105                                index -= (size_t)buffers.size();
106                        else
107                                index ++;
108                }
109
110                void previous(size_t &index)
111                {                       
112                        if ((int)index - 1 < 0)
113                                index += (size_t)buffers.size();
114                        else
115                                index --;
116                }
117
118                T& operator[](size_t index)
119                {
120                        assert(index<(size_t)buffers.size());
121                        return buffers[index];
122                }
123
124        public:
125
126                size_t head;
127                size_t tail;
128
129        private:
130                std::vector<T> buffers;
131        };
132    /**
133        This object is the class defining a for all Dynamically physical objects in OgreOde.
134    @remarks
135        This object is tied attached to a scene node,
136        or/and tied a Entity Object using UserDefinedObject
137    @remarks
138        It extends the OGRE UserDefinedObject to allow reverse links from Ogre::Entity.
139        It extends the OGRE MovableObject to allow scene node attachment.
140    */ 
141        class _OgreOdeExport Body : public Ogre::MovableObject, public Ogre::UserDefinedObject
142    {
143                friend class Joint;
144                friend class World;
145                friend class Geometry;
146
147        public:
148                Body(World *world, const Ogre::String& name = Ogre::StringUtil::BLANK);
149                virtual ~Body();
150
151        static const Ogre::String MovableType;
152
153                void _historyResize(const size_t size);
154                inline void updateParentNode();
155                inline void updatePreviousState();
156                inline void updateCurrentState();
157                inline void updateDrawState ();
158                inline void interpolateDrawState(const Ogre::Real alpha);
159                inline void synchronise();
160
161                void deriveLocation();
162
163                void setPosition(const Ogre::Vector3& position); 
164                void setOrientation(const Ogre::Quaternion& orientation); 
165                void setLinearVelocity(const Ogre::Vector3& linear_velocity); 
166                void setAngularVelocity(const Ogre::Vector3& angular_velocity); 
167
168                inline const Ogre::Vector3& getPosition() const;
169
170                inline const Ogre::Quaternion& getOrientation() const;
171                inline void updatePosition(BodyState * const bodystate);
172        inline void updateOrientation(BodyState * const bodystate);
173
174                const Ogre::Vector3& getLinearVelocity(); 
175                const Ogre::Vector3& getAngularVelocity(); 
176
177                virtual const Ogre::String& getMovableType() const; 
178        virtual void _notifyAttached(Ogre::Node* parent,bool isTagPoint = false);
179                virtual const Ogre::String& getName(void) const;
180                virtual void _notifyCurrentCamera(Ogre::Camera* camera);
181                virtual const Ogre::AxisAlignedBox& getBoundingBox(void) const;
182                virtual Ogre::Real getBoundingRadius(void) const;
183        virtual void _updateRenderQueue(Ogre::RenderQueue* queue);
184               
185                void setMass(const Mass& mass);
186                const Mass& getMass();
187
188                void addForce(const Ogre::Vector3& force); 
189                void addTorque(const Ogre::Vector3& torque); 
190                void addRelativeForce(const Ogre::Vector3& force); 
191                void addRelativeTorque(const Ogre::Vector3& torque); 
192                void addForceAt(const Ogre::Vector3& force,const Ogre::Vector3& position); 
193                void addForceAtRelative(const Ogre::Vector3& force,const Ogre::Vector3& position); 
194                void addRelativeForceAt(const Ogre::Vector3& force,const Ogre::Vector3& position); 
195                void addRelativeForceAtRelative(const Ogre::Vector3& force,const Ogre::Vector3& position); 
196
197                const Ogre::Vector3& getForce(); 
198        const Ogre::Vector3& getTorque(); 
199        void setForce(const Ogre::Vector3&); 
200        void setTorque(const Ogre::Vector3&); 
201
202
203                Ogre::Vector3 getPointWorldPosition(const Ogre::Vector3& position); 
204                Ogre::Vector3 getPointWorldVelocity(const Ogre::Vector3& position);
205                Ogre::Vector3 getPointVelocity(const Ogre::Vector3& position); 
206                Ogre::Vector3 getPointBodyPosition(const Ogre::Vector3& position);
207                Ogre::Vector3 getVectorToWorld(const Ogre::Vector3& vector);
208                Ogre::Vector3 getVectorFromWorld(const Ogre::Vector3& vector);
209
210                void wake();
211                void sleep(); 
212                inline bool isAwake() const; 
213                void setAutoSleep(bool auto_sleep);
214                bool getAutoSleep(); 
215                void setAutoSleepLinearThreshold(Ogre::Real linear_threshold);
216                Ogre::Real getAutoSleepLinearThreshold(); 
217                void setAutoSleepAngularThreshold(Ogre::Real angular_threshold);
218                Ogre::Real getAutoSleepAngularThreshold(); 
219                void setAutoSleepSteps(int steps);
220                int  getAutoSleepSteps(); 
221                void setAutoSleepTime(Ogre::Real time);
222                Ogre::Real getAutoSleepTime(); 
223                void setAutoSleepDefaults();
224
225                void setFiniteRotationMode(bool on); 
226                bool getFiniteRotationMode(); 
227                void setFiniteRotationAxis(const Ogre::Vector3& axis); 
228                const Ogre::Vector3& getFiniteRotationAxis(); 
229
230        int getJointCount(); 
231                Joint* getJoint(int index); 
232
233                void setModifyParentOrientation(bool bModify);
234
235        void addGeometry(Geometry *g); 
236        void removeGeometry(Geometry *g); 
237        size_t getGeometryCount(); 
238        Geometry* getGeometry(int index);
239        GeometryArray* getGeometries();
240
241                void setAffectedByGravity(bool on);
242                bool getAffectedByGravity(); 
243
244                void setDamping(Ogre::Real linear_damping, Ogre::Real angular_damping);
245                void setLinearDamping(Ogre::Real linear_damping);
246                void setAngularDamping(Ogre::Real angular_damping);
247                Ogre::Real getLinearDamping();
248                Ogre::Real getAngularDamping();
249
250                void setUserData(unsigned long user_data);
251                unsigned long getUserData();
252
253                virtual unsigned long getID();
254                virtual void setDebug(const bool debug);
255
256        /** Return a string identifying the type of user defined object.
257        @remarks
258            Used to differentiate between different Bodies, Geometries and prefab_object
259        */
260        const Ogre::String& getTypeName(void) const
261        {static Ogre::String sName("Body");return sName;};
262
263        bool collide(void* data, Geometry *g);
264        bool collide(void* data, Body *b);
265        bool collidePlaneBounds(void* data, Ogre::SceneQuery::WorldFragment *);
266
267        protected:
268                dBodyID getBodyID() const;
269
270                void destroyDebugNode();
271                void addDebugNode(Ogre::Node* node);
272
273                void recursiveSetMode(Ogre::SceneNode* node);
274               
275                void applyDamping();
276
277        protected:
278                dBodyID _body;
279                Ogre::String _name;
280                Ogre::Node* _debug_node;
281
282                static int _body_count;
283
284                Ogre::Vector3 _linear_vel;
285                Ogre::Vector3 _angular_vel;
286                Ogre::Vector3 _finite_axis;
287                Ogre::Vector3 _force;
288                Ogre::Vector3 _torque;
289                Ogre::AxisAlignedBox _bounding_box;
290                Mass* _mass;
291
292                bool _is_damped;
293                bool _is_linear_damped;
294                dReal _linear_damping;
295                bool _is_angular_damped;
296                dReal _angular_damping;
297
298                unsigned long _user_data;
299
300                // Major members
301                bool _isEnabled;
302                bool _modify_parent_orientation; 
303
304                BodyState          _draw_state;
305        CircularBuffer<BodyState *> _state_history;
306
307        /// Collision proxies, must be set up if collision enabled
308        GeometryArray _geometries;
309       
310                World *_world;
311
312        };
313
314    //-----------------------------------------------------------------------
315    inline bool Body::isAwake() const { return _isEnabled; }
316    //-----------------------------------------------------------------------
317    inline void Body::updateParentNode()
318    {
319        if (mParentNode)
320        { 
321            mParentNode->setPosition(_draw_state._position);
322            mParentNode->setOrientation(_draw_state._orientation);
323        }
324
325        if (_debug_node)
326        {
327            _debug_node->setPosition(_draw_state._position);
328            _debug_node->setOrientation(_draw_state._orientation);
329
330            recursiveSetMode(static_cast<Ogre::SceneNode*>(_debug_node));
331        }
332    } 
333    //-----------------------------------------------------------------------
334    inline void Body::updatePreviousState()
335    {
336        _isEnabled = dBodyIsEnabled(_body) || _debug_node;
337        if (_isEnabled)
338        {
339            BodyState *previous = _state_history.almostNewest ();
340            updatePosition (previous);
341            updateOrientation (previous);
342        }
343    }
344    //-----------------------------------------------------------------------
345    inline void Body::updateCurrentState()
346    {
347        _isEnabled = dBodyIsEnabled(_body) || _debug_node;
348        if (_isEnabled)
349        {
350            BodyState *current = _state_history.newest ();
351            updatePosition(current);
352            updateOrientation(current);
353        }
354    }
355    //-----------------------------------------------------------------------
356    inline void Body::updateDrawState ()
357    {
358        _isEnabled = dBodyIsEnabled(_body) || _debug_node;
359        if (_isEnabled)
360        {
361            updatePosition(&_draw_state);
362            updateOrientation(&_draw_state);
363        }
364    }
365    //-----------------------------------------------------------------------
366    inline void Body::interpolateDrawState(const Ogre::Real alpha)
367    {
368        if (_isEnabled)
369        {
370            BodyState *current = _state_history.newest ();
371            BodyState *previous = _state_history.almostNewest ();
372            assert (current != previous);
373            _draw_state.interpolate (previous, current, alpha);
374        }
375    }
376    //-----------------------------------------------------------------------
377    inline void Body::synchronise()
378    {
379        if (_isEnabled)
380        {
381            if (_is_damped)
382                applyDamping();
383            updateParentNode();
384        }
385    }
386    //-----------------------------------------------------------------------
387    inline const Ogre::Vector3& Body::getPosition() const
388    {
389        return _draw_state._position;
390    }
391    //-----------------------------------------------------------------------
392    inline const Ogre::Quaternion& Body::getOrientation() const
393    {
394        return _draw_state._orientation;
395    }
396    //-----------------------------------------------------------------------
397    inline void Body::updatePosition(BodyState * const bodystate)
398    {
399        const dReal * const position = dBodyGetPosition(_body);
400
401        bodystate->_position.x = (Ogre::Real)position[0];
402        bodystate->_position.y = (Ogre::Real)position[1];
403        bodystate->_position.z = (Ogre::Real)position[2];
404    }
405    //-----------------------------------------------------------------------
406    inline void Body::updateOrientation(BodyState * const bodystate)
407    {
408        const dReal * const orientation = dBodyGetQuaternion(_body); 
409        bodystate->_orientation.w = (Ogre::Real)orientation[0];
410        bodystate->_orientation.x = (Ogre::Real)orientation[1];
411        bodystate->_orientation.y = (Ogre::Real)orientation[2];
412        bodystate->_orientation.z = (Ogre::Real)orientation[3];
413    }
414    //-----------------------------------------------------------------------
415}
416
417#endif
Note: See TracBrowser for help on using the repository browser.