collision.cpp 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. #include <UnitTest++.h>
  2. #include <ode/ode.h>
  3. TEST(test_collision_trimesh_sphere)
  4. {
  5. /*
  6. * This tests some extreme cases, where a sphere barely touches some triangles
  7. * with zero depth.
  8. */
  9. dInitODE();
  10. {
  11. const int VertexCount = 4;
  12. const int IndexCount = 2*3;
  13. // this is a square on the XY plane
  14. float vertices[VertexCount * 3] = {
  15. -1,-1,0,
  16. 1,-1,0,
  17. 1,1,0,
  18. -1,1,0
  19. };
  20. dTriIndex indices[IndexCount] = {
  21. 0,1,2,
  22. 0,2,3
  23. };
  24. dTriMeshDataID data = dGeomTriMeshDataCreate();
  25. dGeomTriMeshDataBuildSingle(data,
  26. vertices,
  27. 3 * sizeof(float),
  28. VertexCount,
  29. indices,
  30. IndexCount,
  31. 3 * sizeof(dTriIndex));
  32. dGeomID trimesh = dCreateTriMesh(0, data, 0, 0, 0);
  33. const dReal radius = 4;
  34. dGeomID sphere = dCreateSphere(0, radius);
  35. dGeomSetPosition(sphere, 0,0,radius);
  36. dContactGeom cg[4];
  37. int nc;
  38. // check extreme case
  39. nc = dCollide(trimesh, sphere, 4, &cg[0], sizeof cg[0]);
  40. CHECK_EQUAL(1, nc);
  41. CHECK_EQUAL(0, cg[0].depth);
  42. // now translate both geoms
  43. dGeomSetPosition(trimesh, 10,30,40);
  44. dGeomSetPosition(sphere, 10,30,40+radius);
  45. // check extreme case, again
  46. nc = dCollide(trimesh, sphere, 4, &cg[0], sizeof cg[0]);
  47. CHECK_EQUAL(1, nc);
  48. CHECK_EQUAL(0, cg[0].depth);
  49. // and now, let's rotate the trimesh, 90 degrees on X
  50. dMatrix3 rot = { 1, 0, 0, 0,
  51. 0, 0, -1, 0,
  52. 0, 1, 0, 0 };
  53. dGeomSetPosition(trimesh, 10,30,40);
  54. dGeomSetRotation(trimesh, rot);
  55. dGeomSetPosition(sphere, 10,30-radius,40);
  56. // check extreme case, again
  57. nc = dCollide(trimesh, sphere, 4, &cg[0], sizeof cg[0]);
  58. CHECK_EQUAL(1, nc);
  59. CHECK_EQUAL(0, cg[0].depth);
  60. }
  61. dCloseODE();
  62. }
  63. TEST(test_collision_heightfield_ray_fail)
  64. {
  65. /*
  66. * This test demonstrated a bug in the AABB handling of the
  67. * heightfield.
  68. */
  69. dInitODE();
  70. {
  71. // Create quick heightfield with dummy data
  72. dHeightfieldDataID heightfieldData = dGeomHeightfieldDataCreate();
  73. unsigned char dataBuffer[16+1] = "1234567890123456";
  74. dGeomHeightfieldDataBuildByte(heightfieldData, dataBuffer, 0, 4, 4, 4, 4, 1, 0, 0, 0);
  75. dGeomHeightfieldDataSetBounds(heightfieldData, '0', '9');
  76. dGeomID height = dCreateHeightfield(0, heightfieldData, 1);
  77. // Create ray outside bounds
  78. dGeomID ray = dCreateRay(0, 20);
  79. dGeomRaySet(ray, 5, 10, 1, 0, -1, 0);
  80. dContact contactBuf[10];
  81. // Crash!
  82. dCollide(ray, height, 10, &(contactBuf[0].geom), sizeof(dContact));
  83. dGeomDestroy(height);
  84. dGeomDestroy(ray);
  85. dGeomHeightfieldDataDestroy(heightfieldData);
  86. }
  87. dCloseODE();
  88. }