Advertisement
Guest User

Untitled

a guest
Nov 14th, 2016
252
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.15 KB | None | 0 0
  1. #include "CGjk.h"
  2.  
  3. CGjk::CGjk() {
  4.     m_psfpSimplexUpdateFuncs[SIMPLEX::ST_EDGE] = &CGjk::SimplexEdgeUpdate;
  5.     m_psfpSimplexUpdateFuncs[SIMPLEX::ST_FACE] = &CGjk::SimplexFaceUpdate;
  6.     m_psfpSimplexUpdateFuncs[SIMPLEX::ST_TETRAHEDRON] = &CGjk::SimplexTetrahedronUpdate;
  7. }
  8.  
  9. CGjk::~CGjk() {
  10. }
  11.  
  12. void CGjk::GetSupportPoint(const CVector3& _vSearchDir, const CShapeInstance* _psiLeft, const CShapeInstance* _psiRight, SIMPLEX_VERTEX& _vRet) const {
  13.     CVector3 vSupA;
  14.     _vRet.ui32SupA = (const CPolyhedron*)(_psiLeft->ShapeInstanceShape())->GetSupport(_vSearchDir, vSupA);
  15.     CVector3 vSupB;
  16.     _vRet.ui32SupB = (const CPolyhedron*)(_psiRight->ShapeInstanceShape())->GetSupport(-_vSearchDir, vSupB);
  17.     _vRet.vSupA = vSupA;
  18.     _vRet.vSupB = vSupB;
  19.     _vRet.vMinkSup = _vRet.vSupA - _vRet.vSupB;
  20. }
  21.  
  22. bool CGjk::Intersect(const CShapeInstance* _psiLeft, const CShapeInstance* _psiRight) {
  23.     m_vSearchDir = CVector3( ML_ONE, ML_ONE, ML_ONE );
  24.  
  25.     //vA it's our first supporting point.
  26.     GetSupportPoint(m_vSearchDir, _psiLeft, _psiRight, m_sSimplex.vA);
  27.     m_sSimplex.ssSimplexType = SIMPLEX::ST_POINT;
  28.  
  29.     m_vSearchDir = -m_vSearchDir;
  30.  
  31.     for ( unsigned int I = 0UL; I < GJK_ITERATIONS; ++I ) {
  32.         SIMPLEX_VERTEX vNewSimplexVertex;
  33.         GetSupportPoint(m_vSearchDir, _psiLeft, _psiRight, vNewSimplexVertex);
  34.        
  35.         if (vNewSimplexVertex.vMinkSup.Dot(m_vSearchDir) <= ML_ZERO) { return false; }
  36.  
  37.         //Add new point to create a new simplex.
  38.         if (m_sSimplex.ssSimplexType == SIMPLEX::ST_POINT) {
  39.             m_sSimplex.vB = m_sSimplex.vA;
  40.             m_sSimplex.vA = vNewSimplexVertex;
  41.             m_sSimplex.ssSimplexType = SIMPLEX::ST_EDGE;
  42.         }
  43.         else if (m_sSimplex.ssSimplexType == SIMPLEX::ST_EDGE) {
  44.             m_sSimplex.vC = m_sSimplex.vB;
  45.             m_sSimplex.vB = m_sSimplex.vA;
  46.             m_sSimplex.vA = vNewSimplexVertex;
  47.             m_sSimplex.ssSimplexType = SIMPLEX::ST_FACE;
  48.         }
  49.         else if (m_sSimplex.ssSimplexType == SIMPLEX::ST_FACE) {
  50.             m_sSimplex.vD = m_sSimplex.vC;
  51.             m_sSimplex.vC = m_sSimplex.vB;
  52.             m_sSimplex.vB = m_sSimplex.vA;
  53.             m_sSimplex.vA = vNewSimplexVertex;
  54.             m_sSimplex.ssSimplexType = SIMPLEX::ST_TETRAHEDRON;
  55.         }
  56.  
  57.         //Check if the simplex contains the origin.
  58.         //Update simplex and direction.
  59.         if ( UpdateSimplex() ) { return true; }
  60.     }
  61.  
  62.     return false;
  63. }
  64.  
  65. bool CGjk::UpdateSimplex() {
  66.     return (this->*m_psfpSimplexUpdateFuncs[m_sSimplex.ssSimplexType])();
  67. }
  68.  
  69. bool CGjk::SimplexEdgeUpdate() {
  70.     CVector3 vAo = -m_sSimplex.vA.vMinkSup;
  71.     CVector3 vAb = m_sSimplex.vB.vMinkSup - m_sSimplex.vA.vMinkSup;
  72.     m_vSearchDir = vAb.Cross(vAo).Cross(vAb);
  73.     return false;
  74. }
  75.  
  76. bool CGjk::SimplexFaceUpdate() {
  77.     CVector3 vAo = -m_sSimplex.vA.vMinkSup;
  78.     CVector3 vAb = m_sSimplex.vB.vMinkSup - m_sSimplex.vA.vMinkSup;
  79.     CVector3 vAc = m_sSimplex.vC.vMinkSup - m_sSimplex.vA.vMinkSup;
  80.     CVector3 vFaceNormal = vAb.Cross(vAc);
  81.  
  82.     if ( vAb.Cross(vFaceNormal).Dot(vAo) > ML_ZERO ) {
  83.         m_sSimplex.ssSimplexType = SIMPLEX::ST_EDGE;
  84.         //A and B makes the edge.
  85.         m_vSearchDir = vAb.Cross(vAo).Cross(vAb); //Ab to Ao.
  86.         return false;
  87.     }
  88.    
  89.     if ( vFaceNormal.Cross(vAc).Dot(vAo) > ML_ZERO ) {
  90.         //A and B makes the edge.
  91.         m_sSimplex.vB = m_sSimplex.vC;
  92.         m_sSimplex.ssSimplexType = SIMPLEX::ST_EDGE;
  93.         m_vSearchDir = vAc.Cross(vAo).Cross(vAc); //Ac to Ao.
  94.         return false;
  95.     }
  96.  
  97.     if ( vFaceNormal.Dot(vAo) > ML_ZERO ) {
  98.         //Above face.
  99.         m_vSearchDir = vFaceNormal;
  100.         return false;
  101.     }
  102.    
  103.     //Below face.
  104.     CMathLib::Swap(m_sSimplex.vB, m_sSimplex.vC);
  105.     m_vSearchDir = -vFaceNormal;
  106.     return false;
  107. }
  108.  
  109. bool CGjk::SimplexTetrahedronUpdate() {
  110.     CVector3 vAo = -m_sSimplex.vA.vMinkSup;
  111.  
  112.     CVector3 vAb = m_sSimplex.vB.vMinkSup - m_sSimplex.vA.vMinkSup;
  113.     CVector3 vAc = m_sSimplex.vC.vMinkSup - m_sSimplex.vA.vMinkSup;
  114.     if ( vAb.Cross(vAc).Dot(vAo) > ML_ZERO ) {
  115.         return UpdateSimplexTetrahedronFace(vAo);
  116.     }
  117.  
  118.     CVector3 vAd = m_sSimplex.vD.vMinkSup - m_sSimplex.vA.vMinkSup;
  119.     if ( vAc.Cross(vAd).Dot(vAo) > ML_ZERO ) {
  120.         m_sSimplex.vB = m_sSimplex.vC;
  121.         m_sSimplex.vC = m_sSimplex.vD;
  122.         return UpdateSimplexTetrahedronFace(vAo);
  123.     }
  124.    
  125.     if ( vAd.Cross(vAb).Dot(vAo) > ML_ZERO ) {
  126.         SIMPLEX_VERTEX vOldB = m_sSimplex.vB;
  127.         m_sSimplex.vB = m_sSimplex.vD;
  128.         m_sSimplex.vC = vOldB;
  129.         return UpdateSimplexTetrahedronFace(vAo);
  130.     }
  131.  
  132.     return true;
  133. }
  134.  
  135. bool CGjk::UpdateSimplexTetrahedronFace(const CVector3& _vAo) {
  136.     CVector3 vAb = m_sSimplex.vB.vMinkSup - m_sSimplex.vA.vMinkSup;
  137.     CVector3 vAc = m_sSimplex.vC.vMinkSup - m_sSimplex.vA.vMinkSup;
  138.     CVector3 vFaceNormal = vAb.Cross(vAc);
  139.  
  140.     if (vAb.Cross(vFaceNormal).Dot(_vAo) > ML_ZERO) {
  141.         //Test if origin it is in the voronoi region of the AB edge.
  142.         m_sSimplex.ssSimplexType = SIMPLEX::ST_EDGE;
  143.         //Get the perpendicular direction of the edge towards the origin.
  144.         m_vSearchDir = vAb.Cross(_vAo).Cross(vAb);
  145.         return false;
  146.     }
  147.    
  148.     if ( vFaceNormal.Cross(vAc).Dot(_vAo) > ML_ZERO ) {
  149.         //Test if origin it is in the voronoi region of the AC edge.
  150.         //Change to edge.
  151.         m_sSimplex.vB = m_sSimplex.vC;
  152.         m_sSimplex.ssSimplexType = SIMPLEX::ST_EDGE;
  153.         //Get the perpendicular direction of the edge towards the origin.
  154.         m_vSearchDir = vAc.Cross(_vAo).Cross(vAc);
  155.         return false;
  156.     }
  157.  
  158.     m_sSimplex.ssSimplexType = SIMPLEX::ST_FACE;
  159.     m_vSearchDir = vFaceNormal;
  160.    
  161.     return false;
  162. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement