Advertisement
Guest User

Untitled

a guest
Dec 11th, 2017
78
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.28 KB | None | 0 0
  1.  
  2. std::vector<glm::vec3> ColliderTester::getVertices(OBB obb)
  3. {
  4.     std::vector<glm::vec3> v;
  5.     v.resize(8);
  6.  
  7.     glm::vec3 C = obb.getPosition(); // OBB Center
  8.     glm::vec3 E = obb.getSize(); // OBB Extents
  9.     const float* o = glm::value_ptr(obb.getOrientation());
  10.     glm::vec3 A[] = { // OBB Axis
  11.         glm::vec3(o[0], o[1], o[2]),
  12.         glm::vec3(o[3], o[4], o[5]),
  13.         glm::vec3(o[6], o[7], o[8]),
  14.     };
  15.  
  16.  
  17.     v[0] = C + A[0] * E[0] + A[1] * E[1] + A[2] * E[2];
  18.     v[1] = C - A[0] * E[0] + A[1] * E[1] + A[2] * E[2];
  19.     v[2] = C + A[0] * E[0] - A[1] * E[1] + A[2] * E[2];
  20.     v[3] = C + A[0] * E[0] + A[1] * E[1] - A[2] * E[2];
  21.     v[4] = C - A[0] * E[0] - A[1] * E[1] - A[2] * E[2];
  22.     v[5] = C + A[0] * E[0] - A[1] * E[1] - A[2] * E[2];
  23.     v[6] = C - A[0] * E[0] + A[1] * E[1] - A[2] * E[2];
  24.     v[7] = C - A[0] * E[0] - A[1] * E[1] + A[2] * E[2];
  25.  
  26.     return v;
  27.  
  28. }
  29.  
  30. std::vector<Line> ColliderTester::getEdges( OBB  obb)
  31. {
  32.     std::vector<Line> result;
  33.     result.reserve(12);
  34.  
  35.     //gets vertices
  36.     auto v = getVertices(obb);
  37.     //TODO!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  38.    
  39.     ////array holding pairs of vertices
  40.     int index[][2] = { // Indices of edge-vertices
  41.         { 6,1 },{ 6,3 },{ 6,4 },{ 2,7 },{ 2,5 },{ 2,0 },
  42.         { 0,1 },{ 0,3 },{ 7,1 },{ 7,4 },{ 4,5 },{ 5,3 }
  43.     };
  44.    
  45.     //loop trough index array and construct edges
  46.     for (int j = 0; j < 12; ++j) {
  47.         result.push_back(Line(v[0], v[1]));
  48.     }
  49.  
  50.     return result;
  51.  
  52. }
  53.  
  54. std::vector<Plane> ColliderTester::getPlanes( OBB  obb)
  55. {
  56.     glm::vec3 c = obb.getPosition(); // OBB Center
  57.     glm::vec3 e = obb.getSize(); // OBB Extents
  58.     const float* o = glm::value_ptr(obb.getOrientation());
  59.     glm::vec3 a[] = { // OBB Axis
  60.         glm::vec3(o[0], o[1], o[2]),
  61.         glm::vec3(o[3], o[4], o[5]),
  62.         glm::vec3(o[6], o[7], o[8]),
  63.     };
  64.  
  65.     std::vector<Plane> result;
  66.     result.resize(6);
  67.  
  68.     //construct a plane for each face using a point  and the normal of the face
  69.     result[0] = Plane(a[0], glm::dot(a[0], (c + a[0] * e.x)));
  70.     result[1] = Plane(a[0] * -1.0f, -glm::dot(a[0], (c - a[0] * e.x)));
  71.     result[2] = Plane(a[1], glm::dot(a[1], (c + a[1] * e.y)));
  72.     result[3] = Plane(a[1] * -1.0f, -glm::dot(a[1], (c - a[1] * e.y)));
  73.     result[4] = Plane(a[2], glm::dot(a[2], (c + a[2] * e.z)));
  74.     result[5] = Plane(a[2] * -1.0f, -glm::dot(a[2], (c - a[2] * e.z)));
  75.  
  76.     return result;
  77.     //Macro CMP and rest of the intersection data methods needed for implementation of the Responce
  78.     //PS prayer to god everything works out ok
  79. }
  80.  
  81. bool ColliderTester::clipToPlane( Plane  plane, const Line & line, glm::vec3 * outPoint)
  82. {
  83.     //Find if it intersects with the plane
  84.     auto normal = glm::normalize(plane.getNormal());
  85.     glm::vec3 ab = line.end - line.start;
  86.     float nAB = glm::dot(normal, ab);
  87.    
  88.     if (islessequal(nAB, 0))
  89.     {
  90.         return  false;
  91.     }
  92.     //  Find where it intersects with the plane
  93.     float   nA = glm::dot(normal, line.start);         
  94.     float   t = (plane.getDistance() - nA) / nAB;
  95.  
  96.     //if intersects return the point of intersection and true
  97.     if (t >= 0.0f && t <= 1.0f) {
  98.         if (outPoint != 0) {
  99.             *outPoint = line.start + ab * t;
  100.         }
  101.         return true;
  102.     }
  103.     return  false;
  104.  
  105. }
  106.  
  107. std::vector<glm::vec3> ColliderTester::clipEdgesToOBB(const std::vector<Line>& edges, OBB obb)
  108. {
  109.     std::vector<glm::vec3>  result;
  110.     result.reserve(edges.size());
  111.     glm::vec3 intersection;
  112.     std::vector<Plane>& planes = ColliderTester::getPlanes(obb);
  113.  
  114.     for (int i = 0; i < planes.size(); ++i)
  115.     {
  116.         for (int j = 0; j < edges.size(); ++j)
  117.         {
  118.             if (ColliderTester::clipToPlane(planes[i], edges[j], &intersection))
  119.             {
  120.                 result.push_back(intersection);
  121.             }
  122.         }
  123.     }
  124.  
  125.     return result;
  126. }
  127.  
  128. float ColliderTester::penetrationDepth( OBB o1,  OBB  o2, const glm::vec3 & axis, bool * outShouldFlip)
  129. {
  130.     Interval i1 = ColliderTester::getInterval(o1, glm::normalize(axis));
  131.     Interval i2 = ColliderTester::getInterval(o2, glm::normalize(axis));
  132.  
  133.     if (!((i2.min <= i1.max) && (i1.min <= i2.max))) {
  134.         return 0.0f; // No penerattion
  135.     }
  136.  
  137.     //legth of intervals
  138.     float len1 = i1.max - i1.min;
  139.     float len2 = i2.max - i2.min;
  140.     //max and min point of intervals
  141.     float min = fminf(i1.min, i2.min);
  142.     float max = fmaxf(i1.max, i2.max);
  143.  
  144.     float length = max - min;
  145.  
  146.  
  147.     //flips collision normal if needed
  148.     if (outShouldFlip != 0) {
  149.         *outShouldFlip = (i2.min < i1.min);
  150.     }
  151.  
  152.     return (len1 + len2) - length;
  153.  
  154.    
  155. }
  156.  
  157.  
  158. IntersectData ColliderTester::FindCollisionFeatures(OBB A, OBB B) {
  159.    
  160.     IntersectData result=IntersectData();
  161.    
  162.     const float* o1 = value_ptr(A.getOrientation());
  163.     const float* o2 = value_ptr(B.getOrientation());
  164.  
  165.     glm::vec3 test[15] = { // Face axis
  166.         glm::vec3(o1[0], o1[1], o1[2]),
  167.         glm::vec3(o1[3], o1[4], o1[5]),
  168.         glm::vec3(o1[6], o1[7], o1[8]),
  169.         glm::vec3(o2[0], o2[1], o2[2]),
  170.         glm::vec3(o2[3], o2[4], o2[5]),
  171.         glm::vec3(o2[6], o2[7], o2[8])
  172.     };
  173.     for (int i = 0; i< 3; ++i) { // Fill out rest of axis
  174.         test[6 + i * 3 + 0] = glm::cross(test[i], test[0]);
  175.         test[6 + i * 3 + 1] = glm::cross(test[i], test[1]);
  176.         test[6 + i * 3 + 2] = glm::cross(test[i], test[2]);
  177.     }
  178.  
  179.     glm::vec3* hitNormal = 0;
  180.     bool shouldFlip;
  181.  
  182.     for (int i = 0; i< 15; ++i) {
  183.         if (glm::length2(test[i])< 0.001f) {
  184.             continue;
  185.         }
  186.  
  187.         float depth = penetrationDepth(A, B,test[i], &shouldFlip);
  188.        
  189.         if (depth <= 0.0f) {
  190.              result = IntersectData();
  191.             return result;
  192.         }
  193.         else if (depth < result.getDepth()) {
  194.             if (shouldFlip) {
  195.                 test[i] = test[i] * -1.0f;
  196.             }
  197.             result.setDepth(depth);
  198.             hitNormal = &test[i];
  199.         }
  200.     }
  201.  
  202.     if (hitNormal == 0) {
  203.         result = IntersectData();
  204.         return result;
  205.     }
  206.     glm::vec3 axis = glm::normalize(*hitNormal);
  207.     std::vector<glm::vec3> c1 = clipEdgesToOBB(getEdges(B), A);
  208.     std::vector<glm::vec3> c2 = clipEdgesToOBB(getEdges(A), B);
  209.     std::vector<glm::vec3> resultContacts;
  210.     resultContacts.insert(resultContacts.end(),
  211.         c1.begin(), c1.end());
  212.     resultContacts.insert(resultContacts.end(),
  213.         c2.begin(), c2.end());
  214.    
  215.  
  216.     Interval i = getInterval(A, axis);
  217.     float distance = (i.max - i.min)* 0.5f - result.getDepth() * 0.5f;
  218.     glm::vec3 pointOnPlane = A.getPosition() + (axis * distance);
  219.     for (int i = resultContacts.size() - 1; i >= 0; --i) {
  220.         glm::vec3 contact = resultContacts[i];
  221.  
  222.         resultContacts[i] = contact + (axis *
  223.             glm::dot(axis, pointOnPlane - contact));
  224.     }
  225.     result.setHasIntersection(true);
  226.     result.insertContact(resultContacts);
  227.     result.setNormal(axis);
  228.  
  229.     return result;
  230.  
  231. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement