Bullet Collision Detection & Physics Library
btPersistentManifold.cpp
Go to the documentation of this file.
1/*
2Bullet Continuous Collision Detection and Physics Library
3Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
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
19
20
29
30
33m_body0(0),
34m_body1(0),
35m_cachedPoints (0),
36m_index1a(0)
37{
38}
39
40
41
42
43#ifdef DEBUG_PERSISTENCY
44#include <stdio.h>
45void btPersistentManifold::DebugPersistency()
46{
47 int i;
48 printf("DebugPersistency : numPoints %d\n",m_cachedPoints);
49 for (i=0;i<m_cachedPoints;i++)
50 {
51 printf("m_pointCache[%d].m_userPersistentData = %x\n",i,m_pointCache[i].m_userPersistentData);
52 }
53}
54#endif //DEBUG_PERSISTENCY
55
57{
58
59 void* oldPtr = pt.m_userPersistentData;
60 if (oldPtr)
61 {
62#ifdef DEBUG_PERSISTENCY
63 int i;
64 int occurance = 0;
65 for (i=0;i<m_cachedPoints;i++)
66 {
67 if (m_pointCache[i].m_userPersistentData == oldPtr)
68 {
69 occurance++;
70 if (occurance>1)
71 printf("error in clearUserCache\n");
72 }
73 }
75#endif //DEBUG_PERSISTENCY
76
77 if (pt.m_userPersistentData && gContactDestroyedCallback)
78 {
79 (*gContactDestroyedCallback)(pt.m_userPersistentData);
80 pt.m_userPersistentData = 0;
81 }
82
83#ifdef DEBUG_PERSISTENCY
85#endif
86 }
87
88
89}
90
91static inline btScalar calcArea4Points(const btVector3 &p0,const btVector3 &p1,const btVector3 &p2,const btVector3 &p3)
92{
93 // It calculates possible 3 area constructed from random 4 points and returns the biggest one.
94
95 btVector3 a[3],b[3];
96 a[0] = p0 - p1;
97 a[1] = p0 - p2;
98 a[2] = p0 - p3;
99 b[0] = p2 - p3;
100 b[1] = p1 - p3;
101 b[2] = p1 - p2;
102
103 //todo: Following 3 cross production can be easily optimized by SIMD.
104 btVector3 tmp0 = a[0].cross(b[0]);
105 btVector3 tmp1 = a[1].cross(b[1]);
106 btVector3 tmp2 = a[2].cross(b[2]);
107
108 return btMax(btMax(tmp0.length2(),tmp1.length2()),tmp2.length2());
109}
110
112{
113 //calculate 4 possible cases areas, and take biggest area
114 //also need to keep 'deepest'
115
116 int maxPenetrationIndex = -1;
117#define KEEP_DEEPEST_POINT 1
118#ifdef KEEP_DEEPEST_POINT
119 btScalar maxPenetration = pt.getDistance();
120 for (int i=0;i<4;i++)
121 {
122 if (m_pointCache[i].getDistance() < maxPenetration)
123 {
126 }
127 }
128#endif //KEEP_DEEPEST_POINT
129
131
133 {
134 if (maxPenetrationIndex != 0)
135 {
136 btVector3 a0 = pt.m_localPointA-m_pointCache[1].m_localPointA;
138 btVector3 cross = a0.cross(b0);
139 res0 = cross.length2();
140 }
141 if (maxPenetrationIndex != 1)
142 {
143 btVector3 a1 = pt.m_localPointA-m_pointCache[0].m_localPointA;
145 btVector3 cross = a1.cross(b1);
146 res1 = cross.length2();
147 }
148
149 if (maxPenetrationIndex != 2)
150 {
151 btVector3 a2 = pt.m_localPointA-m_pointCache[0].m_localPointA;
153 btVector3 cross = a2.cross(b2);
154 res2 = cross.length2();
155 }
156
157 if (maxPenetrationIndex != 3)
158 {
159 btVector3 a3 = pt.m_localPointA-m_pointCache[0].m_localPointA;
161 btVector3 cross = a3.cross(b3);
162 res3 = cross.length2();
163 }
164 }
165 else
166 {
167 if(maxPenetrationIndex != 0) {
169 }
170
171 if(maxPenetrationIndex != 1) {
173 }
174
175 if(maxPenetrationIndex != 2) {
177 }
178
179 if(maxPenetrationIndex != 3) {
181 }
182 }
184 int biggestarea = maxvec.closestAxis4();
185 return biggestarea;
186
187}
188
189
191{
193 int size = getNumContacts();
194 int nearestPoint = -1;
195 for( int i = 0; i < size; i++ )
196 {
197 const btManifoldPoint &mp = m_pointCache[i];
198
199 btVector3 diffA = mp.m_localPointA- newPoint.m_localPointA;
202 {
204 nearestPoint = i;
205 }
206 }
207 return nearestPoint;
208}
209
211{
212 if (!isPredictive)
213 {
215 }
216
219 {
220#if MANIFOLD_CACHE_SIZE >= 4
221 //sort cache so best points come first, based on area
223#else
224 insertIndex = 0;
225#endif
227
228 } else
229 {
231
232
233 }
234 if (insertIndex<0)
235 insertIndex=0;
236
237 btAssert(m_pointCache[insertIndex].m_userPersistentData==0);
239 return insertIndex;
240}
241
243{
245}
246
247
248
250{
251 int i;
252#ifdef DEBUG_PERSISTENCY
253 printf("refreshContactPoints posA = (%f,%f,%f) posB = (%f,%f,%f)\n",
254 trA.getOrigin().getX(),
255 trA.getOrigin().getY(),
256 trA.getOrigin().getZ(),
257 trB.getOrigin().getX(),
258 trB.getOrigin().getY(),
259 trB.getOrigin().getZ());
260#endif //DEBUG_PERSISTENCY
262 for (i=getNumContacts()-1;i>=0;i--)
263 {
266 manifoldPoint.m_positionWorldOnB = trB( manifoldPoint.m_localPointB );
267 manifoldPoint.m_distance1 = (manifoldPoint.m_positionWorldOnA - manifoldPoint.m_positionWorldOnB).dot(manifoldPoint.m_normalWorldOnB);
268 manifoldPoint.m_lifeTime++;
269 }
270
274 for (i=getNumContacts()-1;i>=0;i--)
275 {
276
278 //contact becomes invalid when signed distance exceeds margin (projected on contactnormal direction)
280 {
282 } else
283 {
284 //todo: friction anchor may require the contact to be around a bit longer
285 //contact also becomes invalid when relative movement orthogonal to normal exceeds margin
286 projectedPoint = manifoldPoint.m_positionWorldOnA - manifoldPoint.m_normalWorldOnB * manifoldPoint.m_distance1;
287 projectedDifference = manifoldPoint.m_positionWorldOnB - projectedPoint;
290 {
292 } else
293 {
294 //contact point processed callback
296 (*gContactProcessedCallback)(manifoldPoint,(void*)m_body0,(void*)m_body1);
297 }
298 }
299 }
300#ifdef DEBUG_PERSISTENCY
302#endif //
303}
304
305
306
307
308
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition btDbvt.cpp:52
const T & btMax(const T &a, const T &b)
Definition btMinMax.h:29
bool gContactCalcArea3Points
gContactCalcArea3Points will approximate the convex hull area using 3 points when setting it to false...
ContactEndedCallback gContactEndedCallback
static btScalar calcArea4Points(const btVector3 &p0, const btVector3 &p1, const btVector3 &p2, const btVector3 &p3)
ContactStartedCallback gContactStartedCallback
ContactProcessedCallback gContactProcessedCallback
ContactDestroyedCallback gContactDestroyedCallback
btScalar gContactBreakingThreshold
maximum contact breaking and merging threshold
void(* ContactEndedCallback)(btPersistentManifold *const &manifold)
ContactProcessedCallback gContactProcessedCallback
bool(* ContactDestroyedCallback)(void *userPersistentData)
void(* ContactStartedCallback)(btPersistentManifold *const &manifold)
@ BT_PERSISTENT_MANIFOLD_TYPE
ContactDestroyedCallback gContactDestroyedCallback
#define MANIFOLD_CACHE_SIZE
bool(* ContactProcessedCallback)(btManifoldPoint &cp, void *body0, void *body1)
btScalar dot(const btQuaternion &q1, const btQuaternion &q2)
Calculate the dot product between two quaternions.
float btScalar
The btScalar type abstracts floating point numbers, to easily switch between double and single floati...
Definition btScalar.h:292
#define btAssert(x)
Definition btScalar.h:131
ManifoldContactPoint collects and maintains persistent contactpoints.
btScalar getDistance() const
btVector3 m_localPointA
btVector3 m_positionWorldOnA
m_positionWorldOnA is redundant information, see getPositionWorldOnA(), but for clarity
const btCollisionObject * m_body1
bool validContactDistance(const btManifoldPoint &pt) const
int getCacheEntry(const btManifoldPoint &newPoint) const
void refreshContactPoints(const btTransform &trA, const btTransform &trB)
calculated new worldspace coordinates and depth, and reject points that exceed the collision margin
int sortCachedPoints(const btManifoldPoint &pt)
sort cached points so most isolated points come first
void clearUserCache(btManifoldPoint &pt)
void removeContactPoint(int index)
int addManifoldPoint(const btManifoldPoint &newPoint, bool isPredictive=false)
btScalar getContactBreakingThreshold() const
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:34
btVector3 can be used to represent 3D points and vectors.
Definition btVector3.h:84
btVector3 cross(const btVector3 &v) const
Return the cross product between this and another vector.
Definition btVector3.h:389
btScalar dot(const btVector3 &v) const
Return the dot product.
Definition btVector3.h:235
btScalar length2() const
Return the length of the vector squared.
Definition btVector3.h:257
rudimentary class to provide type info
Definition btScalar.h:778