added hinge constraint support to Bullet physics
[blender.git] / extern / bullet / BulletDynamics / Dynamics / RigidBody.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 <SimdPoint3.h>
21 #include <SimdTransform.h>
22 #include "BroadphaseCollision/BroadphaseProxy.h"
23
24
25 #include "CollisionDispatch/CollisionObject.h"
26
27 class CollisionShape;
28 struct MassProps;
29 typedef SimdScalar dMatrix3[4*3];
30
31 extern float gLinearAirDamping;
32 extern bool gUseEpa;
33
34 #define MAX_RIGIDBODIES 8192
35
36
37 /// RigidBody class for RigidBody Dynamics
38 /// 
39 class RigidBody  : public CollisionObject
40 {
41 public:
42
43         RigidBody(const MassProps& massProps,SimdScalar linearDamping,SimdScalar angularDamping,SimdScalar friction,SimdScalar restitution);
44
45         void                    proceedToTransform(const SimdTransform& newTrans); 
46         
47         
48         /// continuous collision detection needs prediction
49         void                    predictIntegratedTransform(SimdScalar step, SimdTransform& predictedTransform) const;
50         
51         void                    applyForces(SimdScalar step);
52         
53         void                    setGravity(const SimdVector3& acceleration);  
54         
55         void                    setDamping(SimdScalar lin_damping, SimdScalar ang_damping);
56         
57         inline const CollisionShape*    GetCollisionShape() const {
58                 return m_collisionShape;
59         }
60
61         inline CollisionShape*  GetCollisionShape() {
62                         return m_collisionShape;
63         }
64         
65         void                    setMassProps(SimdScalar mass, const SimdVector3& inertia);
66         
67         SimdScalar              getInvMass() const { return m_inverseMass; }
68         const SimdMatrix3x3& getInvInertiaTensorWorld() const { return m_invInertiaTensorWorld; }
69                 
70         void                    integrateVelocities(SimdScalar step);
71
72         void                    setCenterOfMassTransform(const SimdTransform& xform);
73
74         void                    applyCentralForce(const SimdVector3& force)
75         {
76                 m_totalForce += force;
77         }
78     
79         const SimdVector3& getInvInertiaDiagLocal()
80         {
81                 return m_invInertiaLocal;
82         };
83
84         void    setInvInertiaDiagLocal(const SimdVector3& diagInvInertia)
85         {
86                 m_invInertiaLocal = diagInvInertia;
87         }
88
89         void    applyTorque(const SimdVector3& torque)
90         {
91                 m_totalTorque += torque;
92         }
93         
94         void    applyForce(const SimdVector3& force, const SimdVector3& rel_pos) 
95         {
96                 applyCentralForce(force);
97                 applyTorque(rel_pos.cross(force));
98         }
99         
100         void applyCentralImpulse(const SimdVector3& impulse)
101         {
102                 m_linearVelocity += impulse * m_inverseMass;
103         }
104         
105         void applyTorqueImpulse(const SimdVector3& torque)
106         {
107                 m_angularVelocity += m_invInertiaTensorWorld * torque;
108
109         }
110         
111         void applyImpulse(const SimdVector3& impulse, const SimdVector3& rel_pos) 
112         {
113                 if (m_inverseMass != 0.f)
114                 {
115                         applyCentralImpulse(impulse);
116                         applyTorqueImpulse(rel_pos.cross(impulse));
117                 }
118         }
119         
120         void clearForces() 
121         {
122                 m_totalForce.setValue(0.0f, 0.0f, 0.0f);
123                 m_totalTorque.setValue(0.0f, 0.0f, 0.0f);
124         }
125         
126         void updateInertiaTensor();    
127         
128         const SimdPoint3&     getCenterOfMassPosition() const { return m_worldTransform.getOrigin(); }
129         SimdQuaternion getOrientation() const;
130         
131         const SimdTransform&  getCenterOfMassTransform() const { return m_worldTransform; }
132         const SimdVector3&   getLinearVelocity() const { return m_linearVelocity; }
133         const SimdVector3&    getAngularVelocity() const { return m_angularVelocity; }
134         
135
136         void setLinearVelocity(const SimdVector3& lin_vel);
137         void setAngularVelocity(const SimdVector3& ang_vel) { m_angularVelocity = ang_vel; }
138
139         SimdVector3 getVelocityInLocalPoint(const SimdVector3& rel_pos) const
140         {
141                 return m_linearVelocity + m_angularVelocity.cross(rel_pos);
142         }
143
144         void translate(const SimdVector3& v) 
145         {
146                 m_worldTransform.getOrigin() += v; 
147         }
148
149         
150         void    getAabb(SimdVector3& aabbMin,SimdVector3& aabbMax) const;
151
152
153         void    setRestitution(float rest)
154         {
155                 m_restitution = rest;
156         }
157         float   getRestitution() const
158         {
159                 return m_restitution;
160         }
161         void    setFriction(float frict)
162         {
163                 m_friction = frict;
164         }
165         float   getFriction() const
166         {
167                 return m_friction;
168         }
169
170         
171         inline float ComputeImpulseDenominator(const SimdPoint3& pos, const SimdVector3& normal) const
172         {
173                 SimdVector3 r0 = pos - getCenterOfMassPosition();
174
175                 SimdVector3 c0 = (r0).cross(normal);
176
177                 SimdVector3 vec = (c0 * getInvInertiaTensorWorld()).cross(r0);
178
179                 return m_inverseMass + normal.dot(vec);
180
181         }
182
183         inline float ComputeAngularImpulseDenominator(const SimdVector3& axis) const
184         {
185                 SimdVector3 vec = axis * getInvInertiaTensorWorld();
186                 return axis.dot(vec);
187         }
188
189
190
191 private:
192         
193         SimdMatrix3x3   m_invInertiaTensorWorld;
194         SimdVector3             m_gravity;      
195         SimdVector3             m_invInertiaLocal;
196         SimdVector3             m_totalForce;
197         SimdVector3             m_totalTorque;
198 //      SimdQuaternion  m_orn1;
199         
200         SimdVector3             m_linearVelocity;
201         
202         SimdVector3             m_angularVelocity;
203         
204         SimdScalar              m_linearDamping;
205         SimdScalar              m_angularDamping;
206         SimdScalar              m_inverseMass;
207
208         SimdScalar              m_friction;
209         SimdScalar              m_restitution;
210
211         BroadphaseProxy*        m_broadphaseProxy;
212
213
214
215         
216 public:
217         const BroadphaseProxy*  GetBroadphaseProxy() const
218         {
219                 return m_broadphaseProxy;
220         }
221         BroadphaseProxy*        GetBroadphaseProxy() 
222         {
223                 return m_broadphaseProxy;
224         }
225         void    SetBroadphaseProxy(BroadphaseProxy* broadphaseProxy)
226         {
227                 m_broadphaseProxy = broadphaseProxy;
228         }
229         
230
231         /// for ode solver-binding
232         dMatrix3                m_R;//temp
233         dMatrix3                m_I;
234         dMatrix3                m_invI;
235
236         int                             m_odeTag;
237         float           m_padding[1024];
238         SimdVector3             m_tacc;//temp
239         SimdVector3             m_facc;
240         
241
242         int     m_debugBodyId;
243 };
244
245
246
247 #endif