Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/physics/src/ogreode/OgreOdeBody.h @ 2047

Last change on this file since 2047 was 1923, checked in by rgrieder, 16 years ago

Cleaned up the heavy mess with header file includes in OgreOde. It should now compile a lot faster.

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