test_collision.cpp 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. // Copyright (c) Amer Koleci and Contributors.
  2. // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information.
  3. #include <gtest/gtest.h>
  4. #include "joltc.h"
  5. namespace BroadPhaseLayers {
  6. static constexpr JPH_BroadPhaseLayer NON_MOVING = 0;
  7. static constexpr JPH_BroadPhaseLayer MOVING = 1;
  8. static constexpr uint32_t NUM_LAYERS = 2;
  9. }
  10. namespace ObjectLayers {
  11. static constexpr JPH_ObjectLayer NON_MOVING = 0;
  12. static constexpr JPH_ObjectLayer MOVING = 1;
  13. static constexpr uint32_t NUM_LAYERS = 2;
  14. }
  15. class CollisionTest : public ::testing::Test {
  16. protected:
  17. JPH_PhysicsSystem* physicsSystem = nullptr;
  18. JPH_BodyInterface* bodyInterface = nullptr;
  19. JPH_BroadPhaseLayerInterface* bpLayer = nullptr;
  20. JPH_ObjectLayerPairFilter* objPairFilter = nullptr;
  21. JPH_ObjectVsBroadPhaseLayerFilter* objVsBpFilter = nullptr;
  22. void SetUp() override {
  23. ASSERT_TRUE(JPH_Init());
  24. bpLayer = JPH_BroadPhaseLayerInterfaceTable_Create(ObjectLayers::NUM_LAYERS, BroadPhaseLayers::NUM_LAYERS);
  25. JPH_BroadPhaseLayerInterfaceTable_MapObjectToBroadPhaseLayer(bpLayer, ObjectLayers::NON_MOVING, BroadPhaseLayers::NON_MOVING);
  26. JPH_BroadPhaseLayerInterfaceTable_MapObjectToBroadPhaseLayer(bpLayer, ObjectLayers::MOVING, BroadPhaseLayers::MOVING);
  27. objPairFilter = JPH_ObjectLayerPairFilterTable_Create(ObjectLayers::NUM_LAYERS);
  28. JPH_ObjectLayerPairFilterTable_EnableCollision(objPairFilter, ObjectLayers::NON_MOVING, ObjectLayers::MOVING);
  29. JPH_ObjectLayerPairFilterTable_EnableCollision(objPairFilter, ObjectLayers::MOVING, ObjectLayers::MOVING);
  30. objVsBpFilter = JPH_ObjectVsBroadPhaseLayerFilterTable_Create(
  31. bpLayer, BroadPhaseLayers::NUM_LAYERS,
  32. objPairFilter, ObjectLayers::NUM_LAYERS);
  33. JPH_PhysicsSystemSettings settings = {};
  34. settings.maxBodies = 1024;
  35. settings.maxBodyPairs = 1024;
  36. settings.maxContactConstraints = 1024;
  37. settings.broadPhaseLayerInterface = bpLayer;
  38. settings.objectVsBroadPhaseLayerFilter = objVsBpFilter;
  39. settings.objectLayerPairFilter = objPairFilter;
  40. physicsSystem = JPH_PhysicsSystem_Create(&settings);
  41. bodyInterface = JPH_PhysicsSystem_GetBodyInterface(physicsSystem);
  42. }
  43. void TearDown() override {
  44. if (physicsSystem) JPH_PhysicsSystem_Destroy(physicsSystem);
  45. JPH_Shutdown();
  46. }
  47. JPH_BodyID CreateSphereBody(float x, float y, float z, float radius, JPH_MotionType motionType, JPH_ObjectLayer layer) {
  48. JPH_SphereShape* shape = JPH_SphereShape_Create(radius);
  49. JPH_Vec3 position = {x, y, z};
  50. JPH_Quat rotation = {0.0f, 0.0f, 0.0f, 1.0f};
  51. JPH_BodyCreationSettings* bs = JPH_BodyCreationSettings_Create3((JPH_Shape*)shape, &position, &rotation, motionType, layer);
  52. JPH_Body* body = JPH_BodyInterface_CreateBody(bodyInterface, bs);
  53. JPH_BodyID bodyId = JPH_Body_GetID(body);
  54. JPH_BodyInterface_AddBody(bodyInterface, bodyId, JPH_Activation_Activate);
  55. JPH_BodyCreationSettings_Destroy(bs);
  56. JPH_Shape_Destroy((JPH_Shape*)shape);
  57. return bodyId;
  58. }
  59. void RemoveAndDestroyBody(JPH_BodyID bodyId) {
  60. JPH_BodyInterface_RemoveBody(bodyInterface, bodyId);
  61. JPH_BodyInterface_DestroyBody(bodyInterface, bodyId);
  62. }
  63. };
  64. TEST_F(CollisionTest, GetNarrowPhaseQuery) {
  65. const JPH_NarrowPhaseQuery* query = JPH_PhysicsSystem_GetNarrowPhaseQuery(physicsSystem);
  66. EXPECT_NE(query, nullptr);
  67. }
  68. TEST_F(CollisionTest, GetNarrowPhaseQueryNoLock) {
  69. const JPH_NarrowPhaseQuery* query = JPH_PhysicsSystem_GetNarrowPhaseQueryNoLock(physicsSystem);
  70. EXPECT_NE(query, nullptr);
  71. }
  72. TEST_F(CollisionTest, RayCast_Hit) {
  73. JPH_BodyID sphereId = CreateSphereBody(0.0f, 0.0f, 0.0f, 1.0f, JPH_MotionType_Static, ObjectLayers::NON_MOVING);
  74. JPH_PhysicsSystem_OptimizeBroadPhase(physicsSystem);
  75. const JPH_NarrowPhaseQuery* query = JPH_PhysicsSystem_GetNarrowPhaseQuery(physicsSystem);
  76. JPH_RVec3 origin = {-5.0f, 0.0f, 0.0f};
  77. JPH_Vec3 direction = {10.0f, 0.0f, 0.0f};
  78. JPH_RayCastResult hit;
  79. bool hasHit = JPH_NarrowPhaseQuery_CastRay(query, &origin, &direction, &hit, nullptr, nullptr, nullptr);
  80. EXPECT_TRUE(hasHit);
  81. EXPECT_NEAR(hit.fraction, 0.4f, 0.01f);
  82. EXPECT_EQ(hit.bodyID, sphereId);
  83. RemoveAndDestroyBody(sphereId);
  84. }
  85. TEST_F(CollisionTest, RayCast_Miss) {
  86. JPH_BodyID sphereId = CreateSphereBody(0.0f, 0.0f, 0.0f, 1.0f, JPH_MotionType_Static, ObjectLayers::NON_MOVING);
  87. JPH_PhysicsSystem_OptimizeBroadPhase(physicsSystem);
  88. const JPH_NarrowPhaseQuery* query = JPH_PhysicsSystem_GetNarrowPhaseQuery(physicsSystem);
  89. JPH_RVec3 origin = {0.0f, 10.0f, 0.0f};
  90. JPH_Vec3 direction = {10.0f, 0.0f, 0.0f};
  91. JPH_RayCastResult hit;
  92. bool hasHit = JPH_NarrowPhaseQuery_CastRay(query, &origin, &direction, &hit, nullptr, nullptr, nullptr);
  93. EXPECT_FALSE(hasHit);
  94. RemoveAndDestroyBody(sphereId);
  95. }
  96. TEST_F(CollisionTest, RayCast_ClosestHit) {
  97. JPH_BodyID sphere1Id = CreateSphereBody(-3.0f, 0.0f, 0.0f, 1.0f, JPH_MotionType_Static, ObjectLayers::NON_MOVING);
  98. JPH_BodyID sphere2Id = CreateSphereBody(3.0f, 0.0f, 0.0f, 1.0f, JPH_MotionType_Dynamic, ObjectLayers::MOVING);
  99. JPH_PhysicsSystem_OptimizeBroadPhase(physicsSystem);
  100. const JPH_NarrowPhaseQuery* query = JPH_PhysicsSystem_GetNarrowPhaseQuery(physicsSystem);
  101. JPH_RVec3 origin = {-10.0f, 0.0f, 0.0f};
  102. JPH_Vec3 direction = {20.0f, 0.0f, 0.0f};
  103. JPH_RayCastResult hit;
  104. bool hasHit = JPH_NarrowPhaseQuery_CastRay(query, &origin, &direction, &hit, nullptr, nullptr, nullptr);
  105. EXPECT_TRUE(hasHit);
  106. EXPECT_EQ(hit.bodyID, sphere1Id);
  107. RemoveAndDestroyBody(sphere1Id);
  108. RemoveAndDestroyBody(sphere2Id);
  109. }
  110. TEST_F(CollisionTest, GetBroadPhaseQuery) {
  111. const JPH_BroadPhaseQuery* query = JPH_PhysicsSystem_GetBroadPhaseQuery(physicsSystem);
  112. EXPECT_NE(query, nullptr);
  113. }