Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 2141 was 2119, checked in by rgrieder, 16 years ago

Merged physics branch into physics_new branch.

  • 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.