Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

Added OgreODE to our source repository because already we really need the newest version. And there is no hope to find any packages under linux.
The files included should compile and link with Ogre 1.4/1.6 and ODE 0.9/0.10. I was only able to test Ogre 1.4 and ODE 0.9/.10 under msvc until now.

  • 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
Note: See TracBrowser for help on using the repository browser.