Bullet Collision Detection & Physics Library: btPersistentManifold.h Source File

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;
24 #include "LinearMath/btAlignedAllocator.h"
25
26 struct btCollisionResult;
27
29 extern btScalar gContactBreakingThreshold;
30
31 #ifndef SWIG
32 class btPersistentManifold;
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);
38 extern ContactDestroyedCallback gContactDestroyedCallback;
39 extern ContactProcessedCallback gContactProcessedCallback;
40 extern ContactStartedCallback gContactStartedCallback;
41 extern ContactEndedCallback gContactEndedCallback;
42 #endif //SWIG
43
44 //the enum starts at 1024 to avoid type conflicts with btTypedConstraint
45 enum btContactManifoldTypes
46 {
47 MIN_CONTACT_MANIFOLD_TYPE = 1024,
48 BT_PERSISTENT_MANIFOLD_TYPE
49 };
50
51 #define MANIFOLD_CACHE_SIZE 4
52
60
61
62 //ATTRIBUTE_ALIGNED128( class) btPersistentManifold : public btTypedObject
63 ATTRIBUTE_ALIGNED16( class) btPersistentManifold : public btTypedObject
64 {
65
66 btManifoldPoint m_pointCache[MANIFOLD_CACHE_SIZE];
67
69 const btCollisionObject* m_body0;
70 const btCollisionObject* m_body1;
71
72 int m_cachedPoints;
73
74 btScalar m_contactBreakingThreshold;
75 btScalar m_contactProcessingThreshold;
76
77
79 int sortCachedPoints(const btManifoldPoint& pt);
80
81 int findContactPoint(const btManifoldPoint* unUsed, int numUnused,const btManifoldPoint& pt);
82
83 public:
84
85 BT_DECLARE_ALIGNED_ALLOCATOR();
86
87 int m_companionIdA;
88 int m_companionIdB;
89
90 int m_index1a;
91
92 btPersistentManifold();
93
94 btPersistentManifold(const btCollisionObject* body0,const btCollisionObject* body1,int , btScalar contactBreakingThreshold,btScalar contactProcessingThreshold)
95 : btTypedObject(BT_PERSISTENT_MANIFOLD_TYPE),
96 m_body0(body0),m_body1(body1),m_cachedPoints(0),
97 m_contactBreakingThreshold(contactBreakingThreshold),
98 m_contactProcessingThreshold(contactProcessingThreshold)
99 {
100 }
101
102 SIMD_FORCE_INLINE const btCollisionObject* getBody0() const { return m_body0;}
103 SIMD_FORCE_INLINE const btCollisionObject* getBody1() const { return m_body1;}
104
105 void setBodies(const btCollisionObject* body0,const btCollisionObject* body1)
106 {
107 m_body0 = body0;
108 m_body1 = body1;
109 }
110
111 void clearUserCache(btManifoldPoint& pt);
112
113 #ifdef DEBUG_PERSISTENCY
114 void DebugPersistency();
115 #endif //
116
117 SIMD_FORCE_INLINE int getNumContacts() const { return m_cachedPoints;}
119 void setNumContacts(int cachedPoints)
120 {
121 m_cachedPoints = cachedPoints;
122 }
123
124
125 SIMD_FORCE_INLINE const btManifoldPoint& getContactPoint(int index) const
126 {
127 btAssert(index < m_cachedPoints);
128 return m_pointCache[index];
129 }
130
131 SIMD_FORCE_INLINE btManifoldPoint& getContactPoint(int index)
132 {
133 btAssert(index < m_cachedPoints);
134 return m_pointCache[index];
135 }
136
138 btScalar getContactBreakingThreshold() const;
139
140 btScalar getContactProcessingThreshold() const
141 {
142 return m_contactProcessingThreshold;
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 {
164 clearUserCache(m_pointCache[index]);
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
183 if (gContactEndedCallback && m_cachedPoints == 0)
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;
202 if (newPoint.m_contactPointFlags & BT_CONTACT_FLAG_FRICTION_ANCHOR)
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 {
238 return pt.m_distance1 <= getContactBreakingThreshold();
239 }
241 void refreshContactPoints( const btTransform& trA,const btTransform& trB);
242
243
244 SIMD_FORCE_INLINE void clearManifold()
245 {
246 int i;
247 for (i=0;i<m_cachedPoints;i++)
248 {
249 clearUserCache(m_pointCache[i]);
250 }
251
252 if (gContactEndedCallback && m_cachedPoints)
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
btManifoldPoint::m_contactPointFlags
int m_contactPointFlags
Definition: btManifoldPoint.h:116
btPersistentManifold::m_companionIdA
int m_companionIdA
Definition: btPersistentManifold.h:87
btPersistentManifold
btPersistentManifold is a contact point cache, it stays persistent as long as objects are overlapping...
Definition: btPersistentManifold.h:63
btPersistentManifold::m_body1
const btCollisionObject * m_body1
Definition: btPersistentManifold.h:70
btPersistentManifold::getContactBreakingThreshold
btScalar getContactBreakingThreshold() const
Definition: btPersistentManifold.cpp:242
btPersistentManifold::refreshContactPoints
void refreshContactPoints(const btTransform &trA, const btTransform &trB)
calculated new worldspace coordinates and depth, and reject points that exceed the collision margin ...
Definition: btPersistentManifold.cpp:249
BT_PERSISTENT_MANIFOLD_TYPE
Definition: btPersistentManifold.h:48
btVector3.h
btManifoldPoint::m_appliedImpulseLateral1
btScalar m_appliedImpulseLateral1
Definition: btManifoldPoint.h:119
MIN_CONTACT_MANIFOLD_TYPE
Definition: btPersistentManifold.h:47
btPersistentManifold::getNumContacts
int getNumContacts() const
Definition: btPersistentManifold.h:117
btManifoldPoint::m_appliedImpulse
btScalar m_appliedImpulse
Definition: btManifoldPoint.h:118
btAssert
#define btAssert(x)
Definition: btScalar.h:131
btPersistentManifold::validContactDistance
bool validContactDistance(const btManifoldPoint &pt) const
Definition: btPersistentManifold.h:236
SIMD_FORCE_INLINE
#define SIMD_FORCE_INLINE
Definition: btScalar.h:81
gContactDestroyedCallback
ContactDestroyedCallback gContactDestroyedCallback
Definition: btPersistentManifold.cpp:22
btTransform.h
btManifoldPoint
ManifoldContactPoint collects and maintains persistent contactpoints.
Definition: btManifoldPoint.h:49
MANIFOLD_CACHE_SIZE
#define MANIFOLD_CACHE_SIZE
Definition: btPersistentManifold.h:51
btAlignedAllocator.h
btPersistentManifold::m_cachedPoints
int m_cachedPoints
Definition: btPersistentManifold.h:72
btPersistentManifold::sortCachedPoints
int sortCachedPoints(const btManifoldPoint &pt)
sort cached points so most isolated points come first
Definition: btPersistentManifold.cpp:111
btPersistentManifold::getContactPoint
const btManifoldPoint & getContactPoint(int index) const
Definition: btPersistentManifold.h:125
btPersistentManifold::setNumContacts
void setNumContacts(int cachedPoints)
the setNumContacts API is usually not used, except when you gather/fill all contacts manually ...
Definition: btPersistentManifold.h:119
btManifoldPoint::m_userPersistentData
void * m_userPersistentData
Definition: btManifoldPoint.h:114
btPersistentManifold::m_companionIdB
int m_companionIdB
Definition: btPersistentManifold.h:88
btPersistentManifold::getContactPoint
btManifoldPoint & getContactPoint(int index)
Definition: btPersistentManifold.h:131
btPersistentManifold::getBody0
const btCollisionObject * getBody0() const
Definition: btPersistentManifold.h:102
btManifoldPoint::m_appliedImpulseLateral2
btScalar m_appliedImpulseLateral2
Definition: btManifoldPoint.h:120
ContactEndedCallback
void(* ContactEndedCallback)(btPersistentManifold *const &manifold)
Definition: btPersistentManifold.h:37
gContactBreakingThreshold
btScalar gContactBreakingThreshold
maximum contact breaking and merging threshold
Definition: btPersistentManifold.cpp:21
btPersistentManifold::btPersistentManifold
btPersistentManifold()
Definition: btPersistentManifold.cpp:31
btContactManifoldTypes
btContactManifoldTypes
Definition: btPersistentManifold.h:45
btManifoldPoint::m_lifeTime
int m_lifeTime
Definition: btManifoldPoint.h:138
btCollisionObject
btCollisionObject can be used to manage collision detection objects.
Definition: btCollisionObject.h:49
btPersistentManifold::getContactProcessingThreshold
btScalar getContactProcessingThreshold() const
Definition: btPersistentManifold.h:140
gContactStartedCallback
ContactStartedCallback gContactStartedCallback
Definition: btPersistentManifold.cpp:24
btPersistentManifold::m_index1a
int m_index1a
Definition: btPersistentManifold.h:90
ContactDestroyedCallback
bool(* ContactDestroyedCallback)(void *userPersistentData)
Definition: btPersistentManifold.h:34
ContactStartedCallback
void(* ContactStartedCallback)(btPersistentManifold *const &manifold)
Definition: btPersistentManifold.h:36
ATTRIBUTE_ALIGNED16
#define ATTRIBUTE_ALIGNED16(a)
Definition: btScalar.h:82
btPersistentManifold::removeContactPoint
void removeContactPoint(int index)
Definition: btPersistentManifold.h:162
btTransform
The btTransform class supports rigid transforms with only translation and rotation and no scaling/she...
Definition: btTransform.h:34
gContactProcessedCallback
ContactProcessedCallback gContactProcessedCallback
Definition: btPersistentManifold.cpp:23
btManifoldPoint::m_distance1
btScalar m_distance1
Definition: btManifoldPoint.h:102
btPersistentManifold::clearManifold
void clearManifold()
Definition: btPersistentManifold.h:244
ContactProcessedCallback
bool(* ContactProcessedCallback)(btManifoldPoint &cp, void *body0, void *body1)
Definition: btPersistentManifold.h:35
btTypedObject
rudimentary class to provide type info
Definition: btScalar.h:777
BT_CONTACT_FLAG_FRICTION_ANCHOR
Definition: btManifoldPoint.h:44
btPersistentManifold::getBody1
const btCollisionObject * getBody1() const
Definition: btPersistentManifold.h:103
btPersistentManifold::clearUserCache
void clearUserCache(btManifoldPoint &pt)
Definition: btPersistentManifold.cpp:56
BT_DECLARE_ALIGNED_ALLOCATOR
#define BT_DECLARE_ALIGNED_ALLOCATOR()
Definition: btScalar.h:403
btManifoldPoint::m_combinedFriction
btScalar m_combinedFriction
Definition: btManifoldPoint.h:103
btPersistentManifold::m_contactProcessingThreshold
btScalar m_contactProcessingThreshold
Definition: btPersistentManifold.h:75
btPersistentManifold::setContactProcessingThreshold
void setContactProcessingThreshold(btScalar contactProcessingThreshold)
Definition: btPersistentManifold.h:150
btPersistentManifold::m_contactBreakingThreshold
btScalar m_contactBreakingThreshold
Definition: btPersistentManifold.h:74
btPersistentManifold::btPersistentManifold
btPersistentManifold(const btCollisionObject *body0, const btCollisionObject *body1, int, btScalar contactBreakingThreshold, btScalar contactProcessingThreshold)
Definition: btPersistentManifold.h:94
btPersistentManifold::replaceContactPoint
void replaceContactPoint(const btManifoldPoint &newPoint, int insertIndex)
Definition: btPersistentManifold.h:188
btPersistentManifold::findContactPoint
int findContactPoint(const btManifoldPoint *unUsed, int numUnused, const btManifoldPoint &pt)
btPersistentManifold::setContactBreakingThreshold
void setContactBreakingThreshold(btScalar contactBreakingThreshold)
Definition: btPersistentManifold.h:145
btManifoldPoint.h
btPersistentManifold::m_body0
const btCollisionObject * m_body0
this two body pointers can point to the physics rigidbody class.
Definition: btPersistentManifold.h:69
gContactEndedCallback
ContactEndedCallback gContactEndedCallback
Definition: btPersistentManifold.cpp:25
btPersistentManifold::addManifoldPoint
int addManifoldPoint(const btManifoldPoint &newPoint, bool isPredictive=false)
Definition: btPersistentManifold.cpp:210
btManifoldPoint::getLifeTime
int getLifeTime() const
Definition: btManifoldPoint.h:150
btPersistentManifold::setBodies
void setBodies(const btCollisionObject *body0, const btCollisionObject *body1)
Definition: btPersistentManifold.h:105
btScalar
float btScalar
The btScalar type abstracts floating point numbers, to easily switch between double and single floati...
Definition: btScalar.h:292
btPersistentManifold::m_pointCache
btManifoldPoint m_pointCache[MANIFOLD_CACHE_SIZE]
Definition: btPersistentManifold.h:66
btPersistentManifold::getCacheEntry
int getCacheEntry(const btManifoldPoint &newPoint) const
Definition: btPersistentManifold.cpp:190