btBoxBoxDetector.cpp 22 KB

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