Bullet Collision Detection & Physics Library
btPersistentManifold.h
Go to the documentation of this file.
1/*
2Bullet Continuous Collision Detection and Physics Library
3Copyright (c) 2003-2006 Erwin Coumans https://bulletphysics.org
4
5This software is provided 'as-is', without any express or implied warranty.
6In no event will the authors be held liable for any damages arising from the use of this software.
7Permission is granted to anyone to use this software for any purpose,
8including commercial applications, and to alter it and redistribute it freely,
9subject to the following restrictions:
10
111. 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.
122. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
133. 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
21#include "btManifoldPoint.h"
24
25struct btCollisionResult;
28
31
32#ifndef SWIG
34
35typedef bool (*ContactDestroyedCallback)(void* userPersistentData);
36typedef bool (*ContactProcessedCallback)(btManifoldPoint& cp, void* body0, void* body1);
37typedef void (*ContactStartedCallback)(btPersistentManifold* const& manifold);
38typedef 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
82public:
84
87
89
91
92 btPersistentManifold(const btCollisionObject* body0, const btCollisionObject* body1, int, btScalar contactBreakingThreshold, btScalar contactProcessingThreshold)
94 m_body0(body0),
95 m_body1(body1),
97 m_contactBreakingThreshold(contactBreakingThreshold),
98 m_contactProcessingThreshold(contactProcessingThreshold),
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
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_prevRHS = 0.f;
177 m_pointCache[lastUsedIndex].m_contactPointFlags = 0;
178 m_pointCache[lastUsedIndex].m_appliedImpulseLateral1 = 0.f;
179 m_pointCache[lastUsedIndex].m_appliedImpulseLateral2 = 0.f;
180 m_pointCache[lastUsedIndex].m_lifeTime = 0;
181 }
182
183 btAssert(m_pointCache[lastUsedIndex].m_userPersistentData == 0);
185
187 {
189 }
190 }
191 void replaceContactPoint(const btManifoldPoint& newPoint, int insertIndex)
192 {
194
195#define MAINTAIN_PERSISTENCY 1
196#ifdef MAINTAIN_PERSISTENCY
197 int lifeTime = m_pointCache[insertIndex].getLifeTime();
198 btScalar appliedImpulse = m_pointCache[insertIndex].m_appliedImpulse;
199 btScalar prevRHS = m_pointCache[insertIndex].m_prevRHS;
200 btScalar appliedLateralImpulse1 = m_pointCache[insertIndex].m_appliedImpulseLateral1;
201 btScalar appliedLateralImpulse2 = m_pointCache[insertIndex].m_appliedImpulseLateral2;
202
203 bool replacePoint = true;
207 {
208 // printf("appliedImpulse=%f\n", appliedImpulse);
209 // printf("appliedLateralImpulse1=%f\n", appliedLateralImpulse1);
210 // printf("appliedLateralImpulse2=%f\n", appliedLateralImpulse2);
211 // printf("mu = %f\n", m_pointCache[insertIndex].m_combinedFriction);
212 btScalar mu = m_pointCache[insertIndex].m_combinedFriction;
213 btScalar eps = 0; //we could allow to enlarge or shrink the tolerance to check against the friction cone a bit, say 1e-7
214 btScalar a = appliedLateralImpulse1 * appliedLateralImpulse1 + appliedLateralImpulse2 * appliedLateralImpulse2;
215 btScalar b = eps + mu * appliedImpulse;
216 b = b * b;
217 replacePoint = (a) > (b);
218 }
219
220 if (replacePoint)
221 {
222 btAssert(lifeTime >= 0);
223 void* cache = m_pointCache[insertIndex].m_userPersistentData;
224
225 m_pointCache[insertIndex] = newPoint;
226 m_pointCache[insertIndex].m_userPersistentData = cache;
227 m_pointCache[insertIndex].m_appliedImpulse = appliedImpulse;
228 m_pointCache[insertIndex].m_prevRHS = prevRHS;
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
242 {
244 }
246 void refreshContactPoints(const btTransform& trA, const btTransform& trB);
247
249 {
250 int i;
251 for (i = 0; i < m_cachedPoints; i++)
252 {
254 }
255
257 {
259 }
260 m_cachedPoints = 0;
261 }
262
264 const char* serialize(const class btPersistentManifold* manifold, void* dataBuffer, class btSerializer* serializer) const;
265 void deSerialize(const struct btPersistentManifoldDoubleData* manifoldDataPtr);
266 void deSerialize(const struct btPersistentManifoldFloatData* manifoldDataPtr);
267};
268
269// clang-format off
270
272{
302
307
312
315};
316
317
319{
349
354
359
362};
363
364// clang-format on
365
366#ifdef BT_USE_DOUBLE_PRECISION
367#define btPersistentManifoldData btPersistentManifoldDoubleData
368#define btPersistentManifoldDataName "btPersistentManifoldDoubleData"
369#else
370#define btPersistentManifoldData btPersistentManifoldFloatData
371#define btPersistentManifoldDataName "btPersistentManifoldFloatData"
372#endif //BT_USE_DOUBLE_PRECISION
373
374#endif //BT_PERSISTENT_MANIFOLD_H
@ BT_CONTACT_FLAG_FRICTION_ANCHOR
void(* ContactEndedCallback)(btPersistentManifold *const &manifold)
ContactEndedCallback gContactEndedCallback
ContactStartedCallback gContactStartedCallback
void(* ContactStartedCallback)(btPersistentManifold *const &manifold)
ContactProcessedCallback gContactProcessedCallback
bool(* ContactDestroyedCallback)(void *userPersistentData)
btContactManifoldTypes
@ MIN_CONTACT_MANIFOLD_TYPE
@ BT_PERSISTENT_MANIFOLD_TYPE
ContactDestroyedCallback gContactDestroyedCallback
#define MANIFOLD_CACHE_SIZE
btScalar gContactBreakingThreshold
maximum contact breaking and merging threshold
bool(* ContactProcessedCallback)(btManifoldPoint &cp, void *body0, void *body1)
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 btAssert(x)
Definition: btScalar.h:153
btCollisionObject can be used to manage collision detection objects.
ManifoldContactPoint collects and maintains persistent contactpoints.
int getLifeTime() const
btScalar m_appliedImpulseLateral2
btScalar m_appliedImpulse
void * m_userPersistentData
btScalar m_appliedImpulseLateral1
btScalar m_combinedFriction
btPersistentManifold is a contact point cache, it stays persistent as long as objects are overlapping...
const btCollisionObject * m_body1
const btManifoldPoint & getContactPoint(int index) const
bool validContactDistance(const btManifoldPoint &pt) const
const char * serialize(const class btPersistentManifold *manifold, void *dataBuffer, class btSerializer *serializer) const
const btCollisionObject * getBody0() const
int getCacheEntry(const btManifoldPoint &newPoint) const
void replaceContactPoint(const btManifoldPoint &newPoint, int insertIndex)
void setContactBreakingThreshold(btScalar contactBreakingThreshold)
btManifoldPoint & getContactPoint(int index)
void refreshContactPoints(const btTransform &trA, const btTransform &trB)
calculated new worldspace coordinates and depth, and reject points that exceed the collision margin
int calculateSerializeBufferSize() const
int sortCachedPoints(const btManifoldPoint &pt)
sort cached points so most isolated points come first
void setBodies(const btCollisionObject *body0, const btCollisionObject *body1)
int findContactPoint(const btManifoldPoint *unUsed, int numUnused, const btManifoldPoint &pt)
const btCollisionObject * getBody1() const
void clearUserCache(btManifoldPoint &pt)
void removeContactPoint(int index)
void deSerialize(const struct btPersistentManifoldDoubleData *manifoldDataPtr)
void setNumContacts(int cachedPoints)
the setNumContacts API is usually not used, except when you gather/fill all contacts manually
int addManifoldPoint(const btManifoldPoint &newPoint, bool isPredictive=false)
btScalar getContactBreakingThreshold() const
btScalar getContactProcessingThreshold() const
void setContactProcessingThreshold(btScalar contactProcessingThreshold)
btPersistentManifold(const btCollisionObject *body0, const btCollisionObject *body1, int, btScalar contactBreakingThreshold, btScalar contactProcessingThreshold)
const btCollisionObject * m_body0
this two body pointers can point to the physics rigidbody class.
btManifoldPoint m_pointCache[MANIFOLD_CACHE_SIZE]
The btTransform class supports rigid transforms with only translation and rotation and no scaling/she...
Definition: btTransform.h:30
const btScalar eps
Definition: poly34.cpp:11
do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64
do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64
btVector3DoubleData m_pointCacheLateralFrictionDir1[4]
btVector3DoubleData m_pointCachePositionWorldOnB[4]
btVector3DoubleData m_pointCacheLocalPointB[4]
btVector3DoubleData m_pointCachePositionWorldOnA[4]
btVector3DoubleData m_pointCacheNormalWorldOnB[4]
btCollisionObjectDoubleData * m_body0
btCollisionObjectDoubleData * m_body1
btVector3DoubleData m_pointCacheLateralFrictionDir2[4]
btVector3DoubleData m_pointCacheLocalPointA[4]
btCollisionObjectFloatData * m_body1
btVector3FloatData m_pointCacheNormalWorldOnB[4]
btVector3FloatData m_pointCacheLocalPointB[4]
btCollisionObjectFloatData * m_body0
btVector3FloatData m_pointCachePositionWorldOnB[4]
btVector3FloatData m_pointCacheLocalPointA[4]
btVector3FloatData m_pointCachePositionWorldOnA[4]
btVector3FloatData m_pointCacheLateralFrictionDir1[4]
btVector3FloatData m_pointCacheLateralFrictionDir2[4]
rudimentary class to provide type info
Definition: btScalar.h:800