update Bullet 2.x with latest changes, notice that the integration is not finished...
[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 RIGIDBODY_H
17 #define RIGIDBODY_H
18
19 #include <vector>
20 #include <LinearMath/btPoint3.h>
21 #include <LinearMath/btTransform.h>
22 #include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h"
23
24
25 #include "BulletCollision/CollisionDispatch/btCollisionObject.h"
26
27 class btCollisionShape;
28 class btMotionState;
29
30
31
32 extern float gLinearAirDamping;
33 extern bool gUseEpa;
34
35 extern float gDeactivationTime;
36 extern bool gDisableDeactivation;
37 extern float gLinearSleepingThreshold;
38 extern float gAngularSleepingThreshold;
39
40
41 /// btRigidBody class for btRigidBody Dynamics
42 /// 
43 class btRigidBody  : public btCollisionObject
44 {
45
46         btMatrix3x3     m_invInertiaTensorWorld;
47         btVector3               m_linearVelocity;
48         btVector3               m_angularVelocity;
49         btScalar                m_inverseMass;
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
60         //m_optionalMotionState allows to automatic synchronize the world transform for active objects
61         btMotionState*  m_optionalMotionState;
62
63 public:
64
65         btRigidBody(float mass, const btTransform& worldTransform, btCollisionShape* collisionShape, const btVector3& localInertia=btVector3(0,0,0),btScalar linearDamping=0.f,btScalar angularDamping=0.f,btScalar friction=0.5f,btScalar restitution=0.f);
66         btRigidBody(float mass, btMotionState* motionState, btCollisionShape* collisionShape, const btVector3& localInertia=btVector3(0,0,0),btScalar linearDamping=0.f,btScalar angularDamping=0.f,btScalar friction=0.5f,btScalar restitution=0.f);
67
68         void                    proceedToTransform(const btTransform& newTrans); 
69         
70         ///to keep collision detection and dynamics separate we don't store a rigidbody pointer
71         ///but a rigidbody is derived from btCollisionObject, so we can safely perform an upcast
72         static const btRigidBody*       upcast(const btCollisionObject* colObj)
73         {
74                 return (const btRigidBody*)colObj->m_internalOwner;
75         }
76         static btRigidBody*     upcast(btCollisionObject* colObj)
77         {
78                 return (btRigidBody*)colObj->m_internalOwner;
79         }
80         
81         /// continuous collision detection needs prediction
82         void                    predictIntegratedTransform(btScalar step, btTransform& predictedTransform) ;
83         
84         void                    saveKinematicState(btScalar step);
85         
86
87         void                    applyForces(btScalar step);
88         
89         void                    setGravity(const btVector3& acceleration);  
90
91         const btVector3&        getGravity() const
92         {
93                 return m_gravity;
94         }
95
96         void                    setDamping(btScalar lin_damping, btScalar ang_damping);
97         
98         inline const btCollisionShape*  getCollisionShape() const {
99                 return m_collisionShape;
100         }
101
102         inline btCollisionShape*        getCollisionShape() {
103                         return m_collisionShape;
104         }
105         
106         void                    setMassProps(btScalar mass, const btVector3& inertia);
107         
108         btScalar                getInvMass() const { return m_inverseMass; }
109         const btMatrix3x3& getInvInertiaTensorWorld() const { 
110                 return m_invInertiaTensorWorld; 
111         }
112                 
113         void                    integrateVelocities(btScalar step);
114
115         void                    setCenterOfMassTransform(const btTransform& xform);
116
117         void                    applyCentralForce(const btVector3& force)
118         {
119                 m_totalForce += force;
120         }
121     
122         const btVector3& getInvInertiaDiagLocal()
123         {
124                 return m_invInertiaLocal;
125         };
126
127         void    setInvInertiaDiagLocal(const btVector3& diagInvInertia)
128         {
129                 m_invInertiaLocal = diagInvInertia;
130         }
131
132         void    applyTorque(const btVector3& torque)
133         {
134                 m_totalTorque += torque;
135         }
136         
137         void    applyForce(const btVector3& force, const btVector3& rel_pos) 
138         {
139                 applyCentralForce(force);
140                 applyTorque(rel_pos.cross(force));
141         }
142         
143         void applyCentralImpulse(const btVector3& impulse)
144         {
145                 m_linearVelocity += impulse * m_inverseMass;
146         }
147         
148         void applyTorqueImpulse(const btVector3& torque)
149         {
150                         m_angularVelocity += m_invInertiaTensorWorld * torque;
151         }
152         
153         void applyImpulse(const btVector3& impulse, const btVector3& rel_pos) 
154         {
155                 if (m_inverseMass != 0.f)
156                 {
157                         applyCentralImpulse(impulse);
158                         applyTorqueImpulse(rel_pos.cross(impulse));
159                 }
160         }
161
162         //Optimization for the iterative solver: avoid calculating constant terms involving inertia, normal, relative position
163         inline void internalApplyImpulse(const btVector3& linearComponent, const btVector3& angularComponent,float impulseMagnitude)
164         {
165                 if (m_inverseMass != 0.f)
166                 {
167                         m_linearVelocity += linearComponent*impulseMagnitude;
168                         m_angularVelocity += angularComponent*impulseMagnitude;
169                 }
170         }
171         
172         void clearForces() 
173         {
174                 m_totalForce.setValue(0.0f, 0.0f, 0.0f);
175                 m_totalTorque.setValue(0.0f, 0.0f, 0.0f);
176         }
177         
178         void updateInertiaTensor();    
179         
180         const btPoint3&     getCenterOfMassPosition() const { 
181                 return m_worldTransform.getOrigin(); 
182         }
183         btQuaternion getOrientation() const;
184         
185         const btTransform&  getCenterOfMassTransform() const { 
186                 return m_worldTransform; 
187         }
188         const btVector3&   getLinearVelocity() const { 
189                 return m_linearVelocity; 
190         }
191         const btVector3&    getAngularVelocity() const { 
192                 return m_angularVelocity; 
193         }
194         
195
196         inline void setLinearVelocity(const btVector3& lin_vel)
197         { 
198                 assert (m_collisionFlags != btCollisionObject::CF_STATIC_OBJECT);
199                 m_linearVelocity = lin_vel; 
200         }
201
202         inline void setAngularVelocity(const btVector3& ang_vel) { 
203                 assert (m_collisionFlags != btCollisionObject::CF_STATIC_OBJECT);
204                 {
205                         m_angularVelocity = ang_vel; 
206                 }
207         }
208
209         btVector3 getVelocityInLocalPoint(const btVector3& rel_pos) const
210         {
211                 //we also calculate lin/ang velocity for kinematic objects
212                 return m_linearVelocity + m_angularVelocity.cross(rel_pos);
213
214                 //for kinematic objects, we could also use use:
215                 //              return  (m_worldTransform(rel_pos) - m_interpolationWorldTransform(rel_pos)) / m_kinematicTimeStep;
216         }
217
218         void translate(const btVector3& v) 
219         {
220                 m_worldTransform.getOrigin() += v; 
221         }
222
223         
224         void    getAabb(btVector3& aabbMin,btVector3& aabbMax) const;
225
226
227
228
229         
230         inline float computeImpulseDenominator(const btPoint3& pos, const btVector3& normal) const
231         {
232                 btVector3 r0 = pos - getCenterOfMassPosition();
233
234                 btVector3 c0 = (r0).cross(normal);
235
236                 btVector3 vec = (c0 * getInvInertiaTensorWorld()).cross(r0);
237
238                 return m_inverseMass + normal.dot(vec);
239
240         }
241
242         inline float computeAngularImpulseDenominator(const btVector3& axis) const
243         {
244                 btVector3 vec = axis * getInvInertiaTensorWorld();
245                 return axis.dot(vec);
246         }
247
248         inline void     updateDeactivation(float timeStep)
249         {
250                 if ( (GetActivationState() == ISLAND_SLEEPING) || (GetActivationState() == DISABLE_DEACTIVATION))
251                         return;
252
253                 if ((getLinearVelocity().length2() < gLinearSleepingThreshold*gLinearSleepingThreshold) &&
254                         (getAngularVelocity().length2() < gAngularSleepingThreshold*gAngularSleepingThreshold))
255                 {
256                         m_deactivationTime += timeStep;
257                 } else
258                 {
259                         m_deactivationTime=0.f;
260                         SetActivationState(0);
261                 }
262
263         }
264
265         inline bool     wantsSleeping()
266         {
267
268                 if (GetActivationState() == DISABLE_DEACTIVATION)
269                         return false;
270
271                 //disable deactivation
272                 if (gDisableDeactivation || (gDeactivationTime == 0.f))
273                         return false;
274
275                 if ( (GetActivationState() == ISLAND_SLEEPING) || (GetActivationState() == WANTS_DEACTIVATION))
276                         return true;
277
278                 if (m_deactivationTime> gDeactivationTime)
279                 {
280                         return true;
281                 }
282                 return false;
283         }
284
285
286         
287         const btBroadphaseProxy*        getBroadphaseProxy() const
288         {
289                 return m_broadphaseHandle;
290         }
291         btBroadphaseProxy*      getBroadphaseProxy() 
292         {
293                 return m_broadphaseHandle;
294         }
295         void    setNewBroadphaseProxy(btBroadphaseProxy* broadphaseProxy)
296         {
297                 m_broadphaseHandle = broadphaseProxy;
298         }
299
300         //btMotionState allows to automatic synchronize the world transform for active objects
301         btMotionState*  getMotionState()
302         {
303                 return m_optionalMotionState;
304         }
305         const btMotionState*    getMotionState() const
306         {
307                 return m_optionalMotionState;
308         }
309         void    setMotionState(btMotionState* motionState)
310         {
311                 m_optionalMotionState = motionState;
312         }
313
314         //for experimental overriding of friction/contact solver func
315         int     m_contactSolverType;
316         int     m_frictionSolverType;
317
318         
319
320         int     m_debugBodyId;
321 };
322
323
324
325 #endif
326