Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

Minor adjustments to OgreODE when compiling under gcc.

  • Property svn:eol-style set to native
File size: 12.3 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#if OGRE_VERSION >= ((1 << 16) | (5 << 8))
185                virtual void visitRenderables(Ogre::Renderable::Visitor* visitor, bool debugRenderables = false){}
186#endif
187                void setMass(const Mass& mass);
188                const Mass& getMass();
189
190                void addForce(const Ogre::Vector3& force); 
191                void addTorque(const Ogre::Vector3& torque); 
192                void addRelativeForce(const Ogre::Vector3& force); 
193                void addRelativeTorque(const Ogre::Vector3& torque); 
194                void addForceAt(const Ogre::Vector3& force,const Ogre::Vector3& position); 
195                void addForceAtRelative(const Ogre::Vector3& force,const Ogre::Vector3& position); 
196                void addRelativeForceAt(const Ogre::Vector3& force,const Ogre::Vector3& position); 
197                void addRelativeForceAtRelative(const Ogre::Vector3& force,const Ogre::Vector3& position); 
198
199                const Ogre::Vector3& getForce(); 
200        const Ogre::Vector3& getTorque(); 
201        void setForce(const Ogre::Vector3&); 
202        void setTorque(const Ogre::Vector3&); 
203
204
205                Ogre::Vector3 getPointWorldPosition(const Ogre::Vector3& position); 
206                Ogre::Vector3 getPointWorldVelocity(const Ogre::Vector3& position);
207                Ogre::Vector3 getPointVelocity(const Ogre::Vector3& position); 
208                Ogre::Vector3 getPointBodyPosition(const Ogre::Vector3& position);
209                Ogre::Vector3 getVectorToWorld(const Ogre::Vector3& vector);
210                Ogre::Vector3 getVectorFromWorld(const Ogre::Vector3& vector);
211
212                void wake();
213                void sleep(); 
214                inline bool isAwake() const; 
215                void setAutoSleep(bool auto_sleep);
216                bool getAutoSleep(); 
217                void setAutoSleepLinearThreshold(Ogre::Real linear_threshold);
218                Ogre::Real getAutoSleepLinearThreshold(); 
219                void setAutoSleepAngularThreshold(Ogre::Real angular_threshold);
220                Ogre::Real getAutoSleepAngularThreshold(); 
221                void setAutoSleepSteps(int steps);
222                int  getAutoSleepSteps(); 
223                void setAutoSleepTime(Ogre::Real time);
224                Ogre::Real getAutoSleepTime(); 
225                void setAutoSleepDefaults();
226
227                void setFiniteRotationMode(bool on); 
228                bool getFiniteRotationMode(); 
229                void setFiniteRotationAxis(const Ogre::Vector3& axis); 
230                const Ogre::Vector3& getFiniteRotationAxis(); 
231
232        int getJointCount(); 
233                Joint* getJoint(int index); 
234
235                void setModifyParentOrientation(bool bModify);
236
237        void addGeometry(Geometry *g); 
238        void removeGeometry(Geometry *g); 
239        size_t getGeometryCount(); 
240        Geometry* getGeometry(int index);
241        GeometryArray* getGeometries();
242
243                void setAffectedByGravity(bool on);
244                bool getAffectedByGravity(); 
245
246                void setDamping(Ogre::Real linear_damping, Ogre::Real angular_damping);
247                void setLinearDamping(Ogre::Real linear_damping);
248                void setAngularDamping(Ogre::Real angular_damping);
249                Ogre::Real getLinearDamping();
250                Ogre::Real getAngularDamping();
251
252                void setUserData(size_t user_data);
253                size_t getUserData();
254
255                virtual size_t getID();
256                virtual void setDebug(const bool debug);
257
258        /** Return a string identifying the type of user defined object.
259        @remarks
260            Used to differentiate between different Bodies, Geometries and prefab_object
261        */
262        const Ogre::String& getTypeName(void) const
263        {static Ogre::String sName("Body");return sName;};
264
265        bool collide(void* data, Geometry *g);
266        bool collide(void* data, Body *b);
267        bool collidePlaneBounds(void* data, Ogre::SceneQuery::WorldFragment *);
268
269        protected:
270                dBodyID getBodyID() const;
271
272                void destroyDebugNode();
273                void addDebugNode(Ogre::Node* node);
274
275                void recursiveSetMode(Ogre::SceneNode* node);
276               
277                void applyDamping();
278
279        protected:
280                dBodyID _body;
281                Ogre::String _name;
282                Ogre::Node* _debug_node;
283
284                static int _body_count;
285
286                Ogre::Vector3 _linear_vel;
287                Ogre::Vector3 _angular_vel;
288                Ogre::Vector3 _finite_axis;
289                Ogre::Vector3 _force;
290                Ogre::Vector3 _torque;
291                Ogre::AxisAlignedBox _bounding_box;
292                Mass* _mass;
293
294                bool _is_damped;
295                bool _is_linear_damped;
296                dReal _linear_damping;
297                bool _is_angular_damped;
298                dReal _angular_damping;
299
300                size_t _user_data;
301
302                // Major members
303                bool _isEnabled;
304                bool _modify_parent_orientation; 
305
306                BodyState          _draw_state;
307        CircularBuffer<BodyState *> _state_history;
308
309        /// Collision proxies, must be set up if collision enabled
310        GeometryArray _geometries;
311       
312                World *_world;
313
314        };
315
316    //-----------------------------------------------------------------------
317    inline bool Body::isAwake() const { return _isEnabled; }
318    //-----------------------------------------------------------------------
319    inline void Body::updateParentNode()
320    {
321        if (mParentNode)
322        { 
323            mParentNode->setPosition(_draw_state._position);
324            mParentNode->setOrientation(_draw_state._orientation);
325        }
326
327        if (_debug_node)
328        {
329            _debug_node->setPosition(_draw_state._position);
330            _debug_node->setOrientation(_draw_state._orientation);
331
332            recursiveSetMode(static_cast<Ogre::SceneNode*>(_debug_node));
333        }
334    } 
335    //-----------------------------------------------------------------------
336    inline void Body::updatePreviousState()
337    {
338        _isEnabled = dBodyIsEnabled(_body) || _debug_node;
339        if (_isEnabled)
340        {
341            BodyState *previous = _state_history.almostNewest ();
342            updatePosition (previous);
343            updateOrientation (previous);
344        }
345    }
346    //-----------------------------------------------------------------------
347    inline void Body::updateCurrentState()
348    {
349        _isEnabled = dBodyIsEnabled(_body) || _debug_node;
350        if (_isEnabled)
351        {
352            BodyState *current = _state_history.newest ();
353            updatePosition(current);
354            updateOrientation(current);
355        }
356    }
357    //-----------------------------------------------------------------------
358    inline void Body::updateDrawState ()
359    {
360        _isEnabled = dBodyIsEnabled(_body) || _debug_node;
361        if (_isEnabled)
362        {
363            updatePosition(&_draw_state);
364            updateOrientation(&_draw_state);
365        }
366    }
367    //-----------------------------------------------------------------------
368    inline void Body::interpolateDrawState(const Ogre::Real alpha)
369    {
370        if (_isEnabled)
371        {
372            BodyState *current = _state_history.newest ();
373            BodyState *previous = _state_history.almostNewest ();
374            assert (current != previous);
375            _draw_state.interpolate (previous, current, alpha);
376        }
377    }
378    //-----------------------------------------------------------------------
379    inline void Body::synchronise()
380    {
381        if (_isEnabled)
382        {
383            if (_is_damped)
384                applyDamping();
385            updateParentNode();
386        }
387    }
388    //-----------------------------------------------------------------------
389    inline const Ogre::Vector3& Body::getPosition() const
390    {
391        return _draw_state._position;
392    }
393    //-----------------------------------------------------------------------
394    inline const Ogre::Quaternion& Body::getOrientation() const
395    {
396        return _draw_state._orientation;
397    }
398    //-----------------------------------------------------------------------
399    inline void Body::updatePosition(BodyState * const bodystate)
400    {
401        const dReal * const position = dBodyGetPosition(_body);
402
403        bodystate->_position.x = (Ogre::Real)position[0];
404        bodystate->_position.y = (Ogre::Real)position[1];
405        bodystate->_position.z = (Ogre::Real)position[2];
406    }
407    //-----------------------------------------------------------------------
408    inline void Body::updateOrientation(BodyState * const bodystate)
409    {
410        const dReal * const orientation = dBodyGetQuaternion(_body); 
411        bodystate->_orientation.w = (Ogre::Real)orientation[0];
412        bodystate->_orientation.x = (Ogre::Real)orientation[1];
413        bodystate->_orientation.y = (Ogre::Real)orientation[2];
414        bodystate->_orientation.z = (Ogre::Real)orientation[3];
415    }
416    //-----------------------------------------------------------------------
417}
418
419#endif
420
Note: See TracBrowser for help on using the repository browser.