added anisotropic friction support for Bullet. Both for static and dynamic objects
[blender-staging.git] / extern / bullet2 / src / BulletCollision / CollisionDispatch / btCollisionObject.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 COLLISION_OBJECT_H
17 #define COLLISION_OBJECT_H
18
19 #include "LinearMath/btTransform.h"
20
21 //island management, m_activationState1
22 #define ACTIVE_TAG 1
23 #define ISLAND_SLEEPING 2
24 #define WANTS_DEACTIVATION 3
25 #define DISABLE_DEACTIVATION 4
26 #define DISABLE_SIMULATION 5
27
28 struct  btBroadphaseProxy;
29 class   btCollisionShape;
30 #include "LinearMath/btMotionState.h"
31 #include "LinearMath/btAlignedAllocator.h"
32
33
34
35 /// btCollisionObject can be used to manage collision detection objects. 
36 /// btCollisionObject maintains all information that is needed for a collision detection: Shape, Transform and AABB proxy.
37 /// They can be added to the btCollisionWorld.
38 ATTRIBUTE_ALIGNED16(class)      btCollisionObject
39 {
40
41 protected:
42
43         btTransform     m_worldTransform;
44
45         ///m_interpolationWorldTransform is used for CCD and interpolation
46         ///it can be either previous or future (predicted) transform
47         btTransform     m_interpolationWorldTransform;
48         //those two are experimental: just added for bullet time effect, so you can still apply impulses (directly modifying velocities) 
49         //without destroying the continuous interpolated motion (which uses this interpolation velocities)
50         btVector3       m_interpolationLinearVelocity;
51         btVector3       m_interpolationAngularVelocity;
52         btVector3               m_anisotropicFriction;
53         bool    m_hasAnisotropicFriction;
54
55         btBroadphaseProxy*              m_broadphaseHandle;
56         btCollisionShape*               m_collisionShape;
57         
58         ///m_rootCollisionShape is temporarily used to store the original collision shape
59         ///The m_collisionShape might be temporarily replaced by a child collision shape during collision detection purposes
60         ///If it is NULL, the m_collisionShape is not temporarily replaced.
61         btCollisionShape*               m_rootCollisionShape;
62
63         int                             m_collisionFlags;
64
65         int                             m_islandTag1;
66         int                             m_companionId;
67
68         int                             m_activationState1;
69         btScalar                        m_deactivationTime;
70
71         btScalar                m_friction;
72         btScalar                m_restitution;
73
74         ///users can point to their objects, m_userPointer is not used by Bullet, see setUserPointer/getUserPointer
75         void*                   m_userObjectPointer;
76
77         ///m_internalType is reserved to distinguish Bullet's btCollisionObject, btRigidBody, btSoftBody etc.
78         ///do not assign your own m_internalType unless you write a new dynamics object class.
79         int                             m_internalType;
80
81         ///time of impact calculation
82         btScalar                m_hitFraction; 
83         
84         ///Swept sphere radius (0.0 by default), see btConvexConvexAlgorithm::
85         btScalar                m_ccdSweptSphereRadius;
86
87         /// Don't do continuous collision detection if the motion (in one step) is less then m_ccdMotionThreshold
88         btScalar                m_ccdMotionThreshold;
89         
90         /// If some object should have elaborate collision filtering by sub-classes
91         bool                    m_checkCollideWith;
92
93         char    m_pad[7];
94
95         virtual bool    checkCollideWithOverride(btCollisionObject* /* co */)
96         {
97                 return true;
98         }
99
100 public:
101
102         BT_DECLARE_ALIGNED_ALLOCATOR();
103
104         enum CollisionFlags
105         {
106                 CF_STATIC_OBJECT= 1,
107                 CF_KINEMATIC_OBJECT= 2,
108                 CF_NO_CONTACT_RESPONSE = 4,
109                 CF_CUSTOM_MATERIAL_CALLBACK = 8//this allows per-triangle material (friction/restitution)
110         };
111
112         enum    CollisionObjectTypes
113         {
114                 CO_COLLISION_OBJECT =1,
115                 CO_RIGID_BODY,
116                 CO_SOFT_BODY
117         };
118
119         SIMD_FORCE_INLINE bool mergesSimulationIslands() const
120         {
121                 ///static objects, kinematic and object without contact response don't merge islands
122                 return  ((m_collisionFlags & (CF_STATIC_OBJECT | CF_KINEMATIC_OBJECT | CF_NO_CONTACT_RESPONSE) )==0);
123         }
124
125         const btVector3& getAnisotropicFriction() const
126         {
127                 return m_anisotropicFriction;
128         }
129         void    setAnisotropicFriction(const btVector3& anisotropicFriction)
130         {
131                 m_anisotropicFriction = anisotropicFriction;
132                 m_hasAnisotropicFriction = (anisotropicFriction[0]!=1.f) || (anisotropicFriction[1]!=1.f) || (anisotropicFriction[2]!=1.f);
133         }
134         bool    hasAnisotropicFriction() const
135         {
136                 return m_hasAnisotropicFriction;
137         }
138
139
140         SIMD_FORCE_INLINE bool          isStaticObject() const {
141                 return (m_collisionFlags & CF_STATIC_OBJECT) != 0;
142         }
143
144         SIMD_FORCE_INLINE bool          isKinematicObject() const
145         {
146                 return (m_collisionFlags & CF_KINEMATIC_OBJECT) != 0;
147         }
148
149         SIMD_FORCE_INLINE bool          isStaticOrKinematicObject() const
150         {
151                 return (m_collisionFlags & (CF_KINEMATIC_OBJECT | CF_STATIC_OBJECT)) != 0 ;
152         }
153
154         SIMD_FORCE_INLINE bool          hasContactResponse() const {
155                 return (m_collisionFlags & CF_NO_CONTACT_RESPONSE)==0;
156         }
157
158         
159         btCollisionObject();
160
161         virtual ~btCollisionObject();
162
163         virtual void    setCollisionShape(btCollisionShape* collisionShape)
164         {
165                 m_collisionShape = collisionShape;
166                 m_rootCollisionShape = collisionShape;
167         }
168
169         SIMD_FORCE_INLINE const btCollisionShape*       getCollisionShape() const
170         {
171                 return m_collisionShape;
172         }
173
174         SIMD_FORCE_INLINE btCollisionShape*     getCollisionShape()
175         {
176                 return m_collisionShape;
177         }
178
179         SIMD_FORCE_INLINE const btCollisionShape*       getRootCollisionShape() const
180         {
181                 return m_rootCollisionShape;
182         }
183
184         SIMD_FORCE_INLINE btCollisionShape*     getRootCollisionShape()
185         {
186                 return m_rootCollisionShape;
187         }
188
189         ///Avoid using this internal API call
190         ///internalSetTemporaryCollisionShape is used to temporary replace the actual collision shape by a child collision shape.
191         void    internalSetTemporaryCollisionShape(btCollisionShape* collisionShape)
192         {
193                 m_collisionShape = collisionShape;
194         }
195
196         int     getActivationState() const { return m_activationState1;}
197         
198         void setActivationState(int newState);
199
200         void    setDeactivationTime(btScalar time)
201         {
202                 m_deactivationTime = time;
203         }
204         btScalar        getDeactivationTime() const
205         {
206                 return m_deactivationTime;
207         }
208
209         void forceActivationState(int newState);
210
211         void    activate(bool forceActivation = false);
212
213         inline bool isActive() const
214         {
215                 return ((getActivationState() != ISLAND_SLEEPING) && (getActivationState() != DISABLE_SIMULATION));
216         }
217
218         void    setRestitution(btScalar rest)
219         {
220                 m_restitution = rest;
221         }
222         btScalar        getRestitution() const
223         {
224                 return m_restitution;
225         }
226         void    setFriction(btScalar frict)
227         {
228                 m_friction = frict;
229         }
230         btScalar        getFriction() const
231         {
232                 return m_friction;
233         }
234
235         ///reserved for Bullet internal usage
236         int     getInternalType() const
237         {
238                 return m_internalType;
239         }
240
241         btTransform&    getWorldTransform()
242         {
243                 return m_worldTransform;
244         }
245
246         const btTransform&      getWorldTransform() const
247         {
248                 return m_worldTransform;
249         }
250
251         void    setWorldTransform(const btTransform& worldTrans)
252         {
253                 m_worldTransform = worldTrans;
254         }
255
256
257         btBroadphaseProxy*      getBroadphaseHandle()
258         {
259                 return m_broadphaseHandle;
260         }
261
262         const btBroadphaseProxy*        getBroadphaseHandle() const
263         {
264                 return m_broadphaseHandle;
265         }
266
267         void    setBroadphaseHandle(btBroadphaseProxy* handle)
268         {
269                 m_broadphaseHandle = handle;
270         }
271
272
273         const btTransform&      getInterpolationWorldTransform() const
274         {
275                 return m_interpolationWorldTransform;
276         }
277
278         btTransform&    getInterpolationWorldTransform()
279         {
280                 return m_interpolationWorldTransform;
281         }
282
283         void    setInterpolationWorldTransform(const btTransform&       trans)
284         {
285                 m_interpolationWorldTransform = trans;
286         }
287
288         void    setInterpolationLinearVelocity(const btVector3& linvel)
289         {
290                 m_interpolationLinearVelocity = linvel;
291         }
292
293         void    setInterpolationAngularVelocity(const btVector3& angvel)
294         {
295                 m_interpolationAngularVelocity = angvel;
296         }
297
298         const btVector3&        getInterpolationLinearVelocity() const
299         {
300                 return m_interpolationLinearVelocity;
301         }
302
303         const btVector3&        getInterpolationAngularVelocity() const
304         {
305                 return m_interpolationAngularVelocity;
306         }
307
308         const int getIslandTag() const
309         {
310                 return  m_islandTag1;
311         }
312
313         void    setIslandTag(int tag)
314         {
315                 m_islandTag1 = tag;
316         }
317
318         const int getCompanionId() const
319         {
320                 return  m_companionId;
321         }
322
323         void    setCompanionId(int id)
324         {
325                 m_companionId = id;
326         }
327
328         const btScalar                  getHitFraction() const
329         {
330                 return m_hitFraction; 
331         }
332
333         void    setHitFraction(btScalar hitFraction)
334         {
335                 m_hitFraction = hitFraction;
336         }
337
338         
339         const int       getCollisionFlags() const
340         {
341                 return m_collisionFlags;
342         }
343
344         void    setCollisionFlags(int flags)
345         {
346                 m_collisionFlags = flags;
347         }
348         
349         ///Swept sphere radius (0.0 by default), see btConvexConvexAlgorithm::
350         btScalar                        getCcdSweptSphereRadius() const
351         {
352                 return m_ccdSweptSphereRadius;
353         }
354
355         ///Swept sphere radius (0.0 by default), see btConvexConvexAlgorithm::
356         void    setCcdSweptSphereRadius(btScalar radius)
357         {
358                 m_ccdSweptSphereRadius = radius;
359         }
360
361         btScalar        getCcdMotionThreshold() const
362         {
363                 return m_ccdMotionThreshold;
364         }
365
366         btScalar        getCcdSquareMotionThreshold() const
367         {
368                 return m_ccdMotionThreshold*m_ccdMotionThreshold;
369         }
370
371
372
373         /// Don't do continuous collision detection if the motion (in one step) is less then m_ccdMotionThreshold
374         void    setCcdMotionThreshold(btScalar ccdMotionThreshold)
375         {
376                 m_ccdMotionThreshold = ccdMotionThreshold*ccdMotionThreshold;
377         }
378
379         ///users can point to their objects, userPointer is not used by Bullet
380         void*   getUserPointer() const
381         {
382                 return m_userObjectPointer;
383         }
384         
385         ///users can point to their objects, userPointer is not used by Bullet
386         void    setUserPointer(void* userPointer)
387         {
388                 m_userObjectPointer = userPointer;
389         }
390
391
392         inline bool checkCollideWith(btCollisionObject* co)
393         {
394                 if (m_checkCollideWith)
395                         return checkCollideWithOverride(co);
396
397                 return true;
398         }
399 };
400
401 #endif //COLLISION_OBJECT_H