MeshTools.cpp 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. // Include own header
  2. #include "MeshTools.hpp"
  3. // Include modules
  4. #include "MainWindow.hpp"
  5. // Include dependencies
  6. #include <math.h>
  7. #include <osg/ComputeBoundsVisitor>
  8. void MeshTools::calculateNormals(const std::vector<Lib3MF::sPosition> verticesBuffer, const std::vector<Lib3MF::sTriangle> triangleBuffer, osg::ref_ptr<osg::Vec3Array> vertices, osg::ref_ptr<osg::Vec3Array> normals) {
  9. for (const Lib3MF::sTriangle triangle: triangleBuffer) {
  10. // Create osg vectors
  11. osg::Vec3 vertex[3] = {};
  12. for (char i = 0; i < 3; i++) {
  13. vertex[i] = osg::Vec3(verticesBuffer[triangle.m_Indices[i]].m_Coordinates[0], verticesBuffer[triangle.m_Indices[i]].m_Coordinates[1], verticesBuffer[triangle.m_Indices[i]].m_Coordinates[2]);
  14. }
  15. // Calculate normal
  16. osg::Vec3 edgeOne = vertex[1].operator-(vertex[0]);
  17. osg::Vec3 edgeTwo = vertex[2].operator-(vertex[0]);
  18. osg::Vec3 normal = edgeOne.operator^(edgeTwo);
  19. normal.normalize();
  20. // Store them
  21. for (int i = 0; i < 3; i++) {
  22. vertices->push_back(vertex[i]);
  23. normals->push_back(normal);
  24. }
  25. }
  26. }
  27. float MeshTools::angleBetween(osg::Vec3 a, osg::Vec3 b) {
  28. float normA = a.length();
  29. float normB = b.length();
  30. float dotProduct = a.operator*(b);
  31. return acos(dotProduct / (normA * normB));
  32. }
  33. float MeshTools::compensationLength(osg::Vec3 a, osg::Vec3 b, float length) {
  34. osg::Matrix modifierRotation = osg::Matrix::rotate(b.x() * M_PI / 180, osg::Vec3(1.0f, 0.0f, 0.0f), b.y() * M_PI / 180, osg::Vec3(0.0f, 1.0f, 0.0f), b.z() * M_PI / 180, osg::Vec3(0.0f, 0.0f, 1.0f));
  35. osg::Vec3 newNormal = modifierRotation.preMult(a);
  36. newNormal.normalize();
  37. float angle = MeshTools::angleBetween(a, newNormal);
  38. return isnan(tan(angle) * length) ? 0.0f : tan(angle) * length;
  39. }
  40. bool MeshTools::optiTrackSanityCheck(const std::vector<OptiTrackPoint*> points, const bool showSuccessMessage) {
  41. if (!MainWindow::getInstance()->getEditWiget()->getOptiTrackSanityCheckStatus()) {
  42. return false;
  43. }
  44. // Check for three on a line
  45. bool foundLineProblem = false;
  46. if (points.size() >= 3) {
  47. for (int i = 0; i < (points.size() - 1); i++) {
  48. for (int j = i + 1; j < points.size(); j++) {
  49. for (int k = 0; k < points.size(); k++) {
  50. if (k != i && k != j) {
  51. osg::Vec3 a = points[i]->getTrackPoint();
  52. osg::Vec3 b = points[j]->getTrackPoint().operator-(a);
  53. osg::Vec3 point = points[k]->getTrackPoint();
  54. osg::Vec3 pMinusA = point.operator-(a);
  55. osg::Vec3 crossProduct = pMinusA.operator^(b);
  56. float distance = crossProduct.length() / b.length();
  57. if (distance < OPTITRACK_SANITY_DISTANCE_THRESHOLD) {
  58. foundLineProblem = true;
  59. }
  60. }
  61. }
  62. }
  63. }
  64. }
  65. // Check for four on a plane
  66. bool foundPlaneProblem = false;
  67. if (points.size() >= 4) {
  68. for (int i = 0; i < (points.size() - 2); i++) {
  69. for (int j = i + 1; j < (points.size() - 1); j++) {
  70. for (int k = j + 1; k < points.size(); k++) {
  71. for (int l = 0; l < points.size(); l++) {
  72. if (l != i && l != j && l != k) {
  73. osg::Vec3 a = points[i]->getTrackPoint();
  74. osg::Vec3 b = points[j]->getTrackPoint();
  75. osg::Vec3 c = points[k]->getTrackPoint();
  76. osg::Vec3 point = points[l]->getTrackPoint();
  77. osg::Plane* plane = new osg::Plane(a, b, c);
  78. float distance = std::abs(plane->distance(point));
  79. delete plane;
  80. if (distance < OPTITRACK_SANITY_DISTANCE_THRESHOLD) {
  81. foundPlaneProblem = true;
  82. }
  83. }
  84. }
  85. }
  86. }
  87. }
  88. }
  89. if (foundLineProblem) {
  90. MainWindow::getInstance()->showOptiTrackSanityLineError();
  91. }
  92. if (foundPlaneProblem) {
  93. MainWindow::getInstance()->showOptiTrackSanityPlaneError();
  94. }
  95. if (!foundLineProblem && !foundPlaneProblem && showSuccessMessage) {
  96. MainWindow::getInstance()->showOptiTrackSanitySuccess();
  97. }
  98. return foundLineProblem || foundPlaneProblem;
  99. }
  100. bool MeshTools::steamVrTrackCollisionCheck(std::vector<SteamVRTrackPoint*> points, const bool showSuccessMessage, osg::ref_ptr<osg::Group> verifyGroup) {
  101. if (!MainWindow::getInstance()->getEditWiget()->getSteamVRTrackCollisionCheckStatus()) {
  102. return false;
  103. }
  104. MainWindow::getInstance()->getOsgWidget()->loadSteamvrCollision();
  105. bool foundProblem = false;
  106. for (SteamVRTrackPoint* point: points) {
  107. osg::ref_ptr<osg::MatrixTransform> move = new osg::MatrixTransform;
  108. osg::Vec3f movementVector = osg::Vec3f(0.0f, 0.0f, 1.0f).operator*(point->getLength());
  109. move->setMatrix(osg::Matrix::translate(movementVector));
  110. osg::ref_ptr<osg::MatrixTransform> rotate = new osg::MatrixTransform;
  111. rotate->addChild(move.get());
  112. osg::Vec3f normalModifier = point->getNormalModifier();
  113. osg::Vec3f normal = point->getNormal();
  114. float normalRotation = point->getNormalRotation();
  115. osg::Matrix modifierRotation = osg::Matrix::rotate(normalModifier.x() * M_PI / 180, osg::Vec3(1.0f, 0.0f, 0.0f), normalModifier.y() * M_PI / 180, osg::Vec3(0.0f, 1.0f, 0.0f), normalModifier.z() * M_PI / 180, osg::Vec3(0.0f, 0.0f, 1.0f));
  116. normal = modifierRotation.preMult(normal);
  117. normal.normalize();
  118. osg::Matrix matrix = osg::Matrix::rotate(osg::Vec3f(0.0f, 0.0f, 1.0f), normal);
  119. matrix = matrix.operator*(osg::Matrix::rotate(normalRotation * M_PI / 180, normal));
  120. rotate->setMatrix(matrix);
  121. osg::ref_ptr<osg::MatrixTransform> translate = new osg::MatrixTransform;
  122. translate->addChild(rotate.get());
  123. translate->setMatrix(osg::Matrix::translate(point->getTranslation()));
  124. verifyGroup->addChild(translate.get());
  125. osg::ref_ptr<osg::Geode> tracker = new osg::Geode;
  126. tracker->addDrawable(MainWindow::getInstance()->getOsgWidget()->_steamvrTrackerMesh.get());
  127. move->addChild(tracker.get());
  128. osg::ComputeBoundsVisitor computeBoundsVisitor;
  129. verifyGroup->accept(computeBoundsVisitor);
  130. osg::BoundingBox trackerBox = computeBoundsVisitor.getBoundingBox();
  131. if (trackerBox.intersects(MainWindow::getInstance()->getOsgWidget()->getMesh()->getBoundingBox())) {
  132. foundProblem = true;
  133. }
  134. verifyGroup->removeChild(translate.get());
  135. }
  136. if (foundProblem) {
  137. MainWindow::getInstance()->showSteamVRTrackCollisionCheckError();
  138. }
  139. if (!foundProblem && showSuccessMessage) {
  140. MainWindow::getInstance()->showSteamVRTrackCollisionCheckSuccess();
  141. }
  142. return foundProblem;
  143. }