b3GjkEpa.cpp 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062
  1. /*
  2. Bullet Continuous Collision Detection and Physics Library
  3. Copyright (c) 2003-2008 Erwin Coumans http://continuousphysics.com/Bullet/
  4. This software is provided 'as-is', without any express or implied warranty.
  5. In no event will the authors be held liable for any damages arising from the
  6. 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
  9. freely,
  10. subject to the following restrictions:
  11. 1. The origin of this software must not be misrepresented; you must not
  12. claim that you wrote the original software. If you use this software in a
  13. product, an acknowledgment in the product documentation would be appreciated
  14. but is not required.
  15. 2. Altered source versions must be plainly marked as such, and must not be
  16. misrepresented as being the original software.
  17. 3. This notice may not be removed or altered from any source distribution.
  18. */
  19. /*
  20. GJK-EPA collision solver by Nathanael Presson, 2008
  21. */
  22. #include "b3GjkEpa.h"
  23. #include "b3SupportMappings.h"
  24. namespace gjkepa2_impl2
  25. {
  26. // Config
  27. /* GJK */
  28. #define GJK_MAX_ITERATIONS 128
  29. #define GJK_ACCURACY ((b3Scalar)0.0001)
  30. #define GJK_MIN_DISTANCE ((b3Scalar)0.0001)
  31. #define GJK_DUPLICATED_EPS ((b3Scalar)0.0001)
  32. #define GJK_SIMPLEX2_EPS ((b3Scalar)0.0)
  33. #define GJK_SIMPLEX3_EPS ((b3Scalar)0.0)
  34. #define GJK_SIMPLEX4_EPS ((b3Scalar)0.0)
  35. /* EPA */
  36. #define EPA_MAX_VERTICES 64
  37. #define EPA_MAX_FACES (EPA_MAX_VERTICES * 2)
  38. #define EPA_MAX_ITERATIONS 255
  39. #define EPA_ACCURACY ((b3Scalar)0.0001)
  40. #define EPA_FALLBACK (10 * EPA_ACCURACY)
  41. #define EPA_PLANE_EPS ((b3Scalar)0.00001)
  42. #define EPA_INSIDE_EPS ((b3Scalar)0.01)
  43. // Shorthands
  44. // MinkowskiDiff
  45. struct b3MinkowskiDiff
  46. {
  47. const b3ConvexPolyhedronData* m_shapes[2];
  48. b3Matrix3x3 m_toshape1;
  49. b3Transform m_toshape0;
  50. bool m_enableMargin;
  51. void EnableMargin(bool enable)
  52. {
  53. m_enableMargin = enable;
  54. }
  55. inline b3Vector3 Support0(const b3Vector3& d, const b3AlignedObjectArray<b3Vector3>& verticesA) const
  56. {
  57. if (m_enableMargin)
  58. {
  59. return localGetSupportVertexWithMargin(d, m_shapes[0], verticesA, 0.f);
  60. }
  61. else
  62. {
  63. return localGetSupportVertexWithoutMargin(d, m_shapes[0], verticesA);
  64. }
  65. }
  66. inline b3Vector3 Support1(const b3Vector3& d, const b3AlignedObjectArray<b3Vector3>& verticesB) const
  67. {
  68. if (m_enableMargin)
  69. {
  70. return m_toshape0 * (localGetSupportVertexWithMargin(m_toshape1 * d, m_shapes[1], verticesB, 0.f));
  71. }
  72. else
  73. {
  74. return m_toshape0 * (localGetSupportVertexWithoutMargin(m_toshape1 * d, m_shapes[1], verticesB));
  75. }
  76. }
  77. inline b3Vector3 Support(const b3Vector3& d, const b3AlignedObjectArray<b3Vector3>& verticesA, const b3AlignedObjectArray<b3Vector3>& verticesB) const
  78. {
  79. return (Support0(d, verticesA) - Support1(-d, verticesB));
  80. }
  81. b3Vector3 Support(const b3Vector3& d, unsigned int index, const b3AlignedObjectArray<b3Vector3>& verticesA, const b3AlignedObjectArray<b3Vector3>& verticesB) const
  82. {
  83. if (index)
  84. return (Support1(d, verticesA));
  85. else
  86. return (Support0(d, verticesB));
  87. }
  88. };
  89. typedef b3MinkowskiDiff tShape;
  90. // GJK
  91. struct b3GJK
  92. {
  93. /* Types */
  94. struct sSV
  95. {
  96. b3Vector3 d, w;
  97. };
  98. struct sSimplex
  99. {
  100. sSV* c[4];
  101. b3Scalar p[4];
  102. unsigned int rank;
  103. };
  104. struct eStatus
  105. {
  106. enum _
  107. {
  108. Valid,
  109. Inside,
  110. Failed
  111. };
  112. };
  113. /* Fields */
  114. tShape m_shape;
  115. const b3AlignedObjectArray<b3Vector3>& m_verticesA;
  116. const b3AlignedObjectArray<b3Vector3>& m_verticesB;
  117. b3Vector3 m_ray;
  118. b3Scalar m_distance;
  119. sSimplex m_simplices[2];
  120. sSV m_store[4];
  121. sSV* m_free[4];
  122. unsigned int m_nfree;
  123. unsigned int m_current;
  124. sSimplex* m_simplex;
  125. eStatus::_ m_status;
  126. /* Methods */
  127. b3GJK(const b3AlignedObjectArray<b3Vector3>& verticesA, const b3AlignedObjectArray<b3Vector3>& verticesB)
  128. : m_verticesA(verticesA), m_verticesB(verticesB)
  129. {
  130. Initialize();
  131. }
  132. void Initialize()
  133. {
  134. m_ray = b3MakeVector3(0, 0, 0);
  135. m_nfree = 0;
  136. m_status = eStatus::Failed;
  137. m_current = 0;
  138. m_distance = 0;
  139. }
  140. eStatus::_ Evaluate(const tShape& shapearg, const b3Vector3& guess)
  141. {
  142. unsigned int iterations = 0;
  143. b3Scalar sqdist = 0;
  144. b3Scalar alpha = 0;
  145. b3Vector3 lastw[4];
  146. unsigned int clastw = 0;
  147. /* Initialize solver */
  148. m_free[0] = &m_store[0];
  149. m_free[1] = &m_store[1];
  150. m_free[2] = &m_store[2];
  151. m_free[3] = &m_store[3];
  152. m_nfree = 4;
  153. m_current = 0;
  154. m_status = eStatus::Valid;
  155. m_shape = shapearg;
  156. m_distance = 0;
  157. /* Initialize simplex */
  158. m_simplices[0].rank = 0;
  159. m_ray = guess;
  160. const b3Scalar sqrl = m_ray.length2();
  161. appendvertice(m_simplices[0], sqrl > 0 ? -m_ray : b3MakeVector3(1, 0, 0));
  162. m_simplices[0].p[0] = 1;
  163. m_ray = m_simplices[0].c[0]->w;
  164. sqdist = sqrl;
  165. lastw[0] =
  166. lastw[1] =
  167. lastw[2] =
  168. lastw[3] = m_ray;
  169. /* Loop */
  170. do
  171. {
  172. const unsigned int next = 1 - m_current;
  173. sSimplex& cs = m_simplices[m_current];
  174. sSimplex& ns = m_simplices[next];
  175. /* Check zero */
  176. const b3Scalar rl = m_ray.length();
  177. if (rl < GJK_MIN_DISTANCE)
  178. { /* Touching or inside */
  179. m_status = eStatus::Inside;
  180. break;
  181. }
  182. /* Append new vertice in -'v' direction */
  183. appendvertice(cs, -m_ray);
  184. const b3Vector3& w = cs.c[cs.rank - 1]->w;
  185. bool found = false;
  186. for (unsigned int i = 0; i < 4; ++i)
  187. {
  188. if ((w - lastw[i]).length2() < GJK_DUPLICATED_EPS)
  189. {
  190. found = true;
  191. break;
  192. }
  193. }
  194. if (found)
  195. { /* Return old simplex */
  196. removevertice(m_simplices[m_current]);
  197. break;
  198. }
  199. else
  200. { /* Update lastw */
  201. lastw[clastw = (clastw + 1) & 3] = w;
  202. }
  203. /* Check for termination */
  204. const b3Scalar omega = b3Dot(m_ray, w) / rl;
  205. alpha = b3Max(omega, alpha);
  206. if (((rl - alpha) - (GJK_ACCURACY * rl)) <= 0)
  207. { /* Return old simplex */
  208. removevertice(m_simplices[m_current]);
  209. break;
  210. }
  211. /* Reduce simplex */
  212. b3Scalar weights[4];
  213. unsigned int mask = 0;
  214. switch (cs.rank)
  215. {
  216. case 2:
  217. sqdist = projectorigin(cs.c[0]->w,
  218. cs.c[1]->w,
  219. weights, mask);
  220. break;
  221. case 3:
  222. sqdist = projectorigin(cs.c[0]->w,
  223. cs.c[1]->w,
  224. cs.c[2]->w,
  225. weights, mask);
  226. break;
  227. case 4:
  228. sqdist = projectorigin(cs.c[0]->w,
  229. cs.c[1]->w,
  230. cs.c[2]->w,
  231. cs.c[3]->w,
  232. weights, mask);
  233. break;
  234. }
  235. if (sqdist >= 0)
  236. { /* Valid */
  237. ns.rank = 0;
  238. m_ray = b3MakeVector3(0, 0, 0);
  239. m_current = next;
  240. for (unsigned int i = 0, ni = cs.rank; i < ni; ++i)
  241. {
  242. if (mask & (1 << i))
  243. {
  244. ns.c[ns.rank] = cs.c[i];
  245. ns.p[ns.rank++] = weights[i];
  246. m_ray += cs.c[i]->w * weights[i];
  247. }
  248. else
  249. {
  250. m_free[m_nfree++] = cs.c[i];
  251. }
  252. }
  253. if (mask == 15) m_status = eStatus::Inside;
  254. }
  255. else
  256. { /* Return old simplex */
  257. removevertice(m_simplices[m_current]);
  258. break;
  259. }
  260. m_status = ((++iterations) < GJK_MAX_ITERATIONS) ? m_status : eStatus::Failed;
  261. } while (m_status == eStatus::Valid);
  262. m_simplex = &m_simplices[m_current];
  263. switch (m_status)
  264. {
  265. case eStatus::Valid:
  266. m_distance = m_ray.length();
  267. break;
  268. case eStatus::Inside:
  269. m_distance = 0;
  270. break;
  271. default:
  272. {
  273. }
  274. }
  275. return (m_status);
  276. }
  277. bool EncloseOrigin()
  278. {
  279. switch (m_simplex->rank)
  280. {
  281. case 1:
  282. {
  283. for (unsigned int i = 0; i < 3; ++i)
  284. {
  285. b3Vector3 axis = b3MakeVector3(0, 0, 0);
  286. axis[i] = 1;
  287. appendvertice(*m_simplex, axis);
  288. if (EncloseOrigin()) return (true);
  289. removevertice(*m_simplex);
  290. appendvertice(*m_simplex, -axis);
  291. if (EncloseOrigin()) return (true);
  292. removevertice(*m_simplex);
  293. }
  294. }
  295. break;
  296. case 2:
  297. {
  298. const b3Vector3 d = m_simplex->c[1]->w - m_simplex->c[0]->w;
  299. for (unsigned int i = 0; i < 3; ++i)
  300. {
  301. b3Vector3 axis = b3MakeVector3(0, 0, 0);
  302. axis[i] = 1;
  303. const b3Vector3 p = b3Cross(d, axis);
  304. if (p.length2() > 0)
  305. {
  306. appendvertice(*m_simplex, p);
  307. if (EncloseOrigin()) return (true);
  308. removevertice(*m_simplex);
  309. appendvertice(*m_simplex, -p);
  310. if (EncloseOrigin()) return (true);
  311. removevertice(*m_simplex);
  312. }
  313. }
  314. }
  315. break;
  316. case 3:
  317. {
  318. const b3Vector3 n = b3Cross(m_simplex->c[1]->w - m_simplex->c[0]->w,
  319. m_simplex->c[2]->w - m_simplex->c[0]->w);
  320. if (n.length2() > 0)
  321. {
  322. appendvertice(*m_simplex, n);
  323. if (EncloseOrigin()) return (true);
  324. removevertice(*m_simplex);
  325. appendvertice(*m_simplex, -n);
  326. if (EncloseOrigin()) return (true);
  327. removevertice(*m_simplex);
  328. }
  329. }
  330. break;
  331. case 4:
  332. {
  333. if (b3Fabs(det(m_simplex->c[0]->w - m_simplex->c[3]->w,
  334. m_simplex->c[1]->w - m_simplex->c[3]->w,
  335. m_simplex->c[2]->w - m_simplex->c[3]->w)) > 0)
  336. return (true);
  337. }
  338. break;
  339. }
  340. return (false);
  341. }
  342. /* Internals */
  343. void getsupport(const b3Vector3& d, sSV& sv) const
  344. {
  345. sv.d = d / d.length();
  346. sv.w = m_shape.Support(sv.d, m_verticesA, m_verticesB);
  347. }
  348. void removevertice(sSimplex& simplex)
  349. {
  350. m_free[m_nfree++] = simplex.c[--simplex.rank];
  351. }
  352. void appendvertice(sSimplex& simplex, const b3Vector3& v)
  353. {
  354. simplex.p[simplex.rank] = 0;
  355. simplex.c[simplex.rank] = m_free[--m_nfree];
  356. getsupport(v, *simplex.c[simplex.rank++]);
  357. }
  358. static b3Scalar det(const b3Vector3& a, const b3Vector3& b, const b3Vector3& c)
  359. {
  360. return (a.y * b.z * c.x + a.z * b.x * c.y -
  361. a.x * b.z * c.y - a.y * b.x * c.z +
  362. a.x * b.y * c.z - a.z * b.y * c.x);
  363. }
  364. static b3Scalar projectorigin(const b3Vector3& a,
  365. const b3Vector3& b,
  366. b3Scalar* w, unsigned int& m)
  367. {
  368. const b3Vector3 d = b - a;
  369. const b3Scalar l = d.length2();
  370. if (l > GJK_SIMPLEX2_EPS)
  371. {
  372. const b3Scalar t(l > 0 ? -b3Dot(a, d) / l : 0);
  373. if (t >= 1)
  374. {
  375. w[0] = 0;
  376. w[1] = 1;
  377. m = 2;
  378. return (b.length2());
  379. }
  380. else if (t <= 0)
  381. {
  382. w[0] = 1;
  383. w[1] = 0;
  384. m = 1;
  385. return (a.length2());
  386. }
  387. else
  388. {
  389. w[0] = 1 - (w[1] = t);
  390. m = 3;
  391. return ((a + d * t).length2());
  392. }
  393. }
  394. return (-1);
  395. }
  396. static b3Scalar projectorigin(const b3Vector3& a,
  397. const b3Vector3& b,
  398. const b3Vector3& c,
  399. b3Scalar* w, unsigned int& m)
  400. {
  401. static const unsigned int imd3[] = {1, 2, 0};
  402. const b3Vector3* vt[] = {&a, &b, &c};
  403. const b3Vector3 dl[] = {a - b, b - c, c - a};
  404. const b3Vector3 n = b3Cross(dl[0], dl[1]);
  405. const b3Scalar l = n.length2();
  406. if (l > GJK_SIMPLEX3_EPS)
  407. {
  408. b3Scalar mindist = -1;
  409. b3Scalar subw[2] = {0.f, 0.f};
  410. unsigned int subm(0);
  411. for (unsigned int i = 0; i < 3; ++i)
  412. {
  413. if (b3Dot(*vt[i], b3Cross(dl[i], n)) > 0)
  414. {
  415. const unsigned int j = imd3[i];
  416. const b3Scalar subd(projectorigin(*vt[i], *vt[j], subw, subm));
  417. if ((mindist < 0) || (subd < mindist))
  418. {
  419. mindist = subd;
  420. m = static_cast<unsigned int>(((subm & 1) ? 1 << i : 0) + ((subm & 2) ? 1 << j : 0));
  421. w[i] = subw[0];
  422. w[j] = subw[1];
  423. w[imd3[j]] = 0;
  424. }
  425. }
  426. }
  427. if (mindist < 0)
  428. {
  429. const b3Scalar d = b3Dot(a, n);
  430. const b3Scalar s = b3Sqrt(l);
  431. const b3Vector3 p = n * (d / l);
  432. mindist = p.length2();
  433. m = 7;
  434. w[0] = (b3Cross(dl[1], b - p)).length() / s;
  435. w[1] = (b3Cross(dl[2], c - p)).length() / s;
  436. w[2] = 1 - (w[0] + w[1]);
  437. }
  438. return (mindist);
  439. }
  440. return (-1);
  441. }
  442. static b3Scalar projectorigin(const b3Vector3& a,
  443. const b3Vector3& b,
  444. const b3Vector3& c,
  445. const b3Vector3& d,
  446. b3Scalar* w, unsigned int& m)
  447. {
  448. static const unsigned int imd3[] = {1, 2, 0};
  449. const b3Vector3* vt[] = {&a, &b, &c, &d};
  450. const b3Vector3 dl[] = {a - d, b - d, c - d};
  451. const b3Scalar vl = det(dl[0], dl[1], dl[2]);
  452. const bool ng = (vl * b3Dot(a, b3Cross(b - c, a - b))) <= 0;
  453. if (ng && (b3Fabs(vl) > GJK_SIMPLEX4_EPS))
  454. {
  455. b3Scalar mindist = -1;
  456. b3Scalar subw[3] = {0.f, 0.f, 0.f};
  457. unsigned int subm(0);
  458. for (unsigned int i = 0; i < 3; ++i)
  459. {
  460. const unsigned int j = imd3[i];
  461. const b3Scalar s = vl * b3Dot(d, b3Cross(dl[i], dl[j]));
  462. if (s > 0)
  463. {
  464. const b3Scalar subd = projectorigin(*vt[i], *vt[j], d, subw, subm);
  465. if ((mindist < 0) || (subd < mindist))
  466. {
  467. mindist = subd;
  468. m = static_cast<unsigned int>((subm & 1 ? 1 << i : 0) +
  469. (subm & 2 ? 1 << j : 0) +
  470. (subm & 4 ? 8 : 0));
  471. w[i] = subw[0];
  472. w[j] = subw[1];
  473. w[imd3[j]] = 0;
  474. w[3] = subw[2];
  475. }
  476. }
  477. }
  478. if (mindist < 0)
  479. {
  480. mindist = 0;
  481. m = 15;
  482. w[0] = det(c, b, d) / vl;
  483. w[1] = det(a, c, d) / vl;
  484. w[2] = det(b, a, d) / vl;
  485. w[3] = 1 - (w[0] + w[1] + w[2]);
  486. }
  487. return (mindist);
  488. }
  489. return (-1);
  490. }
  491. };
  492. // EPA
  493. struct b3EPA
  494. {
  495. /* Types */
  496. typedef b3GJK::sSV sSV;
  497. struct sFace
  498. {
  499. b3Vector3 n;
  500. b3Scalar d;
  501. sSV* c[3];
  502. sFace* f[3];
  503. sFace* l[2];
  504. unsigned char e[3];
  505. unsigned char pass;
  506. };
  507. struct sList
  508. {
  509. sFace* root;
  510. unsigned int count;
  511. sList() : root(0), count(0) {}
  512. };
  513. struct sHorizon
  514. {
  515. sFace* cf;
  516. sFace* ff;
  517. unsigned int nf;
  518. sHorizon() : cf(0), ff(0), nf(0) {}
  519. };
  520. struct eStatus
  521. {
  522. enum _
  523. {
  524. Valid,
  525. Touching,
  526. Degenerated,
  527. NonConvex,
  528. InvalidHull,
  529. OutOfFaces,
  530. OutOfVertices,
  531. AccuraryReached,
  532. FallBack,
  533. Failed
  534. };
  535. };
  536. /* Fields */
  537. eStatus::_ m_status;
  538. b3GJK::sSimplex m_result;
  539. b3Vector3 m_normal;
  540. b3Scalar m_depth;
  541. sSV m_sv_store[EPA_MAX_VERTICES];
  542. sFace m_fc_store[EPA_MAX_FACES];
  543. unsigned int m_nextsv;
  544. sList m_hull;
  545. sList m_stock;
  546. /* Methods */
  547. b3EPA()
  548. {
  549. Initialize();
  550. }
  551. static inline void bind(sFace* fa, unsigned int ea, sFace* fb, unsigned int eb)
  552. {
  553. fa->e[ea] = (unsigned char)eb;
  554. fa->f[ea] = fb;
  555. fb->e[eb] = (unsigned char)ea;
  556. fb->f[eb] = fa;
  557. }
  558. static inline void append(sList& list, sFace* face)
  559. {
  560. face->l[0] = 0;
  561. face->l[1] = list.root;
  562. if (list.root) list.root->l[0] = face;
  563. list.root = face;
  564. ++list.count;
  565. }
  566. static inline void remove(sList& list, sFace* face)
  567. {
  568. if (face->l[1]) face->l[1]->l[0] = face->l[0];
  569. if (face->l[0]) face->l[0]->l[1] = face->l[1];
  570. if (face == list.root) list.root = face->l[1];
  571. --list.count;
  572. }
  573. void Initialize()
  574. {
  575. m_status = eStatus::Failed;
  576. m_normal = b3MakeVector3(0, 0, 0);
  577. m_depth = 0;
  578. m_nextsv = 0;
  579. for (unsigned int i = 0; i < EPA_MAX_FACES; ++i)
  580. {
  581. append(m_stock, &m_fc_store[EPA_MAX_FACES - i - 1]);
  582. }
  583. }
  584. eStatus::_ Evaluate(b3GJK& gjk, const b3Vector3& guess)
  585. {
  586. b3GJK::sSimplex& simplex = *gjk.m_simplex;
  587. if ((simplex.rank > 1) && gjk.EncloseOrigin())
  588. {
  589. /* Clean up */
  590. while (m_hull.root)
  591. {
  592. sFace* f = m_hull.root;
  593. remove(m_hull, f);
  594. append(m_stock, f);
  595. }
  596. m_status = eStatus::Valid;
  597. m_nextsv = 0;
  598. /* Orient simplex */
  599. if (gjk.det(simplex.c[0]->w - simplex.c[3]->w,
  600. simplex.c[1]->w - simplex.c[3]->w,
  601. simplex.c[2]->w - simplex.c[3]->w) < 0)
  602. {
  603. b3Swap(simplex.c[0], simplex.c[1]);
  604. b3Swap(simplex.p[0], simplex.p[1]);
  605. }
  606. /* Build initial hull */
  607. sFace* tetra[] = {newface(simplex.c[0], simplex.c[1], simplex.c[2], true),
  608. newface(simplex.c[1], simplex.c[0], simplex.c[3], true),
  609. newface(simplex.c[2], simplex.c[1], simplex.c[3], true),
  610. newface(simplex.c[0], simplex.c[2], simplex.c[3], true)};
  611. if (m_hull.count == 4)
  612. {
  613. sFace* best = findbest();
  614. sFace outer = *best;
  615. unsigned int pass = 0;
  616. unsigned int iterations = 0;
  617. bind(tetra[0], 0, tetra[1], 0);
  618. bind(tetra[0], 1, tetra[2], 0);
  619. bind(tetra[0], 2, tetra[3], 0);
  620. bind(tetra[1], 1, tetra[3], 2);
  621. bind(tetra[1], 2, tetra[2], 1);
  622. bind(tetra[2], 2, tetra[3], 1);
  623. m_status = eStatus::Valid;
  624. for (; iterations < EPA_MAX_ITERATIONS; ++iterations)
  625. {
  626. if (m_nextsv < EPA_MAX_VERTICES)
  627. {
  628. sHorizon horizon;
  629. sSV* w = &m_sv_store[m_nextsv++];
  630. bool valid = true;
  631. best->pass = (unsigned char)(++pass);
  632. gjk.getsupport(best->n, *w);
  633. const b3Scalar wdist = b3Dot(best->n, w->w) - best->d;
  634. if (wdist > EPA_ACCURACY)
  635. {
  636. for (unsigned int j = 0; (j < 3) && valid; ++j)
  637. {
  638. valid &= expand(pass, w,
  639. best->f[j], best->e[j],
  640. horizon);
  641. }
  642. if (valid && (horizon.nf >= 3))
  643. {
  644. bind(horizon.cf, 1, horizon.ff, 2);
  645. remove(m_hull, best);
  646. append(m_stock, best);
  647. best = findbest();
  648. outer = *best;
  649. }
  650. else
  651. {
  652. m_status = eStatus::Failed;
  653. //m_status=eStatus::InvalidHull;
  654. break;
  655. }
  656. }
  657. else
  658. {
  659. m_status = eStatus::AccuraryReached;
  660. break;
  661. }
  662. }
  663. else
  664. {
  665. m_status = eStatus::OutOfVertices;
  666. break;
  667. }
  668. }
  669. const b3Vector3 projection = outer.n * outer.d;
  670. m_normal = outer.n;
  671. m_depth = outer.d;
  672. m_result.rank = 3;
  673. m_result.c[0] = outer.c[0];
  674. m_result.c[1] = outer.c[1];
  675. m_result.c[2] = outer.c[2];
  676. m_result.p[0] = b3Cross(outer.c[1]->w - projection,
  677. outer.c[2]->w - projection)
  678. .length();
  679. m_result.p[1] = b3Cross(outer.c[2]->w - projection,
  680. outer.c[0]->w - projection)
  681. .length();
  682. m_result.p[2] = b3Cross(outer.c[0]->w - projection,
  683. outer.c[1]->w - projection)
  684. .length();
  685. const b3Scalar sum = m_result.p[0] + m_result.p[1] + m_result.p[2];
  686. m_result.p[0] /= sum;
  687. m_result.p[1] /= sum;
  688. m_result.p[2] /= sum;
  689. return (m_status);
  690. }
  691. }
  692. /* Fallback */
  693. m_status = eStatus::FallBack;
  694. m_normal = -guess;
  695. const b3Scalar nl = m_normal.length();
  696. if (nl > 0)
  697. m_normal = m_normal / nl;
  698. else
  699. m_normal = b3MakeVector3(1, 0, 0);
  700. m_depth = 0;
  701. m_result.rank = 1;
  702. m_result.c[0] = simplex.c[0];
  703. m_result.p[0] = 1;
  704. return (m_status);
  705. }
  706. bool getedgedist(sFace* face, sSV* a, sSV* b, b3Scalar& dist)
  707. {
  708. const b3Vector3 ba = b->w - a->w;
  709. const b3Vector3 n_ab = b3Cross(ba, face->n); // Outward facing edge normal direction, on triangle plane
  710. const b3Scalar a_dot_nab = b3Dot(a->w, n_ab); // Only care about the sign to determine inside/outside, so not normalization required
  711. if (a_dot_nab < 0)
  712. {
  713. // Outside of edge a->b
  714. const b3Scalar ba_l2 = ba.length2();
  715. const b3Scalar a_dot_ba = b3Dot(a->w, ba);
  716. const b3Scalar b_dot_ba = b3Dot(b->w, ba);
  717. if (a_dot_ba > 0)
  718. {
  719. // Pick distance vertex a
  720. dist = a->w.length();
  721. }
  722. else if (b_dot_ba < 0)
  723. {
  724. // Pick distance vertex b
  725. dist = b->w.length();
  726. }
  727. else
  728. {
  729. // Pick distance to edge a->b
  730. const b3Scalar a_dot_b = b3Dot(a->w, b->w);
  731. dist = b3Sqrt(b3Max((a->w.length2() * b->w.length2() - a_dot_b * a_dot_b) / ba_l2, (b3Scalar)0));
  732. }
  733. return true;
  734. }
  735. return false;
  736. }
  737. sFace* newface(sSV* a, sSV* b, sSV* c, bool forced)
  738. {
  739. if (m_stock.root)
  740. {
  741. sFace* face = m_stock.root;
  742. remove(m_stock, face);
  743. append(m_hull, face);
  744. face->pass = 0;
  745. face->c[0] = a;
  746. face->c[1] = b;
  747. face->c[2] = c;
  748. face->n = b3Cross(b->w - a->w, c->w - a->w);
  749. const b3Scalar l = face->n.length();
  750. const bool v = l > EPA_ACCURACY;
  751. if (v)
  752. {
  753. if (!(getedgedist(face, a, b, face->d) ||
  754. getedgedist(face, b, c, face->d) ||
  755. getedgedist(face, c, a, face->d)))
  756. {
  757. // Origin projects to the interior of the triangle
  758. // Use distance to triangle plane
  759. face->d = b3Dot(a->w, face->n) / l;
  760. }
  761. face->n /= l;
  762. if (forced || (face->d >= -EPA_PLANE_EPS))
  763. {
  764. return face;
  765. }
  766. else
  767. m_status = eStatus::NonConvex;
  768. }
  769. else
  770. m_status = eStatus::Degenerated;
  771. remove(m_hull, face);
  772. append(m_stock, face);
  773. return 0;
  774. }
  775. m_status = m_stock.root ? eStatus::OutOfVertices : eStatus::OutOfFaces;
  776. return 0;
  777. }
  778. sFace* findbest()
  779. {
  780. sFace* minf = m_hull.root;
  781. b3Scalar mind = minf->d * minf->d;
  782. for (sFace* f = minf->l[1]; f; f = f->l[1])
  783. {
  784. const b3Scalar sqd = f->d * f->d;
  785. if (sqd < mind)
  786. {
  787. minf = f;
  788. mind = sqd;
  789. }
  790. }
  791. return (minf);
  792. }
  793. bool expand(unsigned int pass, sSV* w, sFace* f, unsigned int e, sHorizon& horizon)
  794. {
  795. static const unsigned int i1m3[] = {1, 2, 0};
  796. static const unsigned int i2m3[] = {2, 0, 1};
  797. if (f->pass != pass)
  798. {
  799. const unsigned int e1 = i1m3[e];
  800. if ((b3Dot(f->n, w->w) - f->d) < -EPA_PLANE_EPS)
  801. {
  802. sFace* nf = newface(f->c[e1], f->c[e], w, false);
  803. if (nf)
  804. {
  805. bind(nf, 0, f, e);
  806. if (horizon.cf)
  807. bind(horizon.cf, 1, nf, 2);
  808. else
  809. horizon.ff = nf;
  810. horizon.cf = nf;
  811. ++horizon.nf;
  812. return (true);
  813. }
  814. }
  815. else
  816. {
  817. const unsigned int e2 = i2m3[e];
  818. f->pass = (unsigned char)pass;
  819. if (expand(pass, w, f->f[e1], f->e[e1], horizon) &&
  820. expand(pass, w, f->f[e2], f->e[e2], horizon))
  821. {
  822. remove(m_hull, f);
  823. append(m_stock, f);
  824. return (true);
  825. }
  826. }
  827. }
  828. return (false);
  829. }
  830. };
  831. //
  832. static void Initialize(const b3Transform& transA, const b3Transform& transB,
  833. const b3ConvexPolyhedronData* hullA, const b3ConvexPolyhedronData* hullB,
  834. const b3AlignedObjectArray<b3Vector3>& verticesA,
  835. const b3AlignedObjectArray<b3Vector3>& verticesB,
  836. b3GjkEpaSolver2::sResults& results,
  837. tShape& shape,
  838. bool withmargins)
  839. {
  840. /* Results */
  841. results.witnesses[0] =
  842. results.witnesses[1] = b3MakeVector3(0, 0, 0);
  843. results.status = b3GjkEpaSolver2::sResults::Separated;
  844. /* Shape */
  845. shape.m_shapes[0] = hullA;
  846. shape.m_shapes[1] = hullB;
  847. shape.m_toshape1 = transB.getBasis().transposeTimes(transA.getBasis());
  848. shape.m_toshape0 = transA.inverseTimes(transB);
  849. shape.EnableMargin(withmargins);
  850. }
  851. } // namespace gjkepa2_impl2
  852. //
  853. // Api
  854. //
  855. using namespace gjkepa2_impl2;
  856. //
  857. int b3GjkEpaSolver2::StackSizeRequirement()
  858. {
  859. return (sizeof(b3GJK) + sizeof(b3EPA));
  860. }
  861. //
  862. bool b3GjkEpaSolver2::Distance(const b3Transform& transA, const b3Transform& transB,
  863. const b3ConvexPolyhedronData* hullA, const b3ConvexPolyhedronData* hullB,
  864. const b3AlignedObjectArray<b3Vector3>& verticesA,
  865. const b3AlignedObjectArray<b3Vector3>& verticesB,
  866. const b3Vector3& guess,
  867. sResults& results)
  868. {
  869. tShape shape;
  870. Initialize(transA, transB, hullA, hullB, verticesA, verticesB, results, shape, false);
  871. b3GJK gjk(verticesA, verticesB);
  872. b3GJK::eStatus::_ gjk_status = gjk.Evaluate(shape, guess);
  873. if (gjk_status == b3GJK::eStatus::Valid)
  874. {
  875. b3Vector3 w0 = b3MakeVector3(0, 0, 0);
  876. b3Vector3 w1 = b3MakeVector3(0, 0, 0);
  877. for (unsigned int i = 0; i < gjk.m_simplex->rank; ++i)
  878. {
  879. const b3Scalar p = gjk.m_simplex->p[i];
  880. w0 += shape.Support(gjk.m_simplex->c[i]->d, 0, verticesA, verticesB) * p;
  881. w1 += shape.Support(-gjk.m_simplex->c[i]->d, 1, verticesA, verticesB) * p;
  882. }
  883. results.witnesses[0] = transA * w0;
  884. results.witnesses[1] = transA * w1;
  885. results.normal = w0 - w1;
  886. results.distance = results.normal.length();
  887. results.normal /= results.distance > GJK_MIN_DISTANCE ? results.distance : 1;
  888. return (true);
  889. }
  890. else
  891. {
  892. results.status = gjk_status == b3GJK::eStatus::Inside ? sResults::Penetrating : sResults::GJK_Failed;
  893. return (false);
  894. }
  895. }
  896. //
  897. bool b3GjkEpaSolver2::Penetration(const b3Transform& transA, const b3Transform& transB,
  898. const b3ConvexPolyhedronData* hullA, const b3ConvexPolyhedronData* hullB,
  899. const b3AlignedObjectArray<b3Vector3>& verticesA,
  900. const b3AlignedObjectArray<b3Vector3>& verticesB,
  901. const b3Vector3& guess,
  902. sResults& results,
  903. bool usemargins)
  904. {
  905. tShape shape;
  906. Initialize(transA, transB, hullA, hullB, verticesA, verticesB, results, shape, usemargins);
  907. b3GJK gjk(verticesA, verticesB);
  908. b3GJK::eStatus::_ gjk_status = gjk.Evaluate(shape, guess);
  909. switch (gjk_status)
  910. {
  911. case b3GJK::eStatus::Inside:
  912. {
  913. b3EPA epa;
  914. b3EPA::eStatus::_ epa_status = epa.Evaluate(gjk, -guess);
  915. if (epa_status != b3EPA::eStatus::Failed)
  916. {
  917. b3Vector3 w0 = b3MakeVector3(0, 0, 0);
  918. for (unsigned int i = 0; i < epa.m_result.rank; ++i)
  919. {
  920. w0 += shape.Support(epa.m_result.c[i]->d, 0, verticesA, verticesB) * epa.m_result.p[i];
  921. }
  922. results.status = sResults::Penetrating;
  923. results.witnesses[0] = transA * w0;
  924. results.witnesses[1] = transA * (w0 - epa.m_normal * epa.m_depth);
  925. results.normal = -epa.m_normal;
  926. results.distance = -epa.m_depth;
  927. return (true);
  928. }
  929. else
  930. results.status = sResults::EPA_Failed;
  931. }
  932. break;
  933. case b3GJK::eStatus::Failed:
  934. results.status = sResults::GJK_Failed;
  935. break;
  936. default:
  937. {
  938. }
  939. }
  940. return (false);
  941. }
  942. #if 0
  943. //
  944. b3Scalar b3GjkEpaSolver2::SignedDistance(const b3Vector3& position,
  945. b3Scalar margin,
  946. const b3Transform& transA,
  947. const b3ConvexPolyhedronData& hullA,
  948. const b3AlignedObjectArray<b3Vector3>& verticesA,
  949. sResults& results)
  950. {
  951. tShape shape;
  952. btSphereShape shape1(margin);
  953. b3Transform wtrs1(b3Quaternion(0,0,0,1),position);
  954. Initialize(shape0,wtrs0,&shape1,wtrs1,results,shape,false);
  955. GJK gjk;
  956. GJK::eStatus::_ gjk_status=gjk.Evaluate(shape,b3Vector3(1,1,1));
  957. if(gjk_status==GJK::eStatus::Valid)
  958. {
  959. b3Vector3 w0=b3Vector3(0,0,0);
  960. b3Vector3 w1=b3Vector3(0,0,0);
  961. for(unsigned int i=0;i<gjk.m_simplex->rank;++i)
  962. {
  963. const b3Scalar p=gjk.m_simplex->p[i];
  964. w0+=shape.Support( gjk.m_simplex->c[i]->d,0)*p;
  965. w1+=shape.Support(-gjk.m_simplex->c[i]->d,1)*p;
  966. }
  967. results.witnesses[0] = wtrs0*w0;
  968. results.witnesses[1] = wtrs0*w1;
  969. const b3Vector3 delta= results.witnesses[1]-
  970. results.witnesses[0];
  971. const b3Scalar margin= shape0->getMarginNonVirtual()+
  972. shape1.getMarginNonVirtual();
  973. const b3Scalar length= delta.length();
  974. results.normal = delta/length;
  975. results.witnesses[0] += results.normal*margin;
  976. return(length-margin);
  977. }
  978. else
  979. {
  980. if(gjk_status==GJK::eStatus::Inside)
  981. {
  982. if(Penetration(shape0,wtrs0,&shape1,wtrs1,gjk.m_ray,results))
  983. {
  984. const b3Vector3 delta= results.witnesses[0]-
  985. results.witnesses[1];
  986. const b3Scalar length= delta.length();
  987. if (length >= B3_EPSILON)
  988. results.normal = delta/length;
  989. return(-length);
  990. }
  991. }
  992. }
  993. return(B3_INFINITY);
  994. }
  995. //
  996. bool b3GjkEpaSolver2::SignedDistance(const btConvexShape* shape0,
  997. const b3Transform& wtrs0,
  998. const btConvexShape* shape1,
  999. const b3Transform& wtrs1,
  1000. const b3Vector3& guess,
  1001. sResults& results)
  1002. {
  1003. if(!Distance(shape0,wtrs0,shape1,wtrs1,guess,results))
  1004. return(Penetration(shape0,wtrs0,shape1,wtrs1,guess,results,false));
  1005. else
  1006. return(true);
  1007. }
  1008. #endif
  1009. /* Symbols cleanup */
  1010. #undef GJK_MAX_ITERATIONS
  1011. #undef GJK_ACCURACY
  1012. #undef GJK_MIN_DISTANCE
  1013. #undef GJK_DUPLICATED_EPS
  1014. #undef GJK_SIMPLEX2_EPS
  1015. #undef GJK_SIMPLEX3_EPS
  1016. #undef GJK_SIMPLEX4_EPS
  1017. #undef EPA_MAX_VERTICES
  1018. #undef EPA_MAX_FACES
  1019. #undef EPA_MAX_ITERATIONS
  1020. #undef EPA_ACCURACY
  1021. #undef EPA_FALLBACK
  1022. #undef EPA_PLANE_EPS
  1023. #undef EPA_INSIDE_EPS