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 
20 #include "LinearMath/btVector3.h"
21 #include "LinearMath/btTransform.h"
22 #include "btManifoldPoint.h"
23 class btCollisionObject;
25 
26 struct btCollisionResult;
29 
32 
33 #ifndef SWIG
35 
36 typedef bool (*ContactDestroyedCallback)(void* userPersistentData);
37 typedef bool (*ContactProcessedCallback)(btManifoldPoint& cp,void* body0,void* body1);
38 typedef void (*ContactStartedCallback)(btPersistentManifold* const &manifold);
39 typedef void (*ContactEndedCallback)(btPersistentManifold* const &manifold);
44 #endif //SWIG
45 
46 //the enum starts at 1024 to avoid type conflicts with btTypedConstraint
48 {
51 };
52 
53 #define MANIFOLD_CACHE_SIZE 4
54 
62 
63 
64 //ATTRIBUTE_ALIGNED128( class) btPersistentManifold : public btTypedObject
66 {
67 
69 
73 
75 
78 
79 
81  int sortCachedPoints(const btManifoldPoint& pt);
82 
83  int findContactPoint(const btManifoldPoint* unUsed, int numUnused,const btManifoldPoint& pt);
84 
85 public:
86 
88 
91 
92  int m_index1a;
93 
95 
96  btPersistentManifold(const btCollisionObject* body0,const btCollisionObject* body1,int , btScalar contactBreakingThreshold,btScalar contactProcessingThreshold)
97  : btTypedObject(BT_PERSISTENT_MANIFOLD_TYPE),
98  m_body0(body0),m_body1(body1),m_cachedPoints(0),
99  m_contactBreakingThreshold(contactBreakingThreshold),
100  m_contactProcessingThreshold(contactProcessingThreshold),
101  m_companionIdA(0),
102  m_companionIdB(0),
103  m_index1a(0)
104  {
105  }
106 
109 
110  void setBodies(const btCollisionObject* body0,const btCollisionObject* body1)
111  {
112  m_body0 = body0;
113  m_body1 = body1;
114  }
115 
117 
118 #ifdef DEBUG_PERSISTENCY
119  void DebugPersistency();
120 #endif //
121 
124  void setNumContacts(int cachedPoints)
125  {
126  m_cachedPoints = cachedPoints;
127  }
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 
161 
162 
163  int getCacheEntry(const btManifoldPoint& newPoint) const;
164 
165  int addManifoldPoint( const btManifoldPoint& newPoint, bool isPredictive=false);
166 
167  void removeContactPoint (int index)
168  {
169  clearUserCache(m_pointCache[index]);
170 
171  int lastUsedIndex = getNumContacts() - 1;
172 // m_pointCache[index] = m_pointCache[lastUsedIndex];
173  if(index != lastUsedIndex)
174  {
175  m_pointCache[index] = m_pointCache[lastUsedIndex];
176  //get rid of duplicated userPersistentData pointer
177  m_pointCache[lastUsedIndex].m_userPersistentData = 0;
178  m_pointCache[lastUsedIndex].m_appliedImpulse = 0.f;
179  m_pointCache[lastUsedIndex].m_contactPointFlags = 0;
180  m_pointCache[lastUsedIndex].m_appliedImpulseLateral1 = 0.f;
181  m_pointCache[lastUsedIndex].m_appliedImpulseLateral2 = 0.f;
182  m_pointCache[lastUsedIndex].m_lifeTime = 0;
183  }
184 
185  btAssert(m_pointCache[lastUsedIndex].m_userPersistentData==0);
186  m_cachedPoints--;
187 
188  if (gContactEndedCallback && m_cachedPoints == 0)
189  {
190  gContactEndedCallback(this);
191  }
192  }
193  void replaceContactPoint(const btManifoldPoint& newPoint, int insertIndex)
194  {
195  btAssert(validContactDistance(newPoint));
196 
197 #define MAINTAIN_PERSISTENCY 1
198 #ifdef MAINTAIN_PERSISTENCY
199  int lifeTime = m_pointCache[insertIndex].getLifeTime();
200  btScalar appliedImpulse = m_pointCache[insertIndex].m_appliedImpulse;
201  btScalar appliedLateralImpulse1 = m_pointCache[insertIndex].m_appliedImpulseLateral1;
202  btScalar appliedLateralImpulse2 = m_pointCache[insertIndex].m_appliedImpulseLateral2;
203 
204  bool replacePoint = true;
208  {
209  // printf("appliedImpulse=%f\n", appliedImpulse);
210  // printf("appliedLateralImpulse1=%f\n", appliedLateralImpulse1);
211  // printf("appliedLateralImpulse2=%f\n", appliedLateralImpulse2);
212  // printf("mu = %f\n", m_pointCache[insertIndex].m_combinedFriction);
213  btScalar mu = m_pointCache[insertIndex].m_combinedFriction;
214  btScalar eps = 0; //we could allow to enlarge or shrink the tolerance to check against the friction cone a bit, say 1e-7
215  btScalar a = appliedLateralImpulse1 * appliedLateralImpulse1 + appliedLateralImpulse2 * appliedLateralImpulse2;
216  btScalar b = eps + mu * appliedImpulse;
217  b = b * b;
218  replacePoint = (a) > (b);
219  }
220 
221  if (replacePoint)
222  {
223  btAssert(lifeTime >= 0);
224  void* cache = m_pointCache[insertIndex].m_userPersistentData;
225 
226  m_pointCache[insertIndex] = newPoint;
227  m_pointCache[insertIndex].m_userPersistentData = cache;
228  m_pointCache[insertIndex].m_appliedImpulse = appliedImpulse;
229  m_pointCache[insertIndex].m_appliedImpulseLateral1 = appliedLateralImpulse1;
230  m_pointCache[insertIndex].m_appliedImpulseLateral2 = appliedLateralImpulse2;
231  }
232 
233  m_pointCache[insertIndex].m_lifeTime = lifeTime;
234 #else
235  clearUserCache(m_pointCache[insertIndex]);
236  m_pointCache[insertIndex] = newPoint;
237 
238 #endif
239  }
240 
241  bool validContactDistance(const btManifoldPoint& pt) const
242  {
244  }
246  void refreshContactPoints( const btTransform& trA,const btTransform& trB);
247 
248 
250  {
251  int i;
252  for (i=0;i<m_cachedPoints;i++)
253  {
254  clearUserCache(m_pointCache[i]);
255  }
256 
257  if (gContactEndedCallback && m_cachedPoints)
258  {
259  gContactEndedCallback(this);
260  }
261  m_cachedPoints = 0;
262  }
263 
264  int calculateSerializeBufferSize() const;
265  const char* serialize(const class btPersistentManifold* manifold, void* dataBuffer, class btSerializer* serializer) const;
266  void deSerialize(const struct btPersistentManifoldDoubleData* manifoldDataPtr);
267  void deSerialize(const struct btPersistentManifoldFloatData* manifoldDataPtr);
268 
269 
270 };
271 
272 
273 
275 {
304 
309 
314 
317 };
318 
319 
321 {
350 
355 
360 
363 };
364 
365 #ifdef BT_USE_DOUBLE_PRECISION
366 #define btPersistentManifoldData btPersistentManifoldDoubleData
367 #define btPersistentManifoldDataName "btPersistentManifoldDoubleData"
368 #else
369 #define btPersistentManifoldData btPersistentManifoldFloatData
370 #define btPersistentManifoldDataName "btPersistentManifoldFloatData"
371 #endif //BT_USE_DOUBLE_PRECISION
372 
373 
374 
375 
376 
377 
378 #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 ...
int getCacheEntry(const btManifoldPoint &newPoint) const
const btCollisionObject * m_body1
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 getContactBreakingThreshold() const
btScalar m_appliedImpulseLateral1
int getLifeTime() const
btCollisionObjectFloatData * m_body1
btScalar m_appliedImpulse
#define btAssert(x)
Definition: btScalar.h:131
btVector3DoubleData m_pointCacheLocalPointB[4]
const char * serialize(const class btPersistentManifold *manifold, void *dataBuffer, class btSerializer *serializer) const
#define SIMD_FORCE_INLINE
Definition: btScalar.h:81
ContactDestroyedCallback gContactDestroyedCallback
ManifoldContactPoint collects and maintains persistent contactpoints.
const btCollisionObject * getBody0() const
#define MANIFOLD_CACHE_SIZE
int sortCachedPoints(const btManifoldPoint &pt)
sort cached points so most isolated points come first
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)
btScalar m_appliedImpulseLateral2
void(* ContactEndedCallback)(btPersistentManifold *const &manifold)
btScalar gContactBreakingThreshold
maximum contact breaking and merging threshold
btContactManifoldTypes
btCollisionObject can be used to manage collision detection objects.
btScalar getContactProcessingThreshold() const
btVector3DoubleData m_pointCacheLateralFrictionDir1[4]
ContactStartedCallback gContactStartedCallback
const btManifoldPoint & getContactPoint(int index) const
btCollisionObjectDoubleData * m_body0
bool(* ContactDestroyedCallback)(void *userPersistentData)
void(* ContactStartedCallback)(btPersistentManifold *const &manifold)
#define ATTRIBUTE_ALIGNED16(a)
Definition: btScalar.h:82
void removeContactPoint(int index)
int calculateSerializeBufferSize() const
The btTransform class supports rigid transforms with only translation and rotation and no scaling/she...
Definition: btTransform.h:34
ContactProcessedCallback gContactProcessedCallback
bool(* ContactProcessedCallback)(btManifoldPoint &cp, void *body0, void *body1)
rudimentary class to provide type info
Definition: btScalar.h:777
void clearUserCache(btManifoldPoint &pt)
#define BT_DECLARE_ALIGNED_ALLOCATOR()
Definition: btScalar.h:403
btScalar m_combinedFriction
btVector3DoubleData m_pointCacheLateralFrictionDir2[4]
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
const btCollisionObject * getBody1() const
int addManifoldPoint(const btManifoldPoint &newPoint, bool isPredictive=false)
void setBodies(const btCollisionObject *body0, const btCollisionObject *body1)
float btScalar
The btScalar type abstracts floating point numbers, to easily switch between double and single floati...
Definition: btScalar.h:292
bool validContactDistance(const btManifoldPoint &pt) const
btManifoldPoint m_pointCache[MANIFOLD_CACHE_SIZE]