Bullet Collision Detection & Physics Library
btPolyhedralContactClipping.cpp
Go to the documentation of this file.
1 /*
2 Bullet Continuous Collision Detection and Physics Library
3 Copyright (c) 2011 Advanced Micro Devices, Inc. http://bulletphysics.org
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 
20 
21 
24 
25 #include <float.h> //for FLT_MAX
26 
29 bool gUseInternalObject = true;
30 
31 // Clips a face to the back of a plane
32 void btPolyhedralContactClipping::clipFace(const btVertexArray& pVtxIn, btVertexArray& ppVtxOut, const btVector3& planeNormalWS,btScalar planeEqWS)
33 {
34 
35  int ve;
36  btScalar ds, de;
37  int numVerts = pVtxIn.size();
38  if (numVerts < 2)
39  return;
40 
41  btVector3 firstVertex=pVtxIn[pVtxIn.size()-1];
42  btVector3 endVertex = pVtxIn[0];
43 
44  ds = planeNormalWS.dot(firstVertex)+planeEqWS;
45 
46  for (ve = 0; ve < numVerts; ve++)
47  {
48  endVertex=pVtxIn[ve];
49 
50  de = planeNormalWS.dot(endVertex)+planeEqWS;
51 
52  if (ds<0)
53  {
54  if (de<0)
55  {
56  // Start < 0, end < 0, so output endVertex
57  ppVtxOut.push_back(endVertex);
58  }
59  else
60  {
61  // Start < 0, end >= 0, so output intersection
62  ppVtxOut.push_back( firstVertex.lerp(endVertex,btScalar(ds * 1.f/(ds - de))));
63  }
64  }
65  else
66  {
67  if (de<0)
68  {
69  // Start >= 0, end < 0 so output intersection and end
70  ppVtxOut.push_back(firstVertex.lerp(endVertex,btScalar(ds * 1.f/(ds - de))));
71  ppVtxOut.push_back(endVertex);
72  }
73  }
74  firstVertex = endVertex;
75  ds = de;
76  }
77 }
78 
79 
80 static bool TestSepAxis(const btConvexPolyhedron& hullA, const btConvexPolyhedron& hullB, const btTransform& transA,const btTransform& transB, const btVector3& sep_axis, btScalar& depth, btVector3& witnessPointA, btVector3& witnessPointB)
81 {
82  btScalar Min0,Max0;
83  btScalar Min1,Max1;
84  btVector3 witnesPtMinA,witnesPtMaxA;
85  btVector3 witnesPtMinB,witnesPtMaxB;
86 
87  hullA.project(transA,sep_axis, Min0, Max0,witnesPtMinA,witnesPtMaxA);
88  hullB.project(transB, sep_axis, Min1, Max1,witnesPtMinB,witnesPtMaxB);
89 
90  if(Max0<Min1 || Max1<Min0)
91  return false;
92 
93  btScalar d0 = Max0 - Min1;
94  btAssert(d0>=0.0f);
95  btScalar d1 = Max1 - Min0;
96  btAssert(d1>=0.0f);
97  if (d0<d1)
98  {
99  depth = d0;
100  witnessPointA = witnesPtMaxA;
101  witnessPointB = witnesPtMinB;
102 
103  } else
104  {
105  depth = d1;
106  witnessPointA = witnesPtMinA;
107  witnessPointB = witnesPtMaxB;
108  }
109 
110  return true;
111 }
112 
113 
114 
115 static int gActualSATPairTests=0;
116 
117 inline bool IsAlmostZero(const btVector3& v)
118 {
119  if(btFabs(v.x())>1e-6 || btFabs(v.y())>1e-6 || btFabs(v.z())>1e-6) return false;
120  return true;
121 }
122 
123 #ifdef TEST_INTERNAL_OBJECTS
124 
125 inline void BoxSupport(const btScalar extents[3], const btScalar sv[3], btScalar p[3])
126 {
127  // This version is ~11.000 cycles (4%) faster overall in one of the tests.
128 // IR(p[0]) = IR(extents[0])|(IR(sv[0])&SIGN_BITMASK);
129 // IR(p[1]) = IR(extents[1])|(IR(sv[1])&SIGN_BITMASK);
130 // IR(p[2]) = IR(extents[2])|(IR(sv[2])&SIGN_BITMASK);
131  p[0] = sv[0] < 0.0f ? -extents[0] : extents[0];
132  p[1] = sv[1] < 0.0f ? -extents[1] : extents[1];
133  p[2] = sv[2] < 0.0f ? -extents[2] : extents[2];
134 }
135 
136 void InverseTransformPoint3x3(btVector3& out, const btVector3& in, const btTransform& tr)
137 {
138  const btMatrix3x3& rot = tr.getBasis();
139  const btVector3& r0 = rot[0];
140  const btVector3& r1 = rot[1];
141  const btVector3& r2 = rot[2];
142 
143  const btScalar x = r0.x()*in.x() + r1.x()*in.y() + r2.x()*in.z();
144  const btScalar y = r0.y()*in.x() + r1.y()*in.y() + r2.y()*in.z();
145  const btScalar z = r0.z()*in.x() + r1.z()*in.y() + r2.z()*in.z();
146 
147  out.setValue(x, y, z);
148 }
149 
150  bool TestInternalObjects( const btTransform& trans0, const btTransform& trans1, const btVector3& delta_c, const btVector3& axis, const btConvexPolyhedron& convex0, const btConvexPolyhedron& convex1, btScalar dmin)
151 {
152  const btScalar dp = delta_c.dot(axis);
153 
154  btVector3 localAxis0;
155  InverseTransformPoint3x3(localAxis0, axis,trans0);
156  btVector3 localAxis1;
157  InverseTransformPoint3x3(localAxis1, axis,trans1);
158 
159  btScalar p0[3];
160  BoxSupport(convex0.m_extents, localAxis0, p0);
161  btScalar p1[3];
162  BoxSupport(convex1.m_extents, localAxis1, p1);
163 
164  const btScalar Radius0 = p0[0]*localAxis0.x() + p0[1]*localAxis0.y() + p0[2]*localAxis0.z();
165  const btScalar Radius1 = p1[0]*localAxis1.x() + p1[1]*localAxis1.y() + p1[2]*localAxis1.z();
166 
167  const btScalar MinRadius = Radius0>convex0.m_radius ? Radius0 : convex0.m_radius;
168  const btScalar MaxRadius = Radius1>convex1.m_radius ? Radius1 : convex1.m_radius;
169 
170  const btScalar MinMaxRadius = MaxRadius + MinRadius;
171  const btScalar d0 = MinMaxRadius + dp;
172  const btScalar d1 = MinMaxRadius - dp;
173 
174  const btScalar depth = d0<d1 ? d0:d1;
175  if(depth>dmin)
176  return false;
177  return true;
178 }
179 #endif //TEST_INTERNAL_OBJECTS
180 
181 
182 
184  btVector3& ptsVector,
185  btVector3& offsetA,
186  btVector3& offsetB,
187  btScalar& tA, btScalar& tB,
188  const btVector3& translation,
189  const btVector3& dirA, btScalar hlenA,
190  const btVector3& dirB, btScalar hlenB )
191 {
192  // compute the parameters of the closest points on each line segment
193 
194  btScalar dirA_dot_dirB = btDot(dirA,dirB);
195  btScalar dirA_dot_trans = btDot(dirA,translation);
196  btScalar dirB_dot_trans = btDot(dirB,translation);
197 
198  btScalar denom = 1.0f - dirA_dot_dirB * dirA_dot_dirB;
199 
200  if ( denom == 0.0f ) {
201  tA = 0.0f;
202  } else {
203  tA = ( dirA_dot_trans - dirB_dot_trans * dirA_dot_dirB ) / denom;
204  if ( tA < -hlenA )
205  tA = -hlenA;
206  else if ( tA > hlenA )
207  tA = hlenA;
208  }
209 
210  tB = tA * dirA_dot_dirB - dirB_dot_trans;
211 
212  if ( tB < -hlenB ) {
213  tB = -hlenB;
214  tA = tB * dirA_dot_dirB + dirA_dot_trans;
215 
216  if ( tA < -hlenA )
217  tA = -hlenA;
218  else if ( tA > hlenA )
219  tA = hlenA;
220  } else if ( tB > hlenB ) {
221  tB = hlenB;
222  tA = tB * dirA_dot_dirB + dirA_dot_trans;
223 
224  if ( tA < -hlenA )
225  tA = -hlenA;
226  else if ( tA > hlenA )
227  tA = hlenA;
228  }
229 
230  // compute the closest points relative to segment centers.
231 
232  offsetA = dirA * tA;
233  offsetB = dirB * tB;
234 
235  ptsVector = translation - offsetA + offsetB;
236 }
237 
238 
239 
241 {
243 
244 //#ifdef TEST_INTERNAL_OBJECTS
245  const btVector3 c0 = transA * hullA.m_localCenter;
246  const btVector3 c1 = transB * hullB.m_localCenter;
247  const btVector3 DeltaC2 = c0 - c1;
248 //#endif
249 
250  btScalar dmin = FLT_MAX;
251  int curPlaneTests=0;
252 
253  int numFacesA = hullA.m_faces.size();
254  // Test normals from hullA
255  for(int i=0;i<numFacesA;i++)
256  {
257  const btVector3 Normal(hullA.m_faces[i].m_plane[0], hullA.m_faces[i].m_plane[1], hullA.m_faces[i].m_plane[2]);
258  btVector3 faceANormalWS = transA.getBasis() * Normal;
259  if (DeltaC2.dot(faceANormalWS)<0)
260  faceANormalWS*=-1.f;
261 
262  curPlaneTests++;
263 #ifdef TEST_INTERNAL_OBJECTS
265  if(gUseInternalObject && !TestInternalObjects(transA,transB, DeltaC2, faceANormalWS, hullA, hullB, dmin))
266  continue;
267  gActualNbTests++;
268 #endif
269 
270  btScalar d;
271  btVector3 wA,wB;
272  if(!TestSepAxis( hullA, hullB, transA,transB, faceANormalWS, d,wA,wB))
273  return false;
274 
275  if(d<dmin)
276  {
277  dmin = d;
278  sep = faceANormalWS;
279  }
280  }
281 
282  int numFacesB = hullB.m_faces.size();
283  // Test normals from hullB
284  for(int i=0;i<numFacesB;i++)
285  {
286  const btVector3 Normal(hullB.m_faces[i].m_plane[0], hullB.m_faces[i].m_plane[1], hullB.m_faces[i].m_plane[2]);
287  btVector3 WorldNormal = transB.getBasis() * Normal;
288  if (DeltaC2.dot(WorldNormal)<0)
289  WorldNormal *=-1.f;
290 
291  curPlaneTests++;
292 #ifdef TEST_INTERNAL_OBJECTS
294  if(gUseInternalObject && !TestInternalObjects(transA,transB,DeltaC2, WorldNormal, hullA, hullB, dmin))
295  continue;
296  gActualNbTests++;
297 #endif
298 
299  btScalar d;
300  btVector3 wA,wB;
301  if(!TestSepAxis(hullA, hullB,transA,transB, WorldNormal,d,wA,wB))
302  return false;
303 
304  if(d<dmin)
305  {
306  dmin = d;
307  sep = WorldNormal;
308  }
309  }
310 
311  btVector3 edgeAstart,edgeAend,edgeBstart,edgeBend;
312  int edgeA=-1;
313  int edgeB=-1;
314  btVector3 worldEdgeA;
315  btVector3 worldEdgeB;
316  btVector3 witnessPointA(0,0,0),witnessPointB(0,0,0);
317 
318 
319  int curEdgeEdge = 0;
320  // Test edges
321  for(int e0=0;e0<hullA.m_uniqueEdges.size();e0++)
322  {
323  const btVector3 edge0 = hullA.m_uniqueEdges[e0];
324  const btVector3 WorldEdge0 = transA.getBasis() * edge0;
325  for(int e1=0;e1<hullB.m_uniqueEdges.size();e1++)
326  {
327  const btVector3 edge1 = hullB.m_uniqueEdges[e1];
328  const btVector3 WorldEdge1 = transB.getBasis() * edge1;
329 
330  btVector3 Cross = WorldEdge0.cross(WorldEdge1);
331  curEdgeEdge++;
332  if(!IsAlmostZero(Cross))
333  {
334  Cross = Cross.normalize();
335  if (DeltaC2.dot(Cross)<0)
336  Cross *= -1.f;
337 
338 
339 #ifdef TEST_INTERNAL_OBJECTS
341  if(gUseInternalObject && !TestInternalObjects(transA,transB,DeltaC2, Cross, hullA, hullB, dmin))
342  continue;
343  gActualNbTests++;
344 #endif
345 
346  btScalar dist;
347  btVector3 wA,wB;
348  if(!TestSepAxis( hullA, hullB, transA,transB, Cross, dist,wA,wB))
349  return false;
350 
351  if(dist<dmin)
352  {
353  dmin = dist;
354  sep = Cross;
355  edgeA=e0;
356  edgeB=e1;
357  worldEdgeA = WorldEdge0;
358  worldEdgeB = WorldEdge1;
359  witnessPointA=wA;
360  witnessPointB=wB;
361  }
362  }
363  }
364 
365  }
366 
367  if (edgeA>=0&&edgeB>=0)
368  {
369 // printf("edge-edge\n");
370  //add an edge-edge contact
371 
372  btVector3 ptsVector;
373  btVector3 offsetA;
374  btVector3 offsetB;
375  btScalar tA;
376  btScalar tB;
377 
378  btVector3 translation = witnessPointB-witnessPointA;
379 
380  btVector3 dirA = worldEdgeA;
381  btVector3 dirB = worldEdgeB;
382 
383  btScalar hlenB = 1e30f;
384  btScalar hlenA = 1e30f;
385 
386  btSegmentsClosestPoints(ptsVector,offsetA,offsetB,tA,tB,
387  translation,
388  dirA, hlenA,
389  dirB,hlenB);
390 
391  btScalar nlSqrt = ptsVector.length2();
392  if (nlSqrt>SIMD_EPSILON)
393  {
394  btScalar nl = btSqrt(nlSqrt);
395  ptsVector *= 1.f/nl;
396  if (ptsVector.dot(DeltaC2)<0.f)
397  {
398  ptsVector*=-1.f;
399  }
400  btVector3 ptOnB = witnessPointB + offsetB;
401  btScalar distance = nl;
402  resultOut.addContactPoint(ptsVector, ptOnB,-distance);
403  }
404 
405  }
406 
407 
408  if((DeltaC2.dot(sep))<0.0f)
409  sep = -sep;
410 
411  return true;
412 }
413 
414 void btPolyhedralContactClipping::clipFaceAgainstHull(const btVector3& separatingNormal, const btConvexPolyhedron& hullA, const btTransform& transA, btVertexArray& worldVertsB1,btVertexArray& worldVertsB2, const btScalar minDist, btScalar maxDist,btDiscreteCollisionDetectorInterface::Result& resultOut)
415 {
416  worldVertsB2.resize(0);
417  btVertexArray* pVtxIn = &worldVertsB1;
418  btVertexArray* pVtxOut = &worldVertsB2;
419  pVtxOut->reserve(pVtxIn->size());
420 
421  int closestFaceA=-1;
422  {
423  btScalar dmin = FLT_MAX;
424  for(int face=0;face<hullA.m_faces.size();face++)
425  {
426  const btVector3 Normal(hullA.m_faces[face].m_plane[0], hullA.m_faces[face].m_plane[1], hullA.m_faces[face].m_plane[2]);
427  const btVector3 faceANormalWS = transA.getBasis() * Normal;
428 
429  btScalar d = faceANormalWS.dot(separatingNormal);
430  if (d < dmin)
431  {
432  dmin = d;
433  closestFaceA = face;
434  }
435  }
436  }
437  if (closestFaceA<0)
438  return;
439 
440  const btFace& polyA = hullA.m_faces[closestFaceA];
441 
442  // clip polygon to back of planes of all faces of hull A that are adjacent to witness face
443  int numVerticesA = polyA.m_indices.size();
444  for(int e0=0;e0<numVerticesA;e0++)
445  {
446  const btVector3& a = hullA.m_vertices[polyA.m_indices[e0]];
447  const btVector3& b = hullA.m_vertices[polyA.m_indices[(e0+1)%numVerticesA]];
448  const btVector3 edge0 = a - b;
449  const btVector3 WorldEdge0 = transA.getBasis() * edge0;
450  btVector3 worldPlaneAnormal1 = transA.getBasis()* btVector3(polyA.m_plane[0],polyA.m_plane[1],polyA.m_plane[2]);
451 
452  btVector3 planeNormalWS1 = -WorldEdge0.cross(worldPlaneAnormal1);//.cross(WorldEdge0);
453  btVector3 worldA1 = transA*a;
454  btScalar planeEqWS1 = -worldA1.dot(planeNormalWS1);
455 
456 //int otherFace=0;
457 #ifdef BLA1
458  int otherFace = polyA.m_connectedFaces[e0];
459  btVector3 localPlaneNormal (hullA.m_faces[otherFace].m_plane[0],hullA.m_faces[otherFace].m_plane[1],hullA.m_faces[otherFace].m_plane[2]);
460  btScalar localPlaneEq = hullA.m_faces[otherFace].m_plane[3];
461 
462  btVector3 planeNormalWS = transA.getBasis()*localPlaneNormal;
463  btScalar planeEqWS=localPlaneEq-planeNormalWS.dot(transA.getOrigin());
464 #else
465  btVector3 planeNormalWS = planeNormalWS1;
466  btScalar planeEqWS=planeEqWS1;
467 
468 #endif
469  //clip face
470 
471  clipFace(*pVtxIn, *pVtxOut,planeNormalWS,planeEqWS);
472  btSwap(pVtxIn,pVtxOut);
473  pVtxOut->resize(0);
474  }
475 
476 
477 
478 //#define ONLY_REPORT_DEEPEST_POINT
479 
480  btVector3 point;
481 
482 
483  // only keep points that are behind the witness face
484  {
485  btVector3 localPlaneNormal (polyA.m_plane[0],polyA.m_plane[1],polyA.m_plane[2]);
486  btScalar localPlaneEq = polyA.m_plane[3];
487  btVector3 planeNormalWS = transA.getBasis()*localPlaneNormal;
488  btScalar planeEqWS=localPlaneEq-planeNormalWS.dot(transA.getOrigin());
489  for (int i=0;i<pVtxIn->size();i++)
490  {
491  btVector3 vtx = pVtxIn->at(i);
492  btScalar depth = planeNormalWS.dot(vtx)+planeEqWS;
493  if (depth <=minDist)
494  {
495 // printf("clamped: depth=%f to minDist=%f\n",depth,minDist);
496  depth = minDist;
497  }
498 
499  if (depth <=maxDist)
500  {
501  btVector3 point = pVtxIn->at(i);
502 #ifdef ONLY_REPORT_DEEPEST_POINT
503  curMaxDist = depth;
504 #else
505 #if 0
506  if (depth<-3)
507  {
508  printf("error in btPolyhedralContactClipping depth = %f\n", depth);
509  printf("likely wrong separatingNormal passed in\n");
510  }
511 #endif
512  resultOut.addContactPoint(separatingNormal,point,depth);
513 #endif
514  }
515  }
516  }
517 #ifdef ONLY_REPORT_DEEPEST_POINT
518  if (curMaxDist<maxDist)
519  {
520  resultOut.addContactPoint(separatingNormal,point,curMaxDist);
521  }
522 #endif //ONLY_REPORT_DEEPEST_POINT
523 
524 }
525 
526 
527 
528 
529 
530 void btPolyhedralContactClipping::clipHullAgainstHull(const btVector3& separatingNormal1, const btConvexPolyhedron& hullA, const btConvexPolyhedron& hullB, const btTransform& transA,const btTransform& transB, const btScalar minDist, btScalar maxDist,btVertexArray& worldVertsB1,btVertexArray& worldVertsB2,btDiscreteCollisionDetectorInterface::Result& resultOut)
531 {
532 
533  btVector3 separatingNormal = separatingNormal1.normalized();
534 // const btVector3 c0 = transA * hullA.m_localCenter;
535 // const btVector3 c1 = transB * hullB.m_localCenter;
536  //const btVector3 DeltaC2 = c0 - c1;
537 
538 
539 
540  int closestFaceB=-1;
541  btScalar dmax = -FLT_MAX;
542  {
543  for(int face=0;face<hullB.m_faces.size();face++)
544  {
545  const btVector3 Normal(hullB.m_faces[face].m_plane[0], hullB.m_faces[face].m_plane[1], hullB.m_faces[face].m_plane[2]);
546  const btVector3 WorldNormal = transB.getBasis() * Normal;
547  btScalar d = WorldNormal.dot(separatingNormal);
548  if (d > dmax)
549  {
550  dmax = d;
551  closestFaceB = face;
552  }
553  }
554  }
555  worldVertsB1.resize(0);
556  {
557  const btFace& polyB = hullB.m_faces[closestFaceB];
558  const int numVertices = polyB.m_indices.size();
559  for(int e0=0;e0<numVertices;e0++)
560  {
561  const btVector3& b = hullB.m_vertices[polyB.m_indices[e0]];
562  worldVertsB1.push_back(transB*b);
563  }
564  }
565 
566 
567  if (closestFaceB>=0)
568  clipFaceAgainstHull(separatingNormal, hullA, transA,worldVertsB1, worldVertsB2,minDist, maxDist,resultOut);
569 
570 }
#define SIMD_EPSILON
Definition: btScalar.h:521
btAlignedObjectArray< btVector3 > m_vertices
bool gUseInternalObject
void push_back(const T &_Val)
void setValue(const btScalar &_x, const btScalar &_y, const btScalar &_z)
Definition: btVector3.h:652
const T & at(int n) const
static void clipFaceAgainstHull(const btVector3 &separatingNormal, const btConvexPolyhedron &hullA, const btTransform &transA, btVertexArray &worldVertsB1, btVertexArray &worldVertsB2, const btScalar minDist, btScalar maxDist, btDiscreteCollisionDetectorInterface::Result &resultOut)
btScalar btSqrt(btScalar y)
Definition: btScalar.h:444
#define btAssert(x)
Definition: btScalar.h:131
#define SIMD_FORCE_INLINE
Definition: btScalar.h:81
btAlignedObjectArray< btVector3 > m_uniqueEdges
btScalar dot(const btVector3 &v) const
Return the dot product.
Definition: btVector3.h:235
void btSegmentsClosestPoints(btVector3 &ptsVector, btVector3 &offsetA, btVector3 &offsetB, btScalar &tA, btScalar &tB, const btVector3 &translation, const btVector3 &dirA, btScalar hlenA, const btVector3 &dirB, btScalar hlenB)
static int gActualSATPairTests
btVector3 lerp(const btVector3 &v, const btScalar &t) const
Return the linear interpolation between this and another vector.
Definition: btVector3.h:532
btVector3 & normalize()
Normalize this vector x^2 + y^2 + z^2 = 1.
Definition: btVector3.h:309
const btScalar & x() const
Return the x value.
Definition: btVector3.h:587
static bool TestSepAxis(const btConvexPolyhedron &hullA, const btConvexPolyhedron &hullB, const btTransform &transA, const btTransform &transB, const btVector3 &sep_axis, btScalar &depth, btVector3 &witnessPointA, btVector3 &witnessPointB)
btAlignedObjectArray< int > m_indices
int size() const
return the number of elements in the array
btVector3 & getOrigin()
Return the origin vector translation.
Definition: btTransform.h:117
btAlignedObjectArray< btFace > m_faces
void btSwap(T &a, T &b)
Definition: btScalar.h:621
btVector3 cross(const btVector3 &v) const
Return the cross product between this and another vector.
Definition: btVector3.h:389
btMatrix3x3 & getBasis()
Return the basis matrix for the rotation.
Definition: btTransform.h:112
static btMatrix3x3 Cross(const btVector3 &v)
const btScalar & y() const
Return the y value.
Definition: btVector3.h:589
int gExpectedNbTests
This file was written by Erwin Coumans Separating axis rest based on work from Pierre Terdiman...
btVector3 can be used to represent 3D points and vectors.
Definition: btVector3.h:83
btScalar length2() const
Return the length of the vector squared.
Definition: btVector3.h:257
The btTransform class supports rigid transforms with only translation and rotation and no scaling/she...
Definition: btTransform.h:34
virtual void addContactPoint(const btVector3 &normalOnBInWorld, const btVector3 &pointInWorld, btScalar depth)=0
btVector3 normalized() const
Return a normalized version of this vector.
Definition: btVector3.h:966
btScalar m_plane[4]
void resize(int newsize, const T &fillData=T())
static void clipFace(const btVertexArray &pVtxIn, btVertexArray &ppVtxOut, const btVector3 &planeNormalWS, btScalar planeEqWS)
the clipFace method is used internally
static bool findSeparatingAxis(const btConvexPolyhedron &hullA, const btConvexPolyhedron &hullB, const btTransform &transA, const btTransform &transB, btVector3 &sep, btDiscreteCollisionDetectorInterface::Result &resultOut)
static void clipHullAgainstHull(const btVector3 &separatingNormal1, const btConvexPolyhedron &hullA, const btConvexPolyhedron &hullB, const btTransform &transA, const btTransform &transB, const btScalar minDist, btScalar maxDist, btVertexArray &worldVertsB1, btVertexArray &worldVertsB2, btDiscreteCollisionDetectorInterface::Result &resultOut)
The btMatrix3x3 class implements a 3x3 rotation matrix, to perform linear algebra in combination with...
Definition: btMatrix3x3.h:48
void project(const btTransform &trans, const btVector3 &dir, btScalar &minProj, btScalar &maxProj, btVector3 &witnesPtMin, btVector3 &witnesPtMax) const
btScalar btDot(const btVector3 &v1, const btVector3 &v2)
Return the dot product between two vectors.
Definition: btVector3.h:903
bool IsAlmostZero(const btVector3 &v)
float btScalar
The btScalar type abstracts floating point numbers, to easily switch between double and single floati...
Definition: btScalar.h:292
btScalar btFabs(btScalar x)
Definition: btScalar.h:475
const btScalar & z() const
Return the z value.
Definition: btVector3.h:591