mrDIMAS

GJK EPA 4

Oct 17th, 2015
223
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 38.68 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <float.h>
  4. #include <stdbool.h>
  5. #include <string.h>
  6.  
  7. #include "vector3.h"
  8.  
  9. typedef struct TSupport {
  10.     TVec3 supportA;
  11.     TVec3 minkowskiDifPoint;
  12. } TSupport;
  13.  
  14. typedef struct TSimplex {
  15.     TSupport points[4];
  16.     int size;
  17. } TSimplex;
  18.  
  19. typedef struct TEPAFace {
  20.     int a, b, c;
  21. } TEPAFace;
  22.  
  23. typedef struct TSphereShape {
  24.     float radius;
  25. } TSphereShape;
  26.  
  27. typedef struct TConvexShape {
  28.     TVec3 * points;
  29.     int count;    
  30. } TConvexShape;
  31.  
  32. typedef struct TTriangleShape {
  33.     TVec3 a, b, c;
  34. } TTriangleShape;
  35.  
  36. typedef struct TTriangleMeshShape {
  37.     TVec3 * vertices;
  38.     int vertexCount;
  39.     TEPAFace * faces;
  40.     int faceCount;
  41. } TTriangleMeshShape;
  42.  
  43. typedef struct TBoxShape {
  44.     float size;
  45.     TVec3 vertices[8];
  46. } TBoxShape;
  47.  
  48. typedef struct TShape {
  49.     TConvexShape * convex;
  50.     TSphereShape * sphere;
  51.     TTriangleMeshShape * triMesh;
  52.     TTriangleShape * triangle;
  53.     TBoxShape * box;
  54.     TVec3 position;
  55. } TShape;
  56.  
  57. typedef struct TEPATriangle {
  58.     TSupport a, b, c;
  59.     TVec3 normal;
  60.     float dist;
  61.     int numInPolytope;
  62. } TEPATriangle;
  63.  
  64. typedef struct TEPAContact {
  65.     TVec3 normal;
  66.     float penetrationDepth;
  67. } TEPAContact;
  68.  
  69. typedef struct TEPAPolytope {
  70.     TSupport * vertices;
  71.     int vertexCount;
  72.     TEPAFace * faces;
  73.     int faceCount;
  74. } TEPAPolytope;
  75.  
  76. typedef struct TEdge {
  77.     int a;
  78.     int b;
  79.     bool free;
  80. } TEdge;
  81.  
  82. typedef struct TEdgeList {
  83.     TEdge * edges;
  84.     int count;
  85.     int freeCount;
  86. } TEdgeList;
  87.  
  88. typedef struct TBody {
  89.     TVec3 position;
  90.     TShape * shape;
  91. } TBody;
  92.  
  93. #ifndef M_PI
  94. #   define M_PI 3.14159
  95. #endif
  96.  
  97.  
  98. TEPAPolytope * currentPolytope;
  99. TShape * currentShape1;
  100. TShape * currentShape2;
  101. TShape * currentShape3;
  102.  
  103. TBody * body1;
  104. TBody * body2;
  105. TBody * body3;
  106. // ===========================
  107. // HELPERS
  108. // ===========================
  109. bool Helper_SameDirection( TVec3 a, TVec3 b ) {
  110.     return Vec3_Dot( a, b ) > 0;
  111. }
  112.  
  113. // ===========================
  114. // SIMPLEX ROUTINE
  115. // ===========================
  116. void Simplex_RemovePoint( TSimplex * s, int num ) {
  117.     if( s->size > 0 ) {
  118.         if( num == 0 ) {
  119.             s->points[0] = s->points[1];
  120.             s->points[1] = s->points[2];
  121.             s->points[2] = s->points[3];
  122.         }
  123.         if( num == 1 ) {
  124.             s->points[1] = s->points[2];
  125.             s->points[2] = s->points[3];
  126.         }
  127.         if( num == 2 ) {
  128.             s->points[2] = s->points[3];
  129.         }
  130.         s->size--;
  131.     }
  132. }
  133.  
  134. void Simplex_AddPoint( TSimplex * s, TSupport p ) {
  135.     if( s->size < 4 ) {
  136.         s->points[ s->size ] = p;
  137.         s->size++;
  138.     } else {
  139.         printf( "SIMPLEX WARNING! Not enough space!\n" );
  140.     }
  141. }
  142.  
  143. // ===========================
  144. // CONVEX SHAPE ROUTINE
  145. // ===========================
  146. TShape * ConvexShape_CreateTriangle( TVec3 a, TVec3 b, TVec3 c ) {
  147.     TShape * shape = calloc( 1, sizeof( TShape ));
  148.     shape->convex = calloc( 1, sizeof( TConvexShape ));
  149.     shape->convex->count = 3;
  150.     shape->convex->points = malloc( shape->convex->count * sizeof( TVec3 ));
  151.     shape->convex->points[0] = a;
  152.     shape->convex->points[1] = b;
  153.     shape->convex->points[2] = c;
  154.     return shape;
  155. }
  156.  
  157. TShape * ConvexShape_CreateTetrahedron( TVec3 a, TVec3 b, TVec3 c, TVec3 d ) {
  158.     TShape * shape = calloc( 1, sizeof( TShape ));
  159.     shape->convex = calloc( 1, sizeof( TConvexShape ));
  160.     shape->convex->count = 4;
  161.     shape->convex->points = malloc( shape->convex->count * sizeof( TVec3 ));
  162.     shape->convex->points[0] = a;
  163.     shape->convex->points[1] = b;
  164.     shape->convex->points[2] = c;
  165.     shape->convex->points[3] = d;
  166.     shape->position = Vec3_Set( 0,0,0 );
  167.     return shape;
  168. }
  169.  
  170. TShape * ConvexShape_CreateSphere( TVec3 position, float radius ) {
  171.     TShape * shape = calloc( 1, sizeof( TShape ));
  172.     shape->sphere = calloc( 1, sizeof( TSphereShape ));    
  173.     shape->position = position;
  174.     shape->sphere->radius = radius;
  175.     return shape;
  176. }
  177.  
  178. void ConvexShape_Delete( TShape * shape ) {
  179.     if( shape->convex ) {
  180.         free( shape->convex );
  181.     }
  182.     if( shape->sphere ) {
  183.         free( shape->sphere );
  184.     }
  185.     free( shape );
  186. }
  187.  
  188. TVec3 ConvexShape_GetFarthestPointInDirection( TShape * shape, TVec3 dir ) {
  189.     const float eps = 0.000001;
  190.     if( fabs( dir.x ) < eps && fabs( dir.y ) < eps && fabs( dir.z ) < eps ) {
  191.         printf( "GJK Warning: Zero direction passed!\n" );
  192.     }
  193.     dir = Vec3_Normalize( dir );
  194.     if( shape->convex ) {
  195.         TVec3 farthest;
  196.         float lastDot = -FLT_MAX;
  197.         for( int i = 0; i < shape->convex->count; i++ ) {
  198.             float dot = Vec3_Dot( dir, shape->convex->points[i] );
  199.             if( dot > lastDot ) {
  200.                 farthest = shape->convex->points[i];
  201.                 lastDot = dot;
  202.             }
  203.         }
  204.         farthest = Vec3_Add( farthest, shape->position );
  205.         return farthest;
  206.     }
  207.     if( shape->sphere ) {
  208.         return Vec3_Add( shape->position, Vec3_Scale( dir, shape->sphere->radius ));
  209.     }
  210.     if( shape->box ) {
  211.         TVec3 farthest;
  212.         float lastDot = -FLT_MAX;
  213.         for( int i = 0; i < 8; i++ ) {
  214.             float dot = Vec3_Dot( dir, shape->box->vertices[i] );
  215.             if( dot > lastDot ) {
  216.                 farthest = shape->box->vertices[i];
  217.                 lastDot = dot;
  218.             }
  219.         }
  220.         farthest = Vec3_Add( farthest, shape->position );
  221.         return farthest;
  222.     }
  223.     if( shape->triangle ) {
  224.         int n;
  225.         float lastDot = -FLT_MAX;
  226.         float dots[3] = { Vec3_Dot( dir, shape->triangle->a ), Vec3_Dot( dir, shape->triangle->b ), Vec3_Dot( dir, shape->triangle->c ) };
  227.         for( int i = 0; i < 3; i++ ) {
  228.             if( dots[i] > lastDot ) {
  229.                 n = i;
  230.                 lastDot = dots[i];
  231.             }
  232.         }
  233.         TVec3 farthest;
  234.         if( n == 0 ) {
  235.             farthest = shape->triangle->a;
  236.         }
  237.         if( n == 1 ) {
  238.             farthest = shape->triangle->b;
  239.         }
  240.         if( n == 2 ) {
  241.             farthest = shape->triangle->c;
  242.         }
  243.         farthest = Vec3_Add( farthest, shape->position );
  244.         return farthest;
  245.     }
  246.     return Vec3_Zero();
  247. }
  248.  
  249. TShape * BoxShape_Create( float size ) {
  250.     float hs = size / 2;
  251.     TShape * shape = calloc( 1, sizeof( TShape ));
  252.     shape->box = calloc( 1, sizeof( TBoxShape ));
  253.     shape->box->vertices[0] = Vec3_Set( -hs, -hs, -hs );
  254.     shape->box->vertices[1] = Vec3_Set( -hs, -hs,  hs );
  255.     shape->box->vertices[2] = Vec3_Set(  hs, -hs, -hs );
  256.     shape->box->vertices[3] = Vec3_Set(  hs, -hs,  hs );
  257.    
  258.     shape->box->vertices[4] = Vec3_Set( -hs,  hs, -hs );
  259.     shape->box->vertices[5] = Vec3_Set( -hs,  hs,  hs );
  260.     shape->box->vertices[6] = Vec3_Set(  hs,  hs, -hs );
  261.     shape->box->vertices[7] = Vec3_Set(  hs,  hs,  hs );
  262.     shape->box->size = size;
  263.     return shape;
  264. }
  265.  
  266. // ===========================
  267. // GJK ALGORITHM ROUTINE
  268. // ===========================
  269. TSupport GJK_GetSupport( TShape * shape1, TShape * shape2, TVec3 dir ) {
  270.     TSupport sup;
  271.     sup.supportA = ConvexShape_GetFarthestPointInDirection( shape1, dir );
  272.     sup.minkowskiDifPoint = Vec3_Sub( sup.supportA, ConvexShape_GetFarthestPointInDirection( shape2, Vec3_Negate( dir )));
  273.     return sup;
  274. }
  275.  
  276. bool GJK_ProcessLine( TSimplex * simplex, TVec3 * outDirection ) {
  277.     TVec3 a = simplex->points[1].minkowskiDifPoint;
  278.     TVec3 b = simplex->points[0].minkowskiDifPoint;
  279.     TVec3 ab = Vec3_Sub( b, a );
  280.     TVec3 aO = Vec3_Negate( a );
  281.    
  282.     if( Helper_SameDirection( ab, aO )) {
  283.         *outDirection = Vec3_Cross( Vec3_Cross( ab, aO ), ab );
  284.     } else {
  285.         Simplex_RemovePoint( simplex, 0 );
  286.         *outDirection = aO;
  287.     }
  288.     return false;
  289. }
  290.  
  291. bool GJK_ProcessTriangle( TSimplex * simplex, TVec3 * outDirection ) {
  292.     TVec3 a = simplex->points[2].minkowskiDifPoint;
  293.     TVec3 b = simplex->points[1].minkowskiDifPoint;
  294.     TVec3 c = simplex->points[0].minkowskiDifPoint;
  295.     TVec3 aO = Vec3_Negate( a );
  296.     TVec3 ab = Vec3_Sub( b, a );
  297.     TVec3 ac = Vec3_Sub( c, a );
  298.     TVec3 abc = Vec3_Cross( ab, ac );
  299.     TVec3 acNormal = Vec3_Cross( abc, ac );
  300.     TVec3 abNormal = Vec3_Cross( ab, abc );
  301.    
  302.     if( Helper_SameDirection( acNormal, aO )) {
  303.         if( Helper_SameDirection( ac, aO )) {
  304.             Simplex_RemovePoint( simplex, 1 );
  305.             *outDirection = Vec3_Cross( Vec3_Cross(ac, aO), ac );
  306.         } else {
  307.             if( Helper_SameDirection( ab, aO )) {
  308.                 Simplex_RemovePoint( simplex, 0 );
  309.                 *outDirection = Vec3_Cross( Vec3_Cross(ab, aO), ab);
  310.             } else {
  311.                 Simplex_RemovePoint( simplex, 1 );
  312.                 Simplex_RemovePoint( simplex, 0 );
  313.                 *outDirection = aO;
  314.             }
  315.         }
  316.     } else {
  317.         if( Helper_SameDirection( abNormal, aO )) {
  318.             if( Helper_SameDirection( ab, aO )) {
  319.                 Simplex_RemovePoint( simplex, 0 );
  320.                 *outDirection = Vec3_Cross( Vec3_Cross(ab, aO), ab);
  321.             } else {
  322.                 Simplex_RemovePoint( simplex, 1 );
  323.                 Simplex_RemovePoint( simplex, 0 );
  324.                 *outDirection = aO;
  325.             }
  326.         } else {
  327.             if( Helper_SameDirection( abc, aO )) {
  328.                 *outDirection = Vec3_Cross(Vec3_Cross(abc, aO), abc);
  329.             } else {
  330.                 *outDirection = Vec3_Cross(Vec3_Cross( Vec3_Negate( abc ), aO), Vec3_Negate( abc ) );
  331.             }
  332.         }
  333.     }
  334.    
  335.     return false;
  336. }
  337.  
  338. bool GJK_ProcessTetrahedron( TSimplex * simplex, TVec3 * outDirection ) {
  339.     TVec3 a = simplex->points[3].minkowskiDifPoint;
  340.     TVec3 b = simplex->points[2].minkowskiDifPoint;
  341.     TVec3 c = simplex->points[1].minkowskiDifPoint;
  342.     TVec3 d = simplex->points[0].minkowskiDifPoint;
  343.    
  344.     TVec3 ac = Vec3_Sub( c, a );
  345.     TVec3 ab = Vec3_Sub( b, a );
  346.     TVec3 ad = Vec3_Sub( d, a );
  347.    
  348.     TVec3 acd = Vec3_Cross( ad, ac );
  349.     TVec3 abd = Vec3_Cross( ab, ad );
  350.     TVec3 abc = Vec3_Cross( ac, ab );
  351.    
  352.     TVec3 aO = Vec3_Negate( a );
  353.    
  354.     if( Helper_SameDirection( abc, aO )) {
  355.         if( Helper_SameDirection( Vec3_Cross( abc, ac ), aO )) {
  356.             Simplex_RemovePoint( simplex, 2 );
  357.             Simplex_RemovePoint( simplex, 0 );
  358.             *outDirection = Vec3_Cross( Vec3_Cross( ac, aO ), ac );
  359.         } else if( Helper_SameDirection( Vec3_Cross( ab, abc ), aO )) {
  360.             Simplex_RemovePoint( simplex, 1 );
  361.             Simplex_RemovePoint( simplex, 0 );
  362.             *outDirection = Vec3_Cross( Vec3_Cross( ab, aO ), ab );
  363.         } else {
  364.             Simplex_RemovePoint( simplex, 0 );
  365.             *outDirection = abc;
  366.         }
  367.     } else if( Helper_SameDirection( acd, aO )) {
  368.         if( Helper_SameDirection( Vec3_Cross( acd, ad ), aO )) {
  369.             Simplex_RemovePoint( simplex, 2 );
  370.             Simplex_RemovePoint( simplex, 1 );
  371.             *outDirection = Vec3_Cross( Vec3_Cross( ad, aO ), ad );
  372.         } else if ( Helper_SameDirection( Vec3_Cross( ac, acd ), aO )) {
  373.             Simplex_RemovePoint( simplex, 2 );
  374.             Simplex_RemovePoint( simplex, 0 );
  375.             *outDirection = Vec3_Cross( Vec3_Cross( ac, aO ), ac );
  376.         } else {
  377.            Simplex_RemovePoint( simplex, 2 );
  378.             *outDirection = acd;
  379.         }
  380.     } else if( Helper_SameDirection( abd, aO )) {
  381.         if( Helper_SameDirection( Vec3_Cross( abd, ab ), aO )) {
  382.             Simplex_RemovePoint( simplex, 1 );
  383.             Simplex_RemovePoint( simplex, 0 );
  384.             *outDirection = Vec3_Cross( Vec3_Cross( ab, aO ), ab );
  385.         } else if( Helper_SameDirection( Vec3_Cross( ad, abd ), aO )) {
  386.             Simplex_RemovePoint( simplex, 2 );
  387.             Simplex_RemovePoint( simplex, 1 );
  388.             *outDirection = Vec3_Cross( Vec3_Cross( ad, aO ), ad );
  389.         } else {
  390.             Simplex_RemovePoint( simplex, 1 );
  391.             *outDirection = abd;
  392.         }
  393.     } else {
  394.         return true;
  395.     }
  396.    
  397.     return false;
  398. }
  399.  
  400. bool GJK_ProcessSimplex( TSimplex * simplex, TVec3 * outDirection ) {
  401.     if( simplex->size == 2 ) {
  402.         return GJK_ProcessLine( simplex, outDirection );
  403.     } else if ( simplex->size == 3 ) {
  404.         return GJK_ProcessTriangle( simplex, outDirection );
  405.     } else if( simplex->size == 4 ) {
  406.         return GJK_ProcessTetrahedron( simplex, outDirection );
  407.     }
  408.     return false;
  409. }
  410.  
  411. void GJK_FixSimplex( TSimplex * simplex, TShape * shape1, TShape * shape2 ) {
  412.     float epsilon = 0.0001f;
  413.     static const TVec3 directions[6] = {
  414.         { .x =  1.0f,  .y =  0.0f,  .z =  0.0f },
  415.         { .x = -1.0f,  .y =  0.0f,  .z =  0.0f },
  416.         { .x =  0.0f,  .y =  1.0f,  .z =  0.0f },
  417.         { .x =  0.0f,  .y = -1.0f,  .z =  0.0f },
  418.         { .x =  0.0f,  .y =  0.0f,  .z =  1.0f },
  419.         { .x =  0.0f,  .y =  0.0f,  .z = -1.0f }};            
  420.     switch( simplex->size ) {
  421.         // case 'fall-through' is need to continuously add new points to the simplex
  422.        
  423.         // our simplex is a point
  424.         case 1: {
  425.             TSupport additionalSupport;
  426.             for( int i = 0; i < 6; i++ ) {
  427.                 additionalSupport = GJK_GetSupport( shape1, shape2, directions[i] );
  428.                 if( Vec3_SqrDistance( additionalSupport.minkowskiDifPoint, simplex->points[0].minkowskiDifPoint ) > epsilon ) {
  429.                     Simplex_AddPoint( simplex, additionalSupport );
  430.                     break;
  431.                 }
  432.             }
  433.         }
  434.  
  435.         // our simplex is a line
  436.         case 2: {
  437.            
  438.         }
  439.        
  440.         // our simplex is a triangle
  441.         case 3: {
  442.            
  443.         }
  444.     }
  445. }
  446.  
  447. bool GJK_IsIntersects( TShape * shape1, TShape * shape2, TSimplex * finalSimplex ) {
  448.     TVec3 dir = Vec3_Set( 1, 1, 1 );
  449.    
  450.     TSimplex simplex = { 0 };
  451.     Simplex_AddPoint( &simplex, GJK_GetSupport( shape1, shape2, dir ) );
  452.    
  453.     dir = Vec3_Negate( dir );
  454.     TSimplex lastFullSimplex;
  455.     int convergenceLimit = 1000;
  456.     for( int i = 0; i < convergenceLimit; i++ ) {
  457.         if( simplex.size == 4 ) {
  458.             lastFullSimplex = simplex;
  459.         }
  460.         TSupport lastSupport = GJK_GetSupport( shape1, shape2, dir );              
  461.         if( Helper_SameDirection( dir, lastSupport.minkowskiDifPoint )) {
  462.             Simplex_AddPoint( &simplex, lastSupport );            
  463.             if( GJK_ProcessSimplex( &simplex, &dir )) {
  464.  
  465.                 printf( "GJK: Intersection! %d iteration(s)!\n", i );
  466.                 if( finalSimplex ) {
  467.                     *finalSimplex = simplex;
  468.                 }
  469.                 return true;
  470.             }            
  471.         } else {
  472.             printf( "GJK: No intersection! %d iteration(s)!\n", i );            
  473.             return false;
  474.         }
  475.     }
  476.     //printf( "GJK: No intersection! Convergence limit has reached!\n" );
  477.     if( finalSimplex ) {
  478.         *finalSimplex = lastFullSimplex;
  479.     }
  480.     return true;
  481. }
  482.  
  483. // ===========================
  484. // EPA ALGORITHM ROUTINE
  485. // ===========================
  486. void Polytope_SetFromSimplex( TEPAPolytope * polytope, TSimplex * simplex ) {
  487.     polytope->vertexCount = 4;
  488.     polytope->vertices = calloc( polytope->vertexCount, sizeof( TSupport ));
  489.     for( int i = 0; i < polytope->vertexCount; i++ ) {
  490.         polytope->vertices[i] = simplex->points[i];
  491.     }
  492.     polytope->faceCount = 4;
  493.     polytope->faces = calloc( polytope->faceCount, sizeof( TEPAFace ));
  494.     polytope->faces[0] = (TEPAFace) { 0, 1, 2 };
  495.     polytope->faces[1] = (TEPAFace) { 0, 3, 1 };
  496.     polytope->faces[2] = (TEPAFace) { 0, 2, 3 };
  497.     polytope->faces[3] = (TEPAFace) { 2, 1, 3 };
  498. }
  499.  
  500. void Polytope_Free( TEPAPolytope * polytope ) {
  501.     free( polytope->faces );
  502.     free( polytope->vertices );
  503.     polytope->faceCount = -1;
  504.     polytope->vertexCount = -1;
  505. }
  506.  
  507. void EdgeList_Create( TEdgeList * edgeList, TEPAPolytope * polytope ) {
  508.     edgeList->count = polytope->faceCount * 3;
  509.     edgeList->edges = calloc( edgeList->count, sizeof( TEdge ));
  510. }
  511.  
  512. void EdgeList_Free( TEdgeList * edgeList ) {
  513.     free( edgeList->edges );
  514.     edgeList->count = 0;
  515. }
  516.  
  517. void EdgeList_Fill( TEdgeList * edgeList, TEPAPolytope * polytope ) {
  518.     for( int i = 0, j = 0; i < polytope->faceCount; i++, j += 3 ) {
  519.         edgeList->edges[j+0] = (TEdge) { .a = polytope->faces[i].a, .b = polytope->faces[i].b, .free = true };
  520.         edgeList->edges[j+1] = (TEdge) { .a = polytope->faces[i].b, .b = polytope->faces[i].c, .free = true };
  521.         edgeList->edges[j+2] = (TEdge) { .a = polytope->faces[i].c, .b = polytope->faces[i].a, .free = true };
  522.        // printf( "%d %d\n%d %d\n%d %d\n", edgeList->edges[j+0].a, edgeList->edges[j+0].b, edgeList->edges[j+1].a, edgeList->edges[j+1].b, edgeList->edges[j+2].a, edgeList->edges[j+2].b );
  523.     }
  524. }
  525.  
  526. void EdgeList_MarkHoles( TEdgeList * edgeList ) {
  527.     for( int i = 0; i < edgeList->count; i++ ) {
  528.         for( int j = 0; j < edgeList->count; j++ ) {
  529.             if( edgeList->edges[i].free && edgeList->edges[j].free ) {
  530.                 if( edgeList->edges[j].a == edgeList->edges[i].b && edgeList->edges[j].b == edgeList->edges[i].a ) {
  531.                     edgeList->edges[i].free = false;
  532.                     edgeList->edges[j].free = false;
  533.                 }
  534.             }
  535.         }
  536.     }
  537.     edgeList->freeCount = 0;
  538.     for( int i = 0; i < edgeList->count; i++ ) {
  539.         if( edgeList->edges[i].free ) {
  540.             edgeList->freeCount++;
  541.         }
  542.     }
  543.     //printf( "Free count: %d\n", edgeList->freeCount );
  544. }
  545.  
  546. int Polytope_ReserveFaces( TEPAPolytope * polytope, int faceCount ) {
  547.     int last = polytope->faceCount;
  548.     polytope->faceCount += faceCount;
  549.     polytope->faces = realloc( polytope->faces, polytope->faceCount * sizeof( TEPAFace ));
  550.     return last;
  551. }
  552.  
  553. void Polytope_PatchHoles( TEPAPolytope * polytope, TEdgeList * edgeList, int newPointIndex ) {
  554.     int lastFree = Polytope_ReserveFaces( polytope, edgeList->freeCount );
  555.     for( int i = 0; i < edgeList->count; i++ ) {
  556.         if( edgeList->edges[i].free ) {
  557.             polytope->faces[lastFree] = (TEPAFace) { .a = newPointIndex, .b = edgeList->edges[i].b, .c = edgeList->edges[i].a };
  558.             lastFree++;
  559.         }
  560.     }
  561. }
  562.  
  563. void Polytope_RemoveFace( TEPAPolytope * polytope, int n ) {
  564.     if( n == 0 ) {
  565.         polytope->faceCount--;
  566.         memmove( polytope->faces, polytope->faces + 1, sizeof( TEPAFace ) * polytope->faceCount );
  567.     } else if( n == polytope->faceCount - 1 ) {
  568.         // keep last face in array but reduce face count
  569.         polytope->faceCount--;
  570.     } else {
  571.         memmove( polytope->faces + n, polytope->faces + n + 1, sizeof( TEPAFace ) * ( polytope->faceCount - n ));
  572.         polytope->faceCount--;
  573.     }
  574. }
  575.  
  576. int Polytope_AddVertex( TEPAPolytope * polytope, TSupport newSupport ) {
  577.     int last = polytope->vertexCount;
  578.     polytope->vertexCount++;
  579.     polytope->vertices = realloc( polytope->vertices, polytope->vertexCount * sizeof( TSupport ));
  580.     polytope->vertices[last] = newSupport;
  581.     return last;
  582. }
  583.  
  584. TVec3 Math_ProjectOriginOntoPlane( TVec3 planePoint, TVec3 planeNormal ) {
  585.     float t = -Vec3_Dot( planePoint, planeNormal );
  586.     return Vec3_Negate( Vec3_Scale( planeNormal, t ));
  587. }
  588.  
  589. float Math_DistanceToOrigin( TVec3 normal, TVec3 point ) {
  590.     return Vec3_Dot( normal, point );
  591. }
  592.  
  593. void Math_GetBarycentricCoords( TVec3 p, TVec3 a, TVec3 b, TVec3 c, float *u,float *v,float *w ) {
  594.      TVec3 v0 = Vec3_Sub( b, a );
  595.      TVec3 v1 = Vec3_Sub( c, a );
  596.      TVec3 v2 = Vec3_Sub( p, a );
  597.      float d00 = Vec3_Dot( v0, v0 );
  598.      float d01 = Vec3_Dot( v0, v1 );
  599.      float d11 = Vec3_Dot( v1, v1 );
  600.      float d20 = Vec3_Dot( v2, v0 );
  601.      float d21 = Vec3_Dot( v2, v1 );
  602.      float denom = d00 * d11 - d01 * d01;
  603.      *v = (d11 * d20 - d01 * d21) / denom;
  604.      *w = (d00 * d21 - d01 * d20) / denom;
  605.      *u = 1.0f - *v - *w;
  606. }
  607.  
  608. bool Polytope_IsFaceSeenFromPoint( TEPAPolytope * polytope, int a, int b, int c, TVec3 point ) {
  609.     TVec3 va = polytope->vertices[ a ].minkowskiDifPoint;
  610.     TVec3 vb = polytope->vertices[ b ].minkowskiDifPoint;
  611.     TVec3 vc = polytope->vertices[ c ].minkowskiDifPoint;
  612.     TVec3 normal = Vec3_Cross( Vec3_Sub( vb, va ), Vec3_Sub( vc, va ));
  613.     return Vec3_Dot( normal, Vec3_Sub( point, va )) > 0;
  614. }
  615.  
  616. int Polytope_GetFirstFaceSeenFromPoint( TEPAPolytope * polytope, TVec3 point ) {
  617.     for( int i = 0; i < polytope->faceCount; i++ ) {
  618.         if( Polytope_IsFaceSeenFromPoint( polytope, polytope->faces[i].a, polytope->faces[i].b, polytope->faces[i].c, point )) {
  619.             return i;
  620.         }
  621.     }
  622.     return -1;
  623. }
  624.  
  625. bool Polytope_IsFaceDegenerated( TEPAPolytope * polytope, int n ) {
  626.     TVec3 a = polytope->vertices[ polytope->faces[ n ].a ].minkowskiDifPoint;
  627.     TVec3 b = polytope->vertices[ polytope->faces[ n ].b ].minkowskiDifPoint;
  628.     TVec3 c = polytope->vertices[ polytope->faces[ n ].c ].minkowskiDifPoint;
  629.  
  630.     TVec3 normal = Vec3_Cross( Vec3_Sub( b, a ), Vec3_Sub( c, a ) );
  631.  
  632.     // degenerated triangle, ignore
  633.     return Vec3_SqrLength( normal ) < 0.00001;
  634. }
  635.  
  636. void Polytope_RemoveDegeneratedFaces( TEPAPolytope * polytope ) {
  637.     while( true ) {
  638.         int n = -1;
  639.         for( int i = 0; i < polytope->faceCount; i++ ) {
  640.             if( Polytope_IsFaceDegenerated( polytope, i )) {
  641.                 Polytope_RemoveFace( polytope, i );
  642.                 n = i;
  643.                 break;
  644.             }
  645.         }
  646.         if( n < 0 ) {
  647.             break;
  648.         }
  649.     }
  650. }
  651.  
  652. TEPATriangle Polytope_GetClosestTriangleToOrigin( TEPAPolytope * polytope ) {
  653.     int closest;
  654.     float closestDistance = FLT_MAX;
  655.     TVec3 closestNormal;
  656.     for( int i = 0; i < polytope->faceCount; i++ ) {
  657.         TVec3 a = polytope->vertices[ polytope->faces[ i ].a ].minkowskiDifPoint;
  658.         TVec3 b = polytope->vertices[ polytope->faces[ i ].b ].minkowskiDifPoint;
  659.         TVec3 c = polytope->vertices[ polytope->faces[ i ].c ].minkowskiDifPoint;
  660.  
  661.         TVec3 normal = Vec3_Cross( Vec3_Sub( b, a ), Vec3_Sub( c, a ) );
  662.  
  663.         // degenerated triangle, ignore
  664.         if( Vec3_SqrLength( normal ) < 0.00001 ) {
  665.             continue;
  666.         }
  667.         float d = Math_DistanceToOrigin( normal, a );
  668.         if( d < closestDistance ) {
  669.             closestDistance = d;
  670.             closest = i;
  671.             closestNormal = normal;
  672.         }        
  673.     }
  674.     return (TEPATriangle) { .a = polytope->vertices[ polytope->faces[ closest ].a ], .b = polytope->vertices[ polytope->faces[ closest ].b ],
  675.                             .c = polytope->vertices[ polytope->faces[ closest ].c ], .normal = closestNormal, .dist = closestDistance, .numInPolytope = closest };
  676. }
  677.  
  678. bool EPA_ComputeContacts( TEPAPolytope * polytope, TShape * shape1, TShape * shape2, TEPAContact * outContact ) {
  679.     const int convergenceLimit = 100;
  680.     for( int i = 0; i < convergenceLimit; i++ ) {      
  681.         Polytope_RemoveDegeneratedFaces( polytope );  
  682.         TEPATriangle closestTriangle = Polytope_GetClosestTriangleToOrigin( polytope );
  683.         TSupport p = GJK_GetSupport( shape1, shape2, closestTriangle.normal );
  684.         float d = Vec3_Dot( p.minkowskiDifPoint, closestTriangle.normal );
  685.         if( d - closestTriangle.dist < 0.0001 ) {      
  686.             if( d < 0.00001 ) {
  687.                 return false;
  688.             }      
  689.             TVec3 proj = Math_ProjectOriginOntoPlane( closestTriangle.a.minkowskiDifPoint, closestTriangle.normal );
  690.             float u, v, w;
  691.             Math_GetBarycentricCoords( proj, closestTriangle.a.minkowskiDifPoint, closestTriangle.b.minkowskiDifPoint, closestTriangle.c.minkowskiDifPoint, &u, &v, &w );
  692.             TVec3 a = Vec3_Scale( closestTriangle.a.supportA, u );
  693.             TVec3 b = Vec3_Scale( closestTriangle.b.supportA, v );
  694.             TVec3 c = Vec3_Scale( closestTriangle.c.supportA, w );
  695.             TVec3 collPoint = Vec3_Add( Vec3_Add( a, b ), c );
  696.             closestTriangle.normal = Vec3_Normalize( Vec3_Negate( closestTriangle.normal ));
  697.             outContact->normal = closestTriangle.normal;
  698.             outContact->penetrationDepth = d;
  699.             printf( "EPA: Done in %d iteration(s)!\nClosest: %.3f, %.3f, %.3f\nNormal: %.3f, %.3f, %.3f\nPenetration depth: %f\n", i, collPoint.x, collPoint.y, collPoint.z, closestTriangle.normal.x, closestTriangle.normal.y, closestTriangle.normal.z, d );
  700.             return true;
  701.         } else {                
  702.             TEdgeList edgeList;            
  703.             while( true ) {
  704.                 int seenFace = Polytope_GetFirstFaceSeenFromPoint( polytope, p.minkowskiDifPoint );
  705.                 if( seenFace < 0 ) {
  706.                     break;
  707.                 } else {
  708.                     Polytope_RemoveFace( polytope, seenFace );
  709.                 }
  710.             }        
  711.             EdgeList_Create( &edgeList, polytope );    
  712.             EdgeList_Fill( &edgeList, polytope );
  713.             EdgeList_MarkHoles( &edgeList );
  714.             Polytope_PatchHoles( polytope, &edgeList, Polytope_AddVertex( polytope, p ) );
  715.             EdgeList_Free( &edgeList );            
  716.         }
  717.     }
  718.     printf( "EPA: Convergence limit has reached!\n" );
  719.     return false;
  720. }
  721.  
  722. // ===========================
  723. // TRIANGLE MESH SHAPE ROUTINE
  724. // ===========================
  725. TShape * TriangleMesh_CreatePlane( float width, float depth ) {
  726.     TShape * shape = calloc( 1, sizeof( TShape ));
  727.     TTriangleMeshShape * triMesh = calloc( 1, sizeof( TTriangleMeshShape ));
  728.     triMesh->vertexCount = 4;
  729.     triMesh->vertices = calloc( triMesh->vertexCount, sizeof( TVec3 ));
  730.     float hw = width / 2, hd = depth / 2;
  731.     triMesh->vertices[0] = Vec3_Set( -hw, 0.0, -hd );
  732.     triMesh->vertices[1] = Vec3_Set( -hw, 0.0,  hd );
  733.     triMesh->vertices[2] = Vec3_Set(  hw, 0.0,  hd );
  734.     triMesh->vertices[3] = Vec3_Set(  hw, 0.0, -hd );    
  735.     triMesh->faceCount = 2;
  736.     triMesh->faces = calloc( triMesh->faceCount, sizeof( TEPAFace ));
  737.     triMesh->faces[0] = (TEPAFace) { 0, 1, 2 };
  738.     triMesh->faces[1] = (TEPAFace) { 0, 2, 3 };
  739.     shape->triMesh = triMesh;
  740.     return shape;
  741. }
  742.  
  743. // ===========================
  744. // BODY ROUTINE
  745. // ===========================
  746. TBody * Body_Create( TShape * shape ) {
  747.     TBody * body = calloc( 1, sizeof( TBody ));
  748.     body->position = shape->position;
  749.     body->shape = shape;
  750.     return body;
  751. }
  752.  
  753. void Body_ProcessCollision( TBody * body1, TShape * shape ) {
  754.     TSimplex finalSimplex;
  755.     TEPAContact contact;
  756.     while( GJK_IsIntersects( body1->shape, shape, &finalSimplex )) {
  757.         if( finalSimplex.size == 4 ) {
  758.             if( currentPolytope ) {
  759.                 Polytope_Free( currentPolytope );
  760.                 free( currentPolytope );
  761.             }
  762.             currentPolytope = calloc( 1, sizeof( TEPAPolytope ));
  763.             Polytope_SetFromSimplex( currentPolytope, &finalSimplex );        
  764.             if( EPA_ComputeContacts( currentPolytope, body1->shape, shape, &contact )) {
  765.                 body1->position = Vec3_Add( body1->position, Vec3_Scale( contact.normal, contact.penetrationDepth / 2 ));
  766.             } else {
  767.                 printf( "EPA: Unable to compute contacts!\n" );
  768.                 break;
  769.             }    
  770.             body1->shape->position = body1->position;  
  771.         } else {
  772.             printf( "Wrong simplex size! Must be tetrahedron, got %d\n", finalSimplex.size );
  773.             break;
  774.         }
  775.     }
  776. }
  777.  
  778. void Body_SolveCollision( TBody * body1, TBody * body2 ) {
  779.     if( body1->shape->triMesh ) {
  780.         TBody * temp = body1;
  781.         body1 = body2;
  782.         body2 = temp;
  783.     }
  784.    
  785.     currentShape1 = body1->shape;
  786.     currentShape2 = body2->shape;
  787.  
  788.     body1->shape->position = body1->position;
  789.     body2->shape->position = body2->position;
  790.    
  791.     if( body2->shape->triMesh ) {
  792.         TTriangleMeshShape * triMesh = body2->shape->triMesh;
  793.         for( int i = 0; i < triMesh->faceCount; i++ ) {
  794.             TTriangleShape triangle = { .a = triMesh->vertices[ triMesh->faces[i].a ], .b = triMesh->vertices[ triMesh->faces[i].b ], .c = triMesh->vertices[ triMesh->faces[i].c ] };
  795.             TShape shape = { .position = body2->position, .triangle = &triangle };
  796.             Body_ProcessCollision( body1, &shape );
  797.         }
  798.     } else {
  799.         Body_ProcessCollision( body1, body2->shape );
  800.     }
  801. }
  802.  
  803. // ===========================
  804. // RENDERING ROUTINE
  805. // ===========================
  806. #include <windows.h>
  807. #include "glut.h"
  808. #include "gl/gl.h"
  809.  
  810. #define WINDOW_SIZE 800
  811.  
  812. void Renderer_DrawShape( TShape * shape ) {
  813.    // glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
  814.    
  815.     if( shape->convex ) {
  816.         if( shape->convex->count == 3 ) { // triangle        
  817.             glPushMatrix();
  818.            
  819.             glTranslatef( shape->position.x, shape->position.y, shape->position.z );
  820.            
  821.             TVec3 a = shape->convex->points[0];
  822.             TVec3 b = shape->convex->points[1];
  823.             TVec3 c = shape->convex->points[2];
  824.            
  825.             glBegin(GL_TRIANGLES);
  826.             glColor3ub( 0, 0, 255 );
  827.             glVertex3f( a.x, a.y, a.z );
  828.             glVertex3f( b.x, b.y, b.z );
  829.             glVertex3f( c.x, c.y, c.z );    
  830.            
  831.             glEnd();
  832.            
  833.             glPopMatrix();
  834.         }
  835.        
  836.         if( shape->convex->count == 4 ) { // tetrahedron        
  837.             glPushMatrix();
  838.            
  839.             glTranslatef( shape->position.x, shape->position.y, shape->position.z );
  840.            
  841.             TVec3 a = shape->convex->points[0];
  842.             TVec3 b = shape->convex->points[1];
  843.             TVec3 c = shape->convex->points[2];
  844.             TVec3 d = shape->convex->points[3];
  845.            
  846.             glBegin(GL_TRIANGLES);
  847.             glColor3ub( 255, 0, 0 );
  848.             glVertex3f( a.x, a.y, a.z );
  849.             glVertex3f( b.x, b.y, b.z );
  850.             glVertex3f( c.x, c.y, c.z );
  851.            
  852.             glColor3ub( 0, 255, 0 );
  853.             glVertex3f( a.x, a.y, a.z );
  854.             glVertex3f( d.x, d.y, d.z );
  855.             glVertex3f( b.x, b.y, b.z );
  856.            
  857.             glColor3ub( 0, 0, 255 );
  858.             glVertex3f( a.x, a.y, a.z );
  859.             glVertex3f( c.x, c.y, c.z );
  860.             glVertex3f( d.x, d.y, d.z );            
  861.            
  862.             glColor3ub( 255, 255, 0 );
  863.             glVertex3f( c.x, c.y, c.z );
  864.             glVertex3f( b.x, b.y, b.z );
  865.             glVertex3f( d.x, d.y, d.z );
  866.            
  867.             glEnd();
  868.            
  869.             glPopMatrix();
  870.         }
  871.     } else if( shape->sphere ) {
  872.        
  873.         glPushMatrix();        
  874.         glTranslatef( shape->position.x, shape->position.y, shape->position.z );        
  875.         glutSolidSphere( shape->sphere->radius, 32, 32 );        
  876.         glPopMatrix();
  877.        
  878.     } else if( shape->box ) {
  879.         /*
  880.             shape->box->vertices[0] = Vec3_Set( -hs, -hs, -hs );
  881.     shape->box->vertices[1] = Vec3_Set( -hs, -hs,  hs );
  882.     shape->box->vertices[2] = Vec3_Set(  hs, -hs, -hs );
  883.     shape->box->vertices[3] = Vec3_Set(  hs, -hs,  hs );
  884.    
  885.     shape->box->vertices[4] = Vec3_Set( -hs,  hs, -hs );
  886.     shape->box->vertices[5] = Vec3_Set( -hs,  hs,  hs );
  887.     shape->box->vertices[6] = Vec3_Set(  hs,  hs, -hs );
  888.     shape->box->vertices[7] = Vec3_Set(  hs,  hs,  hs );*/
  889.        
  890.        
  891.         glPushMatrix();        
  892.         glScalef( shape->box->size, shape->box->size, shape->box->size );
  893.         glTranslatef( shape->position.x, shape->position.y, shape->position.z );        
  894.         glutSolidCube( 1 );        
  895.         glPopMatrix();
  896.         /*
  897.         glBegin( GL_QUADS );
  898.        
  899.         glVertex3f( shape->box->vertices[0].x + shape->position.x, shape->box->vertices[0].y + shape->position.y, shape->box->vertices[0].z + shape->position.z );
  900.         glVertex3f( shape->box->vertices[1].x + shape->position.x, shape->box->vertices[1].y + shape->position.y, shape->box->vertices[1].z + shape->position.z );
  901.         glVertex3f( shape->box->vertices[2].x + shape->position.x, shape->box->vertices[2].y + shape->position.y, shape->box->vertices[2].z + shape->position.z );
  902.         glVertex3f( shape->box->vertices[3].x + shape->position.x, shape->box->vertices[3].y + shape->position.y, shape->box->vertices[3].z + shape->position.z );
  903.  
  904.         glVertex3f( shape->box->vertices[4].x + shape->position.x, shape->box->vertices[4].y + shape->position.y, shape->box->vertices[4].z + shape->position.z );
  905.         glVertex3f( shape->box->vertices[5].x + shape->position.x, shape->box->vertices[5].y + shape->position.y, shape->box->vertices[5].z + shape->position.z );
  906.         glVertex3f( shape->box->vertices[6].x + shape->position.x, shape->box->vertices[6].y + shape->position.y, shape->box->vertices[6].z + shape->position.z );
  907.         glVertex3f( shape->box->vertices[7].x + shape->position.x, shape->box->vertices[7].y + shape->position.y, shape->box->vertices[7].z + shape->position.z );
  908.        
  909.         glEnd();*/
  910.        
  911.     } else if( shape->triMesh ) {
  912.         glPushMatrix();        
  913.         glTranslatef( shape->position.x, shape->position.y, shape->position.z );  
  914.        
  915.         glColor3ub( 125, 200, 80 );
  916.        
  917.         glBegin(GL_TRIANGLES);
  918.         for( int i = 0; i < shape->triMesh->faceCount; i++ ) {    
  919.            
  920.             TVec3 a = shape->triMesh->vertices[ shape->triMesh->faces[ i ].a ];
  921.             TVec3 b = shape->triMesh->vertices[ shape->triMesh->faces[ i ].b ];
  922.             TVec3 c = shape->triMesh->vertices[ shape->triMesh->faces[ i ].c ];
  923.            
  924.             glVertex3f( a.x, a.y, a.z );
  925.             glVertex3f( b.x, b.y, b.z );
  926.             glVertex3f( c.x, c.y, c.z );          
  927.         }
  928.         glEnd();
  929.        
  930.         glPopMatrix();
  931.     }
  932. }
  933.  
  934. void Renderer_Display() {
  935.     static float a = 0;
  936.     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  937.  
  938.     glMatrixMode(GL_MODELVIEW);
  939.     glLoadIdentity();
  940.     gluLookAt( 0, 0.4, 2.2, 0, 0, 0, 0, 1, 0 );
  941.     glRotatef( a, 0, 1, 0 );
  942.    // a+=0.725;
  943.    
  944.    /*
  945.     if( currentPolytope ) {
  946.         //glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
  947.        
  948.         for( int i = 0; i < currentPolytope->faceCount; i++ ) {
  949.             int ia = currentPolytope->faces[i].a;
  950.             int ib = currentPolytope->faces[i].b;
  951.             int ic = currentPolytope->faces[i].c;
  952.      
  953.             TVec3 a = currentPolytope->vertices[ ia ].minkowskiDifPoint;
  954.             TVec3 b = currentPolytope->vertices[ ib ].minkowskiDifPoint;
  955.             TVec3 c = currentPolytope->vertices[ ic ].minkowskiDifPoint;
  956.            
  957.             TVec3 normal = Vec3_Normalize( Vec3_Cross( Vec3_Sub( b,a ), Vec3_Sub( c,a )));
  958.            
  959.             glBegin(GL_TRIANGLES);
  960.             //glColor3ub( i * 8 + 50, i * 8 + 50, i * 8 + 50 );
  961.             glVertex3f( a.x, a.y, a.z );
  962.             glVertex3f( b.x, b.y, b.z );
  963.             glVertex3f( c.x, c.y, c.z );
  964.             glEnd();
  965.            
  966.             glBegin(GL_LINES);
  967.             glColor3ub( 255, 0, 255 );
  968.             glVertex3f( a.x * 0.333f + b.x * 0.333f + c.x * 0.333f, a.y * 0.333f + b.y * 0.333f + c.y * 0.333f, a.z * 0.333f + b.z * 0.333f + c.z * 0.333f );
  969.             glVertex3f( a.x * 0.333f + b.x * 0.333f + c.x * 0.333f + normal.x, a.y * 0.333f + b.y * 0.333f + c.y * 0.333f + normal.y, a.z * 0.333f + b.z * 0.333f + c.z * 0.333f + normal.z );
  970.             glEnd();
  971.         }
  972.     }*/
  973.     glColor3ub( 255, 0, 0 );
  974.     Renderer_DrawShape( currentShape1 );
  975.     glColor3ub( 255, 255, 0 );
  976.     Renderer_DrawShape( currentShape2 );
  977.     glColor3ub( 0, 255, 255 );
  978.     Renderer_DrawShape( currentShape3 );  
  979.     glutSwapBuffers();
  980.     glutPostRedisplay();
  981. }
  982.  
  983. void Renderer_Init() {
  984.     glClearColor(0.000, 0.110, 0.392, 0.0);
  985.  
  986.     glMatrixMode(GL_PROJECTION);
  987.     glLoadIdentity();
  988.     gluPerspective( 80, 1, 0.01, 1024 );
  989.    
  990.  
  991.    
  992.     glClearDepth( 1.0f );
  993.     glEnable( GL_DEPTH_TEST );
  994.     glDepthFunc( GL_LEQUAL );
  995.     glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST );
  996.     glEnable( GL_TEXTURE_2D );
  997.     glShadeModel( GL_SMOOTH );
  998.    
  999.     glEnable( GL_CULL_FACE );
  1000.    
  1001.     glDisable( GL_STENCIL_TEST );
  1002.     glCullFace( GL_BACK );    
  1003.     glEnable( GL_ALPHA_TEST );
  1004.     glAlphaFunc( GL_GREATER, 0.025f );
  1005.  
  1006.    
  1007.     //currentShape1 = ConvexShape_CreateTetrahedron( Vec3_Set( -1, .5, 0 ), Vec3_Set( -1, 1.5, 0 ), Vec3_Set( 0.1, 0.5, 0 ), Vec3_Set( -1, 0.5, 1 ));
  1008.     //currentShape1 = ConvexShape_CreateTetrahedron( Vec3_Set( 0, 0, 0 ), Vec3_Set( 0, 1, 0 ), Vec3_Set( 1, 0, 0 ), Vec3_Set( 0, 0, 1 ));
  1009.    
  1010.     //currentShape2 = ConvexShape_CreateSphere( Vec3_Set( 0.5,0,0.0), 0.8 );
  1011.     //currentShape2 = ConvexShape_CreateTriangle( Vec3_Set( 0, 0, 0.5 ), Vec3_Set( 0.5, 1, 0.5 ), Vec3_Set( 0.5, 0, 0 ));
  1012.    // currentShape2 = ConvexShape_CreateTriangle( Vec3_Set( 0, 0.1, 0 ), Vec3_Set( 0, 0.1, 1 ), Vec3_Set( 1, 0.1, 0 ));
  1013.    
  1014.     currentShape1 = BoxShape_Create( 1 );
  1015.     currentShape2 = TriangleMesh_CreatePlane( 2, 2 );
  1016.     currentShape3 = BoxShape_Create( 1 );//ConvexShape_CreateSphere( Vec3_Set( 0,0,0 ), 0.2 );
  1017.    
  1018.     body1 = Body_Create( currentShape1 );
  1019.     body1->position = Vec3_Set( 0, 0.5, 0 );
  1020.    
  1021.     body2 = Body_Create( currentShape2 );    
  1022.    
  1023.     body3 = Body_Create( currentShape3 );
  1024.     body3->position = Vec3_Set( 0, 1, 0 );
  1025.      
  1026.     Body_SolveCollision( body1, body3 );
  1027.     //Body_SolveCollision( body1, body2 );
  1028.     //Body_SolveCollision( body3, body2 );
  1029. }
  1030.  
  1031. void KeyFunc( unsigned char key, int x, int y ) {
  1032.     bool move = false;
  1033.     if( key == 'A' || key == 'a' ) {
  1034.         body1->position = Vec3_Add( body1->position, Vec3_Set( -0.01, 0.0, 0.0 ));
  1035.         move = true;
  1036.     }
  1037.     if( key == 'D' || key == 'd' ) {
  1038.         body1->position = Vec3_Add( body1->position, Vec3_Set(  0.01, 0.0, 0.0 ));
  1039.         move = true;
  1040.     }
  1041.     if( key == 'W' || key == 'w' ) {
  1042.         body1->position = Vec3_Add( body1->position, Vec3_Set( 0.0, 0.0, -0.01 ));
  1043.         move = true;
  1044.     }
  1045.     if( key == 'S' || key == 's' ) {
  1046.         body1->position = Vec3_Add( body1->position, Vec3_Set( 0, 0.0, 0.01 ));
  1047.         move = true;
  1048.     }
  1049.     if( key == 'X' || key == 'x' ) {
  1050.         body1->position = Vec3_Add( body1->position, Vec3_Set( 0.0, 0.01, 0.0 ));
  1051.         move = true;
  1052.     }
  1053.     if( key == 'Z' || key == 'z' ) {
  1054.         body1->position = Vec3_Add( body1->position, Vec3_Set( 0, -0.01, 0.0 ));
  1055.         move = true;
  1056.     }
  1057.     if( move ) {
  1058.         Body_SolveCollision( body1, body3 );
  1059.         //Body_SolveCollision( body1, body2 );
  1060.        // Body_SolveCollision( body3, body2 );
  1061.     }
  1062. }
  1063.  
  1064. // ===========================
  1065. // TESTS
  1066. // ===========================
  1067. int main(int argc, char **argv) {
  1068.     glutInit(&argc, argv);
  1069.     glutInitDisplayMode( GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA );
  1070.     glutInitWindowSize( 800, 800 );
  1071.     glutInitWindowPosition(0, 0);
  1072.     glutCreateWindow("Test");
  1073.     glutDisplayFunc(Renderer_Display);
  1074.     glutKeyboardFunc( KeyFunc );
  1075.    
  1076.     Renderer_Init();
  1077.  
  1078.     glutMainLoop();
  1079. }
Advertisement
Add Comment
Please, Sign In to add comment