test_physics_system.cpp 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465
  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. #include <cstring>
  6. namespace BroadPhaseLayers {
  7. static constexpr JPH_BroadPhaseLayer NON_MOVING = 0;
  8. static constexpr JPH_BroadPhaseLayer MOVING = 1;
  9. static constexpr uint32_t NUM_LAYERS = 2;
  10. }
  11. namespace ObjectLayers {
  12. static constexpr JPH_ObjectLayer NON_MOVING = 0;
  13. static constexpr JPH_ObjectLayer MOVING = 1;
  14. static constexpr uint32_t NUM_LAYERS = 2;
  15. }
  16. class PhysicsSystemTest : public ::testing::Test {
  17. protected:
  18. JPH_JobSystem* jobSystem = nullptr;
  19. JPH_BroadPhaseLayerInterface* broadPhaseLayerInterface = nullptr;
  20. JPH_ObjectVsBroadPhaseLayerFilter* objectVsBroadPhaseLayerFilter = nullptr;
  21. JPH_ObjectLayerPairFilter* objectLayerPairFilter = nullptr;
  22. JPH_PhysicsSystem* physicsSystem = nullptr;
  23. void SetUp() override {
  24. ASSERT_TRUE(JPH_Init());
  25. jobSystem = JPH_JobSystemThreadPool_Create(nullptr);
  26. ASSERT_NE(jobSystem, nullptr);
  27. broadPhaseLayerInterface = JPH_BroadPhaseLayerInterfaceTable_Create(ObjectLayers::NUM_LAYERS, BroadPhaseLayers::NUM_LAYERS);
  28. JPH_BroadPhaseLayerInterfaceTable_MapObjectToBroadPhaseLayer(broadPhaseLayerInterface, ObjectLayers::NON_MOVING, BroadPhaseLayers::NON_MOVING);
  29. JPH_BroadPhaseLayerInterfaceTable_MapObjectToBroadPhaseLayer(broadPhaseLayerInterface, ObjectLayers::MOVING, BroadPhaseLayers::MOVING);
  30. ASSERT_NE(broadPhaseLayerInterface, nullptr);
  31. objectLayerPairFilter = JPH_ObjectLayerPairFilterTable_Create(ObjectLayers::NUM_LAYERS);
  32. JPH_ObjectLayerPairFilterTable_EnableCollision(objectLayerPairFilter, ObjectLayers::NON_MOVING, ObjectLayers::MOVING);
  33. JPH_ObjectLayerPairFilterTable_EnableCollision(objectLayerPairFilter, ObjectLayers::MOVING, ObjectLayers::MOVING);
  34. ASSERT_NE(objectLayerPairFilter, nullptr);
  35. objectVsBroadPhaseLayerFilter = JPH_ObjectVsBroadPhaseLayerFilterTable_Create(
  36. broadPhaseLayerInterface, BroadPhaseLayers::NUM_LAYERS,
  37. objectLayerPairFilter, ObjectLayers::NUM_LAYERS);
  38. ASSERT_NE(objectVsBroadPhaseLayerFilter, nullptr);
  39. JPH_PhysicsSystemSettings settings = {};
  40. settings.maxBodies = 1024;
  41. settings.numBodyMutexes = 0;
  42. settings.maxBodyPairs = 1024;
  43. settings.maxContactConstraints = 1024;
  44. settings.broadPhaseLayerInterface = broadPhaseLayerInterface;
  45. settings.objectVsBroadPhaseLayerFilter = objectVsBroadPhaseLayerFilter;
  46. settings.objectLayerPairFilter = objectLayerPairFilter;
  47. physicsSystem = JPH_PhysicsSystem_Create(&settings);
  48. ASSERT_NE(physicsSystem, nullptr);
  49. }
  50. void TearDown() override {
  51. if (physicsSystem) JPH_PhysicsSystem_Destroy(physicsSystem);
  52. if (jobSystem) JPH_JobSystem_Destroy(jobSystem);
  53. JPH_Shutdown();
  54. }
  55. };
  56. TEST_F(PhysicsSystemTest, Create_ValidSettings) {
  57. EXPECT_NE(physicsSystem, nullptr);
  58. }
  59. TEST_F(PhysicsSystemTest, GetBodyInterface) {
  60. JPH_BodyInterface* bodyInterface = JPH_PhysicsSystem_GetBodyInterface(physicsSystem);
  61. EXPECT_NE(bodyInterface, nullptr);
  62. }
  63. TEST_F(PhysicsSystemTest, GetBodyInterfaceNoLock) {
  64. JPH_BodyInterface* bodyInterface = JPH_PhysicsSystem_GetBodyInterfaceNoLock(physicsSystem);
  65. EXPECT_NE(bodyInterface, nullptr);
  66. }
  67. TEST_F(PhysicsSystemTest, SetGravity) {
  68. JPH_Vec3 gravity = {0.0f, -10.0f, 0.0f};
  69. JPH_PhysicsSystem_SetGravity(physicsSystem, &gravity);
  70. JPH_Vec3 result;
  71. JPH_PhysicsSystem_GetGravity(physicsSystem, &result);
  72. EXPECT_FLOAT_EQ(result.x, 0.0f);
  73. EXPECT_FLOAT_EQ(result.y, -10.0f);
  74. EXPECT_FLOAT_EQ(result.z, 0.0f);
  75. }
  76. TEST_F(PhysicsSystemTest, GetNumBodies_Initial) {
  77. uint32_t numBodies = JPH_PhysicsSystem_GetNumBodies(physicsSystem);
  78. EXPECT_EQ(numBodies, 0u);
  79. }
  80. TEST_F(PhysicsSystemTest, GetNumActiveBodies_Initial) {
  81. uint32_t numActiveBodies = JPH_PhysicsSystem_GetNumActiveBodies(physicsSystem, JPH_BodyType_Rigid);
  82. EXPECT_EQ(numActiveBodies, 0u);
  83. }
  84. TEST_F(PhysicsSystemTest, GetMaxBodies) {
  85. uint32_t maxBodies = JPH_PhysicsSystem_GetMaxBodies(physicsSystem);
  86. EXPECT_EQ(maxBodies, 1024u);
  87. }
  88. TEST_F(PhysicsSystemTest, CreateBody_Sphere) {
  89. JPH_BodyInterface* bodyInterface = JPH_PhysicsSystem_GetBodyInterface(physicsSystem);
  90. ASSERT_NE(bodyInterface, nullptr);
  91. JPH_SphereShape* shape = JPH_SphereShape_Create(1.0f);
  92. ASSERT_NE(shape, nullptr);
  93. JPH_Vec3 position = {0.0f, 10.0f, 0.0f};
  94. JPH_Quat rotation = {0.0f, 0.0f, 0.0f, 1.0f};
  95. JPH_BodyCreationSettings* bodySettings = JPH_BodyCreationSettings_Create3(
  96. (const JPH_Shape*)shape, &position, &rotation,
  97. JPH_MotionType_Dynamic, ObjectLayers::MOVING);
  98. ASSERT_NE(bodySettings, nullptr);
  99. JPH_Body* body = JPH_BodyInterface_CreateBody(bodyInterface, bodySettings);
  100. ASSERT_NE(body, nullptr);
  101. JPH_BodyID bodyId = JPH_Body_GetID(body);
  102. EXPECT_NE(bodyId, 0xFFFFFFFF);
  103. uint32_t numBodies = JPH_PhysicsSystem_GetNumBodies(physicsSystem);
  104. EXPECT_EQ(numBodies, 1u);
  105. JPH_BodyInterface_AddBody(bodyInterface, bodyId, JPH_Activation_Activate);
  106. uint32_t numActiveBodies = JPH_PhysicsSystem_GetNumActiveBodies(physicsSystem, JPH_BodyType_Rigid);
  107. EXPECT_EQ(numActiveBodies, 1u);
  108. JPH_BodyInterface_RemoveBody(bodyInterface, bodyId);
  109. JPH_BodyInterface_DestroyBody(bodyInterface, bodyId);
  110. JPH_BodyCreationSettings_Destroy(bodySettings);
  111. JPH_Shape_Destroy((JPH_Shape*)shape);
  112. }
  113. TEST_F(PhysicsSystemTest, CreateBody_Box) {
  114. JPH_BodyInterface* bodyInterface = JPH_PhysicsSystem_GetBodyInterface(physicsSystem);
  115. ASSERT_NE(bodyInterface, nullptr);
  116. JPH_Vec3 halfExtent = {1.0f, 1.0f, 1.0f};
  117. JPH_BoxShape* shape = JPH_BoxShape_Create(&halfExtent, JPH_DEFAULT_CONVEX_RADIUS);
  118. ASSERT_NE(shape, nullptr);
  119. JPH_Vec3 position = {0.0f, 0.0f, 0.0f};
  120. JPH_Quat rotation = {0.0f, 0.0f, 0.0f, 1.0f};
  121. JPH_BodyCreationSettings* bodySettings = JPH_BodyCreationSettings_Create3(
  122. (const JPH_Shape*)shape, &position, &rotation,
  123. JPH_MotionType_Static, ObjectLayers::NON_MOVING);
  124. JPH_Body* body = JPH_BodyInterface_CreateBody(bodyInterface, bodySettings);
  125. ASSERT_NE(body, nullptr);
  126. JPH_BodyID bodyId = JPH_Body_GetID(body);
  127. JPH_BodyInterface_AddBody(bodyInterface, bodyId, JPH_Activation_DontActivate);
  128. uint32_t numActiveBodies = JPH_PhysicsSystem_GetNumActiveBodies(physicsSystem, JPH_BodyType_Rigid);
  129. EXPECT_EQ(numActiveBodies, 0u);
  130. JPH_BodyInterface_RemoveBody(bodyInterface, bodyId);
  131. JPH_BodyInterface_DestroyBody(bodyInterface, bodyId);
  132. JPH_BodyCreationSettings_Destroy(bodySettings);
  133. JPH_Shape_Destroy((JPH_Shape*)shape);
  134. }
  135. TEST_F(PhysicsSystemTest, Body_GetPosition) {
  136. JPH_BodyInterface* bodyInterface = JPH_PhysicsSystem_GetBodyInterface(physicsSystem);
  137. JPH_SphereShape* shape = JPH_SphereShape_Create(1.0f);
  138. JPH_Vec3 position = {1.0f, 2.0f, 3.0f};
  139. JPH_Quat rotation = {0.0f, 0.0f, 0.0f, 1.0f};
  140. JPH_BodyCreationSettings* bodySettings = JPH_BodyCreationSettings_Create3(
  141. (const JPH_Shape*)shape, &position, &rotation,
  142. JPH_MotionType_Dynamic, ObjectLayers::MOVING);
  143. JPH_Body* body = JPH_BodyInterface_CreateBody(bodyInterface, bodySettings);
  144. JPH_BodyID bodyId = JPH_Body_GetID(body);
  145. JPH_BodyInterface_AddBody(bodyInterface, bodyId, JPH_Activation_Activate);
  146. JPH_RVec3 resultPos;
  147. JPH_BodyInterface_GetPosition(bodyInterface, bodyId, &resultPos);
  148. EXPECT_FLOAT_EQ(resultPos.x, 1.0f);
  149. EXPECT_FLOAT_EQ(resultPos.y, 2.0f);
  150. EXPECT_FLOAT_EQ(resultPos.z, 3.0f);
  151. JPH_BodyInterface_RemoveBody(bodyInterface, bodyId);
  152. JPH_BodyInterface_DestroyBody(bodyInterface, bodyId);
  153. JPH_BodyCreationSettings_Destroy(bodySettings);
  154. JPH_Shape_Destroy((JPH_Shape*)shape);
  155. }
  156. TEST_F(PhysicsSystemTest, Body_SetPosition) {
  157. JPH_BodyInterface* bodyInterface = JPH_PhysicsSystem_GetBodyInterface(physicsSystem);
  158. JPH_SphereShape* shape = JPH_SphereShape_Create(1.0f);
  159. JPH_Vec3 position = {0.0f, 0.0f, 0.0f};
  160. JPH_Quat rotation = {0.0f, 0.0f, 0.0f, 1.0f};
  161. JPH_BodyCreationSettings* bodySettings = JPH_BodyCreationSettings_Create3(
  162. (const JPH_Shape*)shape, &position, &rotation,
  163. JPH_MotionType_Dynamic, ObjectLayers::MOVING);
  164. JPH_Body* body = JPH_BodyInterface_CreateBody(bodyInterface, bodySettings);
  165. JPH_BodyID bodyId = JPH_Body_GetID(body);
  166. JPH_BodyInterface_AddBody(bodyInterface, bodyId, JPH_Activation_Activate);
  167. JPH_RVec3 newPos = {5.0f, 10.0f, 15.0f};
  168. JPH_BodyInterface_SetPosition(bodyInterface, bodyId, &newPos, JPH_Activation_Activate);
  169. JPH_RVec3 resultPos;
  170. JPH_BodyInterface_GetPosition(bodyInterface, bodyId, &resultPos);
  171. EXPECT_FLOAT_EQ(resultPos.x, 5.0f);
  172. EXPECT_FLOAT_EQ(resultPos.y, 10.0f);
  173. EXPECT_FLOAT_EQ(resultPos.z, 15.0f);
  174. JPH_BodyInterface_RemoveBody(bodyInterface, bodyId);
  175. JPH_BodyInterface_DestroyBody(bodyInterface, bodyId);
  176. JPH_BodyCreationSettings_Destroy(bodySettings);
  177. JPH_Shape_Destroy((JPH_Shape*)shape);
  178. }
  179. TEST_F(PhysicsSystemTest, Body_SetLinearVelocity) {
  180. JPH_BodyInterface* bodyInterface = JPH_PhysicsSystem_GetBodyInterface(physicsSystem);
  181. JPH_SphereShape* shape = JPH_SphereShape_Create(1.0f);
  182. JPH_Vec3 position = {0.0f, 10.0f, 0.0f};
  183. JPH_Quat rotation = {0.0f, 0.0f, 0.0f, 1.0f};
  184. JPH_BodyCreationSettings* bodySettings = JPH_BodyCreationSettings_Create3(
  185. (const JPH_Shape*)shape, &position, &rotation,
  186. JPH_MotionType_Dynamic, ObjectLayers::MOVING);
  187. JPH_Body* body = JPH_BodyInterface_CreateBody(bodyInterface, bodySettings);
  188. JPH_BodyID bodyId = JPH_Body_GetID(body);
  189. JPH_BodyInterface_AddBody(bodyInterface, bodyId, JPH_Activation_Activate);
  190. JPH_Vec3 velocity = {1.0f, 2.0f, 3.0f};
  191. JPH_BodyInterface_SetLinearVelocity(bodyInterface, bodyId, &velocity);
  192. JPH_Vec3 resultVel;
  193. JPH_BodyInterface_GetLinearVelocity(bodyInterface, bodyId, &resultVel);
  194. EXPECT_FLOAT_EQ(resultVel.x, 1.0f);
  195. EXPECT_FLOAT_EQ(resultVel.y, 2.0f);
  196. EXPECT_FLOAT_EQ(resultVel.z, 3.0f);
  197. JPH_BodyInterface_RemoveBody(bodyInterface, bodyId);
  198. JPH_BodyInterface_DestroyBody(bodyInterface, bodyId);
  199. JPH_BodyCreationSettings_Destroy(bodySettings);
  200. JPH_Shape_Destroy((JPH_Shape*)shape);
  201. }
  202. TEST_F(PhysicsSystemTest, Body_AddImpulse) {
  203. JPH_BodyInterface* bodyInterface = JPH_PhysicsSystem_GetBodyInterface(physicsSystem);
  204. JPH_SphereShape* shape = JPH_SphereShape_Create(1.0f);
  205. JPH_Vec3 position = {0.0f, 10.0f, 0.0f};
  206. JPH_Quat rotation = {0.0f, 0.0f, 0.0f, 1.0f};
  207. JPH_BodyCreationSettings* bodySettings = JPH_BodyCreationSettings_Create3(
  208. (const JPH_Shape*)shape, &position, &rotation,
  209. JPH_MotionType_Dynamic, ObjectLayers::MOVING);
  210. JPH_Body* body = JPH_BodyInterface_CreateBody(bodyInterface, bodySettings);
  211. JPH_BodyID bodyId = JPH_Body_GetID(body);
  212. JPH_BodyInterface_AddBody(bodyInterface, bodyId, JPH_Activation_Activate);
  213. JPH_Vec3 initialVel;
  214. JPH_BodyInterface_GetLinearVelocity(bodyInterface, bodyId, &initialVel);
  215. EXPECT_FLOAT_EQ(initialVel.x, 0.0f);
  216. JPH_Vec3 impulse = {10.0f, 0.0f, 0.0f};
  217. JPH_BodyInterface_AddImpulse(bodyInterface, bodyId, &impulse);
  218. JPH_Vec3 resultVel;
  219. JPH_BodyInterface_GetLinearVelocity(bodyInterface, bodyId, &resultVel);
  220. EXPECT_GT(resultVel.x, 0.0f);
  221. JPH_BodyInterface_RemoveBody(bodyInterface, bodyId);
  222. JPH_BodyInterface_DestroyBody(bodyInterface, bodyId);
  223. JPH_BodyCreationSettings_Destroy(bodySettings);
  224. JPH_Shape_Destroy((JPH_Shape*)shape);
  225. }
  226. TEST_F(PhysicsSystemTest, Body_GetMotionType) {
  227. JPH_BodyInterface* bodyInterface = JPH_PhysicsSystem_GetBodyInterface(physicsSystem);
  228. JPH_SphereShape* shape = JPH_SphereShape_Create(1.0f);
  229. JPH_Vec3 position = {0.0f, 10.0f, 0.0f};
  230. JPH_Quat rotation = {0.0f, 0.0f, 0.0f, 1.0f};
  231. JPH_BodyCreationSettings* bodySettings = JPH_BodyCreationSettings_Create3(
  232. (const JPH_Shape*)shape, &position, &rotation,
  233. JPH_MotionType_Dynamic, ObjectLayers::MOVING);
  234. JPH_Body* body = JPH_BodyInterface_CreateBody(bodyInterface, bodySettings);
  235. JPH_BodyID bodyId = JPH_Body_GetID(body);
  236. JPH_BodyInterface_AddBody(bodyInterface, bodyId, JPH_Activation_Activate);
  237. JPH_MotionType motionType = JPH_BodyInterface_GetMotionType(bodyInterface, bodyId);
  238. EXPECT_EQ(motionType, JPH_MotionType_Dynamic);
  239. JPH_BodyInterface_RemoveBody(bodyInterface, bodyId);
  240. JPH_BodyInterface_DestroyBody(bodyInterface, bodyId);
  241. JPH_BodyCreationSettings_Destroy(bodySettings);
  242. JPH_Shape_Destroy((JPH_Shape*)shape);
  243. }
  244. TEST_F(PhysicsSystemTest, Body_ActivateDeactivate) {
  245. JPH_BodyInterface* bodyInterface = JPH_PhysicsSystem_GetBodyInterface(physicsSystem);
  246. JPH_SphereShape* shape = JPH_SphereShape_Create(1.0f);
  247. JPH_Vec3 position = {0.0f, 10.0f, 0.0f};
  248. JPH_Quat rotation = {0.0f, 0.0f, 0.0f, 1.0f};
  249. JPH_BodyCreationSettings* bodySettings = JPH_BodyCreationSettings_Create3(
  250. (const JPH_Shape*)shape, &position, &rotation,
  251. JPH_MotionType_Dynamic, ObjectLayers::MOVING);
  252. JPH_Body* body = JPH_BodyInterface_CreateBody(bodyInterface, bodySettings);
  253. JPH_BodyID bodyId = JPH_Body_GetID(body);
  254. JPH_BodyInterface_AddBody(bodyInterface, bodyId, JPH_Activation_DontActivate);
  255. EXPECT_FALSE(JPH_BodyInterface_IsActive(bodyInterface, bodyId));
  256. JPH_BodyInterface_ActivateBody(bodyInterface, bodyId);
  257. EXPECT_TRUE(JPH_BodyInterface_IsActive(bodyInterface, bodyId));
  258. JPH_BodyInterface_DeactivateBody(bodyInterface, bodyId);
  259. EXPECT_FALSE(JPH_BodyInterface_IsActive(bodyInterface, bodyId));
  260. JPH_BodyInterface_RemoveBody(bodyInterface, bodyId);
  261. JPH_BodyInterface_DestroyBody(bodyInterface, bodyId);
  262. JPH_BodyCreationSettings_Destroy(bodySettings);
  263. JPH_Shape_Destroy((JPH_Shape*)shape);
  264. }
  265. TEST_F(PhysicsSystemTest, Body_Restitution) {
  266. JPH_BodyInterface* bodyInterface = JPH_PhysicsSystem_GetBodyInterface(physicsSystem);
  267. JPH_SphereShape* shape = JPH_SphereShape_Create(1.0f);
  268. JPH_Vec3 position = {0.0f, 10.0f, 0.0f};
  269. JPH_Quat rotation = {0.0f, 0.0f, 0.0f, 1.0f};
  270. JPH_BodyCreationSettings* bodySettings = JPH_BodyCreationSettings_Create3(
  271. (const JPH_Shape*)shape, &position, &rotation,
  272. JPH_MotionType_Dynamic, ObjectLayers::MOVING);
  273. JPH_Body* body = JPH_BodyInterface_CreateBody(bodyInterface, bodySettings);
  274. JPH_BodyID bodyId = JPH_Body_GetID(body);
  275. JPH_BodyInterface_AddBody(bodyInterface, bodyId, JPH_Activation_Activate);
  276. JPH_BodyInterface_SetRestitution(bodyInterface, bodyId, 0.8f);
  277. float restitution = JPH_BodyInterface_GetRestitution(bodyInterface, bodyId);
  278. EXPECT_FLOAT_EQ(restitution, 0.8f);
  279. JPH_BodyInterface_RemoveBody(bodyInterface, bodyId);
  280. JPH_BodyInterface_DestroyBody(bodyInterface, bodyId);
  281. JPH_BodyCreationSettings_Destroy(bodySettings);
  282. JPH_Shape_Destroy((JPH_Shape*)shape);
  283. }
  284. TEST_F(PhysicsSystemTest, Body_Friction) {
  285. JPH_BodyInterface* bodyInterface = JPH_PhysicsSystem_GetBodyInterface(physicsSystem);
  286. JPH_SphereShape* shape = JPH_SphereShape_Create(1.0f);
  287. JPH_Vec3 position = {0.0f, 10.0f, 0.0f};
  288. JPH_Quat rotation = {0.0f, 0.0f, 0.0f, 1.0f};
  289. JPH_BodyCreationSettings* bodySettings = JPH_BodyCreationSettings_Create3(
  290. (const JPH_Shape*)shape, &position, &rotation,
  291. JPH_MotionType_Dynamic, ObjectLayers::MOVING);
  292. JPH_Body* body = JPH_BodyInterface_CreateBody(bodyInterface, bodySettings);
  293. JPH_BodyID bodyId = JPH_Body_GetID(body);
  294. JPH_BodyInterface_AddBody(bodyInterface, bodyId, JPH_Activation_Activate);
  295. JPH_BodyInterface_SetFriction(bodyInterface, bodyId, 0.5f);
  296. float friction = JPH_BodyInterface_GetFriction(bodyInterface, bodyId);
  297. EXPECT_FLOAT_EQ(friction, 0.5f);
  298. JPH_BodyInterface_RemoveBody(bodyInterface, bodyId);
  299. JPH_BodyInterface_DestroyBody(bodyInterface, bodyId);
  300. JPH_BodyCreationSettings_Destroy(bodySettings);
  301. JPH_Shape_Destroy((JPH_Shape*)shape);
  302. }
  303. TEST_F(PhysicsSystemTest, Update_FallingBody) {
  304. JPH_BodyInterface* bodyInterface = JPH_PhysicsSystem_GetBodyInterface(physicsSystem);
  305. JPH_SphereShape* shape = JPH_SphereShape_Create(1.0f);
  306. JPH_Vec3 position = {0.0f, 100.0f, 0.0f};
  307. JPH_Quat rotation = {0.0f, 0.0f, 0.0f, 1.0f};
  308. JPH_BodyCreationSettings* bodySettings = JPH_BodyCreationSettings_Create3(
  309. (const JPH_Shape*)shape, &position, &rotation,
  310. JPH_MotionType_Dynamic, ObjectLayers::MOVING);
  311. JPH_Body* body = JPH_BodyInterface_CreateBody(bodyInterface, bodySettings);
  312. JPH_BodyID bodyId = JPH_Body_GetID(body);
  313. JPH_BodyInterface_AddBody(bodyInterface, bodyId, JPH_Activation_Activate);
  314. JPH_Vec3 gravity = {0.0f, -10.0f, 0.0f};
  315. JPH_PhysicsSystem_SetGravity(physicsSystem, &gravity);
  316. JPH_RVec3 initialPos;
  317. JPH_BodyInterface_GetPosition(bodyInterface, bodyId, &initialPos);
  318. JPH_PhysicsSystem_OptimizeBroadPhase(physicsSystem);
  319. JPH_PhysicsUpdateError error = JPH_PhysicsSystem_Update(physicsSystem, 1.0f / 60.0f, 1, jobSystem);
  320. EXPECT_EQ(error, JPH_PhysicsUpdateError_None);
  321. JPH_RVec3 newPos;
  322. JPH_BodyInterface_GetPosition(bodyInterface, bodyId, &newPos);
  323. EXPECT_LT(newPos.y, initialPos.y);
  324. JPH_BodyInterface_RemoveBody(bodyInterface, bodyId);
  325. JPH_BodyInterface_DestroyBody(bodyInterface, bodyId);
  326. JPH_BodyCreationSettings_Destroy(bodySettings);
  327. JPH_Shape_Destroy((JPH_Shape*)shape);
  328. }
  329. TEST_F(PhysicsSystemTest, MultipleBodies) {
  330. JPH_BodyInterface* bodyInterface = JPH_PhysicsSystem_GetBodyInterface(physicsSystem);
  331. const int NUM_BODIES = 10;
  332. JPH_BodyID bodyIds[NUM_BODIES];
  333. for (int i = 0; i < NUM_BODIES; i++) {
  334. JPH_SphereShape* shape = JPH_SphereShape_Create(1.0f);
  335. JPH_Vec3 position = {(float)i * 3.0f, 10.0f, 0.0f};
  336. JPH_Quat rotation = {0.0f, 0.0f, 0.0f, 1.0f};
  337. JPH_BodyCreationSettings* bodySettings = JPH_BodyCreationSettings_Create3(
  338. (const JPH_Shape*)shape, &position, &rotation,
  339. JPH_MotionType_Dynamic, ObjectLayers::MOVING);
  340. JPH_Body* body = JPH_BodyInterface_CreateBody(bodyInterface, bodySettings);
  341. bodyIds[i] = JPH_Body_GetID(body);
  342. JPH_BodyInterface_AddBody(bodyInterface, bodyIds[i], JPH_Activation_Activate);
  343. JPH_BodyCreationSettings_Destroy(bodySettings);
  344. JPH_Shape_Destroy((JPH_Shape*)shape);
  345. }
  346. uint32_t numBodies = JPH_PhysicsSystem_GetNumBodies(physicsSystem);
  347. EXPECT_EQ(numBodies, (uint32_t)NUM_BODIES);
  348. uint32_t numActiveBodies = JPH_PhysicsSystem_GetNumActiveBodies(physicsSystem, JPH_BodyType_Rigid);
  349. EXPECT_EQ(numActiveBodies, (uint32_t)NUM_BODIES);
  350. for (int i = 0; i < NUM_BODIES; i++) {
  351. JPH_BodyInterface_RemoveBody(bodyInterface, bodyIds[i]);
  352. JPH_BodyInterface_DestroyBody(bodyInterface, bodyIds[i]);
  353. }
  354. }