gjk.cpp 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387
  1. //-----------------------------------------------------------------------------
  2. // Copyright (c) 2012 GarageGames, LLC
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy
  5. // of this software and associated documentation files (the "Software"), to
  6. // deal in the Software without restriction, including without limitation the
  7. // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  8. // sell copies of the Software, and to permit persons to whom the Software is
  9. // furnished to do so, subject to the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included in
  12. // all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  19. // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  20. // IN THE SOFTWARE.
  21. //-----------------------------------------------------------------------------
  22. // The core algorithms in this file are inspired by public papers written
  23. // by G. van den Bergen for his interference detection library,
  24. // "SOLID 2.0"
  25. #include "core/dataChunker.h"
  26. #include "collision/collision.h"
  27. #include "scene/sceneObject.h"
  28. #include "collision/convex.h"
  29. #include "collision/gjk.h"
  30. //----------------------------------------------------------------------------
  31. static F32 rel_error = 1E-5f; // relative error in the computed distance
  32. static F32 sTolerance = 1E-3f; // Distance tolerance
  33. static F32 sEpsilon2 = 1E-20f; // Zero length vector
  34. static U32 sIteration = 15; // Stuck in a loop?
  35. S32 num_iterations = 0;
  36. S32 num_irregularities = 0;
  37. //----------------------------------------------------------------------------
  38. GjkCollisionState::GjkCollisionState()
  39. {
  40. a = b = 0;
  41. }
  42. GjkCollisionState::~GjkCollisionState()
  43. {
  44. }
  45. //----------------------------------------------------------------------------
  46. void GjkCollisionState::swap()
  47. {
  48. Convex* t = a; a = b; b = t;
  49. CollisionStateList* l = mLista; mLista = mListb; mListb = l;
  50. v.neg();
  51. }
  52. //----------------------------------------------------------------------------
  53. void GjkCollisionState::compute_det()
  54. {
  55. // Dot new point with current set
  56. for (S32 i = 0, bit = 1; i < 4; ++i, bit <<=1)
  57. if (bits & bit)
  58. dp[i][last] = dp[last][i] = mDot(y[i], y[last]);
  59. dp[last][last] = mDot(y[last], y[last]);
  60. // Calulate the determinent
  61. det[last_bit][last] = 1;
  62. for (S32 j = 0, sj = 1; j < 4; ++j, sj <<= 1) {
  63. if (bits & sj) {
  64. S32 s2 = sj | last_bit;
  65. det[s2][j] = dp[last][last] - dp[last][j];
  66. det[s2][last] = dp[j][j] - dp[j][last];
  67. for (S32 k = 0, sk = 1; k < j; ++k, sk <<= 1) {
  68. if (bits & sk) {
  69. S32 s3 = sk | s2;
  70. det[s3][k] = det[s2][j] * (dp[j][j] - dp[j][k]) +
  71. det[s2][last] * (dp[last][j] - dp[last][k]);
  72. det[s3][j] = det[sk | last_bit][k] * (dp[k][k] - dp[k][j]) +
  73. det[sk | last_bit][last] * (dp[last][k] - dp[last][j]);
  74. det[s3][last] = det[sk | sj][k] * (dp[k][k] - dp[k][last]) +
  75. det[sk | sj][j] * (dp[j][k] - dp[j][last]);
  76. }
  77. }
  78. }
  79. }
  80. if (all_bits == 15) {
  81. det[15][0] = det[14][1] * (dp[1][1] - dp[1][0]) +
  82. det[14][2] * (dp[2][1] - dp[2][0]) +
  83. det[14][3] * (dp[3][1] - dp[3][0]);
  84. det[15][1] = det[13][0] * (dp[0][0] - dp[0][1]) +
  85. det[13][2] * (dp[2][0] - dp[2][1]) +
  86. det[13][3] * (dp[3][0] - dp[3][1]);
  87. det[15][2] = det[11][0] * (dp[0][0] - dp[0][2]) +
  88. det[11][1] * (dp[1][0] - dp[1][2]) +
  89. det[11][3] * (dp[3][0] - dp[3][2]);
  90. det[15][3] = det[7][0] * (dp[0][0] - dp[0][3]) +
  91. det[7][1] * (dp[1][0] - dp[1][3]) +
  92. det[7][2] * (dp[2][0] - dp[2][3]);
  93. }
  94. }
  95. //----------------------------------------------------------------------------
  96. inline void GjkCollisionState::compute_vector(S32 bits, VectorF& v)
  97. {
  98. F32 sum = 0;
  99. v.set(0, 0, 0);
  100. for (S32 i = 0, bit = 1; i < 4; ++i, bit <<= 1) {
  101. if (bits & bit) {
  102. sum += det[bits][i];
  103. v += y[i] * det[bits][i];
  104. }
  105. }
  106. v *= 1 / sum;
  107. }
  108. //----------------------------------------------------------------------------
  109. inline bool GjkCollisionState::valid(S32 s)
  110. {
  111. for (S32 i = 0, bit = 1; i < 4; ++i, bit <<= 1) {
  112. if (all_bits & bit) {
  113. if (s & bit) {
  114. if (det[s][i] <= 0)
  115. return false;
  116. }
  117. else
  118. if (det[s | bit][i] > 0)
  119. return false;
  120. }
  121. }
  122. return true;
  123. }
  124. //----------------------------------------------------------------------------
  125. inline bool GjkCollisionState::closest(VectorF& v)
  126. {
  127. compute_det();
  128. for (S32 s = bits; s; --s) {
  129. if ((s & bits) == s) {
  130. if (valid(s | last_bit)) {
  131. bits = s | last_bit;
  132. if (bits != 15)
  133. compute_vector(bits, v);
  134. return true;
  135. }
  136. }
  137. }
  138. if (valid(last_bit)) {
  139. bits = last_bit;
  140. v = y[last];
  141. return true;
  142. }
  143. return false;
  144. }
  145. //----------------------------------------------------------------------------
  146. inline bool GjkCollisionState::degenerate(const VectorF& w)
  147. {
  148. for (S32 i = 0, bit = 1; i < 4; ++i, bit <<= 1)
  149. if ((all_bits & bit) && y[i] == w)
  150. return true;
  151. return false;
  152. }
  153. //----------------------------------------------------------------------------
  154. inline void GjkCollisionState::nextBit()
  155. {
  156. last = 0;
  157. last_bit = 1;
  158. while (bits & last_bit) {
  159. ++last;
  160. last_bit <<= 1;
  161. }
  162. }
  163. //----------------------------------------------------------------------------
  164. //----------------------------------------------------------------------------
  165. //----------------------------------------------------------------------------
  166. void GjkCollisionState::set(Convex* aa, Convex* bb,
  167. const MatrixF& a2w, const MatrixF& b2w)
  168. {
  169. a = aa;
  170. b = bb;
  171. bits = 0;
  172. all_bits = 0;
  173. reset(a2w,b2w);
  174. // link
  175. mLista = CollisionStateList::alloc();
  176. mLista->mState = this;
  177. mListb = CollisionStateList::alloc();
  178. mListb->mState = this;
  179. }
  180. //----------------------------------------------------------------------------
  181. void GjkCollisionState::reset(const MatrixF& a2w, const MatrixF& b2w)
  182. {
  183. VectorF zero(0,0,0),sa,sb;
  184. a2w.mulP(a->support(zero),&sa);
  185. b2w.mulP(b->support(zero),&sb);
  186. v = sa - sb;
  187. dist = v.len();
  188. }
  189. //----------------------------------------------------------------------------
  190. void GjkCollisionState::getCollisionInfo(const MatrixF& mat, Collision* info)
  191. {
  192. AssertFatal(false, "GjkCollisionState::getCollisionInfo() - There remain scaling problems here.");
  193. // This assumes that the shapes do not intersect
  194. Point3F pa,pb;
  195. if (bits) {
  196. getClosestPoints(pa,pb);
  197. mat.mulP(pa,&info->point);
  198. b->getTransform().mulP(pb,&pa);
  199. info->normal = info->point - pa;
  200. }
  201. else {
  202. mat.mulP(p[last],&info->point);
  203. info->normal = v;
  204. }
  205. info->normal.normalize();
  206. info->object = b->getObject();
  207. }
  208. void GjkCollisionState::getClosestPoints(Point3F& p1, Point3F& p2)
  209. {
  210. F32 sum = 0;
  211. p1.set(0, 0, 0);
  212. p2.set(0, 0, 0);
  213. for (S32 i = 0, bit = 1; i < 4; ++i, bit <<= 1) {
  214. if (bits & bit) {
  215. sum += det[bits][i];
  216. p1 += p[i] * det[bits][i];
  217. p2 += q[i] * det[bits][i];
  218. }
  219. }
  220. F32 s = 1 / sum;
  221. p1 *= s;
  222. p2 *= s;
  223. }
  224. //----------------------------------------------------------------------------
  225. bool GjkCollisionState::intersect(const MatrixF& a2w, const MatrixF& b2w)
  226. {
  227. num_iterations = 0;
  228. MatrixF w2a,w2b;
  229. w2a = a2w;
  230. w2b = b2w;
  231. w2a.inverse();
  232. w2b.inverse();
  233. reset(a2w,b2w);
  234. bits = 0;
  235. all_bits = 0;
  236. do {
  237. nextBit();
  238. VectorF va,sa;
  239. w2a.mulV(-v,&va);
  240. p[last] = a->support(va);
  241. a2w.mulP(p[last],&sa);
  242. VectorF vb,sb;
  243. w2b.mulV(v,&vb);
  244. q[last] = b->support(vb);
  245. b2w.mulP(q[last],&sb);
  246. VectorF w = sa - sb;
  247. if (mDot(v,w) > 0)
  248. return false;
  249. if (degenerate(w)) {
  250. ++num_irregularities;
  251. return false;
  252. }
  253. y[last] = w;
  254. all_bits = bits | last_bit;
  255. ++num_iterations;
  256. if (!closest(v) || num_iterations > sIteration) {
  257. ++num_irregularities;
  258. return false;
  259. }
  260. }
  261. while (bits < 15 && v.lenSquared() > sEpsilon2);
  262. return true;
  263. }
  264. F32 GjkCollisionState::distance(const MatrixF& a2w, const MatrixF& b2w,
  265. const F32 dontCareDist, const MatrixF* _w2a, const MatrixF* _w2b)
  266. {
  267. num_iterations = 0;
  268. MatrixF w2a,w2b;
  269. if (_w2a == NULL || _w2b == NULL) {
  270. w2a = a2w;
  271. w2b = b2w;
  272. w2a.inverse();
  273. w2b.inverse();
  274. }
  275. else {
  276. w2a = *_w2a;
  277. w2b = *_w2b;
  278. }
  279. reset(a2w,b2w);
  280. bits = 0;
  281. all_bits = 0;
  282. F32 mu = 0;
  283. do {
  284. nextBit();
  285. VectorF va,sa;
  286. w2a.mulV(-v,&va);
  287. p[last] = a->support(va);
  288. a2w.mulP(p[last],&sa);
  289. VectorF vb,sb;
  290. w2b.mulV(v,&vb);
  291. q[last] = b->support(vb);
  292. b2w.mulP(q[last],&sb);
  293. VectorF w = sa - sb;
  294. F32 nm = mDot(v, w) / dist;
  295. if (nm > mu)
  296. mu = nm;
  297. if (mu > dontCareDist)
  298. return mu;
  299. if (mFabs(dist - mu) <= dist * rel_error)
  300. return dist;
  301. ++num_iterations;
  302. if (degenerate(w) || num_iterations > sIteration) {
  303. ++num_irregularities;
  304. return dist;
  305. }
  306. y[last] = w;
  307. all_bits = bits | last_bit;
  308. if (!closest(v)) {
  309. ++num_irregularities;
  310. return dist;
  311. }
  312. dist = v.len();
  313. }
  314. while (bits < 15 && dist > sTolerance) ;
  315. if (bits == 15 && mu <= 0)
  316. dist = 0;
  317. return dist;
  318. }