Upgrade Bullet to version 2.83.
[blender.git] / extern / bullet2 / src / BulletDynamics / Dynamics / btRigidBody.h
1 /*
2 Bullet Continuous Collision Detection and Physics Library
3 Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
4
5 This software is provided 'as-is', without any express or implied warranty.
6 In no event will the authors be held liable for any damages arising from the use of this software.
7 Permission is granted to anyone to use this software for any purpose, 
8 including commercial applications, and to alter it and redistribute it freely, 
9 subject to the following restrictions:
10
11 1. 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.
12 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
13 3. This notice may not be removed or altered from any source distribution.
14 */
15
16 #ifndef BT_RIGIDBODY_H
17 #define BT_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
24 class btCollisionShape;
25 class btMotionState;
26 class btTypedConstraint;
27
28
29 extern btScalar gDeactivationTime;
30 extern bool gDisableDeactivation;
31
32 #ifdef BT_USE_DOUBLE_PRECISION
33 #define btRigidBodyData btRigidBodyDoubleData
34 #define btRigidBodyDataName     "btRigidBodyDoubleData"
35 #else
36 #define btRigidBodyData btRigidBodyFloatData
37 #define btRigidBodyDataName     "btRigidBodyFloatData"
38 #endif //BT_USE_DOUBLE_PRECISION
39
40
41 enum    btRigidBodyFlags
42 {
43         BT_DISABLE_WORLD_GRAVITY = 1,
44         ///BT_ENABLE_GYROPSCOPIC_FORCE flags is enabled by default in Bullet 2.83 and onwards.
45         ///and it BT_ENABLE_GYROPSCOPIC_FORCE becomes equivalent to BT_ENABLE_GYROSCOPIC_FORCE_IMPLICIT_BODY
46         ///See Demos/GyroscopicDemo and computeGyroscopicImpulseImplicit
47         BT_ENABLE_GYROSCOPIC_FORCE_EXPLICIT = 2,
48         BT_ENABLE_GYROSCOPIC_FORCE_IMPLICIT_WORLD=4,
49         BT_ENABLE_GYROSCOPIC_FORCE_IMPLICIT_BODY=8,
50         BT_ENABLE_GYROPSCOPIC_FORCE = BT_ENABLE_GYROSCOPIC_FORCE_IMPLICIT_BODY,
51 };
52
53
54 ///The btRigidBody is the main class for rigid body objects. It is derived from btCollisionObject, so it keeps a pointer to a btCollisionShape.
55 ///It is recommended for performance and memory use to share btCollisionShape objects whenever possible.
56 ///There are 3 types of rigid bodies: 
57 ///- A) Dynamic rigid bodies, with positive mass. Motion is controlled by rigid body dynamics.
58 ///- B) Fixed objects with zero mass. They are not moving (basically collision objects)
59 ///- 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.
60 ///Bullet automatically deactivates dynamic rigid bodies, when the velocity is below a threshold for a given time.
61 ///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)
62 class btRigidBody  : public btCollisionObject
63 {
64
65         btMatrix3x3     m_invInertiaTensorWorld;
66         btVector3               m_linearVelocity;
67         btVector3               m_angularVelocity;
68         btScalar                m_inverseMass;
69         btVector3               m_linearFactor;
70
71         btVector3               m_gravity;      
72         btVector3               m_gravity_acceleration;
73         btVector3               m_invInertiaLocal;
74         btVector3               m_totalForce;
75         btVector3               m_totalTorque;
76         
77         btScalar                m_linearDamping;
78         btScalar                m_angularDamping;
79
80         bool                    m_additionalDamping;
81         btScalar                m_additionalDampingFactor;
82         btScalar                m_additionalLinearDampingThresholdSqr;
83         btScalar                m_additionalAngularDampingThresholdSqr;
84         btScalar                m_additionalAngularDampingFactor;
85
86
87         btScalar                m_linearSleepingThreshold;
88         btScalar                m_angularSleepingThreshold;
89
90         //m_optionalMotionState allows to automatic synchronize the world transform for active objects
91         btMotionState*  m_optionalMotionState;
92
93         //keep track of typed constraints referencing this rigid body, to disable collision between linked bodies
94         btAlignedObjectArray<btTypedConstraint*> m_constraintRefs;
95
96         int                             m_rigidbodyFlags;
97         
98         int                             m_debugBodyId;
99         
100
101 protected:
102
103         ATTRIBUTE_ALIGNED16(btVector3           m_deltaLinearVelocity);
104         btVector3               m_deltaAngularVelocity;
105         btVector3               m_angularFactor;
106         btVector3               m_invMass;
107         btVector3               m_pushVelocity;
108         btVector3               m_turnVelocity;
109
110
111 public:
112
113
114         ///The btRigidBodyConstructionInfo structure provides information to create a rigid body. Setting mass to zero creates a fixed (non-dynamic) rigid body.
115         ///For dynamic objects, you can use the collision shape to approximate the local inertia tensor, otherwise use the zero vector (default argument)
116         ///You can use the motion state to synchronize the world transform between physics and graphics objects. 
117         ///And if the motion state is provided, the rigid body will initialize its initial world transform from the motion state,
118         ///m_startWorldTransform is only used when you don't provide a motion state.
119         struct  btRigidBodyConstructionInfo
120         {
121                 btScalar                        m_mass;
122
123                 ///When a motionState is provided, the rigid body will initialize its world transform from the motion state
124                 ///In this case, m_startWorldTransform is ignored.
125                 btMotionState*          m_motionState;
126                 btTransform     m_startWorldTransform;
127
128                 btCollisionShape*       m_collisionShape;
129                 btVector3                       m_localInertia;
130                 btScalar                        m_linearDamping;
131                 btScalar                        m_angularDamping;
132
133                 ///best simulation results when friction is non-zero
134                 btScalar                        m_friction;
135                 ///the m_rollingFriction prevents rounded shapes, such as spheres, cylinders and capsules from rolling forever.
136                 ///See Bullet/Demos/RollingFrictionDemo for usage
137                 btScalar                        m_rollingFriction;
138                 ///best simulation results using zero restitution.
139                 btScalar                        m_restitution;
140
141                 btScalar                        m_linearSleepingThreshold;
142                 btScalar                        m_angularSleepingThreshold;
143
144                 //Additional damping can help avoiding lowpass jitter motion, help stability for ragdolls etc.
145                 //Such damping is undesirable, so once the overall simulation quality of the rigid body dynamics system has improved, this should become obsolete
146                 bool                            m_additionalDamping;
147                 btScalar                        m_additionalDampingFactor;
148                 btScalar                        m_additionalLinearDampingThresholdSqr;
149                 btScalar                        m_additionalAngularDampingThresholdSqr;
150                 btScalar                        m_additionalAngularDampingFactor;
151
152                 btRigidBodyConstructionInfo(    btScalar mass, btMotionState* motionState, btCollisionShape* collisionShape, const btVector3& localInertia=btVector3(0,0,0)):
153                 m_mass(mass),
154                         m_motionState(motionState),
155                         m_collisionShape(collisionShape),
156                         m_localInertia(localInertia),
157                         m_linearDamping(btScalar(0.)),
158                         m_angularDamping(btScalar(0.)),
159                         m_friction(btScalar(0.5)),
160                         m_rollingFriction(btScalar(0)),
161                         m_restitution(btScalar(0.)),
162                         m_linearSleepingThreshold(btScalar(0.8)),
163                         m_angularSleepingThreshold(btScalar(1.f)),
164                         m_additionalDamping(false),
165                         m_additionalDampingFactor(btScalar(0.005)),
166                         m_additionalLinearDampingThresholdSqr(btScalar(0.01)),
167                         m_additionalAngularDampingThresholdSqr(btScalar(0.01)),
168                         m_additionalAngularDampingFactor(btScalar(0.01))
169                 {
170                         m_startWorldTransform.setIdentity();
171                 }
172         };
173
174         ///btRigidBody constructor using construction info
175         btRigidBody(    const btRigidBodyConstructionInfo& constructionInfo);
176
177         ///btRigidBody constructor for backwards compatibility. 
178         ///To specify friction (etc) during rigid body construction, please use the other constructor (using btRigidBodyConstructionInfo)
179         btRigidBody(    btScalar mass, btMotionState* motionState, btCollisionShape* collisionShape, const btVector3& localInertia=btVector3(0,0,0));
180
181
182         virtual ~btRigidBody()
183         { 
184                 //No constraints should point to this rigidbody
185                 //Remove constraints from the dynamics world before you delete the related rigidbodies. 
186                 btAssert(m_constraintRefs.size()==0); 
187         }
188
189 protected:
190
191         ///setupRigidBody is only used internally by the constructor
192         void    setupRigidBody(const btRigidBodyConstructionInfo& constructionInfo);
193
194 public:
195
196         void                    proceedToTransform(const btTransform& newTrans); 
197         
198         ///to keep collision detection and dynamics separate we don't store a rigidbody pointer
199         ///but a rigidbody is derived from btCollisionObject, so we can safely perform an upcast
200         static const btRigidBody*       upcast(const btCollisionObject* colObj)
201         {
202                 if (colObj->getInternalType()&btCollisionObject::CO_RIGID_BODY)
203                         return (const btRigidBody*)colObj;
204                 return 0;
205         }
206         static btRigidBody*     upcast(btCollisionObject* colObj)
207         {
208                 if (colObj->getInternalType()&btCollisionObject::CO_RIGID_BODY)
209                         return (btRigidBody*)colObj;
210                 return 0;
211         }
212         
213         /// continuous collision detection needs prediction
214         void                    predictIntegratedTransform(btScalar step, btTransform& predictedTransform) ;
215         
216         void                    saveKinematicState(btScalar step);
217         
218         void                    applyGravity();
219         
220         void                    setGravity(const btVector3& acceleration);  
221
222         const btVector3&        getGravity() const
223         {
224                 return m_gravity_acceleration;
225         }
226
227         void                    setDamping(btScalar lin_damping, btScalar ang_damping);
228
229         btScalar getLinearDamping() const
230         {
231                 return m_linearDamping;
232         }
233
234         btScalar getAngularDamping() const
235         {
236                 return m_angularDamping;
237         }
238
239         btScalar getLinearSleepingThreshold() const
240         {
241                 return m_linearSleepingThreshold;
242         }
243
244         btScalar getAngularSleepingThreshold() const
245         {
246                 return m_angularSleepingThreshold;
247         }
248
249         void                    applyDamping(btScalar timeStep);
250
251         SIMD_FORCE_INLINE const btCollisionShape*       getCollisionShape() const {
252                 return m_collisionShape;
253         }
254
255         SIMD_FORCE_INLINE btCollisionShape*     getCollisionShape() {
256                         return m_collisionShape;
257         }
258         
259         void                    setMassProps(btScalar mass, const btVector3& inertia);
260         
261         const btVector3& getLinearFactor() const
262         {
263                 return m_linearFactor;
264         }
265         void setLinearFactor(const btVector3& linearFactor)
266         {
267                 m_linearFactor = linearFactor;
268                 m_invMass = m_linearFactor*m_inverseMass;
269         }
270         btScalar                getInvMass() const { return m_inverseMass; }
271         const btMatrix3x3& getInvInertiaTensorWorld() const { 
272                 return m_invInertiaTensorWorld; 
273         }
274                 
275         void                    integrateVelocities(btScalar step);
276
277         void                    setCenterOfMassTransform(const btTransform& xform);
278
279         void                    applyCentralForce(const btVector3& force)
280         {
281                 m_totalForce += force*m_linearFactor;
282         }
283
284         const btVector3& getTotalForce() const
285         {
286                 return m_totalForce;
287         };
288
289         const btVector3& getTotalTorque() const
290         {
291                 return m_totalTorque;
292         };
293     
294         const btVector3& getInvInertiaDiagLocal() const
295         {
296                 return m_invInertiaLocal;
297         };
298
299         void    setInvInertiaDiagLocal(const btVector3& diagInvInertia)
300         {
301                 m_invInertiaLocal = diagInvInertia;
302         }
303
304         void    setSleepingThresholds(btScalar linear,btScalar angular)
305         {
306                 m_linearSleepingThreshold = linear;
307                 m_angularSleepingThreshold = angular;
308         }
309
310         void    applyTorque(const btVector3& torque)
311         {
312                 m_totalTorque += torque*m_angularFactor;
313         }
314         
315         void    applyForce(const btVector3& force, const btVector3& rel_pos) 
316         {
317                 applyCentralForce(force);
318                 applyTorque(rel_pos.cross(force*m_linearFactor));
319         }
320         
321         void applyCentralImpulse(const btVector3& impulse)
322         {
323                 m_linearVelocity += impulse *m_linearFactor * m_inverseMass;
324         }
325         
326         void applyTorqueImpulse(const btVector3& torque)
327         {
328                         m_angularVelocity += m_invInertiaTensorWorld * torque * m_angularFactor;
329         }
330         
331         void applyImpulse(const btVector3& impulse, const btVector3& rel_pos) 
332         {
333                 if (m_inverseMass != btScalar(0.))
334                 {
335                         applyCentralImpulse(impulse);
336                         if (m_angularFactor)
337                         {
338                                 applyTorqueImpulse(rel_pos.cross(impulse*m_linearFactor));
339                         }
340                 }
341         }
342
343         void clearForces() 
344         {
345                 m_totalForce.setValue(btScalar(0.0), btScalar(0.0), btScalar(0.0));
346                 m_totalTorque.setValue(btScalar(0.0), btScalar(0.0), btScalar(0.0));
347         }
348         
349         void updateInertiaTensor();    
350         
351         const btVector3&     getCenterOfMassPosition() const { 
352                 return m_worldTransform.getOrigin(); 
353         }
354         btQuaternion getOrientation() const;
355         
356         const btTransform&  getCenterOfMassTransform() const { 
357                 return m_worldTransform; 
358         }
359         const btVector3&   getLinearVelocity() const { 
360                 return m_linearVelocity; 
361         }
362         const btVector3&    getAngularVelocity() const { 
363                 return m_angularVelocity; 
364         }
365         
366
367         inline void setLinearVelocity(const btVector3& lin_vel)
368         { 
369                 m_updateRevision++;
370                 m_linearVelocity = lin_vel; 
371         }
372
373         inline void setAngularVelocity(const btVector3& ang_vel) 
374         { 
375                 m_updateRevision++;
376                 m_angularVelocity = ang_vel; 
377         }
378
379         btVector3 getVelocityInLocalPoint(const btVector3& rel_pos) const
380         {
381                 //we also calculate lin/ang velocity for kinematic objects
382                 return m_linearVelocity + m_angularVelocity.cross(rel_pos);
383
384                 //for kinematic objects, we could also use use:
385                 //              return  (m_worldTransform(rel_pos) - m_interpolationWorldTransform(rel_pos)) / m_kinematicTimeStep;
386         }
387
388         void translate(const btVector3& v) 
389         {
390                 m_worldTransform.getOrigin() += v; 
391         }
392
393         
394         void    getAabb(btVector3& aabbMin,btVector3& aabbMax) const;
395
396
397
398
399         
400         SIMD_FORCE_INLINE btScalar computeImpulseDenominator(const btVector3& pos, const btVector3& normal) const
401         {
402                 btVector3 r0 = pos - getCenterOfMassPosition();
403
404                 btVector3 c0 = (r0).cross(normal);
405
406                 btVector3 vec = (c0 * getInvInertiaTensorWorld()).cross(r0);
407
408                 return m_inverseMass + normal.dot(vec);
409
410         }
411
412         SIMD_FORCE_INLINE btScalar computeAngularImpulseDenominator(const btVector3& axis) const
413         {
414                 btVector3 vec = axis * getInvInertiaTensorWorld();
415                 return axis.dot(vec);
416         }
417
418         SIMD_FORCE_INLINE void  updateDeactivation(btScalar timeStep)
419         {
420                 if ( (getActivationState() == ISLAND_SLEEPING) || (getActivationState() == DISABLE_DEACTIVATION))
421                         return;
422
423                 if ((getLinearVelocity().length2() < m_linearSleepingThreshold*m_linearSleepingThreshold) &&
424                         (getAngularVelocity().length2() < m_angularSleepingThreshold*m_angularSleepingThreshold))
425                 {
426                         m_deactivationTime += timeStep;
427                 } else
428                 {
429                         m_deactivationTime=btScalar(0.);
430                         setActivationState(0);
431                 }
432
433         }
434
435         SIMD_FORCE_INLINE bool  wantsSleeping()
436         {
437
438                 if (getActivationState() == DISABLE_DEACTIVATION)
439                         return false;
440
441                 //disable deactivation
442                 if (gDisableDeactivation || (gDeactivationTime == btScalar(0.)))
443                         return false;
444
445                 if ( (getActivationState() == ISLAND_SLEEPING) || (getActivationState() == WANTS_DEACTIVATION))
446                         return true;
447
448                 if (m_deactivationTime> gDeactivationTime)
449                 {
450                         return true;
451                 }
452                 return false;
453         }
454
455
456         
457         const btBroadphaseProxy*        getBroadphaseProxy() const
458         {
459                 return m_broadphaseHandle;
460         }
461         btBroadphaseProxy*      getBroadphaseProxy() 
462         {
463                 return m_broadphaseHandle;
464         }
465         void    setNewBroadphaseProxy(btBroadphaseProxy* broadphaseProxy)
466         {
467                 m_broadphaseHandle = broadphaseProxy;
468         }
469
470         //btMotionState allows to automatic synchronize the world transform for active objects
471         btMotionState*  getMotionState()
472         {
473                 return m_optionalMotionState;
474         }
475         const btMotionState*    getMotionState() const
476         {
477                 return m_optionalMotionState;
478         }
479         void    setMotionState(btMotionState* motionState)
480         {
481                 m_optionalMotionState = motionState;
482                 if (m_optionalMotionState)
483                         motionState->getWorldTransform(m_worldTransform);
484         }
485
486         //for experimental overriding of friction/contact solver func
487         int     m_contactSolverType;
488         int     m_frictionSolverType;
489
490         void    setAngularFactor(const btVector3& angFac)
491         {
492                 m_updateRevision++;
493                 m_angularFactor = angFac;
494         }
495
496         void    setAngularFactor(btScalar angFac)
497         {
498                 m_updateRevision++;
499                 m_angularFactor.setValue(angFac,angFac,angFac);
500         }
501         const btVector3&        getAngularFactor() const
502         {
503                 return m_angularFactor;
504         }
505
506         //is this rigidbody added to a btCollisionWorld/btDynamicsWorld/btBroadphase?
507         bool    isInWorld() const
508         {
509                 return (getBroadphaseProxy() != 0);
510         }
511
512         void addConstraintRef(btTypedConstraint* c);
513         void removeConstraintRef(btTypedConstraint* c);
514
515         btTypedConstraint* getConstraintRef(int index)
516         {
517                 return m_constraintRefs[index];
518         }
519
520         int getNumConstraintRefs() const
521         {
522                 return m_constraintRefs.size();
523         }
524
525         void    setFlags(int flags)
526         {
527                 m_rigidbodyFlags = flags;
528         }
529
530         int getFlags() const
531         {
532                 return m_rigidbodyFlags;
533         }
534
535
536         
537
538         ///perform implicit force computation in world space
539         btVector3 computeGyroscopicImpulseImplicit_World(btScalar dt) const;
540         
541         ///perform implicit force computation in body space (inertial frame)
542         btVector3 computeGyroscopicImpulseImplicit_Body(btScalar step) const;
543
544         ///explicit version is best avoided, it gains energy
545         btVector3 computeGyroscopicForceExplicit(btScalar maxGyroscopicForce) const;
546         btVector3 getLocalInertia() const;
547
548         ///////////////////////////////////////////////
549
550         virtual int     calculateSerializeBufferSize()  const;
551
552         ///fills the dataBuffer and returns the struct name (and 0 on failure)
553         virtual const char*     serialize(void* dataBuffer,  class btSerializer* serializer) const;
554
555         virtual void serializeSingleObject(class btSerializer* serializer) const;
556
557 };
558
559 //@todo add m_optionalMotionState and m_constraintRefs to btRigidBodyData
560 ///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64
561 struct  btRigidBodyFloatData
562 {
563         btCollisionObjectFloatData      m_collisionObjectData;
564         btMatrix3x3FloatData            m_invInertiaTensorWorld;
565         btVector3FloatData              m_linearVelocity;
566         btVector3FloatData              m_angularVelocity;
567         btVector3FloatData              m_angularFactor;
568         btVector3FloatData              m_linearFactor;
569         btVector3FloatData              m_gravity;      
570         btVector3FloatData              m_gravity_acceleration;
571         btVector3FloatData              m_invInertiaLocal;
572         btVector3FloatData              m_totalForce;
573         btVector3FloatData              m_totalTorque;
574         float                                   m_inverseMass;
575         float                                   m_linearDamping;
576         float                                   m_angularDamping;
577         float                                   m_additionalDampingFactor;
578         float                                   m_additionalLinearDampingThresholdSqr;
579         float                                   m_additionalAngularDampingThresholdSqr;
580         float                                   m_additionalAngularDampingFactor;
581         float                                   m_linearSleepingThreshold;
582         float                                   m_angularSleepingThreshold;
583         int                                             m_additionalDamping;
584 };
585
586 ///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64
587 struct  btRigidBodyDoubleData
588 {
589         btCollisionObjectDoubleData     m_collisionObjectData;
590         btMatrix3x3DoubleData           m_invInertiaTensorWorld;
591         btVector3DoubleData             m_linearVelocity;
592         btVector3DoubleData             m_angularVelocity;
593         btVector3DoubleData             m_angularFactor;
594         btVector3DoubleData             m_linearFactor;
595         btVector3DoubleData             m_gravity;      
596         btVector3DoubleData             m_gravity_acceleration;
597         btVector3DoubleData             m_invInertiaLocal;
598         btVector3DoubleData             m_totalForce;
599         btVector3DoubleData             m_totalTorque;
600         double                                  m_inverseMass;
601         double                                  m_linearDamping;
602         double                                  m_angularDamping;
603         double                                  m_additionalDampingFactor;
604         double                                  m_additionalLinearDampingThresholdSqr;
605         double                                  m_additionalAngularDampingThresholdSqr;
606         double                                  m_additionalAngularDampingFactor;
607         double                                  m_linearSleepingThreshold;
608         double                                  m_angularSleepingThreshold;
609         int                                             m_additionalDamping;
610         char    m_padding[4];
611 };
612
613
614
615 #endif //BT_RIGIDBODY_H
616