ConvexHullShapeTest.cpp 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. // Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)
  2. // SPDX-FileCopyrightText: 2021 Jorrit Rouwe
  3. // SPDX-License-Identifier: MIT
  4. #include <TestFramework.h>
  5. #include <Tests/Shapes/ConvexHullShapeTest.h>
  6. #include <Jolt/Physics/Collision/Shape/ConvexHullShape.h>
  7. #include <Jolt/Physics/Body/BodyCreationSettings.h>
  8. #include <Layers.h>
  9. JPH_IMPLEMENT_RTTI_VIRTUAL(ConvexHullShapeTest)
  10. {
  11. JPH_ADD_BASE_CLASS(ConvexHullShapeTest, Test)
  12. }
  13. void ConvexHullShapeTest::Initialize()
  14. {
  15. // Floor
  16. CreateFloor();
  17. // Create tetrahedron
  18. Array<Vec3> tetrahedron;
  19. tetrahedron.push_back(Vec3(-5, 0, -5));
  20. tetrahedron.push_back(Vec3(0, 0, 5));
  21. tetrahedron.push_back(Vec3(5, 0, -5));
  22. tetrahedron.push_back(Vec3(0, -5, 0));
  23. Body &body_tetrahedron = *mBodyInterface->CreateBody(BodyCreationSettings(new ConvexHullShapeSettings(tetrahedron), RVec3(0, 10, 0), Quat::sIdentity(), EMotionType::Dynamic, Layers::MOVING));
  24. mBodyInterface->AddBody(body_tetrahedron.GetID(), EActivation::Activate);
  25. // Create box
  26. Array<Vec3> box;
  27. box.push_back(Vec3(5, 5, 5));
  28. box.push_back(Vec3(-5, 5, 5));
  29. box.push_back(Vec3(5, -5, 5));
  30. box.push_back(Vec3(-5, -5, 5));
  31. box.push_back(Vec3(5, 5, -5));
  32. box.push_back(Vec3(-5, 5, -5));
  33. box.push_back(Vec3(5, -5, -5));
  34. box.push_back(Vec3(-5, -5, -5));
  35. Body &body_box = *mBodyInterface->CreateBody(BodyCreationSettings(new ConvexHullShapeSettings(box), RVec3(20, 10, 0), Quat::sIdentity(), EMotionType::Dynamic, Layers::MOVING));
  36. mBodyInterface->AddBody(body_box.GetID(), EActivation::Activate);
  37. // Add a sphere of many points
  38. Array<Vec3> sphere;
  39. for (float theta = 0.0f; theta <= JPH_PI; theta += JPH_PI / 20.0f)
  40. for (float phi = 0.0f; phi <= 2.0f * JPH_PI; phi += 2.0f * JPH_PI / 20.0f)
  41. sphere.push_back(5.0f * Vec3::sUnitSpherical(theta, phi));
  42. Body &body_sphere = *mBodyInterface->CreateBody(BodyCreationSettings(new ConvexHullShapeSettings(sphere), RVec3(40, 10, 0), Quat::sIdentity(), EMotionType::Dynamic, Layers::MOVING));
  43. mBodyInterface->AddBody(body_sphere.GetID(), EActivation::Activate);
  44. // Add a tapered cylinder of many points
  45. Array<Vec3> tapered_cylinder;
  46. for (float theta = 0.0f; theta <= 2.0f * JPH_PI; theta += JPH_PI / 128.0f)
  47. {
  48. tapered_cylinder.push_back(4.0f * Vec3(-0.1f, Sin(theta), Cos(theta)));
  49. tapered_cylinder.push_back(4.5f * Vec3(0.1f, Sin(theta), Cos(theta)));
  50. }
  51. Body &body_tapered_cylinder = *mBodyInterface->CreateBody(BodyCreationSettings(new ConvexHullShapeSettings(tapered_cylinder), RVec3(60, 10, 0), Quat::sIdentity(), EMotionType::Dynamic, Layers::MOVING));
  52. mBodyInterface->AddBody(body_tapered_cylinder.GetID(), EActivation::Activate);
  53. // Create convex hull with on one side nearly coplanar faces
  54. Array<Vec3> coplanar;
  55. coplanar.push_back(Vec3(1.04298747f, 4.68531752f, 0.858853102f));
  56. coplanar.push_back(Vec3(-1.00753999f, 4.63935566f, -0.959064901f));
  57. coplanar.push_back(Vec3(-1.01861656f, 4.72096348f, 0.846121550f));
  58. coplanar.push_back(Vec3(-2.37996006f, 1.26311386f, -1.10994697f));
  59. coplanar.push_back(Vec3(0.213164970f, 0.0198628306f, -1.70677519f));
  60. coplanar.push_back(Vec3(-2.27295995f, -0.899001241f, -0.472913086f));
  61. coplanar.push_back(Vec3(-1.85078228f, -1.25204790f, 2.42339849f));
  62. coplanar.push_back(Vec3(1.91183412f, -1.25204790f, 2.42339849f));
  63. coplanar.push_back(Vec3(-2.75279832f, 3.25019693f, 1.67055058f));
  64. coplanar.push_back(Vec3(-0.0697868019f, -2.78841114f, -0.422013819f));
  65. coplanar.push_back(Vec3(2.26410985f, -0.918261647f, -0.493922710f));
  66. coplanar.push_back(Vec3(0.765828013f, -2.82050991f, 1.91100550f));
  67. coplanar.push_back(Vec3(2.33326006f, 1.26643038f, -1.18808103f));
  68. coplanar.push_back(Vec3(-0.591650009f, 2.27845216f, -1.87628603f));
  69. coplanar.push_back(Vec3(-2.22145009f, 3.04359150f, 0.234738767f));
  70. coplanar.push_back(Vec3(-1.00753999f, 4.39097166f, -1.27783847f));
  71. coplanar.push_back(Vec3(0.995577991f, 4.39734173f, -1.27900386f));
  72. coplanar.push_back(Vec3(0.995577991f, 4.64572525f, -0.960230291f));
  73. coplanar.push_back(Vec3(2.74527335f, 3.06491613f, 1.77647924f));
  74. coplanar.push_back(Vec3(-1.53122997f, -2.18120861f, 2.31516361f));
  75. Body &body_coplanar = *mBodyInterface->CreateBody(BodyCreationSettings(new ConvexHullShapeSettings(coplanar), RVec3(80, 10, 0), Quat::sIdentity(), EMotionType::Dynamic, Layers::MOVING));
  76. mBodyInterface->AddBody(body_coplanar.GetID(), EActivation::Activate);
  77. // Bodies with random convex shapes
  78. default_random_engine random;
  79. uniform_real_distribution<float> hull_size(0.1f, 10.0f);
  80. for (int i = 0; i < 10; ++i)
  81. {
  82. // Create random points
  83. Array<Vec3> points;
  84. for (int j = 0; j < 20; ++j)
  85. points.push_back(hull_size(random) * Vec3::sRandom(random));
  86. Body &body = *mBodyInterface->CreateBody(BodyCreationSettings(new ConvexHullShapeSettings(points), RVec3(-90.0f + i * 18.0f, 10, 20), Quat::sIdentity(), EMotionType::Dynamic, Layers::MOVING));
  87. mBodyInterface->AddBody(body.GetID(), EActivation::Activate);
  88. }
  89. // Bodies with random convex polygons (this is not something you should be doing, but this tests the 2D convex hull shape generation and allows you to test the probe against them)
  90. for (int i = 0; i < 10; ++i)
  91. {
  92. // Create random points
  93. Array<Vec3> points;
  94. for (int j = 0; j < 20; ++j)
  95. {
  96. Vec3 v = hull_size(random) * Vec3::sRandom(random);
  97. v.SetZ(0.0f);
  98. points.push_back(v);
  99. }
  100. // Convex hull needs to be created with convex radius of 0 because the shape has no volume, so we cannot move the planes backwards to make space for the convex radius
  101. Ref<ShapeSettings> shape_settings = new ConvexHullShapeSettings(points, 0.0f);
  102. BodyCreationSettings creation_settings(shape_settings, RVec3(-90.0f + i * 18.0f, 10, 40), Quat::sIdentity(), EMotionType::Dynamic, Layers::MOVING);
  103. // The polygon has no volume, so we need to provide a dummy mass and inertia for this shape
  104. creation_settings.mOverrideMassProperties = EOverrideMassProperties::MassAndInertiaProvided;
  105. creation_settings.mMassPropertiesOverride.mMass = 1.0f;
  106. creation_settings.mMassPropertiesOverride.mInertia = Mat44::sIdentity();
  107. Body &body = *mBodyInterface->CreateBody(creation_settings);
  108. mBodyInterface->AddBody(body.GetID(), EActivation::Activate);
  109. }
  110. }