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;
27 
30 
31 #ifndef SWIG
33 
34 typedef bool (*ContactDestroyedCallback)(void* userPersistentData);
35 typedef bool (*ContactProcessedCallback)(btManifoldPoint& cp,void* body0,void* body1);
36 typedef void (*ContactStartedCallback)(btPersistentManifold* const &manifold);
37 typedef void (*ContactEndedCallback)(btPersistentManifold* const &manifold);
42 #endif //SWIG
43 
44 //the enum starts at 1024 to avoid type conflicts with btTypedConstraint
46 {
49 };
50 
51 #define MANIFOLD_CACHE_SIZE 4
52 
60 
61 
62 //ATTRIBUTE_ALIGNED128( class) btPersistentManifold : public btTypedObject
64 {
65 
67 
71 
73 
76 
77 
79  int sortCachedPoints(const btManifoldPoint& pt);
80 
81  int findContactPoint(const btManifoldPoint* unUsed, int numUnused,const btManifoldPoint& pt);
82 
83 public:
84 
86 
89 
90  int m_index1a;
91 
93 
94  btPersistentManifold(const btCollisionObject* body0,const btCollisionObject* body1,int , btScalar contactBreakingThreshold,btScalar contactProcessingThreshold)
96  m_body0(body0),m_body1(body1),m_cachedPoints(0),
97  m_contactBreakingThreshold(contactBreakingThreshold),
98  m_contactProcessingThreshold(contactProcessingThreshold)
99  {
100  }
101 
104 
105  void setBodies(const btCollisionObject* body0,const btCollisionObject* body1)
106  {
107  m_body0 = body0;
108  m_body1 = body1;
109  }
110 
112 
113 #ifdef DEBUG_PERSISTENCY
114  void DebugPersistency();
115 #endif //
116 
119  void setNumContacts(int cachedPoints)
120  {
121  m_cachedPoints = cachedPoints;
122  }
123 
124 
126  {
127  btAssert(index < m_cachedPoints);
128  return m_pointCache[index];
129  }
130 
132  {
133  btAssert(index < m_cachedPoints);
134  return m_pointCache[index];
135  }
136 
139 
141  {
143  }
144 
145  void setContactBreakingThreshold(btScalar contactBreakingThreshold)
146  {
147  m_contactBreakingThreshold = contactBreakingThreshold;
148  }
149 
150  void setContactProcessingThreshold(btScalar contactProcessingThreshold)
151  {
152  m_contactProcessingThreshold = contactProcessingThreshold;
153  }
154 
155 
156 
157 
158  int getCacheEntry(const btManifoldPoint& newPoint) const;
159 
160  int addManifoldPoint( const btManifoldPoint& newPoint, bool isPredictive=false);
161 
162  void removeContactPoint (int index)
163  {
165 
166  int lastUsedIndex = getNumContacts() - 1;
167 // m_pointCache[index] = m_pointCache[lastUsedIndex];
168  if(index != lastUsedIndex)
169  {
170  m_pointCache[index] = m_pointCache[lastUsedIndex];
171  //get rid of duplicated userPersistentData pointer
172  m_pointCache[lastUsedIndex].m_userPersistentData = 0;
173  m_pointCache[lastUsedIndex].m_appliedImpulse = 0.f;
174  m_pointCache[lastUsedIndex].m_contactPointFlags = 0;
175  m_pointCache[lastUsedIndex].m_appliedImpulseLateral1 = 0.f;
176  m_pointCache[lastUsedIndex].m_appliedImpulseLateral2 = 0.f;
177  m_pointCache[lastUsedIndex].m_lifeTime = 0;
178  }
179 
180  btAssert(m_pointCache[lastUsedIndex].m_userPersistentData==0);
181  m_cachedPoints--;
182 
184  {
185  gContactEndedCallback(this);
186  }
187  }
188  void replaceContactPoint(const btManifoldPoint& newPoint, int insertIndex)
189  {
190  btAssert(validContactDistance(newPoint));
191 
192 #define MAINTAIN_PERSISTENCY 1
193 #ifdef MAINTAIN_PERSISTENCY
194  int lifeTime = m_pointCache[insertIndex].getLifeTime();
195  btScalar appliedImpulse = m_pointCache[insertIndex].m_appliedImpulse;
196  btScalar appliedLateralImpulse1 = m_pointCache[insertIndex].m_appliedImpulseLateral1;
197  btScalar appliedLateralImpulse2 = m_pointCache[insertIndex].m_appliedImpulseLateral2;
198 
199  bool replacePoint = true;
203  {
204  // printf("appliedImpulse=%f\n", appliedImpulse);
205  // printf("appliedLateralImpulse1=%f\n", appliedLateralImpulse1);
206  // printf("appliedLateralImpulse2=%f\n", appliedLateralImpulse2);
207  // printf("mu = %f\n", m_pointCache[insertIndex].m_combinedFriction);
208  btScalar mu = m_pointCache[insertIndex].m_combinedFriction;
209  btScalar eps = 0; //we could allow to enlarge or shrink the tolerance to check against the friction cone a bit, say 1e-7
210  btScalar a = appliedLateralImpulse1 * appliedLateralImpulse1 + appliedLateralImpulse2 * appliedLateralImpulse2;
211  btScalar b = eps + mu * appliedImpulse;
212  b = b * b;
213  replacePoint = (a) > (b);
214  }
215 
216  if (replacePoint)
217  {
218  btAssert(lifeTime >= 0);
219  void* cache = m_pointCache[insertIndex].m_userPersistentData;
220 
221  m_pointCache[insertIndex] = newPoint;
222  m_pointCache[insertIndex].m_userPersistentData = cache;
223  m_pointCache[insertIndex].m_appliedImpulse = appliedImpulse;
224  m_pointCache[insertIndex].m_appliedImpulseLateral1 = appliedLateralImpulse1;
225  m_pointCache[insertIndex].m_appliedImpulseLateral2 = appliedLateralImpulse2;
226  }
227 
228  m_pointCache[insertIndex].m_lifeTime = lifeTime;
229 #else
230  clearUserCache(m_pointCache[insertIndex]);
231  m_pointCache[insertIndex] = newPoint;
232 
233 #endif
234  }
235 
236  bool validContactDistance(const btManifoldPoint& pt) const
237  {
239  }
241  void refreshContactPoints( const btTransform& trA,const btTransform& trB);
242 
243 
245  {
246  int i;
247  for (i=0;i<m_cachedPoints;i++)
248  {
250  }
251 
253  {
254  gContactEndedCallback(this);
255  }
256  m_cachedPoints = 0;
257  }
258 
259 
260 
261 }
262 ;
263 
264 
265 
266 
267 
268 #endif //BT_PERSISTENT_MANIFOLD_H
btPersistentManifold is a contact point cache, it stays persistent as long as objects are overlapping...
const btCollisionObject * m_body1
btScalar getContactBreakingThreshold() const
void refreshContactPoints(const btTransform &trA, const btTransform &trB)
calculated new worldspace coordinates and depth, and reject points that exceed the collision margin ...
btScalar m_appliedImpulseLateral1
btScalar m_appliedImpulse
#define btAssert(x)
Definition: btScalar.h:131
bool validContactDistance(const btManifoldPoint &pt) const
#define SIMD_FORCE_INLINE
Definition: btScalar.h:81
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
void setNumContacts(int cachedPoints)
the setNumContacts API is usually not used, except when you gather/fill all contacts manually ...
void * m_userPersistentData
btManifoldPoint & getContactPoint(int index)
const btCollisionObject * getBody0() const
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
ContactStartedCallback gContactStartedCallback
bool(* ContactDestroyedCallback)(void *userPersistentData)
void(* ContactStartedCallback)(btPersistentManifold *const &manifold)
#define ATTRIBUTE_ALIGNED16(a)
Definition: btScalar.h:82
void removeContactPoint(int index)
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
const btCollisionObject * getBody1() const
void clearUserCache(btManifoldPoint &pt)
#define BT_DECLARE_ALIGNED_ALLOCATOR()
Definition: btScalar.h:403
btScalar m_combinedFriction
void setContactProcessingThreshold(btScalar contactProcessingThreshold)
btPersistentManifold(const btCollisionObject *body0, const btCollisionObject *body1, int, btScalar contactBreakingThreshold, btScalar contactProcessingThreshold)
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)
float btScalar
The btScalar type abstracts floating point numbers, to easily switch between double and single floati...
Definition: btScalar.h:292
btManifoldPoint m_pointCache[MANIFOLD_CACHE_SIZE]
int getCacheEntry(const btManifoldPoint &newPoint) const