| [1963] | 1 | /* | 
|---|
 | 2 |  * Box-Box collision detection re-distributed under the ZLib license with permission from Russell L. Smith | 
|---|
 | 3 |  * Original version is from Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. | 
|---|
 | 4 |  * All rights reserved.  Email: russ@q12.org   Web: www.q12.org | 
|---|
 | 5 |  Bullet Continuous Collision Detection and Physics Library | 
|---|
 | 6 |  Bullet is Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/ | 
|---|
 | 7 |  | 
|---|
 | 8 | This software is provided 'as-is', without any express or implied warranty. | 
|---|
 | 9 | In no event will the authors be held liable for any damages arising from the use of this software. | 
|---|
 | 10 | Permission is granted to anyone to use this software for any purpose,  | 
|---|
 | 11 | including commercial applications, and to alter it and redistribute it freely,  | 
|---|
 | 12 | subject to the following restrictions: | 
|---|
 | 13 |  | 
|---|
 | 14 | 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. | 
|---|
 | 15 | 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. | 
|---|
 | 16 | 3. This notice may not be removed or altered from any source distribution. | 
|---|
 | 17 | */ | 
|---|
 | 18 |  | 
|---|
 | 19 | ///ODE box-box collision detection is adapted to work with Bullet | 
|---|
 | 20 |  | 
|---|
 | 21 | #include "btBoxBoxDetector.h" | 
|---|
 | 22 | #include "BulletCollision/CollisionShapes/btBoxShape.h" | 
|---|
 | 23 |  | 
|---|
 | 24 | #include <float.h> | 
|---|
 | 25 | #include <string.h> | 
|---|
 | 26 |  | 
|---|
 | 27 | btBoxBoxDetector::btBoxBoxDetector(btBoxShape* box1,btBoxShape* box2) | 
|---|
 | 28 | : m_box1(box1), | 
|---|
 | 29 | m_box2(box2) | 
|---|
 | 30 | { | 
|---|
 | 31 |  | 
|---|
 | 32 | } | 
|---|
 | 33 |  | 
|---|
 | 34 |  | 
|---|
 | 35 | // given two boxes (p1,R1,side1) and (p2,R2,side2), collide them together and | 
|---|
 | 36 | // generate contact points. this returns 0 if there is no contact otherwise | 
|---|
 | 37 | // it returns the number of contacts generated. | 
|---|
 | 38 | // `normal' returns the contact normal. | 
|---|
 | 39 | // `depth' returns the maximum penetration depth along that normal. | 
|---|
 | 40 | // `return_code' returns a number indicating the type of contact that was | 
|---|
 | 41 | // detected: | 
|---|
 | 42 | //        1,2,3 = box 2 intersects with a face of box 1 | 
|---|
 | 43 | //        4,5,6 = box 1 intersects with a face of box 2 | 
|---|
 | 44 | //        7..15 = edge-edge contact | 
|---|
 | 45 | // `maxc' is the maximum number of contacts allowed to be generated, i.e. | 
|---|
 | 46 | // the size of the `contact' array. | 
|---|
 | 47 | // `contact' and `skip' are the contact array information provided to the | 
|---|
 | 48 | // collision functions. this function only fills in the position and depth | 
|---|
 | 49 | // fields. | 
|---|
 | 50 | struct dContactGeom; | 
|---|
 | 51 | #define dDOTpq(a,b,p,q) ((a)[0]*(b)[0] + (a)[p]*(b)[q] + (a)[2*(p)]*(b)[2*(q)]) | 
|---|
 | 52 | #define dInfinity FLT_MAX | 
|---|
 | 53 |  | 
|---|
 | 54 |  | 
|---|
 | 55 | /*PURE_INLINE btScalar dDOT   (const btScalar *a, const btScalar *b) { return dDOTpq(a,b,1,1); } | 
|---|
 | 56 | PURE_INLINE btScalar dDOT13 (const btScalar *a, const btScalar *b) { return dDOTpq(a,b,1,3); } | 
|---|
 | 57 | PURE_INLINE btScalar dDOT31 (const btScalar *a, const btScalar *b) { return dDOTpq(a,b,3,1); } | 
|---|
 | 58 | PURE_INLINE btScalar dDOT33 (const btScalar *a, const btScalar *b) { return dDOTpq(a,b,3,3); } | 
|---|
 | 59 | */ | 
|---|
 | 60 | static btScalar dDOT   (const btScalar *a, const btScalar *b) { return dDOTpq(a,b,1,1); } | 
|---|
 | 61 | static btScalar dDOT44 (const btScalar *a, const btScalar *b) { return dDOTpq(a,b,4,4); } | 
|---|
 | 62 | static btScalar dDOT41 (const btScalar *a, const btScalar *b) { return dDOTpq(a,b,4,1); } | 
|---|
 | 63 | static btScalar dDOT14 (const btScalar *a, const btScalar *b) { return dDOTpq(a,b,1,4); } | 
|---|
 | 64 | #define dMULTIPLYOP1_331(A,op,B,C) \ | 
|---|
 | 65 | {\ | 
|---|
 | 66 |   (A)[0] op dDOT41((B),(C)); \ | 
|---|
 | 67 |   (A)[1] op dDOT41((B+1),(C)); \ | 
|---|
 | 68 |   (A)[2] op dDOT41((B+2),(C)); \ | 
|---|
 | 69 | } | 
|---|
 | 70 |  | 
|---|
 | 71 | #define dMULTIPLYOP0_331(A,op,B,C) \ | 
|---|
 | 72 | { \ | 
|---|
 | 73 |   (A)[0] op dDOT((B),(C)); \ | 
|---|
 | 74 |   (A)[1] op dDOT((B+4),(C)); \ | 
|---|
 | 75 |   (A)[2] op dDOT((B+8),(C)); \ | 
|---|
 | 76 | }  | 
|---|
 | 77 |  | 
|---|
 | 78 | #define dMULTIPLY1_331(A,B,C) dMULTIPLYOP1_331(A,=,B,C) | 
|---|
 | 79 | #define dMULTIPLY0_331(A,B,C) dMULTIPLYOP0_331(A,=,B,C) | 
|---|
 | 80 |  | 
|---|
 | 81 | typedef btScalar dMatrix3[4*3]; | 
|---|
 | 82 |  | 
|---|
 | 83 | void dLineClosestApproach (const btVector3& pa, const btVector3& ua, | 
|---|
 | 84 |                            const btVector3& pb, const btVector3& ub, | 
|---|
 | 85 |                            btScalar *alpha, btScalar *beta); | 
|---|
 | 86 | void dLineClosestApproach (const btVector3& pa, const btVector3& ua, | 
|---|
 | 87 |                            const btVector3& pb, const btVector3& ub, | 
|---|
 | 88 |                            btScalar *alpha, btScalar *beta) | 
|---|
 | 89 | { | 
|---|
 | 90 |   btVector3 p; | 
|---|
 | 91 |   p[0] = pb[0] - pa[0]; | 
|---|
 | 92 |   p[1] = pb[1] - pa[1]; | 
|---|
 | 93 |   p[2] = pb[2] - pa[2]; | 
|---|
 | 94 |   btScalar uaub = dDOT(ua,ub); | 
|---|
 | 95 |   btScalar q1 =  dDOT(ua,p); | 
|---|
 | 96 |   btScalar q2 = -dDOT(ub,p); | 
|---|
 | 97 |   btScalar d = 1-uaub*uaub; | 
|---|
 | 98 |   if (d <= btScalar(0.0001f)) { | 
|---|
 | 99 |     // @@@ this needs to be made more robust | 
|---|
 | 100 |     *alpha = 0; | 
|---|
 | 101 |     *beta  = 0; | 
|---|
 | 102 |   } | 
|---|
 | 103 |   else { | 
|---|
 | 104 |     d = 1.f/d; | 
|---|
 | 105 |     *alpha = (q1 + uaub*q2)*d; | 
|---|
 | 106 |     *beta  = (uaub*q1 + q2)*d; | 
|---|
 | 107 |   } | 
|---|
 | 108 | } | 
|---|
 | 109 |  | 
|---|
 | 110 |  | 
|---|
 | 111 |  | 
|---|
 | 112 | // find all the intersection points between the 2D rectangle with vertices | 
|---|
 | 113 | // at (+/-h[0],+/-h[1]) and the 2D quadrilateral with vertices (p[0],p[1]), | 
|---|
 | 114 | // (p[2],p[3]),(p[4],p[5]),(p[6],p[7]). | 
|---|
 | 115 | // | 
|---|
 | 116 | // the intersection points are returned as x,y pairs in the 'ret' array. | 
|---|
 | 117 | // the number of intersection points is returned by the function (this will | 
|---|
 | 118 | // be in the range 0 to 8). | 
|---|
 | 119 |  | 
|---|
 | 120 | static int intersectRectQuad2 (btScalar h[2], btScalar p[8], btScalar ret[16]) | 
|---|
 | 121 | { | 
|---|
 | 122 |   // q (and r) contain nq (and nr) coordinate points for the current (and | 
|---|
 | 123 |   // chopped) polygons | 
|---|
 | 124 |   int nq=4,nr=0; | 
|---|
 | 125 |   btScalar buffer[16]; | 
|---|
 | 126 |   btScalar *q = p; | 
|---|
 | 127 |   btScalar *r = ret; | 
|---|
 | 128 |   for (int dir=0; dir <= 1; dir++) { | 
|---|
 | 129 |     // direction notation: xy[0] = x axis, xy[1] = y axis | 
|---|
 | 130 |     for (int sign=-1; sign <= 1; sign += 2) { | 
|---|
 | 131 |       // chop q along the line xy[dir] = sign*h[dir] | 
|---|
 | 132 |       btScalar *pq = q; | 
|---|
 | 133 |       btScalar *pr = r; | 
|---|
 | 134 |       nr = 0; | 
|---|
 | 135 |       for (int i=nq; i > 0; i--) { | 
|---|
 | 136 |         // go through all points in q and all lines between adjacent points | 
|---|
 | 137 |         if (sign*pq[dir] < h[dir]) { | 
|---|
 | 138 |           // this point is inside the chopping line | 
|---|
 | 139 |           pr[0] = pq[0]; | 
|---|
 | 140 |           pr[1] = pq[1]; | 
|---|
 | 141 |           pr += 2; | 
|---|
 | 142 |           nr++; | 
|---|
 | 143 |           if (nr & 8) { | 
|---|
 | 144 |             q = r; | 
|---|
 | 145 |             goto done; | 
|---|
 | 146 |           } | 
|---|
 | 147 |         } | 
|---|
 | 148 |         btScalar *nextq = (i > 1) ? pq+2 : q; | 
|---|
 | 149 |         if ((sign*pq[dir] < h[dir]) ^ (sign*nextq[dir] < h[dir])) { | 
|---|
 | 150 |           // this line crosses the chopping line | 
|---|
 | 151 |           pr[1-dir] = pq[1-dir] + (nextq[1-dir]-pq[1-dir]) / | 
|---|
 | 152 |             (nextq[dir]-pq[dir]) * (sign*h[dir]-pq[dir]); | 
|---|
 | 153 |           pr[dir] = sign*h[dir]; | 
|---|
 | 154 |           pr += 2; | 
|---|
 | 155 |           nr++; | 
|---|
 | 156 |           if (nr & 8) { | 
|---|
 | 157 |             q = r; | 
|---|
 | 158 |             goto done; | 
|---|
 | 159 |           } | 
|---|
 | 160 |         } | 
|---|
 | 161 |         pq += 2; | 
|---|
 | 162 |       } | 
|---|
 | 163 |       q = r; | 
|---|
 | 164 |       r = (q==ret) ? buffer : ret; | 
|---|
 | 165 |       nq = nr; | 
|---|
 | 166 |     } | 
|---|
 | 167 |   } | 
|---|
 | 168 |  done: | 
|---|
 | 169 |   if (q != ret) memcpy (ret,q,nr*2*sizeof(btScalar)); | 
|---|
 | 170 |   return nr; | 
|---|
 | 171 | } | 
|---|
 | 172 |  | 
|---|
 | 173 |  | 
|---|
 | 174 | #define M__PI 3.14159265f | 
|---|
 | 175 |  | 
|---|
 | 176 | // given n points in the plane (array p, of size 2*n), generate m points that | 
|---|
 | 177 | // best represent the whole set. the definition of 'best' here is not | 
|---|
 | 178 | // predetermined - the idea is to select points that give good box-box | 
|---|
 | 179 | // collision detection behavior. the chosen point indexes are returned in the | 
|---|
 | 180 | // array iret (of size m). 'i0' is always the first entry in the array. | 
|---|
 | 181 | // n must be in the range [1..8]. m must be in the range [1..n]. i0 must be | 
|---|
 | 182 | // in the range [0..n-1]. | 
|---|
 | 183 |  | 
|---|
 | 184 | void cullPoints2 (int n, btScalar p[], int m, int i0, int iret[]); | 
|---|
 | 185 | void cullPoints2 (int n, btScalar p[], int m, int i0, int iret[]) | 
|---|
 | 186 | { | 
|---|
 | 187 |   // compute the centroid of the polygon in cx,cy | 
|---|
 | 188 |   int i,j; | 
|---|
 | 189 |   btScalar a,cx,cy,q; | 
|---|
 | 190 |   if (n==1) { | 
|---|
 | 191 |     cx = p[0]; | 
|---|
 | 192 |     cy = p[1]; | 
|---|
 | 193 |   } | 
|---|
 | 194 |   else if (n==2) { | 
|---|
 | 195 |     cx = btScalar(0.5)*(p[0] + p[2]); | 
|---|
 | 196 |     cy = btScalar(0.5)*(p[1] + p[3]); | 
|---|
 | 197 |   } | 
|---|
 | 198 |   else { | 
|---|
 | 199 |     a = 0; | 
|---|
 | 200 |     cx = 0; | 
|---|
 | 201 |     cy = 0; | 
|---|
 | 202 |     for (i=0; i<(n-1); i++) { | 
|---|
 | 203 |       q = p[i*2]*p[i*2+3] - p[i*2+2]*p[i*2+1]; | 
|---|
 | 204 |       a += q; | 
|---|
 | 205 |       cx += q*(p[i*2]+p[i*2+2]); | 
|---|
 | 206 |       cy += q*(p[i*2+1]+p[i*2+3]); | 
|---|
 | 207 |     } | 
|---|
 | 208 |     q = p[n*2-2]*p[1] - p[0]*p[n*2-1]; | 
|---|
| [2430] | 209 |         if (btFabs(a+q) > SIMD_EPSILON) | 
|---|
 | 210 |         { | 
|---|
 | 211 |                 a = 1.f/(btScalar(3.0)*(a+q)); | 
|---|
 | 212 |         } else | 
|---|
 | 213 |         { | 
|---|
| [8351] | 214 |                 a=BT_LARGE_FLOAT; | 
|---|
| [2430] | 215 |         } | 
|---|
| [1963] | 216 |     cx = a*(cx + q*(p[n*2-2]+p[0])); | 
|---|
 | 217 |     cy = a*(cy + q*(p[n*2-1]+p[1])); | 
|---|
 | 218 |   } | 
|---|
 | 219 |  | 
|---|
 | 220 |   // compute the angle of each point w.r.t. the centroid | 
|---|
 | 221 |   btScalar A[8]; | 
|---|
 | 222 |   for (i=0; i<n; i++) A[i] = btAtan2(p[i*2+1]-cy,p[i*2]-cx); | 
|---|
 | 223 |  | 
|---|
 | 224 |   // search for points that have angles closest to A[i0] + i*(2*pi/m). | 
|---|
 | 225 |   int avail[8]; | 
|---|
 | 226 |   for (i=0; i<n; i++) avail[i] = 1; | 
|---|
 | 227 |   avail[i0] = 0; | 
|---|
 | 228 |   iret[0] = i0; | 
|---|
 | 229 |   iret++; | 
|---|
 | 230 |   for (j=1; j<m; j++) { | 
|---|
 | 231 |     a = btScalar(j)*(2*M__PI/m) + A[i0]; | 
|---|
 | 232 |     if (a > M__PI) a -= 2*M__PI; | 
|---|
 | 233 |     btScalar maxdiff=1e9,diff; | 
|---|
 | 234 |  | 
|---|
 | 235 |     *iret = i0;                 // iret is not allowed to keep this value, but it sometimes does, when diff=#QNAN0 | 
|---|
 | 236 |  | 
|---|
 | 237 |     for (i=0; i<n; i++) { | 
|---|
 | 238 |       if (avail[i]) { | 
|---|
 | 239 |         diff = btFabs (A[i]-a); | 
|---|
 | 240 |         if (diff > M__PI) diff = 2*M__PI - diff; | 
|---|
 | 241 |         if (diff < maxdiff) { | 
|---|
 | 242 |           maxdiff = diff; | 
|---|
 | 243 |           *iret = i; | 
|---|
 | 244 |         } | 
|---|
 | 245 |       } | 
|---|
 | 246 |     } | 
|---|
 | 247 | #if defined(DEBUG) || defined (_DEBUG) | 
|---|
 | 248 |     btAssert (*iret != i0);     // ensure iret got set | 
|---|
 | 249 | #endif | 
|---|
 | 250 |     avail[*iret] = 0; | 
|---|
 | 251 |     iret++; | 
|---|
 | 252 |   } | 
|---|
 | 253 | } | 
|---|
 | 254 |  | 
|---|
 | 255 |  | 
|---|
 | 256 |  | 
|---|
 | 257 | int dBoxBox2 (const btVector3& p1, const dMatrix3 R1, | 
|---|
 | 258 |              const btVector3& side1, const btVector3& p2, | 
|---|
 | 259 |              const dMatrix3 R2, const btVector3& side2, | 
|---|
 | 260 |              btVector3& normal, btScalar *depth, int *return_code, | 
|---|
 | 261 |                  int maxc, dContactGeom * /*contact*/, int /*skip*/,btDiscreteCollisionDetectorInterface::Result& output); | 
|---|
 | 262 | int dBoxBox2 (const btVector3& p1, const dMatrix3 R1, | 
|---|
 | 263 |              const btVector3& side1, const btVector3& p2, | 
|---|
 | 264 |              const dMatrix3 R2, const btVector3& side2, | 
|---|
 | 265 |              btVector3& normal, btScalar *depth, int *return_code, | 
|---|
 | 266 |                  int maxc, dContactGeom * /*contact*/, int /*skip*/,btDiscreteCollisionDetectorInterface::Result& output) | 
|---|
 | 267 | { | 
|---|
 | 268 |   const btScalar fudge_factor = btScalar(1.05); | 
|---|
| [8351] | 269 |   btVector3 p,pp,normalC(0.f,0.f,0.f); | 
|---|
| [1963] | 270 |   const btScalar *normalR = 0; | 
|---|
 | 271 |   btScalar A[3],B[3],R11,R12,R13,R21,R22,R23,R31,R32,R33, | 
|---|
 | 272 |     Q11,Q12,Q13,Q21,Q22,Q23,Q31,Q32,Q33,s,s2,l; | 
|---|
 | 273 |   int i,j,invert_normal,code; | 
|---|
 | 274 |  | 
|---|
 | 275 |   // get vector from centers of box 1 to box 2, relative to box 1 | 
|---|
 | 276 |   p = p2 - p1; | 
|---|
 | 277 |   dMULTIPLY1_331 (pp,R1,p);             // get pp = p relative to body 1 | 
|---|
 | 278 |  | 
|---|
 | 279 |   // get side lengths / 2 | 
|---|
 | 280 |   A[0] = side1[0]*btScalar(0.5); | 
|---|
 | 281 |   A[1] = side1[1]*btScalar(0.5); | 
|---|
 | 282 |   A[2] = side1[2]*btScalar(0.5); | 
|---|
 | 283 |   B[0] = side2[0]*btScalar(0.5); | 
|---|
 | 284 |   B[1] = side2[1]*btScalar(0.5); | 
|---|
 | 285 |   B[2] = side2[2]*btScalar(0.5); | 
|---|
 | 286 |  | 
|---|
 | 287 |   // Rij is R1'*R2, i.e. the relative rotation between R1 and R2 | 
|---|
 | 288 |   R11 = dDOT44(R1+0,R2+0); R12 = dDOT44(R1+0,R2+1); R13 = dDOT44(R1+0,R2+2); | 
|---|
 | 289 |   R21 = dDOT44(R1+1,R2+0); R22 = dDOT44(R1+1,R2+1); R23 = dDOT44(R1+1,R2+2); | 
|---|
 | 290 |   R31 = dDOT44(R1+2,R2+0); R32 = dDOT44(R1+2,R2+1); R33 = dDOT44(R1+2,R2+2); | 
|---|
 | 291 |  | 
|---|
 | 292 |   Q11 = btFabs(R11); Q12 = btFabs(R12); Q13 = btFabs(R13); | 
|---|
 | 293 |   Q21 = btFabs(R21); Q22 = btFabs(R22); Q23 = btFabs(R23); | 
|---|
 | 294 |   Q31 = btFabs(R31); Q32 = btFabs(R32); Q33 = btFabs(R33); | 
|---|
 | 295 |  | 
|---|
 | 296 |   // for all 15 possible separating axes: | 
|---|
 | 297 |   //   * see if the axis separates the boxes. if so, return 0. | 
|---|
 | 298 |   //   * find the depth of the penetration along the separating axis (s2) | 
|---|
 | 299 |   //   * if this is the largest depth so far, record it. | 
|---|
 | 300 |   // the normal vector will be set to the separating axis with the smallest | 
|---|
 | 301 |   // depth. note: normalR is set to point to a column of R1 or R2 if that is | 
|---|
 | 302 |   // the smallest depth normal so far. otherwise normalR is 0 and normalC is | 
|---|
 | 303 |   // set to a vector relative to body 1. invert_normal is 1 if the sign of | 
|---|
 | 304 |   // the normal should be flipped. | 
|---|
 | 305 |  | 
|---|
 | 306 | #define TST(expr1,expr2,norm,cc) \ | 
|---|
 | 307 |   s2 = btFabs(expr1) - (expr2); \ | 
|---|
 | 308 |   if (s2 > 0) return 0; \ | 
|---|
 | 309 |   if (s2 > s) { \ | 
|---|
 | 310 |     s = s2; \ | 
|---|
 | 311 |     normalR = norm; \ | 
|---|
 | 312 |     invert_normal = ((expr1) < 0); \ | 
|---|
 | 313 |     code = (cc); \ | 
|---|
 | 314 |   } | 
|---|
 | 315 |  | 
|---|
 | 316 |   s = -dInfinity; | 
|---|
 | 317 |   invert_normal = 0; | 
|---|
 | 318 |   code = 0; | 
|---|
 | 319 |  | 
|---|
 | 320 |   // separating axis = u1,u2,u3 | 
|---|
 | 321 |   TST (pp[0],(A[0] + B[0]*Q11 + B[1]*Q12 + B[2]*Q13),R1+0,1); | 
|---|
 | 322 |   TST (pp[1],(A[1] + B[0]*Q21 + B[1]*Q22 + B[2]*Q23),R1+1,2); | 
|---|
 | 323 |   TST (pp[2],(A[2] + B[0]*Q31 + B[1]*Q32 + B[2]*Q33),R1+2,3); | 
|---|
 | 324 |  | 
|---|
 | 325 |   // separating axis = v1,v2,v3 | 
|---|
 | 326 |   TST (dDOT41(R2+0,p),(A[0]*Q11 + A[1]*Q21 + A[2]*Q31 + B[0]),R2+0,4); | 
|---|
 | 327 |   TST (dDOT41(R2+1,p),(A[0]*Q12 + A[1]*Q22 + A[2]*Q32 + B[1]),R2+1,5); | 
|---|
 | 328 |   TST (dDOT41(R2+2,p),(A[0]*Q13 + A[1]*Q23 + A[2]*Q33 + B[2]),R2+2,6); | 
|---|
 | 329 |  | 
|---|
 | 330 |   // note: cross product axes need to be scaled when s is computed. | 
|---|
 | 331 |   // normal (n1,n2,n3) is relative to box 1. | 
|---|
 | 332 | #undef TST | 
|---|
 | 333 | #define TST(expr1,expr2,n1,n2,n3,cc) \ | 
|---|
 | 334 |   s2 = btFabs(expr1) - (expr2); \ | 
|---|
| [8351] | 335 |   if (s2 > SIMD_EPSILON) return 0; \ | 
|---|
| [1963] | 336 |   l = btSqrt((n1)*(n1) + (n2)*(n2) + (n3)*(n3)); \ | 
|---|
| [8351] | 337 |   if (l > SIMD_EPSILON) { \ | 
|---|
| [1963] | 338 |     s2 /= l; \ | 
|---|
 | 339 |     if (s2*fudge_factor > s) { \ | 
|---|
 | 340 |       s = s2; \ | 
|---|
 | 341 |       normalR = 0; \ | 
|---|
 | 342 |       normalC[0] = (n1)/l; normalC[1] = (n2)/l; normalC[2] = (n3)/l; \ | 
|---|
 | 343 |       invert_normal = ((expr1) < 0); \ | 
|---|
 | 344 |       code = (cc); \ | 
|---|
 | 345 |     } \ | 
|---|
 | 346 |   } | 
|---|
 | 347 |  | 
|---|
| [8351] | 348 |   btScalar fudge2 (1.0e-5f); | 
|---|
 | 349 |  | 
|---|
 | 350 |   Q11 += fudge2; | 
|---|
 | 351 |   Q12 += fudge2; | 
|---|
 | 352 |   Q13 += fudge2; | 
|---|
 | 353 |  | 
|---|
 | 354 |   Q21 += fudge2; | 
|---|
 | 355 |   Q22 += fudge2; | 
|---|
 | 356 |   Q23 += fudge2; | 
|---|
 | 357 |  | 
|---|
 | 358 |   Q31 += fudge2; | 
|---|
 | 359 |   Q32 += fudge2; | 
|---|
 | 360 |   Q33 += fudge2; | 
|---|
 | 361 |  | 
|---|
| [1963] | 362 |   // separating axis = u1 x (v1,v2,v3) | 
|---|
 | 363 |   TST(pp[2]*R21-pp[1]*R31,(A[1]*Q31+A[2]*Q21+B[1]*Q13+B[2]*Q12),0,-R31,R21,7); | 
|---|
 | 364 |   TST(pp[2]*R22-pp[1]*R32,(A[1]*Q32+A[2]*Q22+B[0]*Q13+B[2]*Q11),0,-R32,R22,8); | 
|---|
 | 365 |   TST(pp[2]*R23-pp[1]*R33,(A[1]*Q33+A[2]*Q23+B[0]*Q12+B[1]*Q11),0,-R33,R23,9); | 
|---|
 | 366 |  | 
|---|
 | 367 |   // separating axis = u2 x (v1,v2,v3) | 
|---|
 | 368 |   TST(pp[0]*R31-pp[2]*R11,(A[0]*Q31+A[2]*Q11+B[1]*Q23+B[2]*Q22),R31,0,-R11,10); | 
|---|
 | 369 |   TST(pp[0]*R32-pp[2]*R12,(A[0]*Q32+A[2]*Q12+B[0]*Q23+B[2]*Q21),R32,0,-R12,11); | 
|---|
 | 370 |   TST(pp[0]*R33-pp[2]*R13,(A[0]*Q33+A[2]*Q13+B[0]*Q22+B[1]*Q21),R33,0,-R13,12); | 
|---|
 | 371 |  | 
|---|
 | 372 |   // separating axis = u3 x (v1,v2,v3) | 
|---|
 | 373 |   TST(pp[1]*R11-pp[0]*R21,(A[0]*Q21+A[1]*Q11+B[1]*Q33+B[2]*Q32),-R21,R11,0,13); | 
|---|
 | 374 |   TST(pp[1]*R12-pp[0]*R22,(A[0]*Q22+A[1]*Q12+B[0]*Q33+B[2]*Q31),-R22,R12,0,14); | 
|---|
 | 375 |   TST(pp[1]*R13-pp[0]*R23,(A[0]*Q23+A[1]*Q13+B[0]*Q32+B[1]*Q31),-R23,R13,0,15); | 
|---|
 | 376 |  | 
|---|
 | 377 | #undef TST | 
|---|
 | 378 |  | 
|---|
 | 379 |   if (!code) return 0; | 
|---|
 | 380 |  | 
|---|
 | 381 |   // if we get to this point, the boxes interpenetrate. compute the normal | 
|---|
 | 382 |   // in global coordinates. | 
|---|
 | 383 |   if (normalR) { | 
|---|
 | 384 |     normal[0] = normalR[0]; | 
|---|
 | 385 |     normal[1] = normalR[4]; | 
|---|
 | 386 |     normal[2] = normalR[8]; | 
|---|
 | 387 |   } | 
|---|
 | 388 |   else { | 
|---|
 | 389 |     dMULTIPLY0_331 (normal,R1,normalC); | 
|---|
 | 390 |   } | 
|---|
 | 391 |   if (invert_normal) { | 
|---|
 | 392 |     normal[0] = -normal[0]; | 
|---|
 | 393 |     normal[1] = -normal[1]; | 
|---|
 | 394 |     normal[2] = -normal[2]; | 
|---|
 | 395 |   } | 
|---|
 | 396 |   *depth = -s; | 
|---|
 | 397 |  | 
|---|
 | 398 |   // compute contact point(s) | 
|---|
 | 399 |  | 
|---|
 | 400 |   if (code > 6) { | 
|---|
 | 401 |     // an edge from box 1 touches an edge from box 2. | 
|---|
 | 402 |     // find a point pa on the intersecting edge of box 1 | 
|---|
 | 403 |     btVector3 pa; | 
|---|
 | 404 |     btScalar sign; | 
|---|
 | 405 |     for (i=0; i<3; i++) pa[i] = p1[i]; | 
|---|
 | 406 |     for (j=0; j<3; j++) { | 
|---|
 | 407 |       sign = (dDOT14(normal,R1+j) > 0) ? btScalar(1.0) : btScalar(-1.0); | 
|---|
 | 408 |       for (i=0; i<3; i++) pa[i] += sign * A[j] * R1[i*4+j]; | 
|---|
 | 409 |     } | 
|---|
 | 410 |  | 
|---|
 | 411 |     // find a point pb on the intersecting edge of box 2 | 
|---|
 | 412 |     btVector3 pb; | 
|---|
 | 413 |     for (i=0; i<3; i++) pb[i] = p2[i]; | 
|---|
 | 414 |     for (j=0; j<3; j++) { | 
|---|
 | 415 |       sign = (dDOT14(normal,R2+j) > 0) ? btScalar(-1.0) : btScalar(1.0); | 
|---|
 | 416 |       for (i=0; i<3; i++) pb[i] += sign * B[j] * R2[i*4+j]; | 
|---|
 | 417 |     } | 
|---|
 | 418 |  | 
|---|
 | 419 |     btScalar alpha,beta; | 
|---|
 | 420 |     btVector3 ua,ub; | 
|---|
 | 421 |     for (i=0; i<3; i++) ua[i] = R1[((code)-7)/3 + i*4]; | 
|---|
 | 422 |     for (i=0; i<3; i++) ub[i] = R2[((code)-7)%3 + i*4]; | 
|---|
 | 423 |  | 
|---|
 | 424 |     dLineClosestApproach (pa,ua,pb,ub,&alpha,&beta); | 
|---|
 | 425 |     for (i=0; i<3; i++) pa[i] += ua[i]*alpha; | 
|---|
 | 426 |     for (i=0; i<3; i++) pb[i] += ub[i]*beta; | 
|---|
 | 427 |  | 
|---|
 | 428 |         { | 
|---|
 | 429 |                  | 
|---|
 | 430 |                 //contact[0].pos[i] = btScalar(0.5)*(pa[i]+pb[i]); | 
|---|
 | 431 |                 //contact[0].depth = *depth; | 
|---|
 | 432 |                 btVector3 pointInWorld; | 
|---|
 | 433 |  | 
|---|
 | 434 | #ifdef USE_CENTER_POINT | 
|---|
 | 435 |             for (i=0; i<3; i++)  | 
|---|
 | 436 |                         pointInWorld[i] = (pa[i]+pb[i])*btScalar(0.5); | 
|---|
 | 437 |                 output.addContactPoint(-normal,pointInWorld,-*depth); | 
|---|
 | 438 | #else | 
|---|
 | 439 |                 output.addContactPoint(-normal,pb,-*depth); | 
|---|
| [8351] | 440 |  | 
|---|
| [1963] | 441 | #endif // | 
|---|
 | 442 |                 *return_code = code; | 
|---|
 | 443 |         } | 
|---|
 | 444 |     return 1; | 
|---|
 | 445 |   } | 
|---|
 | 446 |  | 
|---|
 | 447 |   // okay, we have a face-something intersection (because the separating | 
|---|
 | 448 |   // axis is perpendicular to a face). define face 'a' to be the reference | 
|---|
 | 449 |   // face (i.e. the normal vector is perpendicular to this) and face 'b' to be | 
|---|
 | 450 |   // the incident face (the closest face of the other box). | 
|---|
 | 451 |  | 
|---|
 | 452 |   const btScalar *Ra,*Rb,*pa,*pb,*Sa,*Sb; | 
|---|
 | 453 |   if (code <= 3) { | 
|---|
 | 454 |     Ra = R1; | 
|---|
 | 455 |     Rb = R2; | 
|---|
 | 456 |     pa = p1; | 
|---|
 | 457 |     pb = p2; | 
|---|
 | 458 |     Sa = A; | 
|---|
 | 459 |     Sb = B; | 
|---|
 | 460 |   } | 
|---|
 | 461 |   else { | 
|---|
 | 462 |     Ra = R2; | 
|---|
 | 463 |     Rb = R1; | 
|---|
 | 464 |     pa = p2; | 
|---|
 | 465 |     pb = p1; | 
|---|
 | 466 |     Sa = B; | 
|---|
 | 467 |     Sb = A; | 
|---|
 | 468 |   } | 
|---|
 | 469 |  | 
|---|
 | 470 |   // nr = normal vector of reference face dotted with axes of incident box. | 
|---|
 | 471 |   // anr = absolute values of nr. | 
|---|
 | 472 |   btVector3 normal2,nr,anr; | 
|---|
 | 473 |   if (code <= 3) { | 
|---|
 | 474 |     normal2[0] = normal[0]; | 
|---|
 | 475 |     normal2[1] = normal[1]; | 
|---|
 | 476 |     normal2[2] = normal[2]; | 
|---|
 | 477 |   } | 
|---|
 | 478 |   else { | 
|---|
 | 479 |     normal2[0] = -normal[0]; | 
|---|
 | 480 |     normal2[1] = -normal[1]; | 
|---|
 | 481 |     normal2[2] = -normal[2]; | 
|---|
 | 482 |   } | 
|---|
 | 483 |   dMULTIPLY1_331 (nr,Rb,normal2); | 
|---|
 | 484 |   anr[0] = btFabs (nr[0]); | 
|---|
 | 485 |   anr[1] = btFabs (nr[1]); | 
|---|
 | 486 |   anr[2] = btFabs (nr[2]); | 
|---|
 | 487 |  | 
|---|
 | 488 |   // find the largest compontent of anr: this corresponds to the normal | 
|---|
 | 489 |   // for the indident face. the other axis numbers of the indicent face | 
|---|
 | 490 |   // are stored in a1,a2. | 
|---|
 | 491 |   int lanr,a1,a2; | 
|---|
 | 492 |   if (anr[1] > anr[0]) { | 
|---|
 | 493 |     if (anr[1] > anr[2]) { | 
|---|
 | 494 |       a1 = 0; | 
|---|
 | 495 |       lanr = 1; | 
|---|
 | 496 |       a2 = 2; | 
|---|
 | 497 |     } | 
|---|
 | 498 |     else { | 
|---|
 | 499 |       a1 = 0; | 
|---|
 | 500 |       a2 = 1; | 
|---|
 | 501 |       lanr = 2; | 
|---|
 | 502 |     } | 
|---|
 | 503 |   } | 
|---|
 | 504 |   else { | 
|---|
 | 505 |     if (anr[0] > anr[2]) { | 
|---|
 | 506 |       lanr = 0; | 
|---|
 | 507 |       a1 = 1; | 
|---|
 | 508 |       a2 = 2; | 
|---|
 | 509 |     } | 
|---|
 | 510 |     else { | 
|---|
 | 511 |       a1 = 0; | 
|---|
 | 512 |       a2 = 1; | 
|---|
 | 513 |       lanr = 2; | 
|---|
 | 514 |     } | 
|---|
 | 515 |   } | 
|---|
 | 516 |  | 
|---|
 | 517 |   // compute center point of incident face, in reference-face coordinates | 
|---|
 | 518 |   btVector3 center; | 
|---|
 | 519 |   if (nr[lanr] < 0) { | 
|---|
 | 520 |     for (i=0; i<3; i++) center[i] = pb[i] - pa[i] + Sb[lanr] * Rb[i*4+lanr]; | 
|---|
 | 521 |   } | 
|---|
 | 522 |   else { | 
|---|
 | 523 |     for (i=0; i<3; i++) center[i] = pb[i] - pa[i] - Sb[lanr] * Rb[i*4+lanr]; | 
|---|
 | 524 |   } | 
|---|
 | 525 |  | 
|---|
 | 526 |   // find the normal and non-normal axis numbers of the reference box | 
|---|
 | 527 |   int codeN,code1,code2; | 
|---|
 | 528 |   if (code <= 3) codeN = code-1; else codeN = code-4; | 
|---|
 | 529 |   if (codeN==0) { | 
|---|
 | 530 |     code1 = 1; | 
|---|
 | 531 |     code2 = 2; | 
|---|
 | 532 |   } | 
|---|
 | 533 |   else if (codeN==1) { | 
|---|
 | 534 |     code1 = 0; | 
|---|
 | 535 |     code2 = 2; | 
|---|
 | 536 |   } | 
|---|
 | 537 |   else { | 
|---|
 | 538 |     code1 = 0; | 
|---|
 | 539 |     code2 = 1; | 
|---|
 | 540 |   } | 
|---|
 | 541 |  | 
|---|
 | 542 |   // find the four corners of the incident face, in reference-face coordinates | 
|---|
 | 543 |   btScalar quad[8];     // 2D coordinate of incident face (x,y pairs) | 
|---|
 | 544 |   btScalar c1,c2,m11,m12,m21,m22; | 
|---|
 | 545 |   c1 = dDOT14 (center,Ra+code1); | 
|---|
 | 546 |   c2 = dDOT14 (center,Ra+code2); | 
|---|
 | 547 |   // optimize this? - we have already computed this data above, but it is not | 
|---|
 | 548 |   // stored in an easy-to-index format. for now it's quicker just to recompute | 
|---|
 | 549 |   // the four dot products. | 
|---|
 | 550 |   m11 = dDOT44 (Ra+code1,Rb+a1); | 
|---|
 | 551 |   m12 = dDOT44 (Ra+code1,Rb+a2); | 
|---|
 | 552 |   m21 = dDOT44 (Ra+code2,Rb+a1); | 
|---|
 | 553 |   m22 = dDOT44 (Ra+code2,Rb+a2); | 
|---|
 | 554 |   { | 
|---|
 | 555 |     btScalar k1 = m11*Sb[a1]; | 
|---|
 | 556 |     btScalar k2 = m21*Sb[a1]; | 
|---|
 | 557 |     btScalar k3 = m12*Sb[a2]; | 
|---|
 | 558 |     btScalar k4 = m22*Sb[a2]; | 
|---|
 | 559 |     quad[0] = c1 - k1 - k3; | 
|---|
 | 560 |     quad[1] = c2 - k2 - k4; | 
|---|
 | 561 |     quad[2] = c1 - k1 + k3; | 
|---|
 | 562 |     quad[3] = c2 - k2 + k4; | 
|---|
 | 563 |     quad[4] = c1 + k1 + k3; | 
|---|
 | 564 |     quad[5] = c2 + k2 + k4; | 
|---|
 | 565 |     quad[6] = c1 + k1 - k3; | 
|---|
 | 566 |     quad[7] = c2 + k2 - k4; | 
|---|
 | 567 |   } | 
|---|
 | 568 |  | 
|---|
 | 569 |   // find the size of the reference face | 
|---|
 | 570 |   btScalar rect[2]; | 
|---|
 | 571 |   rect[0] = Sa[code1]; | 
|---|
 | 572 |   rect[1] = Sa[code2]; | 
|---|
 | 573 |  | 
|---|
 | 574 |   // intersect the incident and reference faces | 
|---|
 | 575 |   btScalar ret[16]; | 
|---|
 | 576 |   int n = intersectRectQuad2 (rect,quad,ret); | 
|---|
 | 577 |   if (n < 1) return 0;          // this should never happen | 
|---|
 | 578 |  | 
|---|
 | 579 |   // convert the intersection points into reference-face coordinates, | 
|---|
 | 580 |   // and compute the contact position and depth for each point. only keep | 
|---|
 | 581 |   // those points that have a positive (penetrating) depth. delete points in | 
|---|
 | 582 |   // the 'ret' array as necessary so that 'point' and 'ret' correspond. | 
|---|
 | 583 |   btScalar point[3*8];          // penetrating contact points | 
|---|
 | 584 |   btScalar dep[8];                      // depths for those points | 
|---|
 | 585 |   btScalar det1 = 1.f/(m11*m22 - m12*m21); | 
|---|
 | 586 |   m11 *= det1; | 
|---|
 | 587 |   m12 *= det1; | 
|---|
 | 588 |   m21 *= det1; | 
|---|
 | 589 |   m22 *= det1; | 
|---|
 | 590 |   int cnum = 0;                 // number of penetrating contact points found | 
|---|
 | 591 |   for (j=0; j < n; j++) { | 
|---|
 | 592 |     btScalar k1 =  m22*(ret[j*2]-c1) - m12*(ret[j*2+1]-c2); | 
|---|
 | 593 |     btScalar k2 = -m21*(ret[j*2]-c1) + m11*(ret[j*2+1]-c2); | 
|---|
 | 594 |     for (i=0; i<3; i++) point[cnum*3+i] = | 
|---|
 | 595 |                           center[i] + k1*Rb[i*4+a1] + k2*Rb[i*4+a2]; | 
|---|
 | 596 |     dep[cnum] = Sa[codeN] - dDOT(normal2,point+cnum*3); | 
|---|
 | 597 |     if (dep[cnum] >= 0) { | 
|---|
 | 598 |       ret[cnum*2] = ret[j*2]; | 
|---|
 | 599 |       ret[cnum*2+1] = ret[j*2+1]; | 
|---|
 | 600 |       cnum++; | 
|---|
 | 601 |     } | 
|---|
 | 602 |   } | 
|---|
 | 603 |   if (cnum < 1) return 0;       // this should never happen | 
|---|
 | 604 |  | 
|---|
 | 605 |   // we can't generate more contacts than we actually have | 
|---|
 | 606 |   if (maxc > cnum) maxc = cnum; | 
|---|
 | 607 |   if (maxc < 1) maxc = 1; | 
|---|
 | 608 |  | 
|---|
 | 609 |   if (cnum <= maxc) { | 
|---|
| [8351] | 610 |  | 
|---|
 | 611 |           if (code<4)  | 
|---|
 | 612 |           { | 
|---|
| [1963] | 613 |     // we have less contacts than we need, so we use them all | 
|---|
| [8351] | 614 |     for (j=0; j < cnum; j++)  | 
|---|
 | 615 |         { | 
|---|
| [1963] | 616 |                 btVector3 pointInWorld; | 
|---|
 | 617 |                 for (i=0; i<3; i++)  | 
|---|
 | 618 |                         pointInWorld[i] = point[j*3+i] + pa[i]; | 
|---|
 | 619 |                 output.addContactPoint(-normal,pointInWorld,-dep[j]); | 
|---|
 | 620 |  | 
|---|
 | 621 |     } | 
|---|
| [8351] | 622 |           } else | 
|---|
 | 623 |           { | 
|---|
 | 624 |                   // we have less contacts than we need, so we use them all | 
|---|
 | 625 |                 for (j=0; j < cnum; j++)  | 
|---|
 | 626 |                 { | 
|---|
 | 627 |                         btVector3 pointInWorld; | 
|---|
 | 628 |                         for (i=0; i<3; i++)  | 
|---|
 | 629 |                                 pointInWorld[i] = point[j*3+i] + pa[i]-normal[i]*dep[j]; | 
|---|
 | 630 |                                 //pointInWorld[i] = point[j*3+i] + pa[i]; | 
|---|
 | 631 |                         output.addContactPoint(-normal,pointInWorld,-dep[j]); | 
|---|
 | 632 |                 } | 
|---|
 | 633 |           } | 
|---|
| [1963] | 634 |   } | 
|---|
 | 635 |   else { | 
|---|
 | 636 |     // we have more contacts than are wanted, some of them must be culled. | 
|---|
 | 637 |     // find the deepest point, it is always the first contact. | 
|---|
 | 638 |     int i1 = 0; | 
|---|
 | 639 |     btScalar maxdepth = dep[0]; | 
|---|
 | 640 |     for (i=1; i<cnum; i++) { | 
|---|
 | 641 |       if (dep[i] > maxdepth) { | 
|---|
 | 642 |         maxdepth = dep[i]; | 
|---|
 | 643 |         i1 = i; | 
|---|
 | 644 |       } | 
|---|
 | 645 |     } | 
|---|
 | 646 |  | 
|---|
 | 647 |     int iret[8]; | 
|---|
 | 648 |     cullPoints2 (cnum,ret,maxc,i1,iret); | 
|---|
 | 649 |  | 
|---|
 | 650 |     for (j=0; j < maxc; j++) { | 
|---|
 | 651 | //      dContactGeom *con = CONTACT(contact,skip*j); | 
|---|
 | 652 |   //    for (i=0; i<3; i++) con->pos[i] = point[iret[j]*3+i] + pa[i]; | 
|---|
 | 653 |     //  con->depth = dep[iret[j]]; | 
|---|
 | 654 |  | 
|---|
 | 655 |                 btVector3 posInWorld; | 
|---|
 | 656 |                 for (i=0; i<3; i++)  | 
|---|
 | 657 |                         posInWorld[i] = point[iret[j]*3+i] + pa[i]; | 
|---|
| [8351] | 658 |                 if (code<4)  | 
|---|
 | 659 |            { | 
|---|
 | 660 |                         output.addContactPoint(-normal,posInWorld,-dep[iret[j]]); | 
|---|
 | 661 |                 } else | 
|---|
 | 662 |                 { | 
|---|
 | 663 |                         output.addContactPoint(-normal,posInWorld-normal*dep[iret[j]],-dep[iret[j]]); | 
|---|
 | 664 |                 } | 
|---|
| [1963] | 665 |     } | 
|---|
 | 666 |     cnum = maxc; | 
|---|
 | 667 |   } | 
|---|
 | 668 |  | 
|---|
 | 669 |   *return_code = code; | 
|---|
 | 670 |   return cnum; | 
|---|
 | 671 | } | 
|---|
 | 672 |  | 
|---|
 | 673 | void    btBoxBoxDetector::getClosestPoints(const ClosestPointInput& input,Result& output,class btIDebugDraw* /*debugDraw*/,bool /*swapResults*/) | 
|---|
 | 674 | { | 
|---|
 | 675 |          | 
|---|
 | 676 |         const btTransform& transformA = input.m_transformA; | 
|---|
 | 677 |         const btTransform& transformB = input.m_transformB; | 
|---|
 | 678 |          | 
|---|
 | 679 |         int skip = 0; | 
|---|
 | 680 |         dContactGeom *contact = 0; | 
|---|
 | 681 |  | 
|---|
 | 682 |         dMatrix3 R1; | 
|---|
 | 683 |         dMatrix3 R2; | 
|---|
 | 684 |  | 
|---|
 | 685 |         for (int j=0;j<3;j++) | 
|---|
 | 686 |         { | 
|---|
 | 687 |                 R1[0+4*j] = transformA.getBasis()[j].x(); | 
|---|
 | 688 |                 R2[0+4*j] = transformB.getBasis()[j].x(); | 
|---|
 | 689 |  | 
|---|
 | 690 |                 R1[1+4*j] = transformA.getBasis()[j].y(); | 
|---|
 | 691 |                 R2[1+4*j] = transformB.getBasis()[j].y(); | 
|---|
 | 692 |  | 
|---|
 | 693 |  | 
|---|
 | 694 |                 R1[2+4*j] = transformA.getBasis()[j].z(); | 
|---|
 | 695 |                 R2[2+4*j] = transformB.getBasis()[j].z(); | 
|---|
 | 696 |  | 
|---|
 | 697 |         } | 
|---|
 | 698 |  | 
|---|
 | 699 |          | 
|---|
 | 700 |  | 
|---|
 | 701 |         btVector3 normal; | 
|---|
 | 702 |         btScalar depth; | 
|---|
 | 703 |         int return_code; | 
|---|
 | 704 |         int maxc = 4; | 
|---|
 | 705 |  | 
|---|
 | 706 |  | 
|---|
 | 707 |         dBoxBox2 (transformA.getOrigin(),  | 
|---|
 | 708 |         R1, | 
|---|
 | 709 |         2.f*m_box1->getHalfExtentsWithMargin(), | 
|---|
 | 710 |         transformB.getOrigin(), | 
|---|
 | 711 |         R2,  | 
|---|
 | 712 |         2.f*m_box2->getHalfExtentsWithMargin(), | 
|---|
 | 713 |         normal, &depth, &return_code, | 
|---|
 | 714 |         maxc, contact, skip, | 
|---|
 | 715 |         output | 
|---|
 | 716 |         ); | 
|---|
 | 717 |  | 
|---|
 | 718 | } | 
|---|