PageRenderTime 47ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 1ms

/VirtualRobot/CollisionDetection/CollisionChecker.cpp

https://gitlab.com/terlemez/simox
C++ | 763 lines | 423 code | 112 blank | 228 comment | 100 complexity | c514591f6a0d98dc13a95d1d328880d9 MD5 | raw file
  1. #include "CollisionChecker.h"
  2. #include "CollisionModel.h"
  3. #include "../SceneObjectSet.h"
  4. #include "../SceneObject.h"
  5. #include "../Robot.h"
  6. #include "../VirtualRobotException.h"
  7. #include <cfloat>
  8. #include <Eigen/Core>
  9. #include <Eigen/Geometry>
  10. #if defined(VR_COLLISION_DETECTION_PQP)
  11. #define COL_CHECKER_IMPL CollisionCheckerPQP
  12. #else
  13. #define COL_CHECKER_IMPL CollisionCheckerDummy
  14. #endif
  15. namespace VirtualRobot
  16. {
  17. namespace
  18. {
  19. boost::mutex mutex;
  20. };
  21. CollisionCheckerPtr CollisionChecker::globalCollisionChecker;
  22. CollisionChecker::Cleanup::~Cleanup()
  23. {
  24. boost::lock_guard<boost::mutex> lock(mutex);
  25. CollisionChecker::globalCollisionChecker.reset();
  26. }
  27. CollisionCheckerPtr CollisionChecker::getGlobalCollisionChecker()
  28. {
  29. static Cleanup _Cleanup;
  30. if (true)
  31. {
  32. boost::lock_guard<boost::mutex> lock(mutex);
  33. if (!globalCollisionChecker)
  34. {
  35. globalCollisionChecker.reset(new CollisionChecker());
  36. }
  37. }
  38. return globalCollisionChecker;
  39. }
  40. //----------------------------------------------------------------------
  41. // class CollisionChecker constructor
  42. //----------------------------------------------------------------------
  43. CollisionChecker::CollisionChecker()
  44. {
  45. initialized = true;
  46. debugOutput = false; // ENABLES OUTPUT OF COLLISION MODEL TRIANGLES
  47. automaticSizeCheck = true;
  48. collisionCheckerImplementation.reset(new COL_CHECKER_IMPL());
  49. }
  50. //----------------------------------------------------------------------
  51. // class CollisionChecker destructor
  52. //----------------------------------------------------------------------
  53. CollisionChecker::~CollisionChecker()
  54. {
  55. }
  56. float CollisionChecker::calculateDistance(SceneObjectSetPtr model1, SceneObjectSetPtr model2)
  57. {
  58. VR_ASSERT(model1 && model2);
  59. return calculateDistance(model1, model2, tmpV1, tmpV2, NULL, NULL);
  60. }
  61. float CollisionChecker::calculateDistance(CollisionModelPtr model1, SceneObjectSetPtr model2)
  62. {
  63. VR_ASSERT(model1 && model2);
  64. return calculateDistance(model1, model2, tmpV1, tmpV2, NULL, NULL);
  65. }
  66. float CollisionChecker::calculateDistance(CollisionModelPtr model1, CollisionModelPtr model2)
  67. {
  68. VR_ASSERT(model1 && model2);
  69. return calculateDistance(model1, model2, tmpV1, tmpV2, NULL, NULL);
  70. }
  71. float CollisionChecker::calculateDistance(SceneObjectPtr model1, SceneObjectSetPtr model2)
  72. {
  73. VR_ASSERT(model1 && model2);
  74. RobotPtr r = boost::dynamic_pointer_cast<Robot>(model1);
  75. if (r)
  76. {
  77. SceneObjectSetPtr robotModels = getRobotModels(r);
  78. return calculateDistance(robotModels, model2);
  79. }
  80. else
  81. {
  82. return calculateDistance(model1->getCollisionModel(), model2, tmpV1, tmpV2, NULL, NULL);
  83. }
  84. }
  85. float CollisionChecker::calculateDistance(SceneObjectPtr model1, SceneObjectPtr model2)
  86. {
  87. VR_ASSERT(model1 && model2);
  88. RobotPtr r = boost::dynamic_pointer_cast<Robot>(model1);
  89. RobotPtr r2 = boost::dynamic_pointer_cast<Robot>(model2);
  90. if (r && r2)
  91. {
  92. SceneObjectSetPtr robotModels = getRobotModels(r);
  93. SceneObjectSetPtr robotModels2 = getRobotModels(r2);
  94. return calculateDistance(robotModels, robotModels2);
  95. }
  96. else if (r && !r2)
  97. {
  98. SceneObjectSetPtr robotModels = getRobotModels(r);
  99. return calculateDistance(model2, robotModels);
  100. }
  101. else if (!r && r2)
  102. {
  103. SceneObjectSetPtr robotModels2 = getRobotModels(r2);
  104. return calculateDistance(model1, robotModels2);
  105. }
  106. else
  107. {
  108. return calculateDistance(model1->getCollisionModel(), model2->getCollisionModel(), tmpV1, tmpV2, NULL, NULL);
  109. }
  110. }
  111. float CollisionChecker::calculateDistance(SceneObjectPtr model1, SceneObjectSetPtr model2, Eigen::Vector3f& P1, Eigen::Vector3f& P2, int* trID1, int* trID2)
  112. {
  113. VR_ASSERT(model1 && model2);
  114. RobotPtr r = boost::dynamic_pointer_cast<Robot>(model1);
  115. if (r)
  116. {
  117. SceneObjectSetPtr robotModels = getRobotModels(r);
  118. return calculateDistance(robotModels, model2, P1, P2, trID1, trID2);
  119. }
  120. else
  121. {
  122. return calculateDistance(model1->getCollisionModel(), model2, P1, P2, trID1, trID2);
  123. }
  124. }
  125. float CollisionChecker::calculateDistance(SceneObjectPtr model1, SceneObjectPtr model2, Eigen::Vector3f& P1, Eigen::Vector3f& P2, int* trID1, int* trID2)
  126. {
  127. VR_ASSERT(model1 && model2);
  128. RobotPtr r = boost::dynamic_pointer_cast<Robot>(model1);
  129. RobotPtr r2 = boost::dynamic_pointer_cast<Robot>(model2);
  130. if (r && r2)
  131. {
  132. SceneObjectSetPtr robotModels = getRobotModels(r);
  133. SceneObjectSetPtr robotModels2 = getRobotModels(r2);
  134. return calculateDistance(robotModels, robotModels2, P1, P2, trID1, trID2);
  135. }
  136. else if (r && !r2)
  137. {
  138. SceneObjectSetPtr robotModels = getRobotModels(r);
  139. return calculateDistance(model2, robotModels, P2, P1, trID2, trID1);
  140. }
  141. else if (!r && r2)
  142. {
  143. SceneObjectSetPtr robotModels2 = getRobotModels(r2);
  144. return calculateDistance(model1, robotModels2, P1, P2, trID1, trID2);
  145. }
  146. else
  147. {
  148. return calculateDistance(model1->getCollisionModel(), model2->getCollisionModel(), P1, P2, trID1, trID2);
  149. }
  150. }
  151. float CollisionChecker::calculateDistance(SceneObjectSetPtr model1, SceneObjectSetPtr model2, Eigen::Vector3f& P1, Eigen::Vector3f& P2, int* trID1, int* trID2)
  152. {
  153. VR_ASSERT(model1 && model2);
  154. VR_ASSERT_MESSAGE(model1->getCollisionChecker() == model2->getCollisionChecker(), "Collision models are linked to different Collision Checker instances");
  155. VR_ASSERT_MESSAGE(model1->getCollisionChecker() == shared_from_this(), "Collision models are linked to different Collision Checker instances");
  156. VR_ASSERT(isInitialized());
  157. std::vector< CollisionModelPtr > colModels1 = model1->getCollisionModels();
  158. std::vector< CollisionModelPtr > colModels2 = model2->getCollisionModels();
  159. if (colModels1.size() == 0 || colModels2.size() == 0)
  160. {
  161. VR_WARNING << "no internal data..." << endl;
  162. return -1.0f;
  163. }
  164. float fResult = FLT_MAX;
  165. Eigen::Vector3f v1;
  166. Eigen::Vector3f v2;
  167. int trID1_r;
  168. int trID2_r;
  169. std::vector< CollisionModelPtr >::iterator it1 = colModels1.begin();
  170. while (it1 != colModels1.end())
  171. {
  172. std::vector< CollisionModelPtr >::iterator it2 = colModels2.begin();
  173. while (it2 != colModels2.end())
  174. {
  175. float fRes = calculateDistance(*it1, *it2, v1, v2, &trID1_r, &trID2_r);
  176. if (fRes <= fResult)
  177. {
  178. fResult = fRes;
  179. P1 = v1;
  180. P2 = v2;
  181. if (trID1)
  182. {
  183. *trID1 = trID1_r;
  184. }
  185. if (trID2)
  186. {
  187. *trID2 = trID2_r;
  188. }
  189. }
  190. it2++;
  191. }
  192. it1++;
  193. }
  194. return fResult;
  195. }
  196. float CollisionChecker::calculateDistance(CollisionModelPtr model1, SceneObjectSetPtr model2, Eigen::Vector3f& P1, Eigen::Vector3f& P2, int* trID1, int* trID2)
  197. {
  198. VR_ASSERT(model1 && model2);
  199. VR_ASSERT_MESSAGE(model1->getCollisionChecker() == model2->getCollisionChecker(), "Collision models are linked to different Collision Checker instances");
  200. VR_ASSERT_MESSAGE(model1->getCollisionChecker() == shared_from_this(), "Collision models are linked to different Collision Checker instances");
  201. VR_ASSERT(isInitialized());
  202. std::vector< CollisionModelPtr > colModels = model2->getCollisionModels();
  203. if (colModels.size() == 0)
  204. {
  205. VR_WARNING << "no internal data..." << endl;
  206. return -1.0f;
  207. }
  208. float fResult = FLT_MAX;
  209. Eigen::Vector3f v1;
  210. Eigen::Vector3f v2;
  211. int trID1_r;
  212. int trID2_r;
  213. std::vector< CollisionModelPtr >::iterator it = colModels.begin();
  214. while (it != colModels.end())
  215. {
  216. float fRes = calculateDistance(model1, *it, v1, v2, &trID1_r, &trID2_r);
  217. if (fRes <= fResult)
  218. {
  219. fResult = fRes;
  220. P1 = v1;
  221. P2 = v2;
  222. if (trID1)
  223. {
  224. *trID1 = trID1_r;
  225. }
  226. if (trID2)
  227. {
  228. *trID2 = trID2_r;
  229. }
  230. }
  231. it++;
  232. }
  233. return fResult;
  234. }
  235. float CollisionChecker::calculateDistance(CollisionModelPtr model1, CollisionModelPtr model2, Eigen::Vector3f& P1, Eigen::Vector3f& P2, int* trID1, int* trID2)
  236. {
  237. VR_ASSERT(model1 && model2);
  238. VR_ASSERT_MESSAGE(model1->getCollisionChecker() == model2->getCollisionChecker(), "Collision models are linked to different Collision Checker instances");
  239. VR_ASSERT_MESSAGE(model1->getCollisionChecker() == shared_from_this(), "Collision models are linked to different Collision Checker instances");
  240. VR_ASSERT(isInitialized());
  241. return collisionCheckerImplementation->calculateDistance(model1, model2, P1, P2, trID1, trID2);
  242. }
  243. bool CollisionChecker::checkCollision(std::vector<CollisionModelPtr>& model1, CollisionModelPtr model2)
  244. {
  245. VR_ASSERT(model2);
  246. VR_ASSERT(isInitialized());
  247. if (model1.size() == 0)
  248. {
  249. VR_WARNING << "no internal data..." << endl;
  250. return false;
  251. }
  252. std::vector< CollisionModelPtr >::iterator it1 = model1.begin();
  253. while (it1 != model1.end())
  254. {
  255. if (checkCollision(*it1, model2))
  256. {
  257. return true;
  258. }
  259. it1++;
  260. }
  261. return false;
  262. }
  263. bool CollisionChecker::checkCollision(SceneObjectSetPtr model1, SceneObjectSetPtr model2)
  264. {
  265. VR_ASSERT(model1 && model2);
  266. VR_ASSERT_MESSAGE(model1->getCollisionChecker() == model2->getCollisionChecker(), "Collision models are linked to different Collision Checker instances");
  267. VR_ASSERT_MESSAGE(model1->getCollisionChecker() == shared_from_this(), "Collision models are linked to different Collision Checker instances");
  268. VR_ASSERT(isInitialized());
  269. std::vector< CollisionModelPtr > vColModels1 = model1->getCollisionModels();
  270. std::vector< CollisionModelPtr > vColModels2 = model2->getCollisionModels();
  271. if (vColModels1.size() == 0 || vColModels2.size() == 0)
  272. {
  273. VR_WARNING << "no internal data..." << endl;
  274. return false;
  275. }
  276. std::vector< CollisionModelPtr >::iterator it1 = vColModels1.begin();
  277. while (it1 != vColModels1.end())
  278. {
  279. std::vector< CollisionModelPtr >::iterator it2 = vColModels2.begin();
  280. while (it2 != vColModels2.end())
  281. {
  282. if (checkCollision(*it1, *it2))
  283. {
  284. return true;
  285. }
  286. it2++;
  287. }
  288. it1++;
  289. }
  290. return false;
  291. }
  292. bool CollisionChecker::checkCollision(SceneObjectPtr model1, SceneObjectSetPtr model2)
  293. {
  294. VR_ASSERT(model1 && model2);
  295. RobotPtr r = boost::dynamic_pointer_cast<Robot>(model1);
  296. if (r)
  297. {
  298. SceneObjectSetPtr robotModels = getRobotModels(r);
  299. return checkCollision(robotModels, model2);
  300. }
  301. else
  302. {
  303. return checkCollision(model1->getCollisionModel(), model2);
  304. }
  305. }
  306. SceneObjectSetPtr CollisionChecker::getRobotModels(RobotPtr r)
  307. {
  308. SceneObjectSetPtr result(new SceneObjectSet(r->getName(), shared_from_this()));
  309. std::vector<RobotNodePtr> cm = r->getRobotNodes();
  310. for (size_t i = 0; i < cm.size(); i++)
  311. {
  312. if (cm[i]->getCollisionModel())
  313. {
  314. result->addSceneObject(cm[i]);
  315. }
  316. }
  317. return result;
  318. }
  319. bool CollisionChecker::checkCollision(CollisionModelPtr model1, SceneObjectSetPtr model2)
  320. {
  321. VR_ASSERT(model1 && model2);
  322. VR_ASSERT_MESSAGE(model1->getCollisionChecker() == model2->getCollisionChecker(), "Collision models are linked to different Collision Checker instances");
  323. VR_ASSERT_MESSAGE(model1->getCollisionChecker() == shared_from_this(), "Collision models are linked to different Collision Checker instances");
  324. VR_ASSERT(isInitialized());
  325. std::vector< CollisionModelPtr > vColModels = model2->getCollisionModels();
  326. if (vColModels.size() == 0)
  327. {
  328. VR_WARNING << "no internal data..." << endl;
  329. return false;
  330. }
  331. std::vector< CollisionModelPtr >::iterator it = vColModels.begin();
  332. while (it != vColModels.end())
  333. {
  334. if (checkCollision(model1, *it))
  335. {
  336. return true;
  337. }
  338. it++;
  339. }
  340. return false;
  341. }
  342. bool CollisionChecker::checkCollision(SceneObjectPtr model1, SceneObjectPtr model2)
  343. {
  344. VR_ASSERT(model1 && model2);
  345. RobotPtr r = boost::dynamic_pointer_cast<Robot>(model1);
  346. RobotPtr r2 = boost::dynamic_pointer_cast<Robot>(model2);
  347. if (r && r2)
  348. {
  349. SceneObjectSetPtr robotModels = getRobotModels(r);
  350. SceneObjectSetPtr robotModels2 = getRobotModels(r2);
  351. return checkCollision(robotModels, robotModels2);
  352. }
  353. else if (r && !r2)
  354. {
  355. SceneObjectSetPtr robotModels = getRobotModels(r);
  356. return checkCollision(model2, robotModels);
  357. }
  358. else if (!r && r2)
  359. {
  360. SceneObjectSetPtr robotModels2 = getRobotModels(r2);
  361. return checkCollision(model1, robotModels2);
  362. }
  363. else
  364. {
  365. return checkCollision(model1->getCollisionModel(), model2->getCollisionModel());
  366. }
  367. }
  368. bool CollisionChecker::checkCollision(CollisionModelPtr model1, CollisionModelPtr model2)
  369. {
  370. VR_ASSERT(model1 && model2);
  371. VR_ASSERT_MESSAGE(model1->getCollisionChecker() == model2->getCollisionChecker(), "Collision models are linked to different Collision Checker instances");
  372. VR_ASSERT_MESSAGE(model1->getCollisionChecker() == shared_from_this(), "Collision models are linked to different Collision Checker instances");
  373. VR_ASSERT(isInitialized());
  374. return collisionCheckerImplementation->checkCollision(model1, model2);//, storeContact);
  375. }
  376. /*
  377. bool CollisionChecker::getAllCollisonTriangles (SceneObjectSetPtr model1, SceneObjectSetPtr model2, std::vector<int> &storePairs)
  378. {
  379. if (!model1 || !model2)
  380. {
  381. printf ("CollisionChecker:GetAllCollisongTriangles - NULL data...\n");
  382. return false;
  383. }
  384. if (model1->getCollisionChecker() != model2->getCollisionChecker() || model1->getCollisionChecker()!=shared_from_this())
  385. {
  386. VR_WARNING << "Could not go on, collision models are linked to different Collision Checker instances." << endl;
  387. return false;
  388. }
  389. if (!isInitialized())
  390. {
  391. VR_WARNING << "not initialized." << endl;
  392. return false;
  393. }
  394. return collisionCheckerImplementation->getAllCollisonTriangles(model1,model2,storePairs);
  395. }*/
  396. void CollisionChecker::setAutomaticSizeCheck(bool checkSizeOnColModelCreation)
  397. {
  398. automaticSizeCheck = checkSizeOnColModelCreation;
  399. collisionCheckerImplementation->setAutomaticSizeCheck(automaticSizeCheck);
  400. }
  401. /*
  402. bool CollisionChecker::checkCollision( SbXfBox3f& box1, SbXfBox3f& box2 )
  403. {
  404. ////return box1.intersect(box2);
  405. //box1.setBounds(-100, -100, -100, 100, 100, 100);
  406. //box2.setBounds(-100, -100, -100, 100, 100, 100);
  407. //SbMatrix tr;
  408. //tr.setTranslate(SbVec3f(0,0,0));
  409. //box1.setTransform(tr);
  410. //tr.setTranslate(SbVec3f(0, 0, 250));
  411. //box2.setTransform(tr);
  412. // OBB Intersection test from Neoengine
  413. const float fParallellCutoff = 0.99999f;
  414. bool bParallellAxes = false;
  415. SbRotation kRotA;
  416. SbRotation kRotB;
  417. SbVec3f kTransA;
  418. SbVec3f kTransB;
  419. SbMatrix kRotMatA;
  420. SbMatrix kRotMatB;
  421. SbVec3f tmpV;
  422. SbRotation tmpR;
  423. box1.getTransform().getTransform(kTransA, kRotA, tmpV, tmpR);
  424. box2.getTransform().getTransform(kTransB, kRotB, tmpV, tmpR);
  425. kRotMatA.setRotate(kRotA);
  426. kRotMatB.setRotate(kRotB);
  427. SbVec3f akAxesA[3] = { SbVec3f(kRotMatA[0]), SbVec3f(kRotMatA[1]), SbVec3f(kRotMatA[2]) };
  428. SbVec3f akAxesB[3] = { SbVec3f(kRotMatB[0]), SbVec3f(kRotMatB[1]), SbVec3f(kRotMatB[2]) };
  429. float afDimA[3];
  430. float afDimB[3];
  431. float dx, dy, dz;
  432. box1.getSize(dx, dy, dz);
  433. afDimA[0] = dx/2;
  434. afDimA[1] = dy/2;
  435. afDimA[2] = dz/2;
  436. box2.getSize(dx, dy, dz);
  437. afDimB[0] = dx/2;
  438. afDimB[1] = dy/2;
  439. afDimB[2] = dz/2;
  440. //Difference of box positions
  441. SbVec3f kDiff = kTransB - kTransA;
  442. ////////Early out test
  443. //float radiusA2 = 0, radiusB2 = 0;
  444. //SbBox3f aabb1(box1);
  445. //SbBox3f aabb2(box2);
  446. //radiusA2 = (aabb1.getMax()-aabb1.getCenter()).length();
  447. //radiusB2 = (aabb2.getMax()-aabb2.getCenter()).length();
  448. //if( ( radiusA2 + radiusB2 ) < kDiff.length() )
  449. // return false;
  450. float afAxisDot[3][3]; // afAxisDot[i][j] = akAxesA[i]Ptr akAxesB[j];
  451. float afAbsAxisDot[3][3]; // afAbsAxisDot[i][j] = |afAxisDot[i][j]|
  452. float afAxesADotDiff[3]; // afAxesADotDiff[i] = akAxesA[i]Ptr kDiff
  453. //Test all 15 possible separating axes
  454. //Axis Ax
  455. //First calculate AxPtr Bi axis dot products (length of each B axis along Ax)
  456. afAxisDot[0][0] = akAxesA[0].dot(akAxesB[0]);
  457. afAxisDot[0][1] = akAxesA[0].dot(akAxesB[1]);
  458. afAxisDot[0][2] = akAxesA[0].dot(akAxesB[2]);
  459. //Get absolute value of dot products
  460. afAbsAxisDot[0][0] = fabsf( afAxisDot[0][0] ); if( afAbsAxisDot[0][0] > fParallellCutoff ) bParallellAxes = true;
  461. afAbsAxisDot[0][1] = fabsf( afAxisDot[0][1] ); if( afAbsAxisDot[0][1] > fParallellCutoff ) bParallellAxes = true;
  462. afAbsAxisDot[0][2] = fabsf( afAxisDot[0][2] ); if( afAbsAxisDot[0][2] > fParallellCutoff ) bParallellAxes = true;
  463. //calculate AxPtr D dot product (length of center difference along Ax axis)
  464. afAxesADotDiff[0] = akAxesA[0].dot(kDiff);
  465. // int iDeepAxis = 0;
  466. // SbVec3f kNormal;
  467. // float fOverlapMax = -numeric_limits< float >::max();
  468. float fOverlap;
  469. //Check if distance between centers along axis is greater than sum of boxes dimensions along axis
  470. if( ( fOverlap = fabsf( afAxesADotDiff[0] ) - ( ( afDimA[0] ) + ( afDimB[0]Ptr afAbsAxisDot[0][0] + afDimB[1]Ptr afAbsAxisDot[0][1] + afDimB[2]Ptr afAbsAxisDot[0][2] ) ) ) > 0.0f )
  471. return false;
  472. //Axis Ay
  473. afAxisDot[1][0] = akAxesA[1].dot(akAxesB[0]);
  474. afAxisDot[1][1] = akAxesA[1].dot(akAxesB[1]);
  475. afAxisDot[1][2] = akAxesA[1].dot(akAxesB[2]);
  476. afAbsAxisDot[1][0] = fabsf( afAxisDot[1][0] ); if( afAbsAxisDot[1][0] > fParallellCutoff ) bParallellAxes = true;
  477. afAbsAxisDot[1][1] = fabsf( afAxisDot[1][1] ); if( afAbsAxisDot[1][1] > fParallellCutoff ) bParallellAxes = true;
  478. afAbsAxisDot[1][2] = fabsf( afAxisDot[1][2] ); if( afAbsAxisDot[1][2] > fParallellCutoff ) bParallellAxes = true;
  479. afAxesADotDiff[1] = akAxesA[1].dot(kDiff);
  480. if( ( fOverlap = fabsf( afAxesADotDiff[1] ) - ( ( afDimA[1] ) + ( afDimB[0]Ptr afAbsAxisDot[1][0] + afDimB[1]Ptr afAbsAxisDot[1][1] + afDimB[2]Ptr afAbsAxisDot[1][2] ) ) ) > 0.0f )
  481. return false;
  482. //Axis Az
  483. afAxisDot[2][0] = akAxesA[2].dot(akAxesB[0]);
  484. afAxisDot[2][1] = akAxesA[2].dot(akAxesB[1]);
  485. afAxisDot[2][2] = akAxesA[2].dot(akAxesB[2]);
  486. afAbsAxisDot[2][0] = fabsf( afAxisDot[2][0] ); if( afAbsAxisDot[2][0] > fParallellCutoff ) bParallellAxes = true;
  487. afAbsAxisDot[2][1] = fabsf( afAxisDot[2][1] ); if( afAbsAxisDot[2][1] > fParallellCutoff ) bParallellAxes = true;
  488. afAbsAxisDot[2][2] = fabsf( afAxisDot[2][2] ); if( afAbsAxisDot[2][2] > fParallellCutoff ) bParallellAxes = true;
  489. afAxesADotDiff[2] = akAxesA[2].dot(kDiff);
  490. if( ( fOverlap = fabsf( afAxesADotDiff[2] ) - ( ( afDimA[2] ) + ( afDimB[0]Ptr afAbsAxisDot[2][0] + afDimB[1]Ptr afAbsAxisDot[2][1] + afDimB[2]Ptr afAbsAxisDot[2][2] ) ) ) > 0.0f )
  491. return false;
  492. float fProj;
  493. // float fScale;
  494. //Axis Bx
  495. //We already have all axis*axis dot products, only calculate center difference along Bx axis and compare
  496. if( ( fOverlap = fabsf( ( fProj = akAxesB[0].dot(kDiff) ) ) - ( ( afDimA[0]Ptr afAbsAxisDot[0][0] + afDimA[1]Ptr afAbsAxisDot[1][0] + afDimA[2]Ptr afAbsAxisDot[2][0] ) + ( afDimB[0] ) ) ) > 0.0f )
  497. return false;
  498. //Axis By
  499. if( ( fOverlap = fabsf( ( fProj = akAxesB[1].dot(kDiff) ) ) - ( ( afDimA[0]Ptr afAbsAxisDot[0][1] + afDimA[1]Ptr afAbsAxisDot[1][1] + afDimA[2]Ptr afAbsAxisDot[2][1] ) + ( afDimB[1] ) ) ) > 0.0f )
  500. return false;
  501. //Axis Bz
  502. if( ( fOverlap = fabsf( ( fProj = akAxesB[2].dot(kDiff) ) ) - ( ( afDimA[0]Ptr afAbsAxisDot[0][2] + afDimA[1]Ptr afAbsAxisDot[1][2] + afDimA[2]Ptr afAbsAxisDot[2][2] ) + ( afDimB[2] ) ) ) > 0.0f )
  503. return false;
  504. //if not contact set, do extra tests to avoid reporting false collisions in parallell axis threshold zone
  505. if( !bParallellAxes )
  506. {
  507. //Axis Ax X Bx
  508. if( ( fOverlap = fabsf( ( fProj = afAxisDot[1][0]Ptr afAxesADotDiff[2] - afAxisDot[2][0]Ptr afAxesADotDiff[1] ) ) -
  509. ( ( afDimA[1]Ptr afAbsAxisDot[2][0] + afDimA[2]Ptr afAbsAxisDot[1][0] ) + ( afDimB[1]Ptr afAbsAxisDot[0][2] + afDimB[2]Ptr afAbsAxisDot[0][1] ) ) ) > 0.0f )
  510. return false;
  511. //Axis Ax X By
  512. if( ( fOverlap = fabsf( ( fProj = afAxisDot[1][1]Ptr afAxesADotDiff[2] - afAxisDot[2][1]Ptr afAxesADotDiff[1] ) ) -
  513. ( ( afDimA[1]Ptr afAbsAxisDot[2][1] + afDimA[2]Ptr afAbsAxisDot[1][1] ) + ( afDimB[0]Ptr afAbsAxisDot[0][2] + afDimB[2]Ptr afAbsAxisDot[0][0] ) ) ) > 0.0f )
  514. return false;
  515. //Axis Ax X Bz
  516. if( ( fOverlap = fabsf( ( fProj = afAxisDot[1][2]Ptr afAxesADotDiff[2] - afAxisDot[2][2]Ptr afAxesADotDiff[1] ) ) -
  517. ( ( afDimA[1]Ptr afAbsAxisDot[2][2] + afDimA[2]Ptr afAbsAxisDot[1][2] ) + ( afDimB[0]Ptr afAbsAxisDot[0][1] + afDimB[1]Ptr afAbsAxisDot[0][0] ) ) ) > 0.0f )
  518. return false;
  519. //Axis Ay X Bx
  520. if( ( fOverlap = fabsf( ( fProj = afAxisDot[2][0]Ptr afAxesADotDiff[0] - afAxisDot[0][0]Ptr afAxesADotDiff[2] ) ) -
  521. ( ( afDimA[0]Ptr afAbsAxisDot[2][0] + afDimA[2]Ptr afAbsAxisDot[0][0] ) + ( afDimB[1]Ptr afAbsAxisDot[1][2] + afDimB[2]Ptr afAbsAxisDot[1][1] ) ) ) > 0.0f )
  522. return false;
  523. //Axis Ay X By
  524. if( ( fOverlap = fabsf( ( fProj = afAxisDot[2][1]Ptr afAxesADotDiff[0] - afAxisDot[0][1]Ptr afAxesADotDiff[2] ) ) -
  525. ( ( afDimA[0]Ptr afAbsAxisDot[2][1] + afDimA[2]Ptr afAbsAxisDot[0][1] ) + ( afDimB[0]Ptr afAbsAxisDot[1][2] + afDimB[2]Ptr afAbsAxisDot[1][0] ) ) ) > 0.0f )
  526. return false;
  527. //Axis Ay X Bz
  528. if( ( fOverlap = fabsf( ( fProj = afAxisDot[2][2]Ptr afAxesADotDiff[0] - afAxisDot[0][2]Ptr afAxesADotDiff[2] ) ) -
  529. ( ( afDimA[0]Ptr afAbsAxisDot[2][2] + afDimA[2]Ptr afAbsAxisDot[0][2] ) + ( afDimB[0]Ptr afAbsAxisDot[1][1] + afDimB[1]Ptr afAbsAxisDot[1][0] ) ) ) > 0.0f )
  530. return false;
  531. //Axis Az X Bx
  532. if( ( fOverlap = fabsf( ( fProj = afAxisDot[0][0]Ptr afAxesADotDiff[1] - afAxisDot[1][0]Ptr afAxesADotDiff[0] ) ) -
  533. ( ( afDimA[0]Ptr afAbsAxisDot[1][0] + afDimA[1]Ptr afAbsAxisDot[0][0] ) + ( afDimB[1]Ptr afAbsAxisDot[2][2] + afDimB[2]Ptr afAbsAxisDot[2][1] ) ) ) > 0.0f )
  534. return false;
  535. //Axis Az X By
  536. if( ( fOverlap = fabsf( ( fProj = afAxisDot[0][1]Ptr afAxesADotDiff[1] - afAxisDot[1][1]Ptr afAxesADotDiff[0] ) ) -
  537. ( ( afDimA[0]Ptr afAbsAxisDot[1][1] + afDimA[1]Ptr afAbsAxisDot[0][1] ) + ( afDimB[0]Ptr afAbsAxisDot[2][2] + afDimB[2]Ptr afAbsAxisDot[2][0] ) ) ) > 0.0f )
  538. return false;
  539. //Axis Az X Bz
  540. if( ( fOverlap = fabsf( ( fProj = afAxisDot[0][2]Ptr afAxesADotDiff[1] - afAxisDot[1][2]Ptr afAxesADotDiff[0] ) ) -
  541. ( ( afDimA[0]Ptr afAbsAxisDot[1][2] + afDimA[1]Ptr afAbsAxisDot[0][2] ) + ( afDimB[0]Ptr afAbsAxisDot[2][1] + afDimB[1]Ptr afAbsAxisDot[2][0] ) ) ) > 0.0f )
  542. return false;
  543. } // if( bParallellAxes )
  544. return true;
  545. }
  546. */
  547. bool CollisionChecker::IsSupported_CollisionDetection()
  548. {
  549. return COL_CHECKER_IMPL::IsSupported_CollisionDetection();
  550. }
  551. bool CollisionChecker::IsSupported_ContinuousCollisionDetection()
  552. {
  553. return COL_CHECKER_IMPL::IsSupported_ContinuousCollisionDetection();
  554. }
  555. bool CollisionChecker::IsSupported_DistanceCalculations()
  556. {
  557. return COL_CHECKER_IMPL::IsSupported_DistanceCalculations();
  558. }
  559. bool CollisionChecker::IsSupported_Multithreading_Threadsafe()
  560. {
  561. return COL_CHECKER_IMPL::IsSupported_Multithreading_Threadsafe();
  562. }
  563. bool CollisionChecker::IsSupported_Multithreading_MultipleColCheckers()
  564. {
  565. return COL_CHECKER_IMPL::IsSupported_Multithreading_MultipleColCheckers();
  566. }
  567. void CollisionChecker::getContacts(const MathTools::Plane& p, CollisionModelPtr colModel, std::vector< MathTools::ContactPoint >& storeContatcs, float maxDist /*= 1.0f*/)
  568. {
  569. THROW_VR_EXCEPTION_IF(!colModel, "NULl data");
  570. // first check if plane hits bounding box
  571. BoundingBox bbox = colModel->getBoundingBox(false);
  572. // enlarge bbox by maxDist
  573. bbox.min -= Eigen::Vector3f(maxDist, maxDist, maxDist);
  574. bbox.max += Eigen::Vector3f(maxDist, maxDist, maxDist);
  575. std::vector <Eigen::Vector3f> ptsBB = bbox.getPoints();
  576. for (size_t i = 0; i < ptsBB.size(); i++)
  577. {
  578. ptsBB[i] = MathTools::transformPosition(ptsBB[i], colModel->getGlobalPose());
  579. }
  580. BoundingBox bboxGlobal(ptsBB);
  581. if (!bboxGlobal.planeGoesThrough(p))
  582. {
  583. // plane is not going through bounding box
  584. return;
  585. }
  586. // bbox was hit, test all points...
  587. std::vector< Eigen::Vector3f > pts = colModel->getModelVeticesGlobal();
  588. for (std::vector< Eigen::Vector3f >::iterator i = pts.begin(); i != pts.end(); i++)
  589. {
  590. if (MathTools::getDistancePointPlane(*i, p) <= maxDist)
  591. {
  592. MathTools::ContactPoint contact;
  593. contact.n = p.n;
  594. contact.p = *i;
  595. storeContatcs.push_back(contact);
  596. }
  597. }
  598. }
  599. /*
  600. bool CollisionChecker::checkContinuousCollision( CollisionModelPtr model1, SbMatrix &mGoalPose1, CollisionModelPtr model2, SbMatrix &mGoalPose2, float &fStoreTOC )
  601. {
  602. return collisionCheckerImplementation->checkContinuousCollision(model1,mGoalPose1,model2,mGoalPose2, fStoreTOC);
  603. }
  604. */
  605. } // namespace VirtualRobot