2
0

BroadPhaseTests.cpp 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. // SPDX-FileCopyrightText: 2021 Jorrit Rouwe
  2. // SPDX-License-Identifier: MIT
  3. #include "UnitTestFramework.h"
  4. #include <Jolt/Physics/Collision/BroadPhase/BroadPhaseQuadTree.h>
  5. #include <Jolt/Physics/Collision/Shape/BoxShape.h>
  6. #include <Jolt/Physics/Collision/CollisionCollectorImpl.h>
  7. #include <Jolt/Physics/Collision/RayCast.h>
  8. #include <Jolt/Physics/Collision/CastResult.h>
  9. #include <Jolt/Physics/Body/BodyManager.h>
  10. #include <Jolt/Physics/Body/BodyCreationSettings.h>
  11. #include "Layers.h"
  12. TEST_SUITE("BroadPhaseTests")
  13. {
  14. TEST_CASE("TestBroadPhaseOptimize")
  15. {
  16. BPLayerInterfaceImpl broad_phase_layer_interface;
  17. // Create body manager
  18. BodyManager body_manager;
  19. body_manager.Init(1, 0, broad_phase_layer_interface);
  20. // Create quad tree
  21. BroadPhaseQuadTree broadphase;
  22. broadphase.Init(&body_manager, broad_phase_layer_interface);
  23. // Create a box
  24. BodyCreationSettings settings(new BoxShape(Vec3::sReplicate(1.0f)), Vec3::sZero(), Quat::sIdentity(), EMotionType::Static, Layers::NON_MOVING);
  25. Body &body = *body_manager.AllocateBody(settings);
  26. body_manager.AddBody(&body);
  27. // Add it to the broadphase
  28. BodyID id = body.GetID();
  29. BroadPhase::AddState add_state = broadphase.AddBodiesPrepare(&id, 1);
  30. broadphase.AddBodiesFinalize(&id, 1, add_state);
  31. // Test that we hit the box at its current location and not where we're going to move it to
  32. AllHitCollisionCollector<RayCastBodyCollector> collector;
  33. broadphase.CastRay({ Vec3(0, 2, 0), Vec3(0, -2, 0) }, collector, BroadPhaseLayerFilter(), ObjectLayerFilter());
  34. CHECK(collector.mHits.size() == 1);
  35. CHECK(collector.mHits[0].mBodyID == id);
  36. CHECK_APPROX_EQUAL(collector.mHits[0].mFraction, 0.5f);
  37. collector.Reset();
  38. broadphase.CastRay({ Vec3(2, 2, 0), Vec3(0, -2, 0) }, collector, BroadPhaseLayerFilter(), ObjectLayerFilter());
  39. CHECK(collector.mHits.empty());
  40. broadphase.CastRay({ Vec3(4, 2, 0), Vec3(0, -2, 0) }, collector, BroadPhaseLayerFilter(), ObjectLayerFilter());
  41. CHECK(collector.mHits.empty());
  42. // Move the body
  43. body.SetPositionAndRotationInternal(Vec3(2, 0, 0), Quat::sIdentity());
  44. broadphase.NotifyBodiesAABBChanged(&id, 1, true);
  45. // Test that we hit the box at its previous and current location
  46. broadphase.CastRay({ Vec3(0, 2, 0), Vec3(0, -2, 0) }, collector, BroadPhaseLayerFilter(), ObjectLayerFilter());
  47. CHECK(collector.mHits.size() == 1);
  48. CHECK(collector.mHits[0].mBodyID == id);
  49. CHECK_APPROX_EQUAL(collector.mHits[0].mFraction, 0.5f);
  50. collector.Reset();
  51. broadphase.CastRay({ Vec3(2, 2, 0), Vec3(0, -2, 0) }, collector, BroadPhaseLayerFilter(), ObjectLayerFilter());
  52. CHECK(collector.mHits.size() == 1);
  53. CHECK(collector.mHits[0].mBodyID == id);
  54. CHECK_APPROX_EQUAL(collector.mHits[0].mFraction, 0.5f);
  55. collector.Reset();
  56. broadphase.CastRay({ Vec3(4, 2, 0), Vec3(0, -2, 0) }, collector, BroadPhaseLayerFilter(), ObjectLayerFilter());
  57. CHECK(collector.mHits.empty());
  58. // Optimize the broadphase
  59. broadphase.Optimize();
  60. // Test that we hit the box only at the new location
  61. broadphase.CastRay({ Vec3(0, 2, 0), Vec3(0, -2, 0) }, collector, BroadPhaseLayerFilter(), ObjectLayerFilter());
  62. CHECK(collector.mHits.empty());
  63. broadphase.CastRay({ Vec3(2, 2, 0), Vec3(0, -2, 0) }, collector, BroadPhaseLayerFilter(), ObjectLayerFilter());
  64. CHECK(collector.mHits.size() == 1);
  65. CHECK(collector.mHits[0].mBodyID == id);
  66. CHECK_APPROX_EQUAL(collector.mHits[0].mFraction, 0.5f);
  67. collector.Reset();
  68. broadphase.CastRay({ Vec3(4, 2, 0), Vec3(0, -2, 0) }, collector, BroadPhaseLayerFilter(), ObjectLayerFilter());
  69. CHECK(collector.mHits.empty());
  70. // Move the body again (so that for the next optimize we'll have to discard a tree)
  71. body.SetPositionAndRotationInternal(Vec3(4, 0, 0), Quat::sIdentity());
  72. broadphase.NotifyBodiesAABBChanged(&id, 1, true);
  73. // Test that we hit the box at its previous and current location
  74. broadphase.CastRay({ Vec3(0, 2, 0), Vec3(0, -2, 0) }, collector, BroadPhaseLayerFilter(), ObjectLayerFilter());
  75. CHECK(collector.mHits.empty());
  76. broadphase.CastRay({ Vec3(2, 2, 0), Vec3(0, -2, 0) }, collector, BroadPhaseLayerFilter(), ObjectLayerFilter());
  77. CHECK(collector.mHits.size() == 1);
  78. CHECK(collector.mHits[0].mBodyID == id);
  79. CHECK_APPROX_EQUAL(collector.mHits[0].mFraction, 0.5f);
  80. collector.Reset();
  81. broadphase.CastRay({ Vec3(4, 2, 0), Vec3(0, -2, 0) }, collector, BroadPhaseLayerFilter(), ObjectLayerFilter());
  82. CHECK(collector.mHits.size() == 1);
  83. CHECK(collector.mHits[0].mBodyID == id);
  84. CHECK_APPROX_EQUAL(collector.mHits[0].mFraction, 0.5f);
  85. collector.Reset();
  86. // Optimize the broadphase (this will internally have to discard a tree)
  87. broadphase.Optimize();
  88. // Test that we hit the box only at the new location
  89. broadphase.CastRay({ Vec3(0, 2, 0), Vec3(0, -2, 0) }, collector, BroadPhaseLayerFilter(), ObjectLayerFilter());
  90. CHECK(collector.mHits.empty());
  91. broadphase.CastRay({ Vec3(2, 2, 0), Vec3(0, -2, 0) }, collector, BroadPhaseLayerFilter(), ObjectLayerFilter());
  92. CHECK(collector.mHits.empty());
  93. broadphase.CastRay({ Vec3(4, 2, 0), Vec3(0, -2, 0) }, collector, BroadPhaseLayerFilter(), ObjectLayerFilter());
  94. CHECK(collector.mHits.size() == 1);
  95. CHECK(collector.mHits[0].mBodyID == id);
  96. CHECK_APPROX_EQUAL(collector.mHits[0].mFraction, 0.5f);
  97. collector.Reset();
  98. }
  99. }