Bullet Collision Detection & Physics Library
btPersistentManifold.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_PERSISTENT_MANIFOLD_H
17 #define BT_PERSISTENT_MANIFOLD_H
18 
19 #include "LinearMath/btVector3.h"
20 #include "LinearMath/btTransform.h"
21 #include "btManifoldPoint.h"
22 class btCollisionObject;
24 
25 struct btCollisionResult;
28 
31 
32 #ifndef SWIG
34 
35 typedef bool (*ContactDestroyedCallback)(void* userPersistentData);
36 typedef bool (*ContactProcessedCallback)(btManifoldPoint& cp, void* body0, void* body1);
37 typedef void (*ContactStartedCallback)(btPersistentManifold* const& manifold);
38 typedef void (*ContactEndedCallback)(btPersistentManifold* const& manifold);
43 #endif //SWIG
44 
45 //the enum starts at 1024 to avoid type conflicts with btTypedConstraint
47 {
50 };
51 
52 #define MANIFOLD_CACHE_SIZE 4
53 
61 
62 //ATTRIBUTE_ALIGNED128( class) btPersistentManifold : public btTypedObject
65 {
67 
71 
73 
76 
78  int sortCachedPoints(const btManifoldPoint& pt);
79 
80  int findContactPoint(const btManifoldPoint* unUsed, int numUnused, const btManifoldPoint& pt);
81 
82 public:
84 
87 
88  int m_index1a;
89 
91 
92  btPersistentManifold(const btCollisionObject* body0, const btCollisionObject* body1, int, btScalar contactBreakingThreshold, btScalar contactProcessingThreshold)
94  m_body0(body0),
95  m_body1(body1),
96  m_cachedPoints(0),
97  m_contactBreakingThreshold(contactBreakingThreshold),
98  m_contactProcessingThreshold(contactProcessingThreshold),
99  m_companionIdA(0),
100  m_companionIdB(0),
101  m_index1a(0)
102  {
103  }
104 
107 
108  void setBodies(const btCollisionObject* body0, const btCollisionObject* body1)
109  {
110  m_body0 = body0;
111  m_body1 = body1;
112  }
113 
114  void clearUserCache(btManifoldPoint & pt);
115 
116 #ifdef DEBUG_PERSISTENCY
117  void DebugPersistency();
118 #endif //
119 
121  {
122  return m_cachedPoints;
123  }
125  void setNumContacts(int cachedPoints)
126  {
127  m_cachedPoints = cachedPoints;
128  }
129 
131  {
132  btAssert(index < m_cachedPoints);
133  return m_pointCache[index];
134  }
135 
137  {
138  btAssert(index < m_cachedPoints);
139  return m_pointCache[index];
140  }
141 
144 
146  {
148  }
149 
150  void setContactBreakingThreshold(btScalar contactBreakingThreshold)
151  {
152  m_contactBreakingThreshold = contactBreakingThreshold;
153  }
154 
155  void setContactProcessingThreshold(btScalar contactProcessingThreshold)
156  {
157  m_contactProcessingThreshold = contactProcessingThreshold;
158  }
159 
160  int getCacheEntry(const btManifoldPoint& newPoint) const;
161 
162  int addManifoldPoint(const btManifoldPoint& newPoint, bool isPredictive = false);
163 
164  void removeContactPoint(int index)
165  {
167 
168  int lastUsedIndex = getNumContacts() - 1;
169  // m_pointCache[index] = m_pointCache[lastUsedIndex];
170  if (index != lastUsedIndex)
171  {
172  m_pointCache[index] = m_pointCache[lastUsedIndex];
173  //get rid of duplicated userPersistentData pointer
174  m_pointCache[lastUsedIndex].m_userPersistentData = 0;
175  m_pointCache[lastUsedIndex].m_appliedImpulse = 0.f;
176  m_pointCache[lastUsedIndex].m_contactPointFlags = 0;
177  m_pointCache[lastUsedIndex].m_appliedImpulseLateral1 = 0.f;
178  m_pointCache[lastUsedIndex].m_appliedImpulseLateral2 = 0.f;
179  m_pointCache[lastUsedIndex].m_lifeTime = 0;
180  }
181 
182  btAssert(m_pointCache[lastUsedIndex].m_userPersistentData == 0);
183  m_cachedPoints--;
184 
186  {
187  gContactEndedCallback(this);
188  }
189  }
190  void replaceContactPoint(const btManifoldPoint& newPoint, int insertIndex)
191  {
192  btAssert(validContactDistance(newPoint));
193 
194 #define MAINTAIN_PERSISTENCY 1
195 #ifdef MAINTAIN_PERSISTENCY
196  int lifeTime = m_pointCache[insertIndex].getLifeTime();
197  btScalar appliedImpulse = m_pointCache[insertIndex].m_appliedImpulse;
198  btScalar appliedLateralImpulse1 = m_pointCache[insertIndex].m_appliedImpulseLateral1;
199  btScalar appliedLateralImpulse2 = m_pointCache[insertIndex].m_appliedImpulseLateral2;
200 
201  bool replacePoint = true;
205  {
206  // printf("appliedImpulse=%f\n", appliedImpulse);
207  // printf("appliedLateralImpulse1=%f\n", appliedLateralImpulse1);
208  // printf("appliedLateralImpulse2=%f\n", appliedLateralImpulse2);
209  // printf("mu = %f\n", m_pointCache[insertIndex].m_combinedFriction);
210  btScalar mu = m_pointCache[insertIndex].m_combinedFriction;
211  btScalar eps = 0; //we could allow to enlarge or shrink the tolerance to check against the friction cone a bit, say 1e-7
212  btScalar a = appliedLateralImpulse1 * appliedLateralImpulse1 + appliedLateralImpulse2 * appliedLateralImpulse2;
213  btScalar b = eps + mu * appliedImpulse;
214  b = b * b;
215  replacePoint = (a) > (b);
216  }
217 
218  if (replacePoint)
219  {
220  btAssert(lifeTime >= 0);
221  void* cache = m_pointCache[insertIndex].m_userPersistentData;
222 
223  m_pointCache[insertIndex] = newPoint;
224  m_pointCache[insertIndex].m_userPersistentData = cache;
225  m_pointCache[insertIndex].m_appliedImpulse = appliedImpulse;
226  m_pointCache[insertIndex].m_appliedImpulseLateral1 = appliedLateralImpulse1;
227  m_pointCache[insertIndex].m_appliedImpulseLateral2 = appliedLateralImpulse2;
228  }
229 
230  m_pointCache[insertIndex].m_lifeTime = lifeTime;
231 #else
232  clearUserCache(m_pointCache[insertIndex]);
233  m_pointCache[insertIndex] = newPoint;
234 
235 #endif
236  }
237 
238  bool validContactDistance(const btManifoldPoint& pt) const
239  {
241  }
243  void refreshContactPoints(const btTransform& trA, const btTransform& trB);
244 
246  {
247  int i;
248  for (i = 0; i < m_cachedPoints; i++)
249  {
251  }
252 
254  {
255  gContactEndedCallback(this);
256  }
257  m_cachedPoints = 0;
258  }
259 
260  int calculateSerializeBufferSize() const;
261  const char* serialize(const class btPersistentManifold* manifold, void* dataBuffer, class btSerializer* serializer) const;
262  void deSerialize(const struct btPersistentManifoldDoubleData* manifoldDataPtr);
263  void deSerialize(const struct btPersistentManifoldFloatData* manifoldDataPtr);
264 };
265 
266 // clang-format off
267 
269 {
298 
303 
308 
311 };
312 
313 
315 {
344 
349 
354 
357 };
358 
359 // clang-format on
360 
361 #ifdef BT_USE_DOUBLE_PRECISION
362 #define btPersistentManifoldData btPersistentManifoldDoubleData
363 #define btPersistentManifoldDataName "btPersistentManifoldDoubleData"
364 #else
365 #define btPersistentManifoldData btPersistentManifoldFloatData
366 #define btPersistentManifoldDataName "btPersistentManifoldFloatData"
367 #endif //BT_USE_DOUBLE_PRECISION
368 
369 #endif //BT_PERSISTENT_MANIFOLD_H
btPersistentManifold is a contact point cache, it stays persistent as long as objects are overlapping...
do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64 ...
const btCollisionObject * m_body1
btScalar getContactBreakingThreshold() const
btVector3DoubleData m_pointCachePositionWorldOnB[4]
void refreshContactPoints(const btTransform &trA, const btTransform &trB)
calculated new worldspace coordinates and depth, and reject points that exceed the collision margin ...
btCollisionObjectDoubleData * m_body1
btScalar m_appliedImpulseLateral1
btCollisionObjectFloatData * m_body1
void(* ContactEndedCallback)(btPersistentManifold *const &manifold)
btScalar m_appliedImpulse
#define btAssert(x)
Definition: btScalar.h:133
btVector3DoubleData m_pointCacheLocalPointB[4]
bool validContactDistance(const btManifoldPoint &pt) const
#define SIMD_FORCE_INLINE
Definition: btScalar.h:83
ContactDestroyedCallback gContactDestroyedCallback
ManifoldContactPoint collects and maintains persistent contactpoints.
#define MANIFOLD_CACHE_SIZE
int sortCachedPoints(const btManifoldPoint &pt)
sort cached points so most isolated points come first
const btManifoldPoint & getContactPoint(int index) const
btVector3DoubleData m_pointCacheNormalWorldOnB[4]
void setNumContacts(int cachedPoints)
the setNumContacts API is usually not used, except when you gather/fill all contacts manually ...
do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64 ...
btVector3DoubleData m_pointCachePositionWorldOnA[4]
void * m_userPersistentData
btManifoldPoint & getContactPoint(int index)
btVector3FloatData m_pointCacheLocalPointB[4]
const btCollisionObject * getBody0() const
btScalar m_appliedImpulseLateral2
void(* ContactStartedCallback)(btPersistentManifold *const &manifold)
btScalar gContactBreakingThreshold
maximum contact breaking and merging threshold
btContactManifoldTypes
btCollisionObject can be used to manage collision detection objects.
btVector3FloatData m_pointCachePositionWorldOnB[4]
btVector3DoubleData m_pointCacheLateralFrictionDir1[4]
btVector3FloatData m_pointCacheNormalWorldOnB[4]
btScalar getContactProcessingThreshold() const
ContactStartedCallback gContactStartedCallback
int calculateSerializeBufferSize() const
btCollisionObjectDoubleData * m_body0
bool(* ContactDestroyedCallback)(void *userPersistentData)
#define ATTRIBUTE_ALIGNED16(a)
Definition: btScalar.h:84
void removeContactPoint(int index)
The btTransform class supports rigid transforms with only translation and rotation and no scaling/she...
Definition: btTransform.h:28
ContactProcessedCallback gContactProcessedCallback
btVector3FloatData m_pointCacheLocalPointA[4]
bool(* ContactProcessedCallback)(btManifoldPoint &cp, void *body0, void *body1)
rudimentary class to provide type info
Definition: btScalar.h:779
btVector3FloatData m_pointCacheLateralFrictionDir2[4]
const btCollisionObject * getBody1() const
void clearUserCache(btManifoldPoint &pt)
#define BT_DECLARE_ALIGNED_ALLOCATOR()
Definition: btScalar.h:405
btScalar m_combinedFriction
btVector3DoubleData m_pointCacheLateralFrictionDir2[4]
const char * serialize(const class btPersistentManifold *manifold, void *dataBuffer, class btSerializer *serializer) const
void setContactProcessingThreshold(btScalar contactProcessingThreshold)
void deSerialize(const struct btPersistentManifoldDoubleData *manifoldDataPtr)
btPersistentManifold(const btCollisionObject *body0, const btCollisionObject *body1, int, btScalar contactBreakingThreshold, btScalar contactProcessingThreshold)
btCollisionObjectFloatData * m_body0
btVector3DoubleData m_pointCacheLocalPointA[4]
void replaceContactPoint(const btManifoldPoint &newPoint, int insertIndex)
int findContactPoint(const btManifoldPoint *unUsed, int numUnused, const btManifoldPoint &pt)
void setContactBreakingThreshold(btScalar contactBreakingThreshold)
const btCollisionObject * m_body0
this two body pointers can point to the physics rigidbody class.
ContactEndedCallback gContactEndedCallback
int addManifoldPoint(const btManifoldPoint &newPoint, bool isPredictive=false)
int getLifeTime() const
void setBodies(const btCollisionObject *body0, const btCollisionObject *body1)
btVector3FloatData m_pointCacheLateralFrictionDir1[4]
float btScalar
The btScalar type abstracts floating point numbers, to easily switch between double and single floati...
Definition: btScalar.h:294
btVector3FloatData m_pointCachePositionWorldOnA[4]
btManifoldPoint m_pointCache[MANIFOLD_CACHE_SIZE]
int getCacheEntry(const btManifoldPoint &newPoint) const