ManifoldReductionTest.cpp 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  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/General/ManifoldReductionTest.h>
  6. #include <Math/Perlin.h>
  7. #include <Jolt/Physics/Collision/Shape/BoxShape.h>
  8. #include <Jolt/Physics/Collision/Shape/MeshShape.h>
  9. #include <Jolt/Physics/Collision/Shape/StaticCompoundShape.h>
  10. #include <Jolt/Physics/Collision/Shape/ScaledShape.h>
  11. #include <Jolt/Physics/Collision/PhysicsMaterialSimple.h>
  12. #include <Jolt/Physics/Body/BodyCreationSettings.h>
  13. #include <Layers.h>
  14. JPH_IMPLEMENT_RTTI_VIRTUAL(ManifoldReductionTest)
  15. {
  16. JPH_ADD_BASE_CLASS(ManifoldReductionTest, Test)
  17. }
  18. void ManifoldReductionTest::Initialize()
  19. {
  20. constexpr float cPerturbance = 0.02f;
  21. // Create mesh of regular grid of triangles
  22. TriangleList triangles;
  23. for (int x = -10; x < 10; ++x)
  24. for (int z = -10; z < 10; ++z)
  25. {
  26. float x1 = 0.1f * x;
  27. float z1 = 0.1f * z;
  28. float x2 = x1 + 0.1f;
  29. float z2 = z1 + 0.1f;
  30. Float3 v1 = Float3(x1, cPerturbance * PerlinNoise3(x1, 0, z1, 256, 256, 256), z1);
  31. Float3 v2 = Float3(x2, cPerturbance * PerlinNoise3(x2, 0, z1, 256, 256, 256), z1);
  32. Float3 v3 = Float3(x1, cPerturbance * PerlinNoise3(x1, 0, z2, 256, 256, 256), z2);
  33. Float3 v4 = Float3(x2, cPerturbance * PerlinNoise3(x2, 0, z2, 256, 256, 256), z2);
  34. triangles.push_back(Triangle(v1, v3, v4, 0));
  35. triangles.push_back(Triangle(v1, v4, v2, 0));
  36. }
  37. PhysicsMaterialList materials;
  38. materials.push_back(new PhysicsMaterialSimple());
  39. Ref<ShapeSettings> mesh_shape = new MeshShapeSettings(triangles, std::move(materials));
  40. // Floor
  41. Body &floor = *mBodyInterface->CreateBody(BodyCreationSettings(new ScaledShapeSettings(mesh_shape, Vec3::sReplicate(20)), RVec3::sZero(), Quat::sIdentity(), EMotionType::Static, Layers::NON_MOVING));
  42. mBodyInterface->AddBody(floor.GetID(), EActivation::DontActivate);
  43. // Create a box made of meshes
  44. Ref<StaticCompoundShapeSettings> mesh_box_shape = new StaticCompoundShapeSettings;
  45. mesh_box_shape->AddShape(Vec3(0, -1, 0), Quat::sRotation(Vec3::sAxisX(), JPH_PI), mesh_shape);
  46. mesh_box_shape->AddShape(Vec3(0, 1, 0), Quat::sIdentity(), mesh_shape);
  47. mesh_box_shape->AddShape(Vec3(-1, 0, 0), Quat::sRotation(Vec3::sAxisZ(), 0.5f * JPH_PI), mesh_shape);
  48. mesh_box_shape->AddShape(Vec3(1, 0, 0), Quat::sRotation(Vec3::sAxisZ(), -0.5f * JPH_PI), mesh_shape);
  49. mesh_box_shape->AddShape(Vec3(0, 0, -1), Quat::sRotation(Vec3::sAxisX(), -0.5f * JPH_PI), mesh_shape);
  50. mesh_box_shape->AddShape(Vec3(0, 0, 1), Quat::sRotation(Vec3::sAxisX(), 0.5f * JPH_PI), mesh_shape);
  51. // A convex box
  52. RefConst<ShapeSettings> box_shape = new BoxShapeSettings(Vec3(1, 1, 1), 0.0f);
  53. {
  54. // Create a compound of 3 mesh boxes
  55. Ref<StaticCompoundShapeSettings> three_mesh_box_shape = new StaticCompoundShapeSettings;
  56. three_mesh_box_shape->AddShape(Vec3(-2.1f, 0, 0), Quat::sIdentity(), mesh_box_shape);
  57. three_mesh_box_shape->AddShape(Vec3(0, -1, 0), Quat::sIdentity(), mesh_box_shape);
  58. three_mesh_box_shape->AddShape(Vec3(2.1f, 0, 0), Quat::sIdentity(), mesh_box_shape);
  59. // Create a compound of 3 convex boxes
  60. Ref<StaticCompoundShapeSettings> three_box_shape = new StaticCompoundShapeSettings;
  61. three_box_shape->AddShape(Vec3(-2.1f, 0, 0), Quat::sIdentity(), box_shape);
  62. three_box_shape->AddShape(Vec3(0, -1.1f, 0), Quat::sIdentity(), box_shape);
  63. three_box_shape->AddShape(Vec3(2.1f, 0, 0), Quat::sIdentity(), box_shape);
  64. // A set of 3 mesh boxes to rest on
  65. Body &three_mesh_box = *mBodyInterface->CreateBody(BodyCreationSettings(three_mesh_box_shape, RVec3(0, 1, 0), Quat::sIdentity(), EMotionType::Static, Layers::NON_MOVING));
  66. mBodyInterface->AddBody(three_mesh_box.GetID(), EActivation::DontActivate);
  67. // A set of 3 boxes that are dynamic where the middle one penetrates more than the other two
  68. BodyCreationSettings box_settings(three_box_shape, RVec3(0, 2.95f, 0), Quat::sIdentity(), EMotionType::Dynamic, Layers::MOVING);
  69. box_settings.mAllowSleeping = false;
  70. Body &box = *mBodyInterface->CreateBody(box_settings);
  71. mBodyInterface->AddBody(box.GetID(), EActivation::Activate);
  72. }
  73. {
  74. // Create a compound of 2 mesh boxes
  75. Ref<StaticCompoundShapeSettings> two_mesh_box_shape = new StaticCompoundShapeSettings;
  76. two_mesh_box_shape->AddShape(Vec3(-2.1f, 0, 0), Quat::sIdentity(), mesh_box_shape);
  77. two_mesh_box_shape->AddShape(Vec3(0, -1, 0), Quat::sIdentity(), mesh_box_shape);
  78. // Create a compound of 2 convex boxes
  79. Ref<StaticCompoundShapeSettings> two_box_shape = new StaticCompoundShapeSettings;
  80. two_box_shape->AddShape(Vec3(-2.1f, 0, 0), Quat::sIdentity(), box_shape);
  81. two_box_shape->AddShape(Vec3(0, -1, 0), Quat::sIdentity(), box_shape);
  82. // A set of 2 mesh boxes to rest on
  83. Body &two_mesh_box = *mBodyInterface->CreateBody(BodyCreationSettings(two_mesh_box_shape, RVec3(0, 1, 4), Quat::sIdentity(), EMotionType::Static, Layers::NON_MOVING));
  84. mBodyInterface->AddBody(two_mesh_box.GetID(), EActivation::DontActivate);
  85. // A set of 2 boxes that are dynamic, one is lower than the other
  86. BodyCreationSettings box_settings(two_box_shape, RVec3(0, 4, 4), Quat::sIdentity(), EMotionType::Dynamic, Layers::MOVING);
  87. box_settings.mAllowSleeping = false;
  88. Body &box = *mBodyInterface->CreateBody(box_settings);
  89. mBodyInterface->AddBody(box.GetID(), EActivation::Activate);
  90. }
  91. {
  92. // Create a compound of 2 meshes under small angle, small enough to combine the manifolds.
  93. Ref<StaticCompoundShapeSettings> two_mesh_shape = new StaticCompoundShapeSettings;
  94. two_mesh_shape->AddShape(Vec3(1, 0, 0), Quat::sRotation(Vec3::sAxisZ(), DegreesToRadians(2)), mesh_shape);
  95. two_mesh_shape->AddShape(Vec3(-1, 0, 0), Quat::sRotation(Vec3::sAxisZ(), DegreesToRadians(-2)), mesh_shape);
  96. // A set of 2 meshes to rest on
  97. Body &two_mesh_box = *mBodyInterface->CreateBody(BodyCreationSettings(two_mesh_shape, RVec3(0, 1, -4), Quat::sIdentity(), EMotionType::Static, Layers::NON_MOVING));
  98. mBodyInterface->AddBody(two_mesh_box.GetID(), EActivation::DontActivate);
  99. // A box that is dynamic, resting on the slightly sloped surface. The surface normals are close enough so that the manifold should be merged.
  100. BodyCreationSettings box_settings(box_shape, RVec3(0, 4, -4), Quat::sIdentity(), EMotionType::Dynamic, Layers::MOVING);
  101. box_settings.mAllowSleeping = false;
  102. Body &box = *mBodyInterface->CreateBody(box_settings);
  103. mBodyInterface->AddBody(box.GetID(), EActivation::Activate);
  104. }
  105. {
  106. // Create a compound of 2 meshes under small angle, but bigger than the limit to combine the manifolds.
  107. Ref<StaticCompoundShapeSettings> two_mesh_shape = new StaticCompoundShapeSettings();
  108. two_mesh_shape->AddShape(Vec3(1, 0, 0), Quat::sRotation(Vec3::sAxisZ(), DegreesToRadians(3)), mesh_shape);
  109. two_mesh_shape->AddShape(Vec3(-1, 0, 0), Quat::sRotation(Vec3::sAxisZ(), DegreesToRadians(-3)), mesh_shape);
  110. // A set of 2 meshes to rest on
  111. Body &two_mesh_box = *mBodyInterface->CreateBody(BodyCreationSettings(two_mesh_shape, RVec3(0, 1, -8), Quat::sIdentity(), EMotionType::Static, Layers::NON_MOVING));
  112. mBodyInterface->AddBody(two_mesh_box.GetID(), EActivation::DontActivate);
  113. // A box that is dynamic, resting on the slightly sloped surface. The surface normals are not close enough so that the manifold should be merged.
  114. BodyCreationSettings box_settings(box_shape, RVec3(0, 4, -8), Quat::sIdentity(), EMotionType::Dynamic, Layers::MOVING);
  115. box_settings.mAllowSleeping = false;
  116. Body &box = *mBodyInterface->CreateBody(box_settings);
  117. mBodyInterface->AddBody(box.GetID(), EActivation::Activate);
  118. }
  119. }