Upgrade Bullet to version 2.83.
[blender.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 BT_COLLISION_OBJECT_H
17 #define BT_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 struct btCollisionShapeData;
31 #include "LinearMath/btMotionState.h"
32 #include "LinearMath/btAlignedAllocator.h"
33 #include "LinearMath/btAlignedObjectArray.h"
34
35 typedef btAlignedObjectArray<class btCollisionObject*> btCollisionObjectArray;
36
37 #ifdef BT_USE_DOUBLE_PRECISION
38 #define btCollisionObjectData btCollisionObjectDoubleData
39 #define btCollisionObjectDataName "btCollisionObjectDoubleData"
40 #else
41 #define btCollisionObjectData btCollisionObjectFloatData
42 #define btCollisionObjectDataName "btCollisionObjectFloatData"
43 #endif
44
45
46 /// btCollisionObject can be used to manage collision detection objects. 
47 /// btCollisionObject maintains all information that is needed for a collision detection: Shape, Transform and AABB proxy.
48 /// They can be added to the btCollisionWorld.
49 ATTRIBUTE_ALIGNED16(class)      btCollisionObject
50 {
51
52 protected:
53
54         btTransform     m_worldTransform;
55
56         ///m_interpolationWorldTransform is used for CCD and interpolation
57         ///it can be either previous or future (predicted) transform
58         btTransform     m_interpolationWorldTransform;
59         //those two are experimental: just added for bullet time effect, so you can still apply impulses (directly modifying velocities) 
60         //without destroying the continuous interpolated motion (which uses this interpolation velocities)
61         btVector3       m_interpolationLinearVelocity;
62         btVector3       m_interpolationAngularVelocity;
63         
64         btVector3       m_anisotropicFriction;
65         int                     m_hasAnisotropicFriction;
66         btScalar        m_contactProcessingThreshold;   
67
68         btBroadphaseProxy*              m_broadphaseHandle;
69         btCollisionShape*               m_collisionShape;
70         ///m_extensionPointer is used by some internal low-level Bullet extensions.
71         void*                                   m_extensionPointer;
72         
73         ///m_rootCollisionShape is temporarily used to store the original collision shape
74         ///The m_collisionShape might be temporarily replaced by a child collision shape during collision detection purposes
75         ///If it is NULL, the m_collisionShape is not temporarily replaced.
76         btCollisionShape*               m_rootCollisionShape;
77
78         int                             m_collisionFlags;
79
80         int                             m_islandTag1;
81         int                             m_companionId;
82
83         mutable int                             m_activationState1;
84         mutable btScalar                        m_deactivationTime;
85
86         btScalar                m_friction;
87         btScalar                m_restitution;
88         btScalar                m_rollingFriction;
89
90         ///m_internalType is reserved to distinguish Bullet's btCollisionObject, btRigidBody, btSoftBody, btGhostObject etc.
91         ///do not assign your own m_internalType unless you write a new dynamics object class.
92         int                             m_internalType;
93
94         ///users can point to their objects, m_userPointer is not used by Bullet, see setUserPointer/getUserPointer
95
96     void*                       m_userObjectPointer;
97     
98     int m_userIndex;
99
100         ///time of impact calculation
101         btScalar                m_hitFraction; 
102         
103         ///Swept sphere radius (0.0 by default), see btConvexConvexAlgorithm::
104         btScalar                m_ccdSweptSphereRadius;
105
106         /// Don't do continuous collision detection if the motion (in one step) is less then m_ccdMotionThreshold
107         btScalar                m_ccdMotionThreshold;
108         
109         /// If some object should have elaborate collision filtering by sub-classes
110         int                     m_checkCollideWith;
111
112         btAlignedObjectArray<const btCollisionObject*> m_objectsWithoutCollisionCheck;
113
114         ///internal update revision number. It will be increased when the object changes. This allows some subsystems to perform lazy evaluation.
115         int                     m_updateRevision;
116
117
118 public:
119
120         BT_DECLARE_ALIGNED_ALLOCATOR();
121
122         enum CollisionFlags
123         {
124                 CF_STATIC_OBJECT= 1,
125                 CF_KINEMATIC_OBJECT= 2,
126                 CF_NO_CONTACT_RESPONSE = 4,
127                 CF_CUSTOM_MATERIAL_CALLBACK = 8,//this allows per-triangle material (friction/restitution)
128                 CF_CHARACTER_OBJECT = 16,
129                 CF_DISABLE_VISUALIZE_OBJECT = 32, //disable debug drawing
130                 CF_DISABLE_SPU_COLLISION_PROCESSING = 64//disable parallel/SPU processing
131         };
132
133         enum    CollisionObjectTypes
134         {
135                 CO_COLLISION_OBJECT =1,
136                 CO_RIGID_BODY=2,
137                 ///CO_GHOST_OBJECT keeps track of all objects overlapping its AABB and that pass its collision filter
138                 ///It is useful for collision sensors, explosion objects, character controller etc.
139                 CO_GHOST_OBJECT=4,
140                 CO_SOFT_BODY=8,
141                 CO_HF_FLUID=16,
142                 CO_USER_TYPE=32,
143                 CO_FEATHERSTONE_LINK=64
144         };
145
146         enum AnisotropicFrictionFlags
147         {
148                 CF_ANISOTROPIC_FRICTION_DISABLED=0,
149                 CF_ANISOTROPIC_FRICTION = 1,
150                 CF_ANISOTROPIC_ROLLING_FRICTION = 2
151         };
152
153         SIMD_FORCE_INLINE bool mergesSimulationIslands() const
154         {
155                 ///static objects, kinematic and object without contact response don't merge islands
156                 return  ((m_collisionFlags & (CF_STATIC_OBJECT | CF_KINEMATIC_OBJECT | CF_NO_CONTACT_RESPONSE) )==0);
157         }
158
159         const btVector3& getAnisotropicFriction() const
160         {
161                 return m_anisotropicFriction;
162         }
163         void    setAnisotropicFriction(const btVector3& anisotropicFriction, int frictionMode = CF_ANISOTROPIC_FRICTION)
164         {
165                 m_anisotropicFriction = anisotropicFriction;
166                 bool isUnity = (anisotropicFriction[0]!=1.f) || (anisotropicFriction[1]!=1.f) || (anisotropicFriction[2]!=1.f);
167                 m_hasAnisotropicFriction = isUnity?frictionMode : 0;
168         }
169         bool    hasAnisotropicFriction(int frictionMode = CF_ANISOTROPIC_FRICTION) const
170         {
171                 return (m_hasAnisotropicFriction&frictionMode)!=0;
172         }
173
174         ///the constraint solver can discard solving contacts, if the distance is above this threshold. 0 by default.
175         ///Note that using contacts with positive distance can improve stability. It increases, however, the chance of colliding with degerate contacts, such as 'interior' triangle edges
176         void    setContactProcessingThreshold( btScalar contactProcessingThreshold)
177         {
178                 m_contactProcessingThreshold = contactProcessingThreshold;
179         }
180         btScalar        getContactProcessingThreshold() const
181         {
182                 return m_contactProcessingThreshold;
183         }
184
185         SIMD_FORCE_INLINE bool          isStaticObject() const {
186                 return (m_collisionFlags & CF_STATIC_OBJECT) != 0;
187         }
188
189         SIMD_FORCE_INLINE bool          isKinematicObject() const
190         {
191                 return (m_collisionFlags & CF_KINEMATIC_OBJECT) != 0;
192         }
193
194         SIMD_FORCE_INLINE bool          isStaticOrKinematicObject() const
195         {
196                 return (m_collisionFlags & (CF_KINEMATIC_OBJECT | CF_STATIC_OBJECT)) != 0 ;
197         }
198
199         SIMD_FORCE_INLINE bool          hasContactResponse() const {
200                 return (m_collisionFlags & CF_NO_CONTACT_RESPONSE)==0;
201         }
202
203         
204         btCollisionObject();
205
206         virtual ~btCollisionObject();
207
208         virtual void    setCollisionShape(btCollisionShape* collisionShape)
209         {
210                 m_updateRevision++;
211                 m_collisionShape = collisionShape;
212                 m_rootCollisionShape = collisionShape;
213         }
214
215         SIMD_FORCE_INLINE const btCollisionShape*       getCollisionShape() const
216         {
217                 return m_collisionShape;
218         }
219
220         SIMD_FORCE_INLINE btCollisionShape*     getCollisionShape()
221         {
222                 return m_collisionShape;
223         }
224
225         void    setIgnoreCollisionCheck(const btCollisionObject* co, bool ignoreCollisionCheck)
226         {
227                 if (ignoreCollisionCheck)
228                 {
229                         //We don't check for duplicates. Is it ok to leave that up to the user of this API?
230                         //int index = m_objectsWithoutCollisionCheck.findLinearSearch(co);
231                         //if (index == m_objectsWithoutCollisionCheck.size())
232                         //{
233                         m_objectsWithoutCollisionCheck.push_back(co);
234                         //}
235                 }
236                 else
237                 {
238                         m_objectsWithoutCollisionCheck.remove(co);
239                 }
240                 m_checkCollideWith = m_objectsWithoutCollisionCheck.size() > 0;
241         }
242
243         virtual bool    checkCollideWithOverride(const btCollisionObject*  co) const
244         {
245                 int index = m_objectsWithoutCollisionCheck.findLinearSearch(co);
246                 if (index < m_objectsWithoutCollisionCheck.size())
247                 {
248                         return false;
249                 }
250                 return true;
251         }
252
253
254         
255
256         ///Avoid using this internal API call, the extension pointer is used by some Bullet extensions. 
257         ///If you need to store your own user pointer, use 'setUserPointer/getUserPointer' instead.
258         void*           internalGetExtensionPointer() const
259         {
260                 return m_extensionPointer;
261         }
262         ///Avoid using this internal API call, the extension pointer is used by some Bullet extensions
263         ///If you need to store your own user pointer, use 'setUserPointer/getUserPointer' instead.
264         void    internalSetExtensionPointer(void* pointer)
265         {
266                 m_extensionPointer = pointer;
267         }
268
269         SIMD_FORCE_INLINE       int     getActivationState() const { return m_activationState1;}
270         
271         void setActivationState(int newState) const;
272
273         void    setDeactivationTime(btScalar time)
274         {
275                 m_deactivationTime = time;
276         }
277         btScalar        getDeactivationTime() const
278         {
279                 return m_deactivationTime;
280         }
281
282         void forceActivationState(int newState) const;
283
284         void    activate(bool forceActivation = false) const;
285
286         SIMD_FORCE_INLINE bool isActive() const
287         {
288                 return ((getActivationState() != ISLAND_SLEEPING) && (getActivationState() != DISABLE_SIMULATION));
289         }
290
291         void    setRestitution(btScalar rest)
292         {
293                 m_updateRevision++;
294                 m_restitution = rest;
295         }
296         btScalar        getRestitution() const
297         {
298                 return m_restitution;
299         }
300         void    setFriction(btScalar frict)
301         {
302                 m_updateRevision++;
303                 m_friction = frict;
304         }
305         btScalar        getFriction() const
306         {
307                 return m_friction;
308         }
309
310         void    setRollingFriction(btScalar frict)
311         {
312                 m_updateRevision++;
313                 m_rollingFriction = frict;
314         }
315         btScalar        getRollingFriction() const
316         {
317                 return m_rollingFriction;
318         }
319
320
321         ///reserved for Bullet internal usage
322         int     getInternalType() const
323         {
324                 return m_internalType;
325         }
326
327         btTransform&    getWorldTransform()
328         {
329                 return m_worldTransform;
330         }
331
332         const btTransform&      getWorldTransform() const
333         {
334                 return m_worldTransform;
335         }
336
337         void    setWorldTransform(const btTransform& worldTrans)
338         {
339                 m_updateRevision++;
340                 m_worldTransform = worldTrans;
341         }
342
343
344         SIMD_FORCE_INLINE btBroadphaseProxy*    getBroadphaseHandle()
345         {
346                 return m_broadphaseHandle;
347         }
348
349         SIMD_FORCE_INLINE const btBroadphaseProxy*      getBroadphaseHandle() const
350         {
351                 return m_broadphaseHandle;
352         }
353
354         void    setBroadphaseHandle(btBroadphaseProxy* handle)
355         {
356                 m_broadphaseHandle = handle;
357         }
358
359
360         const btTransform&      getInterpolationWorldTransform() const
361         {
362                 return m_interpolationWorldTransform;
363         }
364
365         btTransform&    getInterpolationWorldTransform()
366         {
367                 return m_interpolationWorldTransform;
368         }
369
370         void    setInterpolationWorldTransform(const btTransform&       trans)
371         {
372                 m_updateRevision++;
373                 m_interpolationWorldTransform = trans;
374         }
375
376         void    setInterpolationLinearVelocity(const btVector3& linvel)
377         {
378                 m_updateRevision++;
379                 m_interpolationLinearVelocity = linvel;
380         }
381
382         void    setInterpolationAngularVelocity(const btVector3& angvel)
383         {
384                 m_updateRevision++;
385                 m_interpolationAngularVelocity = angvel;
386         }
387
388         const btVector3&        getInterpolationLinearVelocity() const
389         {
390                 return m_interpolationLinearVelocity;
391         }
392
393         const btVector3&        getInterpolationAngularVelocity() const
394         {
395                 return m_interpolationAngularVelocity;
396         }
397
398         SIMD_FORCE_INLINE int getIslandTag() const
399         {
400                 return  m_islandTag1;
401         }
402
403         void    setIslandTag(int tag)
404         {
405                 m_islandTag1 = tag;
406         }
407
408         SIMD_FORCE_INLINE int getCompanionId() const
409         {
410                 return  m_companionId;
411         }
412
413         void    setCompanionId(int id)
414         {
415                 m_companionId = id;
416         }
417
418         SIMD_FORCE_INLINE btScalar                      getHitFraction() const
419         {
420                 return m_hitFraction; 
421         }
422
423         void    setHitFraction(btScalar hitFraction)
424         {
425                 m_hitFraction = hitFraction;
426         }
427
428         
429         SIMD_FORCE_INLINE int   getCollisionFlags() const
430         {
431                 return m_collisionFlags;
432         }
433
434         void    setCollisionFlags(int flags)
435         {
436                 m_collisionFlags = flags;
437         }
438         
439         ///Swept sphere radius (0.0 by default), see btConvexConvexAlgorithm::
440         btScalar                        getCcdSweptSphereRadius() const
441         {
442                 return m_ccdSweptSphereRadius;
443         }
444
445         ///Swept sphere radius (0.0 by default), see btConvexConvexAlgorithm::
446         void    setCcdSweptSphereRadius(btScalar radius)
447         {
448                 m_ccdSweptSphereRadius = radius;
449         }
450
451         btScalar        getCcdMotionThreshold() const
452         {
453                 return m_ccdMotionThreshold;
454         }
455
456         btScalar        getCcdSquareMotionThreshold() const
457         {
458                 return m_ccdMotionThreshold*m_ccdMotionThreshold;
459         }
460
461
462
463         /// Don't do continuous collision detection if the motion (in one step) is less then m_ccdMotionThreshold
464         void    setCcdMotionThreshold(btScalar ccdMotionThreshold)
465         {
466                 m_ccdMotionThreshold = ccdMotionThreshold;
467         }
468
469         ///users can point to their objects, userPointer is not used by Bullet
470         void*   getUserPointer() const
471         {
472                 return m_userObjectPointer;
473         }
474
475         int     getUserIndex() const
476         {
477                 return m_userIndex;
478         }
479         ///users can point to their objects, userPointer is not used by Bullet
480         void    setUserPointer(void* userPointer)
481         {
482                 m_userObjectPointer = userPointer;
483         }
484
485         ///users can point to their objects, userPointer is not used by Bullet
486         void    setUserIndex(int index)
487         {
488                 m_userIndex = index;
489         }
490
491         int     getUpdateRevisionInternal() const
492         {
493                 return m_updateRevision;
494         }
495
496
497         inline bool checkCollideWith(const btCollisionObject* co) const
498         {
499                 if (m_checkCollideWith)
500                         return checkCollideWithOverride(co);
501
502                 return true;
503         }
504
505         virtual int     calculateSerializeBufferSize()  const;
506
507         ///fills the dataBuffer and returns the struct name (and 0 on failure)
508         virtual const char*     serialize(void* dataBuffer, class btSerializer* serializer) const;
509
510         virtual void serializeSingleObject(class btSerializer* serializer) const;
511
512 };
513
514 ///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64
515 struct  btCollisionObjectDoubleData
516 {
517         void                                    *m_broadphaseHandle;
518         void                                    *m_collisionShape;
519         btCollisionShapeData    *m_rootCollisionShape;
520         char                                    *m_name;
521
522         btTransformDoubleData   m_worldTransform;
523         btTransformDoubleData   m_interpolationWorldTransform;
524         btVector3DoubleData             m_interpolationLinearVelocity;
525         btVector3DoubleData             m_interpolationAngularVelocity;
526         btVector3DoubleData             m_anisotropicFriction;
527         double                                  m_contactProcessingThreshold;   
528         double                                  m_deactivationTime;
529         double                                  m_friction;
530         double                                  m_rollingFriction;
531         double                                  m_restitution;
532         double                                  m_hitFraction; 
533         double                                  m_ccdSweptSphereRadius;
534         double                                  m_ccdMotionThreshold;
535
536         int                                             m_hasAnisotropicFriction;
537         int                                             m_collisionFlags;
538         int                                             m_islandTag1;
539         int                                             m_companionId;
540         int                                             m_activationState1;
541         int                                             m_internalType;
542         int                                             m_checkCollideWith;
543
544         char    m_padding[4];
545 };
546
547 ///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64
548 struct  btCollisionObjectFloatData
549 {
550         void                                    *m_broadphaseHandle;
551         void                                    *m_collisionShape;
552         btCollisionShapeData    *m_rootCollisionShape;
553         char                                    *m_name;
554
555         btTransformFloatData    m_worldTransform;
556         btTransformFloatData    m_interpolationWorldTransform;
557         btVector3FloatData              m_interpolationLinearVelocity;
558         btVector3FloatData              m_interpolationAngularVelocity;
559         btVector3FloatData              m_anisotropicFriction;
560         float                                   m_contactProcessingThreshold;   
561         float                                   m_deactivationTime;
562         float                                   m_friction;
563         float                                   m_rollingFriction;
564
565         float                                   m_restitution;
566         float                                   m_hitFraction; 
567         float                                   m_ccdSweptSphereRadius;
568         float                                   m_ccdMotionThreshold;
569
570         int                                             m_hasAnisotropicFriction;
571         int                                             m_collisionFlags;
572         int                                             m_islandTag1;
573         int                                             m_companionId;
574         int                                             m_activationState1;
575         int                                             m_internalType;
576         int                                             m_checkCollideWith;
577         char                                    m_padding[4];
578 };
579
580
581
582 SIMD_FORCE_INLINE       int     btCollisionObject::calculateSerializeBufferSize() const
583 {
584         return sizeof(btCollisionObjectData);
585 }
586
587
588
589 #endif //BT_COLLISION_OBJECT_H