Bullet Collision Detection & Physics Library
btCollisionObject.h
Go to the documentation of this file.
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 #define FIXED_BASE_MULTI_BODY 6
28 
29 struct btBroadphaseProxy;
30 class btCollisionShape;
35 
37 
38 #ifdef BT_USE_DOUBLE_PRECISION
39 #define btCollisionObjectData btCollisionObjectDoubleData
40 #define btCollisionObjectDataName "btCollisionObjectDoubleData"
41 #else
42 #define btCollisionObjectData btCollisionObjectFloatData
43 #define btCollisionObjectDataName "btCollisionObjectFloatData"
44 #endif
45 
51 {
52 protected:
54 
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)
62 
66 
71 
76 
78 
81  int m_worldArrayIndex; // index of object in world's collisionObjects array
82 
83  mutable int m_activationState1;
85 
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)
92 
96 
98 
100 
102 
104 
106 
109 
112 
115 
118 
120 
123 
125 
126 public:
128 
130  {
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
143  };
144 
146  {
147  CO_COLLISION_OBJECT = 1,
148  CO_RIGID_BODY = 2,
151  CO_GHOST_OBJECT = 4,
152  CO_SOFT_BODY = 8,
153  CO_HF_FLUID = 16,
154  CO_USER_TYPE = 32,
155  CO_FEATHERSTONE_LINK = 64
156  };
157 
159  {
160  CF_ANISOTROPIC_FRICTION_DISABLED = 0,
161  CF_ANISOTROPIC_FRICTION = 1,
162  CF_ANISOTROPIC_ROLLING_FRICTION = 2
163  };
164 
166  {
168  return ((m_collisionFlags & (CF_STATIC_OBJECT | CF_KINEMATIC_OBJECT | CF_NO_CONTACT_RESPONSE)) == 0);
169  }
170 
172  {
173  return m_anisotropicFriction;
174  }
175  void setAnisotropicFriction(const btVector3& anisotropicFriction, int frictionMode = CF_ANISOTROPIC_FRICTION)
176  {
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;
180  }
181  bool hasAnisotropicFriction(int frictionMode = CF_ANISOTROPIC_FRICTION) const
182  {
183  return (m_hasAnisotropicFriction & frictionMode) != 0;
184  }
185 
188  void setContactProcessingThreshold(btScalar contactProcessingThreshold)
189  {
190  m_contactProcessingThreshold = contactProcessingThreshold;
191  }
193  {
194  return m_contactProcessingThreshold;
195  }
196 
198  {
199  return (m_collisionFlags & CF_STATIC_OBJECT) != 0;
200  }
201 
203  {
204  return (m_collisionFlags & CF_KINEMATIC_OBJECT) != 0;
205  }
206 
208  {
209  return (m_collisionFlags & (CF_KINEMATIC_OBJECT | CF_STATIC_OBJECT)) != 0;
210  }
211 
213  {
214  return (m_collisionFlags & CF_NO_CONTACT_RESPONSE) == 0;
215  }
216 
218 
219  virtual ~btCollisionObject();
220 
221  virtual void setCollisionShape(btCollisionShape * collisionShape)
222  {
223  m_updateRevision++;
224  m_collisionShape = collisionShape;
225  m_rootCollisionShape = collisionShape;
226  }
227 
229  {
230  return m_collisionShape;
231  }
232 
234  {
235  return m_collisionShape;
236  }
237 
238  void setIgnoreCollisionCheck(const btCollisionObject* co, bool ignoreCollisionCheck)
239  {
240  if (ignoreCollisionCheck)
241  {
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())
245  //{
246  m_objectsWithoutCollisionCheck.push_back(co);
247  //}
248  }
249  else
250  {
251  m_objectsWithoutCollisionCheck.remove(co);
252  }
253  m_checkCollideWith = m_objectsWithoutCollisionCheck.size() > 0;
254  }
255 
257  {
258  return m_objectsWithoutCollisionCheck.size();
259  }
260 
262  {
263  return m_objectsWithoutCollisionCheck[index];
264  }
265 
266  virtual bool checkCollideWithOverride(const btCollisionObject* co) const
267  {
268  int index = m_objectsWithoutCollisionCheck.findLinearSearch(co);
269  if (index < m_objectsWithoutCollisionCheck.size())
270  {
271  return false;
272  }
273  return true;
274  }
275 
279  {
280  return m_extensionPointer;
281  }
284  void internalSetExtensionPointer(void* pointer)
285  {
286  m_extensionPointer = pointer;
287  }
288 
289  SIMD_FORCE_INLINE int getActivationState() const { return m_activationState1; }
290 
291  void setActivationState(int newState) const;
292 
294  {
295  m_deactivationTime = time;
296  }
298  {
299  return m_deactivationTime;
300  }
301 
302  void forceActivationState(int newState) const;
303 
304  void activate(bool forceActivation = false) const;
305 
307  {
308  return ((getActivationState() != FIXED_BASE_MULTI_BODY) && (getActivationState() != ISLAND_SLEEPING) && (getActivationState() != DISABLE_SIMULATION));
309  }
310 
312  {
313  m_updateRevision++;
314  m_restitution = rest;
315  }
317  {
318  return m_restitution;
319  }
320  void setFriction(btScalar frict)
321  {
322  m_updateRevision++;
323  m_friction = frict;
324  }
326  {
327  return m_friction;
328  }
329 
331  {
332  m_updateRevision++;
333  m_rollingFriction = frict;
334  }
336  {
337  return m_rollingFriction;
338  }
340  {
341  m_updateRevision++;
342  m_spinningFriction = frict;
343  }
345  {
346  return m_spinningFriction;
347  }
349  {
350  m_updateRevision++;
351  m_contactStiffness = stiffness;
352  m_contactDamping = damping;
353 
354  m_collisionFlags |= CF_HAS_CONTACT_STIFFNESS_DAMPING;
355 
356  //avoid divisions by zero...
357  if (m_contactStiffness < SIMD_EPSILON)
358  {
359  m_contactStiffness = SIMD_EPSILON;
360  }
361  }
362 
364  {
365  return m_contactStiffness;
366  }
367 
369  {
370  return m_contactDamping;
371  }
372 
374  int getInternalType() const
375  {
376  return m_internalType;
377  }
378 
380  {
381  return m_worldTransform;
382  }
383 
385  {
386  return m_worldTransform;
387  }
388 
389  void setWorldTransform(const btTransform& worldTrans)
390  {
391  m_updateRevision++;
392  m_worldTransform = worldTrans;
393  }
394 
396  {
397  return m_broadphaseHandle;
398  }
399 
401  {
402  return m_broadphaseHandle;
403  }
404 
406  {
407  m_broadphaseHandle = handle;
408  }
409 
411  {
412  return m_interpolationWorldTransform;
413  }
414 
416  {
417  return m_interpolationWorldTransform;
418  }
419 
421  {
422  m_updateRevision++;
423  m_interpolationWorldTransform = trans;
424  }
425 
427  {
428  m_updateRevision++;
429  m_interpolationLinearVelocity = linvel;
430  }
431 
433  {
434  m_updateRevision++;
435  m_interpolationAngularVelocity = angvel;
436  }
437 
439  {
440  return m_interpolationLinearVelocity;
441  }
442 
444  {
445  return m_interpolationAngularVelocity;
446  }
447 
449  {
450  return m_islandTag1;
451  }
452 
453  void setIslandTag(int tag)
454  {
455  m_islandTag1 = tag;
456  }
457 
459  {
460  return m_companionId;
461  }
462 
463  void setCompanionId(int id)
464  {
465  m_companionId = id;
466  }
467 
469  {
470  return m_worldArrayIndex;
471  }
472 
473  // only should be called by CollisionWorld
474  void setWorldArrayIndex(int ix)
475  {
476  m_worldArrayIndex = ix;
477  }
478 
480  {
481  return m_hitFraction;
482  }
483 
484  void setHitFraction(btScalar hitFraction)
485  {
486  m_hitFraction = hitFraction;
487  }
488 
490  {
491  return m_collisionFlags;
492  }
493 
494  void setCollisionFlags(int flags)
495  {
496  m_collisionFlags = flags;
497  }
498 
501  {
502  return m_ccdSweptSphereRadius;
503  }
504 
507  {
508  m_ccdSweptSphereRadius = radius;
509  }
510 
512  {
513  return m_ccdMotionThreshold;
514  }
515 
517  {
518  return m_ccdMotionThreshold * m_ccdMotionThreshold;
519  }
520 
522  void setCcdMotionThreshold(btScalar ccdMotionThreshold)
523  {
524  m_ccdMotionThreshold = ccdMotionThreshold;
525  }
526 
528  void* getUserPointer() const
529  {
530  return m_userObjectPointer;
531  }
532 
533  int getUserIndex() const
534  {
535  return m_userIndex;
536  }
537 
538  int getUserIndex2() const
539  {
540  return m_userIndex2;
541  }
542 
543  int getUserIndex3() const
544  {
545  return m_userIndex3;
546  }
547 
549  void setUserPointer(void* userPointer)
550  {
551  m_userObjectPointer = userPointer;
552  }
553 
555  void setUserIndex(int index)
556  {
557  m_userIndex = index;
558  }
559 
560  void setUserIndex2(int index)
561  {
562  m_userIndex2 = index;
563  }
564 
565  void setUserIndex3(int index)
566  {
567  m_userIndex3 = index;
568  }
569 
571  {
572  return m_updateRevision;
573  }
574 
575  void setCustomDebugColor(const btVector3& colorRGB)
576  {
577  m_customDebugColorRGB = colorRGB;
578  m_collisionFlags |= CF_HAS_CUSTOM_DEBUG_RENDERING_COLOR;
579  }
580 
582  {
583  m_collisionFlags &= ~CF_HAS_CUSTOM_DEBUG_RENDERING_COLOR;
584  }
585 
586  bool getCustomDebugColor(btVector3 & colorRGB) const
587  {
588  bool hasCustomColor = (0 != (m_collisionFlags & CF_HAS_CUSTOM_DEBUG_RENDERING_COLOR));
589  if (hasCustomColor)
590  {
591  colorRGB = m_customDebugColorRGB;
592  }
593  return hasCustomColor;
594  }
595 
596  inline bool checkCollideWith(const btCollisionObject* co) const
597  {
598  if (m_checkCollideWith)
599  return checkCollideWithOverride(co);
600 
601  return true;
602  }
603 
604  virtual int calculateSerializeBufferSize() const;
605 
607  virtual const char* serialize(void* dataBuffer, class btSerializer* serializer) const;
608 
609  virtual void serializeSingleObject(class btSerializer * serializer) const;
610 };
611 
612 // clang-format off
613 
616 {
620  char *m_name;
621 
629  double m_friction;
634  double m_hitFraction;
646  int m_uniqueId;//m_uniqueId is introduced for paircache. could get rid of this, by calculating the address offset etc.
647 };
648 
651 {
655  char *m_name;
656 
664  float m_friction;
682 };
683 // clang-format on
684 
686 {
687  return sizeof(btCollisionObjectData);
688 }
689 
690 #endif //BT_COLLISION_OBJECT_H
#define btCollisionObjectData
#define FIXED_BASE_MULTI_BODY
btAlignedObjectArray< class btCollisionObject * > btCollisionObjectArray
#define ISLAND_SLEEPING
#define DISABLE_SIMULATION
float btScalar
The btScalar type abstracts floating point numbers, to easily switch between double and single floati...
Definition: btScalar.h:314
#define ATTRIBUTE_ALIGNED16(a)
Definition: btScalar.h:99
#define SIMD_FORCE_INLINE
Definition: btScalar.h:98
#define SIMD_EPSILON
Definition: btScalar.h:543
The btAlignedObjectArray template class uses a subset of the stl::vector interface for its methods It...
int size() const
return the number of elements in the array
int findLinearSearch(const T &key) const
void remove(const T &key)
void push_back(const T &_Val)
btCollisionObject can be used to manage collision detection objects.
btScalar getContactStiffness() const
void setRestitution(btScalar rest)
int m_updateRevision
internal update revision number. It will be increased when the object changes. This allows some subsy...
virtual bool checkCollideWithOverride(const btCollisionObject *co) const
const btTransform & getInterpolationWorldTransform() const
void setSpinningFriction(btScalar frict)
bool isStaticOrKinematicObject() const
btScalar getHitFraction() const
void setAnisotropicFriction(const btVector3 &anisotropicFriction, int frictionMode=CF_ANISOTROPIC_FRICTION)
void setWorldArrayIndex(int ix)
void setCollisionFlags(int flags)
btTransform & getWorldTransform()
int m_checkCollideWith
If some object should have elaborate collision filtering by sub-classes.
const btVector3 & getInterpolationAngularVelocity() const
btBroadphaseProxy * getBroadphaseHandle()
int getUserIndex3() const
const btVector3 & getInterpolationLinearVelocity() const
btTransform m_worldTransform
btCollisionShape * m_collisionShape
int getUserIndex2() const
void setUserPointer(void *userPointer)
users can point to their objects, userPointer is not used by Bullet
const btVector3 & getAnisotropicFriction() const
int getInternalType() const
reserved for Bullet internal usage
int getUserIndex() const
virtual void setCollisionShape(btCollisionShape *collisionShape)
btScalar getDeactivationTime() const
bool hasContactResponse() const
btVector3 m_interpolationLinearVelocity
void setIgnoreCollisionCheck(const btCollisionObject *co, bool ignoreCollisionCheck)
btScalar getSpinningFriction() const
const btBroadphaseProxy * getBroadphaseHandle() const
bool isStaticObject() const
void setContactProcessingThreshold(btScalar contactProcessingThreshold)
the constraint solver can discard solving contacts, if the distance is above this threshold.
btCollisionShape * m_rootCollisionShape
m_rootCollisionShape is temporarily used to store the original collision shape The m_collisionShape m...
void * m_extensionPointer
m_extensionPointer is used by some internal low-level Bullet extensions.
bool checkCollideWith(const btCollisionObject *co) const
btVector3 m_interpolationAngularVelocity
bool getCustomDebugColor(btVector3 &colorRGB) const
int m_internalType
m_internalType is reserved to distinguish Bullet's btCollisionObject, btRigidBody,...
void setWorldTransform(const btTransform &worldTrans)
void * m_userObjectPointer
users can point to their objects, m_userPointer is not used by Bullet, see setUserPointer/getUserPoin...
void setCustomDebugColor(const btVector3 &colorRGB)
btScalar getFriction() const
btVector3 m_anisotropicFriction
btScalar getContactProcessingThreshold() const
int getWorldArrayIndex() const
void setCcdMotionThreshold(btScalar ccdMotionThreshold)
Don't do continuous collision detection if the motion (in one step) is less then m_ccdMotionThreshold...
btScalar m_ccdSweptSphereRadius
Swept sphere radius (0.0 by default), see btConvexConvexAlgorithm::
bool hasAnisotropicFriction(int frictionMode=CF_ANISOTROPIC_FRICTION) const
virtual int calculateSerializeBufferSize() const
const btTransform & getWorldTransform() const
btTransform m_interpolationWorldTransform
m_interpolationWorldTransform is used for CCD and interpolation it can be either previous or future (...
void setCompanionId(int id)
int getNumObjectsWithoutCollision() const
bool isKinematicObject() const
btScalar getContactDamping() const
int getIslandTag() const
int getCompanionId() const
void setUserIndex2(int index)
void setFriction(btScalar frict)
void * getUserPointer() const
users can point to their objects, userPointer is not used by Bullet
void internalSetExtensionPointer(void *pointer)
Avoid using this internal API call, the extension pointer is used by some Bullet extensions If you ne...
btAlignedObjectArray< const btCollisionObject * > m_objectsWithoutCollisionCheck
void setCcdSweptSphereRadius(btScalar radius)
Swept sphere radius (0.0 by default), see btConvexConvexAlgorithm::
void setContactStiffnessAndDamping(btScalar stiffness, btScalar damping)
void setDeactivationTime(btScalar time)
btCollisionShape * getCollisionShape()
bool mergesSimulationIslands() const
btScalar m_ccdMotionThreshold
Don't do continuous collision detection if the motion (in one step) is less then m_ccdMotionThreshold...
btScalar m_contactProcessingThreshold
void setRollingFriction(btScalar frict)
void setIslandTag(int tag)
void setBroadphaseHandle(btBroadphaseProxy *handle)
btBroadphaseProxy * m_broadphaseHandle
const btCollisionObject * getObjectWithoutCollision(int index)
int getCollisionFlags() const
void setInterpolationAngularVelocity(const btVector3 &angvel)
btScalar getCcdMotionThreshold() const
void setHitFraction(btScalar hitFraction)
void * internalGetExtensionPointer() const
Avoid using this internal API call, the extension pointer is used by some Bullet extensions.
btVector3 m_customDebugColorRGB
void setInterpolationLinearVelocity(const btVector3 &linvel)
btTransform & getInterpolationWorldTransform()
btScalar m_hitFraction
time of impact calculation
int getUpdateRevisionInternal() const
void setUserIndex(int index)
users can point to their objects, userPointer is not used by Bullet
btScalar getRestitution() const
int getActivationState() const
btScalar getRollingFriction() const
btScalar getCcdSquareMotionThreshold() const
void setInterpolationWorldTransform(const btTransform &trans)
const btCollisionShape * getCollisionShape() const
void setUserIndex3(int index)
btScalar getCcdSweptSphereRadius() const
Swept sphere radius (0.0 by default), see btConvexConvexAlgorithm::
The btCollisionShape class provides an interface for collision shapes that can be shared among btColl...
The btTransform class supports rigid transforms with only translation and rotation and no scaling/she...
Definition: btTransform.h:30
btVector3 can be used to represent 3D points and vectors.
Definition: btVector3.h:82
The btBroadphaseProxy is the main class that can be used with the Bullet broadphases.
do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64
btVector3DoubleData m_anisotropicFriction
btVector3DoubleData m_interpolationLinearVelocity
btTransformDoubleData m_interpolationWorldTransform
btTransformDoubleData m_worldTransform
btVector3DoubleData m_interpolationAngularVelocity
btCollisionShapeData * m_rootCollisionShape
do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64
btVector3FloatData m_interpolationLinearVelocity
btVector3FloatData m_anisotropicFriction
btTransformFloatData m_interpolationWorldTransform
btVector3FloatData m_interpolationAngularVelocity
btTransformFloatData m_worldTransform
btCollisionShapeData * m_rootCollisionShape
do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64
for serialization
Definition: btTransform.h:245