Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/physics/src/bullet/BulletDynamics/Dynamics/btRigidBody.h @ 2056

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

Added Bullet physics engine.

  • Property svn:eol-style set to native
File size: 14.1 KB
Line 
1/*
2Bullet Continuous Collision Detection and Physics Library
3Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
4
5This software is provided 'as-is', without any express or implied warranty.
6In no event will the authors be held liable for any damages arising from the use of this software.
7Permission is granted to anyone to use this software for any purpose,
8including commercial applications, and to alter it and redistribute it freely,
9subject to the following restrictions:
10
111. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
122. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
133. This notice may not be removed or altered from any source distribution.
14*/
15
16#ifndef RIGIDBODY_H
17#define RIGIDBODY_H
18
19#include "LinearMath/btAlignedObjectArray.h"
20#include "LinearMath/btPoint3.h"
21#include "LinearMath/btTransform.h"
22#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h"
23#include "BulletCollision/CollisionDispatch/btCollisionObject.h"
24
25class btCollisionShape;
26class btMotionState;
27class btTypedConstraint;
28
29
30extern btScalar gDeactivationTime;
31extern bool gDisableDeactivation;
32
33
34///btRigidBody is the main class for rigid body objects. It is derived from btCollisionObject, so it keeps a pointer to a btCollisionShape.
35///It is recommended for performance and memory use to share btCollisionShape objects whenever possible.
36///There are 3 types of rigid bodies:
37///- A) Dynamic rigid bodies, with positive mass. Motion is controlled by rigid body dynamics.
38///- B) Fixed objects with zero mass. They are not moving (basically collision objects)
39///- C) Kinematic objects, which are objects without mass, but the user can move them. There is on-way interaction, and Bullet calculates a velocity based on the timestep and previous and current world transform.
40///Bullet automatically deactivates dynamic rigid bodies, when the velocity is below a threshold for a given time.
41///Deactivated (sleeping) rigid bodies don't take any processing time, except a minor broadphase collision detection impact (to allow active objects to activate/wake up sleeping objects)
42class btRigidBody  : public btCollisionObject
43{
44
45        btMatrix3x3     m_invInertiaTensorWorld;
46        btVector3               m_linearVelocity;
47        btVector3               m_angularVelocity;
48        btScalar                m_inverseMass;
49        btScalar                m_angularFactor;
50
51        btVector3               m_gravity;     
52        btVector3               m_invInertiaLocal;
53        btVector3               m_totalForce;
54        btVector3               m_totalTorque;
55       
56        btScalar                m_linearDamping;
57        btScalar                m_angularDamping;
58
59        bool                    m_additionalDamping;
60        btScalar                m_additionalDampingFactor;
61        btScalar                m_additionalLinearDampingThresholdSqr;
62        btScalar                m_additionalAngularDampingThresholdSqr;
63        btScalar                m_additionalAngularDampingFactor;
64
65
66        btScalar                m_linearSleepingThreshold;
67        btScalar                m_angularSleepingThreshold;
68
69        //m_optionalMotionState allows to automatic synchronize the world transform for active objects
70        btMotionState*  m_optionalMotionState;
71
72        //keep track of typed constraints referencing this rigid body
73        btAlignedObjectArray<btTypedConstraint*> m_constraintRefs;
74
75public:
76
77
78        ///btRigidBodyConstructionInfo provides information to create a rigid body. Setting mass to zero creates a fixed (non-dynamic) rigid body.
79        ///For dynamic objects, you can use the collision shape to approximate the local inertia tensor, otherwise use the zero vector (default argument)
80        ///You can use the motion state to synchronize the world transform between physics and graphics objects.
81        ///And if the motion state is provided, the rigid body will initialize its initial world transform from the motion state,
82        ///m_startWorldTransform is only used when you don't provide a motion state.
83        struct  btRigidBodyConstructionInfo
84        {
85                btScalar                        m_mass;
86
87                ///When a motionState is provided, the rigid body will initialize its world transform from the motion state
88                ///In this case, m_startWorldTransform is ignored.
89                btMotionState*          m_motionState;
90                btTransform     m_startWorldTransform;
91
92                btCollisionShape*       m_collisionShape;
93                btVector3                       m_localInertia;
94                btScalar                        m_linearDamping;
95                btScalar                        m_angularDamping;
96
97                ///best simulation results when friction is non-zero
98                btScalar                        m_friction;
99                ///best simulation results using zero restitution.
100                btScalar                        m_restitution;
101
102                btScalar                        m_linearSleepingThreshold;
103                btScalar                        m_angularSleepingThreshold;
104
105                //Additional damping can help avoiding lowpass jitter motion, help stability for ragdolls etc.
106                //Such damping is undesirable, so once the overall simulation quality of the rigid body dynamics system has improved, this should become obsolete
107                bool                            m_additionalDamping;
108                btScalar                        m_additionalDampingFactor;
109                btScalar                        m_additionalLinearDampingThresholdSqr;
110                btScalar                        m_additionalAngularDampingThresholdSqr;
111                btScalar                        m_additionalAngularDampingFactor;
112
113               
114                btRigidBodyConstructionInfo(    btScalar mass, btMotionState* motionState, btCollisionShape* collisionShape, const btVector3& localInertia=btVector3(0,0,0)):
115                m_mass(mass),
116                        m_motionState(motionState),
117                        m_collisionShape(collisionShape),
118                        m_localInertia(localInertia),
119                        m_linearDamping(btScalar(0.)),
120                        m_angularDamping(btScalar(0.)),
121                        m_friction(btScalar(0.5)),
122                        m_restitution(btScalar(0.)),
123                        m_linearSleepingThreshold(btScalar(0.8)),
124                        m_angularSleepingThreshold(btScalar(1.f)),
125                        m_additionalDamping(false),
126                        m_additionalDampingFactor(btScalar(0.005)),
127                        m_additionalLinearDampingThresholdSqr(btScalar(0.01)),
128                        m_additionalAngularDampingThresholdSqr(btScalar(0.01)),
129                        m_additionalAngularDampingFactor(btScalar(0.01))
130                {
131                        m_startWorldTransform.setIdentity();
132                }
133        };
134
135        ///btRigidBody constructor using construction info
136        btRigidBody(    const btRigidBodyConstructionInfo& constructionInfo);
137
138        ///btRigidBody constructor for backwards compatibility.
139        ///To specify friction (etc) during rigid body construction, please use the other constructor (using btRigidBodyConstructionInfo)
140        btRigidBody(    btScalar mass, btMotionState* motionState, btCollisionShape* collisionShape, const btVector3& localInertia=btVector3(0,0,0));
141
142
143        virtual ~btRigidBody()
144        { 
145                //No constraints should point to this rigidbody
146                //Remove constraints from the dynamics world before you delete the related rigidbodies.
147                btAssert(m_constraintRefs.size()==0); 
148        }
149
150protected:
151
152        ///setupRigidBody is only used internally by the constructor
153        void    setupRigidBody(const btRigidBodyConstructionInfo& constructionInfo);
154
155public:
156
157        void                    proceedToTransform(const btTransform& newTrans); 
158       
159        ///to keep collision detection and dynamics separate we don't store a rigidbody pointer
160        ///but a rigidbody is derived from btCollisionObject, so we can safely perform an upcast
161        static const btRigidBody*       upcast(const btCollisionObject* colObj)
162        {
163                if (colObj->getInternalType()==btCollisionObject::CO_RIGID_BODY)
164                        return (const btRigidBody*)colObj;
165                return 0;
166        }
167        static btRigidBody*     upcast(btCollisionObject* colObj)
168        {
169                if (colObj->getInternalType()==btCollisionObject::CO_RIGID_BODY)
170                        return (btRigidBody*)colObj;
171                return 0;
172        }
173       
174        /// continuous collision detection needs prediction
175        void                    predictIntegratedTransform(btScalar step, btTransform& predictedTransform) ;
176       
177        void                    saveKinematicState(btScalar step);
178       
179        void                    applyGravity();
180       
181        void                    setGravity(const btVector3& acceleration); 
182
183        const btVector3&        getGravity() const
184        {
185                return m_gravity;
186        }
187
188        void                    setDamping(btScalar lin_damping, btScalar ang_damping);
189
190        btScalar getLinearDamping() const
191        {
192                return m_linearDamping;
193        }
194
195        btScalar getAngularDamping() const
196        {
197                return m_angularDamping;
198        }
199
200        btScalar getLinearSleepingThreshold() const
201        {
202                return m_linearSleepingThreshold;
203        }
204
205        btScalar getAngularSleepingThreshold() const
206        {
207                return m_angularSleepingThreshold;
208        }
209
210        void                    applyDamping(btScalar timeStep);
211
212        SIMD_FORCE_INLINE const btCollisionShape*       getCollisionShape() const {
213                return m_collisionShape;
214        }
215
216        SIMD_FORCE_INLINE btCollisionShape*     getCollisionShape() {
217                        return m_collisionShape;
218        }
219       
220        void                    setMassProps(btScalar mass, const btVector3& inertia);
221       
222        btScalar                getInvMass() const { return m_inverseMass; }
223        const btMatrix3x3& getInvInertiaTensorWorld() const { 
224                return m_invInertiaTensorWorld; 
225        }
226               
227        void                    integrateVelocities(btScalar step);
228
229        void                    setCenterOfMassTransform(const btTransform& xform);
230
231        void                    applyCentralForce(const btVector3& force)
232        {
233                m_totalForce += force;
234        }
235   
236        const btVector3& getInvInertiaDiagLocal()
237        {
238                return m_invInertiaLocal;
239        };
240
241        void    setInvInertiaDiagLocal(const btVector3& diagInvInertia)
242        {
243                m_invInertiaLocal = diagInvInertia;
244        }
245
246        void    setSleepingThresholds(btScalar linear,btScalar angular)
247        {
248                m_linearSleepingThreshold = linear;
249                m_angularSleepingThreshold = angular;
250        }
251
252        void    applyTorque(const btVector3& torque)
253        {
254                m_totalTorque += torque;
255        }
256       
257        void    applyForce(const btVector3& force, const btVector3& rel_pos) 
258        {
259                applyCentralForce(force);
260                applyTorque(rel_pos.cross(force)*m_angularFactor);
261        }
262       
263        void applyCentralImpulse(const btVector3& impulse)
264        {
265                m_linearVelocity += impulse * m_inverseMass;
266        }
267       
268        void applyTorqueImpulse(const btVector3& torque)
269        {
270                        m_angularVelocity += m_invInertiaTensorWorld * torque;
271        }
272       
273        void applyImpulse(const btVector3& impulse, const btVector3& rel_pos) 
274        {
275                if (m_inverseMass != btScalar(0.))
276                {
277                        applyCentralImpulse(impulse);
278                        if (m_angularFactor)
279                        {
280                                applyTorqueImpulse(rel_pos.cross(impulse)*m_angularFactor);
281                        }
282                }
283        }
284
285        //Optimization for the iterative solver: avoid calculating constant terms involving inertia, normal, relative position
286        SIMD_FORCE_INLINE void internalApplyImpulse(const btVector3& linearComponent, const btVector3& angularComponent,btScalar impulseMagnitude)
287        {
288                if (m_inverseMass != btScalar(0.))
289                {
290                        m_linearVelocity += linearComponent*impulseMagnitude;
291                        if (m_angularFactor)
292                        {
293                                m_angularVelocity += angularComponent*impulseMagnitude*m_angularFactor;
294                        }
295                }
296        }
297       
298        void clearForces() 
299        {
300                m_totalForce.setValue(btScalar(0.0), btScalar(0.0), btScalar(0.0));
301                m_totalTorque.setValue(btScalar(0.0), btScalar(0.0), btScalar(0.0));
302        }
303       
304        void updateInertiaTensor();   
305       
306        const btPoint3&     getCenterOfMassPosition() const { 
307                return m_worldTransform.getOrigin(); 
308        }
309        btQuaternion getOrientation() const;
310       
311        const btTransform&  getCenterOfMassTransform() const { 
312                return m_worldTransform; 
313        }
314        const btVector3&   getLinearVelocity() const { 
315                return m_linearVelocity; 
316        }
317        const btVector3&    getAngularVelocity() const { 
318                return m_angularVelocity; 
319        }
320       
321
322        inline void setLinearVelocity(const btVector3& lin_vel)
323        { 
324                assert (m_collisionFlags != btCollisionObject::CF_STATIC_OBJECT);
325                m_linearVelocity = lin_vel; 
326        }
327
328        inline void setAngularVelocity(const btVector3& ang_vel) { 
329                assert (m_collisionFlags != btCollisionObject::CF_STATIC_OBJECT);
330                {
331                        m_angularVelocity = ang_vel; 
332                }
333        }
334
335        btVector3 getVelocityInLocalPoint(const btVector3& rel_pos) const
336        {
337                //we also calculate lin/ang velocity for kinematic objects
338                return m_linearVelocity + m_angularVelocity.cross(rel_pos);
339
340                //for kinematic objects, we could also use use:
341                //              return  (m_worldTransform(rel_pos) - m_interpolationWorldTransform(rel_pos)) / m_kinematicTimeStep;
342        }
343
344        void translate(const btVector3& v) 
345        {
346                m_worldTransform.getOrigin() += v; 
347        }
348
349       
350        void    getAabb(btVector3& aabbMin,btVector3& aabbMax) const;
351
352
353
354
355       
356        SIMD_FORCE_INLINE btScalar computeImpulseDenominator(const btPoint3& pos, const btVector3& normal) const
357        {
358                btVector3 r0 = pos - getCenterOfMassPosition();
359
360                btVector3 c0 = (r0).cross(normal);
361
362                btVector3 vec = (c0 * getInvInertiaTensorWorld()).cross(r0);
363
364                return m_inverseMass + normal.dot(vec);
365
366        }
367
368        SIMD_FORCE_INLINE btScalar computeAngularImpulseDenominator(const btVector3& axis) const
369        {
370                btVector3 vec = axis * getInvInertiaTensorWorld();
371                return axis.dot(vec);
372        }
373
374        SIMD_FORCE_INLINE void  updateDeactivation(btScalar timeStep)
375        {
376                if ( (getActivationState() == ISLAND_SLEEPING) || (getActivationState() == DISABLE_DEACTIVATION))
377                        return;
378
379                if ((getLinearVelocity().length2() < m_linearSleepingThreshold*m_linearSleepingThreshold) &&
380                        (getAngularVelocity().length2() < m_angularSleepingThreshold*m_angularSleepingThreshold))
381                {
382                        m_deactivationTime += timeStep;
383                } else
384                {
385                        m_deactivationTime=btScalar(0.);
386                        setActivationState(0);
387                }
388
389        }
390
391        SIMD_FORCE_INLINE bool  wantsSleeping()
392        {
393
394                if (getActivationState() == DISABLE_DEACTIVATION)
395                        return false;
396
397                //disable deactivation
398                if (gDisableDeactivation || (gDeactivationTime == btScalar(0.)))
399                        return false;
400
401                if ( (getActivationState() == ISLAND_SLEEPING) || (getActivationState() == WANTS_DEACTIVATION))
402                        return true;
403
404                if (m_deactivationTime> gDeactivationTime)
405                {
406                        return true;
407                }
408                return false;
409        }
410
411
412       
413        const btBroadphaseProxy*        getBroadphaseProxy() const
414        {
415                return m_broadphaseHandle;
416        }
417        btBroadphaseProxy*      getBroadphaseProxy() 
418        {
419                return m_broadphaseHandle;
420        }
421        void    setNewBroadphaseProxy(btBroadphaseProxy* broadphaseProxy)
422        {
423                m_broadphaseHandle = broadphaseProxy;
424        }
425
426        //btMotionState allows to automatic synchronize the world transform for active objects
427        btMotionState*  getMotionState()
428        {
429                return m_optionalMotionState;
430        }
431        const btMotionState*    getMotionState() const
432        {
433                return m_optionalMotionState;
434        }
435        void    setMotionState(btMotionState* motionState)
436        {
437                m_optionalMotionState = motionState;
438                if (m_optionalMotionState)
439                        motionState->getWorldTransform(m_worldTransform);
440        }
441
442        //for experimental overriding of friction/contact solver func
443        int     m_contactSolverType;
444        int     m_frictionSolverType;
445
446        void    setAngularFactor(btScalar angFac)
447        {
448                m_angularFactor = angFac;
449        }
450        btScalar        getAngularFactor() const
451        {
452                return m_angularFactor;
453        }
454
455        //is this rigidbody added to a btCollisionWorld/btDynamicsWorld/btBroadphase?
456        bool    isInWorld() const
457        {
458                return (getBroadphaseProxy() != 0);
459        }
460
461        virtual bool checkCollideWithOverride(btCollisionObject* co);
462
463        void addConstraintRef(btTypedConstraint* c);
464        void removeConstraintRef(btTypedConstraint* c);
465
466        btTypedConstraint* getConstraintRef(int index)
467        {
468                return m_constraintRefs[index];
469        }
470
471        int getNumConstraintRefs()
472        {
473                return m_constraintRefs.size();
474        }
475
476        int     m_debugBodyId;
477};
478
479
480
481#endif
482
Note: See TracBrowser for help on using the repository browser.