test.c 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. #include <stdio.h>
  2. #include "tinyphysicsengine.h"
  3. #define F TPE_FRACTIONS_PER_UNIT
  4. #define TOLERANCE 10
  5. int tolerance(TPE_Unit x, TPE_Unit expX)
  6. {
  7. return (x <= (expX + TOLERANCE)) && (x >= (expX - TOLERANCE));
  8. }
  9. int testRotToQuat(
  10. TPE_Unit x, TPE_Unit y, TPE_Unit z, TPE_Unit angle,
  11. TPE_Unit expX, TPE_Unit expY, TPE_Unit expZ, TPE_Unit expW)
  12. {
  13. printf("testing axis + rot -> quaternion ([%d,%d,%d] %d -> %d %d %d %d): ",
  14. x,y,z,angle,expX,expY,expZ,expW);
  15. TPE_Vec4 q, axis;
  16. TPE_vec4Set(&axis,x,y,z,0);
  17. TPE_rotationToQuaternion(axis,angle,&q);
  18. if (!tolerance(q.x,expX) ||
  19. !tolerance(q.y,expY) ||
  20. !tolerance(q.z,expZ) ||
  21. !tolerance(q.w,expW))
  22. {
  23. printf("bad (%d %d %d %d)\n",q.x,q.y,q.z,q.w);
  24. return 0;
  25. }
  26. puts("OK");
  27. return 1;
  28. }
  29. int ass(const char *what, int cond)
  30. {
  31. printf("testing %s: %s\n",what,cond ? "OK" : "ERROR");
  32. return cond;
  33. }
  34. int testColl(const TPE_Body *b1, const TPE_Body *b2,
  35. TPE_Unit expRet, TPE_Unit expX, TPE_Unit expY, TPE_Unit expZ,
  36. TPE_Unit expNX, TPE_Unit expNY, TPE_Unit expNZ)
  37. {
  38. printf("testing collision detection, %d %d: ",b1->shape,b2->shape);
  39. TPE_Vec4 p, n;
  40. TPE_vec4Set(&p,0,0,0,0);
  41. TPE_vec4Set(&n,0,0,0,0);
  42. TPE_Unit ret = TPE_bodyCollides(b1,b2,&p,&n);
  43. #if 1
  44. printf("\nret: %d\n",ret);
  45. TPE_PRINTF_VEC4(p);
  46. TPE_PRINTF_VEC4(n);
  47. printf("\n");
  48. #endif
  49. if (!tolerance(ret,expRet) ||
  50. ((ret != 0) &&
  51. (!tolerance(p.x,expX) ||
  52. !tolerance(p.y,expY) ||
  53. !tolerance(p.z,expZ) ||
  54. !tolerance(n.x,expNX) ||
  55. !tolerance(n.y,expNY) ||
  56. !tolerance(n.z,expNZ))))
  57. return 0;
  58. puts("OK");
  59. return 1;
  60. }
  61. int main(void)
  62. {
  63. #define ASS(what) if (!what) { puts("ERROR"); return 0; }
  64. {
  65. ASS(ass("shape ID",TPE_COLLISION_TYPE(TPE_SHAPE_SPHERE,TPE_SHAPE_CUBOID) == TPE_COLLISION_TYPE(TPE_SHAPE_CUBOID,TPE_SHAPE_SPHERE)))
  66. ASS(testRotToQuat(F,0,0, 0, 0,0,0,F));
  67. ASS(testRotToQuat(F,0,0, F/4, 361,0,0,361));
  68. ASS(testRotToQuat(0,F,0, F/4, 0,361,0,361));
  69. ASS(testRotToQuat(0,0,F, F/2, 0,0,F,0));
  70. ASS(testRotToQuat(-F,F,F, -F/8, 112,-112,-112,472));
  71. TPE_Vec4 p = TPE_vec4(10,200,100,0), p2, q;
  72. p2 = p;
  73. TPE_rotationToQuaternion(TPE_vec4(512,0,0,0),F/4,&q);
  74. TPE_rotatePoint(&p2,q);
  75. #define TEST_LINE_SEGMENT_CLOSE(ax,ay,az,bx,by,bz,px,py,pz,rx,ry,rz) \
  76. ASS(ass("line segment closest",TPE_vec3Dist(TPE_lineSegmentClosestPoint(\
  77. TPE_vec4(ax,ay,az,0),TPE_vec4(bx,by,bz,0),TPE_vec4(px,py,pz,0)),\
  78. TPE_vec4(rx,ry,rz,0)) < 10))
  79. TEST_LINE_SEGMENT_CLOSE(0,0,0, 100,0,0, 50,0,0, 50,0,0)
  80. TEST_LINE_SEGMENT_CLOSE(-100,-100,20, 1000,10000,20000, -3000,-5000,-1000, -100,-100,20)
  81. return 0;
  82. }
  83. {
  84. puts("collisions:");
  85. TPE_Body sphere, cylinder;
  86. TPE_Vec4 collPoint, collNorm;
  87. TPE_bodyInit(&sphere);
  88. TPE_bodyInit(&cylinder);
  89. // sphere, sphere:
  90. sphere.shape = TPE_SHAPE_SPHERE;
  91. cylinder.shape = TPE_SHAPE_SPHERE;
  92. sphere.shapeParams[0] = TPE_FRACTIONS_PER_UNIT;
  93. cylinder.shapeParams[1] = TPE_FRACTIONS_PER_UNIT;
  94. sphere.position = TPE_vec4(F,F / 2,0,0);
  95. cylinder.position = TPE_vec4(F + F / 2,F / 2,0,0);
  96. ASS(testColl(&sphere,&cylinder,256,640,256,0,512,0,0));
  97. ASS(testColl(&cylinder,&sphere,256,640,256,0,-512,0,0));
  98. // sphere, cylinder:
  99. sphere.shape = TPE_SHAPE_SPHERE;
  100. cylinder.shape = TPE_SHAPE_CYLINDER;
  101. sphere.shapeParams[0] = F;
  102. cylinder.shapeParams[0] = F * 2;
  103. cylinder.shapeParams[1] = F * 3;
  104. sphere.position.y = 6 * F;
  105. ASS(testColl(&sphere,&cylinder,0,0,0,0,0,0,0)); // no collision
  106. sphere.position = TPE_vec4(F * 3 + F / 2,F,0,0);
  107. cylinder.position = TPE_vec4(F,0,0,0);
  108. ASS(testColl(&sphere,&cylinder,F / 2,3 * F,F,0,-1 * F,0,0)); // collision with cyl. body
  109. ASS(testColl(&cylinder,&sphere,F / 2,3 * F,F,0,F,0,0));
  110. sphere.position.x = F + F / 2;
  111. sphere.position.y = 2 * F;
  112. ASS(testColl(&sphere,&cylinder,F / 2,F + F / 2,F + F / 2,0,0,-1 * F,0)); // collision with cyl. body
  113. ASS(testColl(&cylinder,&sphere,F / 2,F + F / 2,F + F / 2,0,0,F,0));
  114. sphere.position.x = 3 * F + F / 2;
  115. sphere.position.y = 2 * F;
  116. ASS(testColl(&sphere,&cylinder,150,3 * F,F + F / 2,0,-362,-362,0)); // collision with cyl. edge
  117. }
  118. return 0;
  119. }