Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/trunk/src/bullet/BulletDynamics/Dynamics/btRigidBody.h @ 2801

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

Merged presentation branch back to trunk.

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