Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/core4/src/bullet/BulletDynamics/Dynamics/btRigidBody.h @ 3864

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

Update from Bullet 2.73 to 2.74.

  • Property svn:eol-style set to native
File size: 14.2 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/btTransform.h"
21#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h"
22#include "BulletCollision/CollisionDispatch/btCollisionObject.h"
23
24class btCollisionShape;
25class btMotionState;
26class btTypedConstraint;
27
28
29extern btScalar gDeactivationTime;
30extern bool gDisableDeactivation;
31
32
33///The btRigidBody is the main class for rigid body objects. It is derived from btCollisionObject, so it keeps a pointer to a btCollisionShape.
34///It is recommended for performance and memory use to share btCollisionShape objects whenever possible.
35///There are 3 types of rigid bodies:
36///- A) Dynamic rigid bodies, with positive mass. Motion is controlled by rigid body dynamics.
37///- B) Fixed objects with zero mass. They are not moving (basically collision objects)
38///- 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.
39///Bullet automatically deactivates dynamic rigid bodies, when the velocity is below a threshold for a given time.
40///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)
41class btRigidBody  : public btCollisionObject
42{
43
44        btMatrix3x3     m_invInertiaTensorWorld;
45        btVector3               m_linearVelocity;
46        btVector3               m_angularVelocity;
47        btScalar                m_inverseMass;
48        btScalar                m_angularFactor;
49
50        btVector3               m_gravity;     
51        btVector3               m_gravity_acceleration;
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        ///The btRigidBodyConstructionInfo structure 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_acceleration;
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& getTotalForce()
237        {
238                return m_totalForce;
239        };
240
241        const btVector3& getTotalTorque()
242        {
243                return m_totalTorque;
244        };
245   
246        const btVector3& getInvInertiaDiagLocal() const
247        {
248                return m_invInertiaLocal;
249        };
250
251        void    setInvInertiaDiagLocal(const btVector3& diagInvInertia)
252        {
253                m_invInertiaLocal = diagInvInertia;
254        }
255
256        void    setSleepingThresholds(btScalar linear,btScalar angular)
257        {
258                m_linearSleepingThreshold = linear;
259                m_angularSleepingThreshold = angular;
260        }
261
262        void    applyTorque(const btVector3& torque)
263        {
264                m_totalTorque += torque;
265        }
266       
267        void    applyForce(const btVector3& force, const btVector3& rel_pos) 
268        {
269                applyCentralForce(force);
270                applyTorque(rel_pos.cross(force)*m_angularFactor);
271        }
272       
273        void applyCentralImpulse(const btVector3& impulse)
274        {
275                m_linearVelocity += impulse * m_inverseMass;
276        }
277       
278        void applyTorqueImpulse(const btVector3& torque)
279        {
280                        m_angularVelocity += m_invInertiaTensorWorld * torque;
281        }
282       
283        void applyImpulse(const btVector3& impulse, const btVector3& rel_pos) 
284        {
285                if (m_inverseMass != btScalar(0.))
286                {
287                        applyCentralImpulse(impulse);
288                        if (m_angularFactor)
289                        {
290                                applyTorqueImpulse(rel_pos.cross(impulse)*m_angularFactor);
291                        }
292                }
293        }
294
295        //Optimization for the iterative solver: avoid calculating constant terms involving inertia, normal, relative position
296        SIMD_FORCE_INLINE void internalApplyImpulse(const btVector3& linearComponent, const btVector3& angularComponent,btScalar impulseMagnitude)
297        {
298                if (m_inverseMass != btScalar(0.))
299                {
300                        m_linearVelocity += linearComponent*impulseMagnitude;
301                        if (m_angularFactor)
302                        {
303                                m_angularVelocity += angularComponent*impulseMagnitude*m_angularFactor;
304                        }
305                }
306        }
307       
308        void clearForces() 
309        {
310                m_totalForce.setValue(btScalar(0.0), btScalar(0.0), btScalar(0.0));
311                m_totalTorque.setValue(btScalar(0.0), btScalar(0.0), btScalar(0.0));
312        }
313       
314        void updateInertiaTensor();   
315       
316        const btVector3&     getCenterOfMassPosition() const { 
317                return m_worldTransform.getOrigin(); 
318        }
319        btQuaternion getOrientation() const;
320       
321        const btTransform&  getCenterOfMassTransform() const { 
322                return m_worldTransform; 
323        }
324        const btVector3&   getLinearVelocity() const { 
325                return m_linearVelocity; 
326        }
327        const btVector3&    getAngularVelocity() const { 
328                return m_angularVelocity; 
329        }
330       
331
332        inline void setLinearVelocity(const btVector3& lin_vel)
333        { 
334                m_linearVelocity = lin_vel; 
335        }
336
337        inline void setAngularVelocity(const btVector3& ang_vel) 
338        { 
339                m_angularVelocity = ang_vel; 
340        }
341
342        btVector3 getVelocityInLocalPoint(const btVector3& rel_pos) const
343        {
344                //we also calculate lin/ang velocity for kinematic objects
345                return m_linearVelocity + m_angularVelocity.cross(rel_pos);
346
347                //for kinematic objects, we could also use use:
348                //              return  (m_worldTransform(rel_pos) - m_interpolationWorldTransform(rel_pos)) / m_kinematicTimeStep;
349        }
350
351        void translate(const btVector3& v) 
352        {
353                m_worldTransform.getOrigin() += v; 
354        }
355
356       
357        void    getAabb(btVector3& aabbMin,btVector3& aabbMax) const;
358
359
360
361
362       
363        SIMD_FORCE_INLINE btScalar computeImpulseDenominator(const btVector3& pos, const btVector3& normal) const
364        {
365                btVector3 r0 = pos - getCenterOfMassPosition();
366
367                btVector3 c0 = (r0).cross(normal);
368
369                btVector3 vec = (c0 * getInvInertiaTensorWorld()).cross(r0);
370
371                return m_inverseMass + normal.dot(vec);
372
373        }
374
375        SIMD_FORCE_INLINE btScalar computeAngularImpulseDenominator(const btVector3& axis) const
376        {
377                btVector3 vec = axis * getInvInertiaTensorWorld();
378                return axis.dot(vec);
379        }
380
381        SIMD_FORCE_INLINE void  updateDeactivation(btScalar timeStep)
382        {
383                if ( (getActivationState() == ISLAND_SLEEPING) || (getActivationState() == DISABLE_DEACTIVATION))
384                        return;
385
386                if ((getLinearVelocity().length2() < m_linearSleepingThreshold*m_linearSleepingThreshold) &&
387                        (getAngularVelocity().length2() < m_angularSleepingThreshold*m_angularSleepingThreshold))
388                {
389                        m_deactivationTime += timeStep;
390                } else
391                {
392                        m_deactivationTime=btScalar(0.);
393                        setActivationState(0);
394                }
395
396        }
397
398        SIMD_FORCE_INLINE bool  wantsSleeping()
399        {
400
401                if (getActivationState() == DISABLE_DEACTIVATION)
402                        return false;
403
404                //disable deactivation
405                if (gDisableDeactivation || (gDeactivationTime == btScalar(0.)))
406                        return false;
407
408                if ( (getActivationState() == ISLAND_SLEEPING) || (getActivationState() == WANTS_DEACTIVATION))
409                        return true;
410
411                if (m_deactivationTime> gDeactivationTime)
412                {
413                        return true;
414                }
415                return false;
416        }
417
418
419       
420        const btBroadphaseProxy*        getBroadphaseProxy() const
421        {
422                return m_broadphaseHandle;
423        }
424        btBroadphaseProxy*      getBroadphaseProxy() 
425        {
426                return m_broadphaseHandle;
427        }
428        void    setNewBroadphaseProxy(btBroadphaseProxy* broadphaseProxy)
429        {
430                m_broadphaseHandle = broadphaseProxy;
431        }
432
433        //btMotionState allows to automatic synchronize the world transform for active objects
434        btMotionState*  getMotionState()
435        {
436                return m_optionalMotionState;
437        }
438        const btMotionState*    getMotionState() const
439        {
440                return m_optionalMotionState;
441        }
442        void    setMotionState(btMotionState* motionState)
443        {
444                m_optionalMotionState = motionState;
445                if (m_optionalMotionState)
446                        motionState->getWorldTransform(m_worldTransform);
447        }
448
449        //for experimental overriding of friction/contact solver func
450        int     m_contactSolverType;
451        int     m_frictionSolverType;
452
453        void    setAngularFactor(btScalar angFac)
454        {
455                m_angularFactor = angFac;
456        }
457        btScalar        getAngularFactor() const
458        {
459                return m_angularFactor;
460        }
461
462        //is this rigidbody added to a btCollisionWorld/btDynamicsWorld/btBroadphase?
463        bool    isInWorld() const
464        {
465                return (getBroadphaseProxy() != 0);
466        }
467
468        virtual bool checkCollideWithOverride(btCollisionObject* co);
469
470        void addConstraintRef(btTypedConstraint* c);
471        void removeConstraintRef(btTypedConstraint* c);
472
473        btTypedConstraint* getConstraintRef(int index)
474        {
475                return m_constraintRefs[index];
476        }
477
478        int getNumConstraintRefs()
479        {
480                return m_constraintRefs.size();
481        }
482
483        int     m_debugBodyId;
484};
485
486
487
488#endif
489
Note: See TracBrowser for help on using the repository browser.