2 Bullet Continuous Collision Detection and Physics Library
3 Copyright (c) 2003-2006 Erwin Coumans https://bulletphysics.org
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:
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.
16 #ifndef BT_COLLISION_OBJECT_H
17 #define BT_COLLISION_OBJECT_H
19 #include "LinearMath/btTransform.h"
21 //island management, m_activationState1
23 #define ISLAND_SLEEPING 2
24 #define WANTS_DEACTIVATION 3
25 #define DISABLE_DEACTIVATION 4
26 #define DISABLE_SIMULATION 5
27 #define FIXED_BASE_MULTI_BODY 6
29 struct btBroadphaseProxy;
30 class btCollisionShape;
31 struct btCollisionShapeData;
32 #include "LinearMath/btMotionState.h"
33 #include "LinearMath/btAlignedAllocator.h"
34 #include "LinearMath/btAlignedObjectArray.h"
36 typedef btAlignedObjectArray<class btCollisionObject*> btCollisionObjectArray;
38 #ifdef BT_USE_DOUBLE_PRECISION
39 #define btCollisionObjectData btCollisionObjectDoubleData
40 #define btCollisionObjectDataName "btCollisionObjectDoubleData"
42 #define btCollisionObjectData btCollisionObjectFloatData
43 #define btCollisionObjectDataName "btCollisionObjectFloatData"
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)
53 btTransform m_worldTransform;
55 ///m_interpolationWorldTransform is used for CCD and interpolation
56 ///it can be either previous or future (predicted) transform
57 btTransform m_interpolationWorldTransform;
58 //those two are experimental: just added for bullet time effect, so you can still apply impulses (directly modifying velocities)
59 //without destroying the continuous interpolated motion (which uses this interpolation velocities)
60 btVector3 m_interpolationLinearVelocity;
61 btVector3 m_interpolationAngularVelocity;
63 btVector3 m_anisotropicFriction;
64 int m_hasAnisotropicFriction;
65 btScalar m_contactProcessingThreshold;
67 btBroadphaseProxy* m_broadphaseHandle;
68 btCollisionShape* m_collisionShape;
69 ///m_extensionPointer is used by some internal low-level Bullet extensions.
70 void* m_extensionPointer;
72 ///m_rootCollisionShape is temporarily used to store the original collision shape
73 ///The m_collisionShape might be temporarily replaced by a child collision shape during collision detection purposes
74 ///If it is NULL, the m_collisionShape is not temporarily replaced.
75 btCollisionShape* m_rootCollisionShape;
81 int m_worldArrayIndex; // index of object in world's collisionObjects array
83 mutable int m_activationState1;
84 mutable btScalar m_deactivationTime;
87 btScalar m_restitution;
88 btScalar m_rollingFriction; //torsional friction orthogonal to contact normal (useful to stop spheres rolling forever)
89 btScalar m_spinningFriction; // torsional friction around the contact normal (useful for grasping)
90 btScalar m_contactDamping;
91 btScalar m_contactStiffness;
93 ///m_internalType is reserved to distinguish Bullet's btCollisionObject, btRigidBody, btSoftBody, btGhostObject etc.
94 ///do not assign your own m_internalType unless you write a new dynamics object class.
97 ///users can point to their objects, m_userPointer is not used by Bullet, see setUserPointer/getUserPointer
99 void* m_userObjectPointer;
107 ///time of impact calculation
108 btScalar m_hitFraction;
110 ///Swept sphere radius (0.0 by default), see btConvexConvexAlgorithm::
111 btScalar m_ccdSweptSphereRadius;
113 /// Don't do continuous collision detection if the motion (in one step) is less then m_ccdMotionThreshold
114 btScalar m_ccdMotionThreshold;
116 /// If some object should have elaborate collision filtering by sub-classes
117 int m_checkCollideWith;
119 btAlignedObjectArray<const btCollisionObject*> m_objectsWithoutCollisionCheck;
121 ///internal update revision number. It will be increased when the object changes. This allows some subsystems to perform lazy evaluation.
122 int m_updateRevision;
124 btVector3 m_customDebugColorRGB;
127 BT_DECLARE_ALIGNED_ALLOCATOR();
131 CF_DYNAMIC_OBJECT = 0,
132 CF_STATIC_OBJECT = 1,
133 CF_KINEMATIC_OBJECT = 2,
134 CF_NO_CONTACT_RESPONSE = 4,
135 CF_CUSTOM_MATERIAL_CALLBACK = 8, //this allows per-triangle material (friction/restitution)
136 CF_CHARACTER_OBJECT = 16,
137 CF_DISABLE_VISUALIZE_OBJECT = 32, //disable debug drawing
138 CF_DISABLE_SPU_COLLISION_PROCESSING = 64, //disable parallel/SPU processing
139 CF_HAS_CONTACT_STIFFNESS_DAMPING = 128,
140 CF_HAS_CUSTOM_DEBUG_RENDERING_COLOR = 256,
141 CF_HAS_FRICTION_ANCHOR = 512,
142 CF_HAS_COLLISION_SOUND_TRIGGER = 1024
145 enum CollisionObjectTypes
147 CO_COLLISION_OBJECT = 1,
149 ///CO_GHOST_OBJECT keeps track of all objects overlapping its AABB and that pass its collision filter
150 ///It is useful for collision sensors, explosion objects, character controller etc.
155 CO_FEATHERSTONE_LINK = 64
158 enum AnisotropicFrictionFlags
160 CF_ANISOTROPIC_FRICTION_DISABLED = 0,
161 CF_ANISOTROPIC_FRICTION = 1,
162 CF_ANISOTROPIC_ROLLING_FRICTION = 2
165 SIMD_FORCE_INLINE bool mergesSimulationIslands() const
167 ///static objects, kinematic and object without contact response don't merge islands
168 return ((m_collisionFlags & (CF_STATIC_OBJECT | CF_KINEMATIC_OBJECT | CF_NO_CONTACT_RESPONSE)) == 0);
171 const btVector3& getAnisotropicFriction() const
173 return m_anisotropicFriction;
175 void setAnisotropicFriction(const btVector3& anisotropicFriction, int frictionMode = CF_ANISOTROPIC_FRICTION)
177 m_anisotropicFriction = anisotropicFriction;
178 bool isUnity = (anisotropicFriction[0] != 1.f) || (anisotropicFriction[1] != 1.f) || (anisotropicFriction[2] != 1.f);
179 m_hasAnisotropicFriction = isUnity ? frictionMode : 0;
181 bool hasAnisotropicFriction(int frictionMode = CF_ANISOTROPIC_FRICTION) const
183 return (m_hasAnisotropicFriction & frictionMode) != 0;
186 ///the constraint solver can discard solving contacts, if the distance is above this threshold. 0 by default.
187 ///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
188 void setContactProcessingThreshold(btScalar contactProcessingThreshold)
190 m_contactProcessingThreshold = contactProcessingThreshold;
192 btScalar getContactProcessingThreshold() const
194 return m_contactProcessingThreshold;
197 SIMD_FORCE_INLINE bool isStaticObject() const
199 return (m_collisionFlags & CF_STATIC_OBJECT) != 0;
202 SIMD_FORCE_INLINE bool isKinematicObject() const
204 return (m_collisionFlags & CF_KINEMATIC_OBJECT) != 0;
207 SIMD_FORCE_INLINE bool isStaticOrKinematicObject() const
209 return (m_collisionFlags & (CF_KINEMATIC_OBJECT | CF_STATIC_OBJECT)) != 0;
212 SIMD_FORCE_INLINE bool hasContactResponse() const
214 return (m_collisionFlags & CF_NO_CONTACT_RESPONSE) == 0;
219 virtual ~btCollisionObject();
221 virtual void setCollisionShape(btCollisionShape * collisionShape)
224 m_collisionShape = collisionShape;
225 m_rootCollisionShape = collisionShape;
228 SIMD_FORCE_INLINE const btCollisionShape* getCollisionShape() const
230 return m_collisionShape;
233 SIMD_FORCE_INLINE btCollisionShape* getCollisionShape()
235 return m_collisionShape;
238 void setIgnoreCollisionCheck(const btCollisionObject* co, bool ignoreCollisionCheck)
240 if (ignoreCollisionCheck)
242 //We don't check for duplicates. Is it ok to leave that up to the user of this API?
243 //int index = m_objectsWithoutCollisionCheck.findLinearSearch(co);
244 //if (index == m_objectsWithoutCollisionCheck.size())
246 m_objectsWithoutCollisionCheck.push_back(co);
251 m_objectsWithoutCollisionCheck.remove(co);
253 m_checkCollideWith = m_objectsWithoutCollisionCheck.size() > 0;
256 int getNumObjectsWithoutCollision() const
258 return m_objectsWithoutCollisionCheck.size();
261 const btCollisionObject* getObjectWithoutCollision(int index)
263 return m_objectsWithoutCollisionCheck[index];
266 virtual bool checkCollideWithOverride(const btCollisionObject* co) const
268 int index = m_objectsWithoutCollisionCheck.findLinearSearch(co);
269 if (index < m_objectsWithoutCollisionCheck.size())
276 ///Avoid using this internal API call, the extension pointer is used by some Bullet extensions.
277 ///If you need to store your own user pointer, use 'setUserPointer/getUserPointer' instead.
278 void* internalGetExtensionPointer() const
280 return m_extensionPointer;
282 ///Avoid using this internal API call, the extension pointer is used by some Bullet extensions
283 ///If you need to store your own user pointer, use 'setUserPointer/getUserPointer' instead.
284 void internalSetExtensionPointer(void* pointer)
286 m_extensionPointer = pointer;
289 SIMD_FORCE_INLINE int getActivationState() const { return m_activationState1; }
291 void setActivationState(int newState) const;
293 void setDeactivationTime(btScalar time)
295 m_deactivationTime = time;
297 btScalar getDeactivationTime() const
299 return m_deactivationTime;
302 void forceActivationState(int newState) const;
304 void activate(bool forceActivation = false) const;
306 SIMD_FORCE_INLINE bool isActive() const
308 return ((getActivationState() != FIXED_BASE_MULTI_BODY) && (getActivationState() != ISLAND_SLEEPING) && (getActivationState() != DISABLE_SIMULATION));
311 void setRestitution(btScalar rest)
314 m_restitution = rest;
316 btScalar getRestitution() const
318 return m_restitution;
320 void setFriction(btScalar frict)
325 btScalar getFriction() const
330 void setRollingFriction(btScalar frict)
333 m_rollingFriction = frict;
335 btScalar getRollingFriction() const
337 return m_rollingFriction;
339 void setSpinningFriction(btScalar frict)
342 m_spinningFriction = frict;
344 btScalar getSpinningFriction() const
346 return m_spinningFriction;
348 void setContactStiffnessAndDamping(btScalar stiffness, btScalar damping)
351 m_contactStiffness = stiffness;
352 m_contactDamping = damping;
354 m_collisionFlags |= CF_HAS_CONTACT_STIFFNESS_DAMPING;
356 //avoid divisions by zero...
357 if (m_contactStiffness < SIMD_EPSILON)
359 m_contactStiffness = SIMD_EPSILON;
363 btScalar getContactStiffness() const
365 return m_contactStiffness;
368 btScalar getContactDamping() const
370 return m_contactDamping;
373 ///reserved for Bullet internal usage
374 int getInternalType() const
376 return m_internalType;
379 btTransform& getWorldTransform()
381 return m_worldTransform;
384 const btTransform& getWorldTransform() const
386 return m_worldTransform;
389 void setWorldTransform(const btTransform& worldTrans)
392 m_worldTransform = worldTrans;
395 SIMD_FORCE_INLINE btBroadphaseProxy* getBroadphaseHandle()
397 return m_broadphaseHandle;
400 SIMD_FORCE_INLINE const btBroadphaseProxy* getBroadphaseHandle() const
402 return m_broadphaseHandle;
405 void setBroadphaseHandle(btBroadphaseProxy * handle)
407 m_broadphaseHandle = handle;
410 const btTransform& getInterpolationWorldTransform() const
412 return m_interpolationWorldTransform;
415 btTransform& getInterpolationWorldTransform()
417 return m_interpolationWorldTransform;
420 void setInterpolationWorldTransform(const btTransform& trans)
423 m_interpolationWorldTransform = trans;
426 void setInterpolationLinearVelocity(const btVector3& linvel)
429 m_interpolationLinearVelocity = linvel;
432 void setInterpolationAngularVelocity(const btVector3& angvel)
435 m_interpolationAngularVelocity = angvel;
438 const btVector3& getInterpolationLinearVelocity() const
440 return m_interpolationLinearVelocity;
443 const btVector3& getInterpolationAngularVelocity() const
445 return m_interpolationAngularVelocity;
448 SIMD_FORCE_INLINE int getIslandTag() const
453 void setIslandTag(int tag)
458 SIMD_FORCE_INLINE int getCompanionId() const
460 return m_companionId;
463 void setCompanionId(int id)
468 SIMD_FORCE_INLINE int getWorldArrayIndex() const
470 return m_worldArrayIndex;
473 // only should be called by CollisionWorld
474 void setWorldArrayIndex(int ix)
476 m_worldArrayIndex = ix;
479 SIMD_FORCE_INLINE btScalar getHitFraction() const
481 return m_hitFraction;
484 void setHitFraction(btScalar hitFraction)
486 m_hitFraction = hitFraction;
489 SIMD_FORCE_INLINE int getCollisionFlags() const
491 return m_collisionFlags;
494 void setCollisionFlags(int flags)
496 m_collisionFlags = flags;
499 ///Swept sphere radius (0.0 by default), see btConvexConvexAlgorithm::
500 btScalar getCcdSweptSphereRadius() const
502 return m_ccdSweptSphereRadius;
505 ///Swept sphere radius (0.0 by default), see btConvexConvexAlgorithm::
506 void setCcdSweptSphereRadius(btScalar radius)
508 m_ccdSweptSphereRadius = radius;
511 btScalar getCcdMotionThreshold() const
513 return m_ccdMotionThreshold;
516 btScalar getCcdSquareMotionThreshold() const
518 return m_ccdMotionThreshold * m_ccdMotionThreshold;
521 /// Don't do continuous collision detection if the motion (in one step) is less then m_ccdMotionThreshold
522 void setCcdMotionThreshold(btScalar ccdMotionThreshold)
524 m_ccdMotionThreshold = ccdMotionThreshold;
527 ///users can point to their objects, userPointer is not used by Bullet
528 void* getUserPointer() const
530 return m_userObjectPointer;
533 int getUserIndex() const
538 int getUserIndex2() const
543 int getUserIndex3() const
548 ///users can point to their objects, userPointer is not used by Bullet
549 void setUserPointer(void* userPointer)
551 m_userObjectPointer = userPointer;
554 ///users can point to their objects, userPointer is not used by Bullet
555 void setUserIndex(int index)
560 void setUserIndex2(int index)
562 m_userIndex2 = index;
565 void setUserIndex3(int index)
567 m_userIndex3 = index;
570 int getUpdateRevisionInternal() const
572 return m_updateRevision;
575 void setCustomDebugColor(const btVector3& colorRGB)
577 m_customDebugColorRGB = colorRGB;
578 m_collisionFlags |= CF_HAS_CUSTOM_DEBUG_RENDERING_COLOR;
581 void removeCustomDebugColor()
583 m_collisionFlags &= ~CF_HAS_CUSTOM_DEBUG_RENDERING_COLOR;
586 bool getCustomDebugColor(btVector3 & colorRGB) const
588 bool hasCustomColor = (0 != (m_collisionFlags & CF_HAS_CUSTOM_DEBUG_RENDERING_COLOR));
591 colorRGB = m_customDebugColorRGB;
593 return hasCustomColor;
596 inline bool checkCollideWith(const btCollisionObject* co) const
598 if (m_checkCollideWith)
599 return checkCollideWithOverride(co);
604 virtual int calculateSerializeBufferSize() const;
606 ///fills the dataBuffer and returns the struct name (and 0 on failure)
607 virtual const char* serialize(void* dataBuffer, class btSerializer* serializer) const;
609 virtual void serializeSingleObject(class btSerializer * serializer) const;
614 ///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64
615 struct btCollisionObjectDoubleData
617 void *m_broadphaseHandle;
618 void *m_collisionShape;
619 btCollisionShapeData *m_rootCollisionShape;
622 btTransformDoubleData m_worldTransform;
623 btTransformDoubleData m_interpolationWorldTransform;
624 btVector3DoubleData m_interpolationLinearVelocity;
625 btVector3DoubleData m_interpolationAngularVelocity;
626 btVector3DoubleData m_anisotropicFriction;
627 double m_contactProcessingThreshold;
628 double m_deactivationTime;
630 double m_rollingFriction;
631 double m_contactDamping;
632 double m_contactStiffness;
633 double m_restitution;
634 double m_hitFraction;
635 double m_ccdSweptSphereRadius;
636 double m_ccdMotionThreshold;
637 int m_hasAnisotropicFriction;
638 int m_collisionFlags;
641 int m_activationState1;
643 int m_checkCollideWith;
644 int m_collisionFilterGroup;
645 int m_collisionFilterMask;
646 int m_uniqueId;//m_uniqueId is introduced for paircache. could get rid of this, by calculating the address offset etc.
649 ///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64
650 struct btCollisionObjectFloatData
652 void *m_broadphaseHandle;
653 void *m_collisionShape;
654 btCollisionShapeData *m_rootCollisionShape;
657 btTransformFloatData m_worldTransform;
658 btTransformFloatData m_interpolationWorldTransform;
659 btVector3FloatData m_interpolationLinearVelocity;
660 btVector3FloatData m_interpolationAngularVelocity;
661 btVector3FloatData m_anisotropicFriction;
662 float m_contactProcessingThreshold;
663 float m_deactivationTime;
665 float m_rollingFriction;
666 float m_contactDamping;
667 float m_contactStiffness;
670 float m_ccdSweptSphereRadius;
671 float m_ccdMotionThreshold;
672 int m_hasAnisotropicFriction;
673 int m_collisionFlags;
676 int m_activationState1;
678 int m_checkCollideWith;
679 int m_collisionFilterGroup;
680 int m_collisionFilterMask;
685 SIMD_FORCE_INLINE int btCollisionObject::calculateSerializeBufferSize() const
687 return sizeof(btCollisionObjectData);
690 #endif //BT_COLLISION_OBJECT_H