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 
28 struct btBroadphaseProxy;
29 class btCollisionShape;
34 
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 
50 {
51 protected:
53 
57  //those two are experimental: just added for bullet time effect, so you can still apply impulses (directly modifying velocities)
58  //without destroying the continuous interpolated motion (which uses this interpolation velocities)
61 
65 
70 
75 
77 
80  int m_worldArrayIndex; // index of object in world's collisionObjects array
81 
82  mutable int m_activationState1;
84 
87  btScalar m_rollingFriction; //torsional friction orthogonal to contact normal (useful to stop spheres rolling forever)
88  btScalar m_spinningFriction; // torsional friction around the contact normal (useful for grasping)
91 
95 
97 
99 
101 
103 
105 
108 
111 
114 
117 
119 
122 
124 
125 public:
127 
129  {
130  CF_DYNAMIC_OBJECT = 0,
131  CF_STATIC_OBJECT = 1,
132  CF_KINEMATIC_OBJECT = 2,
133  CF_NO_CONTACT_RESPONSE = 4,
134  CF_CUSTOM_MATERIAL_CALLBACK = 8, //this allows per-triangle material (friction/restitution)
135  CF_CHARACTER_OBJECT = 16,
136  CF_DISABLE_VISUALIZE_OBJECT = 32, //disable debug drawing
137  CF_DISABLE_SPU_COLLISION_PROCESSING = 64, //disable parallel/SPU processing
138  CF_HAS_CONTACT_STIFFNESS_DAMPING = 128,
139  CF_HAS_CUSTOM_DEBUG_RENDERING_COLOR = 256,
140  CF_HAS_FRICTION_ANCHOR = 512,
141  CF_HAS_COLLISION_SOUND_TRIGGER = 1024
142  };
143 
145  {
146  CO_COLLISION_OBJECT = 1,
147  CO_RIGID_BODY = 2,
150  CO_GHOST_OBJECT = 4,
151  CO_SOFT_BODY = 8,
152  CO_HF_FLUID = 16,
153  CO_USER_TYPE = 32,
154  CO_FEATHERSTONE_LINK = 64
155  };
156 
158  {
159  CF_ANISOTROPIC_FRICTION_DISABLED = 0,
160  CF_ANISOTROPIC_FRICTION = 1,
161  CF_ANISOTROPIC_ROLLING_FRICTION = 2
162  };
163 
165  {
167  return ((m_collisionFlags & (CF_STATIC_OBJECT | CF_KINEMATIC_OBJECT | CF_NO_CONTACT_RESPONSE)) == 0);
168  }
169 
171  {
172  return m_anisotropicFriction;
173  }
174  void setAnisotropicFriction(const btVector3& anisotropicFriction, int frictionMode = CF_ANISOTROPIC_FRICTION)
175  {
176  m_anisotropicFriction = anisotropicFriction;
177  bool isUnity = (anisotropicFriction[0] != 1.f) || (anisotropicFriction[1] != 1.f) || (anisotropicFriction[2] != 1.f);
178  m_hasAnisotropicFriction = isUnity ? frictionMode : 0;
179  }
180  bool hasAnisotropicFriction(int frictionMode = CF_ANISOTROPIC_FRICTION) const
181  {
182  return (m_hasAnisotropicFriction & frictionMode) != 0;
183  }
184 
187  void setContactProcessingThreshold(btScalar contactProcessingThreshold)
188  {
189  m_contactProcessingThreshold = contactProcessingThreshold;
190  }
192  {
193  return m_contactProcessingThreshold;
194  }
195 
197  {
198  return (m_collisionFlags & CF_STATIC_OBJECT) != 0;
199  }
200 
202  {
203  return (m_collisionFlags & CF_KINEMATIC_OBJECT) != 0;
204  }
205 
207  {
208  return (m_collisionFlags & (CF_KINEMATIC_OBJECT | CF_STATIC_OBJECT)) != 0;
209  }
210 
212  {
213  return (m_collisionFlags & CF_NO_CONTACT_RESPONSE) == 0;
214  }
215 
217 
218  virtual ~btCollisionObject();
219 
220  virtual void setCollisionShape(btCollisionShape * collisionShape)
221  {
222  m_updateRevision++;
223  m_collisionShape = collisionShape;
224  m_rootCollisionShape = collisionShape;
225  }
226 
228  {
229  return m_collisionShape;
230  }
231 
233  {
234  return m_collisionShape;
235  }
236 
237  void setIgnoreCollisionCheck(const btCollisionObject* co, bool ignoreCollisionCheck)
238  {
239  if (ignoreCollisionCheck)
240  {
241  //We don't check for duplicates. Is it ok to leave that up to the user of this API?
242  //int index = m_objectsWithoutCollisionCheck.findLinearSearch(co);
243  //if (index == m_objectsWithoutCollisionCheck.size())
244  //{
245  m_objectsWithoutCollisionCheck.push_back(co);
246  //}
247  }
248  else
249  {
250  m_objectsWithoutCollisionCheck.remove(co);
251  }
252  m_checkCollideWith = m_objectsWithoutCollisionCheck.size() > 0;
253  }
254 
256  {
257  return m_objectsWithoutCollisionCheck.size();
258  }
259 
261  {
262  return m_objectsWithoutCollisionCheck[index];
263  }
264 
265  virtual bool checkCollideWithOverride(const btCollisionObject* co) const
266  {
267  int index = m_objectsWithoutCollisionCheck.findLinearSearch(co);
268  if (index < m_objectsWithoutCollisionCheck.size())
269  {
270  return false;
271  }
272  return true;
273  }
274 
278  {
279  return m_extensionPointer;
280  }
283  void internalSetExtensionPointer(void* pointer)
284  {
285  m_extensionPointer = pointer;
286  }
287 
288  SIMD_FORCE_INLINE int getActivationState() const { return m_activationState1; }
289 
290  void setActivationState(int newState) const;
291 
293  {
294  m_deactivationTime = time;
295  }
297  {
298  return m_deactivationTime;
299  }
300 
301  void forceActivationState(int newState) const;
302 
303  void activate(bool forceActivation = false) const;
304 
306  {
307  return ((getActivationState() != ISLAND_SLEEPING) && (getActivationState() != DISABLE_SIMULATION));
308  }
309 
311  {
312  m_updateRevision++;
313  m_restitution = rest;
314  }
316  {
317  return m_restitution;
318  }
319  void setFriction(btScalar frict)
320  {
321  m_updateRevision++;
322  m_friction = frict;
323  }
325  {
326  return m_friction;
327  }
328 
330  {
331  m_updateRevision++;
332  m_rollingFriction = frict;
333  }
335  {
336  return m_rollingFriction;
337  }
339  {
340  m_updateRevision++;
341  m_spinningFriction = frict;
342  }
344  {
345  return m_spinningFriction;
346  }
348  {
349  m_updateRevision++;
350  m_contactStiffness = stiffness;
351  m_contactDamping = damping;
352 
353  m_collisionFlags |= CF_HAS_CONTACT_STIFFNESS_DAMPING;
354 
355  //avoid divisions by zero...
356  if (m_contactStiffness < SIMD_EPSILON)
357  {
358  m_contactStiffness = SIMD_EPSILON;
359  }
360  }
361 
363  {
364  return m_contactStiffness;
365  }
366 
368  {
369  return m_contactDamping;
370  }
371 
373  int getInternalType() const
374  {
375  return m_internalType;
376  }
377 
379  {
380  return m_worldTransform;
381  }
382 
384  {
385  return m_worldTransform;
386  }
387 
388  void setWorldTransform(const btTransform& worldTrans)
389  {
390  m_updateRevision++;
391  m_worldTransform = worldTrans;
392  }
393 
395  {
396  return m_broadphaseHandle;
397  }
398 
400  {
401  return m_broadphaseHandle;
402  }
403 
405  {
406  m_broadphaseHandle = handle;
407  }
408 
410  {
411  return m_interpolationWorldTransform;
412  }
413 
415  {
416  return m_interpolationWorldTransform;
417  }
418 
420  {
421  m_updateRevision++;
422  m_interpolationWorldTransform = trans;
423  }
424 
426  {
427  m_updateRevision++;
428  m_interpolationLinearVelocity = linvel;
429  }
430 
432  {
433  m_updateRevision++;
434  m_interpolationAngularVelocity = angvel;
435  }
436 
438  {
439  return m_interpolationLinearVelocity;
440  }
441 
443  {
444  return m_interpolationAngularVelocity;
445  }
446 
448  {
449  return m_islandTag1;
450  }
451 
452  void setIslandTag(int tag)
453  {
454  m_islandTag1 = tag;
455  }
456 
458  {
459  return m_companionId;
460  }
461 
462  void setCompanionId(int id)
463  {
464  m_companionId = id;
465  }
466 
468  {
469  return m_worldArrayIndex;
470  }
471 
472  // only should be called by CollisionWorld
473  void setWorldArrayIndex(int ix)
474  {
475  m_worldArrayIndex = ix;
476  }
477 
479  {
480  return m_hitFraction;
481  }
482 
483  void setHitFraction(btScalar hitFraction)
484  {
485  m_hitFraction = hitFraction;
486  }
487 
489  {
490  return m_collisionFlags;
491  }
492 
493  void setCollisionFlags(int flags)
494  {
495  m_collisionFlags = flags;
496  }
497 
500  {
501  return m_ccdSweptSphereRadius;
502  }
503 
506  {
507  m_ccdSweptSphereRadius = radius;
508  }
509 
511  {
512  return m_ccdMotionThreshold;
513  }
514 
516  {
517  return m_ccdMotionThreshold * m_ccdMotionThreshold;
518  }
519 
521  void setCcdMotionThreshold(btScalar ccdMotionThreshold)
522  {
523  m_ccdMotionThreshold = ccdMotionThreshold;
524  }
525 
527  void* getUserPointer() const
528  {
529  return m_userObjectPointer;
530  }
531 
532  int getUserIndex() const
533  {
534  return m_userIndex;
535  }
536 
537  int getUserIndex2() const
538  {
539  return m_userIndex2;
540  }
541 
542  int getUserIndex3() const
543  {
544  return m_userIndex3;
545  }
546 
548  void setUserPointer(void* userPointer)
549  {
550  m_userObjectPointer = userPointer;
551  }
552 
554  void setUserIndex(int index)
555  {
556  m_userIndex = index;
557  }
558 
559  void setUserIndex2(int index)
560  {
561  m_userIndex2 = index;
562  }
563 
564  void setUserIndex3(int index)
565  {
566  m_userIndex3 = index;
567  }
568 
570  {
571  return m_updateRevision;
572  }
573 
574  void setCustomDebugColor(const btVector3& colorRGB)
575  {
576  m_customDebugColorRGB = colorRGB;
577  m_collisionFlags |= CF_HAS_CUSTOM_DEBUG_RENDERING_COLOR;
578  }
579 
581  {
582  m_collisionFlags &= ~CF_HAS_CUSTOM_DEBUG_RENDERING_COLOR;
583  }
584 
585  bool getCustomDebugColor(btVector3 & colorRGB) const
586  {
587  bool hasCustomColor = (0 != (m_collisionFlags & CF_HAS_CUSTOM_DEBUG_RENDERING_COLOR));
588  if (hasCustomColor)
589  {
590  colorRGB = m_customDebugColorRGB;
591  }
592  return hasCustomColor;
593  }
594 
595  inline bool checkCollideWith(const btCollisionObject* co) const
596  {
597  if (m_checkCollideWith)
598  return checkCollideWithOverride(co);
599 
600  return true;
601  }
602 
603  virtual int calculateSerializeBufferSize() const;
604 
606  virtual const char* serialize(void* dataBuffer, class btSerializer* serializer) const;
607 
608  virtual void serializeSingleObject(class btSerializer * serializer) const;
609 };
610 
611 // clang-format off
612 
615 {
619  char *m_name;
620 
628  double m_friction;
633  double m_hitFraction;
645  int m_uniqueId;//m_uniqueId is introduced for paircache. could get rid of this, by calculating the address offset etc.
646 };
647 
650 {
654  char *m_name;
655 
663  float m_friction;
681 };
682 // clang-format on
683 
685 {
686  return sizeof(btCollisionObjectData);
687 }
688 
689 #endif //BT_COLLISION_OBJECT_H
#define btCollisionObjectData
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