main.cpp 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. #include <stdio.h>
  2. #include <stdint.h>
  3. #include <stdlib.h>
  4. #include "JoltC/JoltC.h"
  5. #ifdef _MSC_VER
  6. #define unreachable() __assume(0)
  7. #else
  8. #define unreachable() __builtin_unreachable()
  9. #endif
  10. typedef enum Hello_ObjectLayers {
  11. HELLO_OL_NON_MOVING,
  12. HELLO_OL_MOVING,
  13. HELLO_OL_COUNT,
  14. } Hello_ObjectLayers;
  15. typedef enum Hello_BroadPhaseLayers {
  16. HELLO_BPL_NON_MOVING,
  17. HELLO_BPL_MOVING,
  18. HELLO_BPL_COUNT,
  19. } Hello_BroadPhaseLayers;
  20. unsigned int Hello_BPL_GetNumBroadPhaseLayers(const void *self) {
  21. return HELLO_BPL_COUNT;
  22. }
  23. JPC_BroadPhaseLayer Hello_BPL_GetBroadPhaseLayer(const void *self, JPC_ObjectLayer inLayer) {
  24. switch (inLayer) {
  25. case HELLO_OL_NON_MOVING:
  26. return HELLO_BPL_NON_MOVING;
  27. case HELLO_OL_MOVING:
  28. return HELLO_BPL_MOVING;
  29. default:
  30. unreachable();
  31. }
  32. }
  33. static JPC_BroadPhaseLayerInterfaceFns Hello_BPL = {
  34. .GetNumBroadPhaseLayers = Hello_BPL_GetNumBroadPhaseLayers,
  35. .GetBroadPhaseLayer = Hello_BPL_GetBroadPhaseLayer,
  36. };
  37. bool Hello_OVB_ShouldCollide(const void *self, JPC_ObjectLayer inLayer1, JPC_BroadPhaseLayer inLayer2) {
  38. switch (inLayer1) {
  39. case HELLO_OL_NON_MOVING:
  40. return inLayer2 == HELLO_BPL_MOVING;
  41. case HELLO_OL_MOVING:
  42. return true;
  43. default:
  44. unreachable();
  45. }
  46. }
  47. static JPC_ObjectVsBroadPhaseLayerFilterFns Hello_OVB = {
  48. .ShouldCollide = Hello_OVB_ShouldCollide,
  49. };
  50. bool Hello_OVO_ShouldCollide(const void *self, JPC_ObjectLayer inLayer1, JPC_ObjectLayer inLayer2) {
  51. switch (inLayer1)
  52. {
  53. case HELLO_OL_NON_MOVING:
  54. return inLayer2 == HELLO_OL_MOVING; // Non moving only collides with moving
  55. case HELLO_OL_MOVING:
  56. return true; // Moving collides with everything
  57. default:
  58. unreachable();
  59. }
  60. }
  61. static JPC_ObjectLayerPairFilterFns Hello_OVO = {
  62. .ShouldCollide = Hello_OVO_ShouldCollide,
  63. };
  64. int main() {
  65. JPC_RegisterDefaultAllocator();
  66. JPC_FactoryInit();
  67. JPC_RegisterTypes();
  68. JPC_TempAllocatorImpl* temp_allocator = JPC_TempAllocatorImpl_new(10 * 1024 * 1024);
  69. JPC_JobSystemThreadPool* job_system = JPC_JobSystemThreadPool_new2(JPC_MAX_PHYSICS_JOBS, JPC_MAX_PHYSICS_BARRIERS);
  70. JPC_BroadPhaseLayerInterface* broad_phase_layer_interface = JPC_BroadPhaseLayerInterface_new(nullptr, Hello_BPL);
  71. JPC_ObjectVsBroadPhaseLayerFilter* object_vs_broad_phase_layer_filter = JPC_ObjectVsBroadPhaseLayerFilter_new(nullptr, Hello_OVB);
  72. JPC_ObjectLayerPairFilter* object_vs_object_layer_filter = JPC_ObjectLayerPairFilter_new(nullptr, Hello_OVO);
  73. const unsigned int cMaxBodies = 1024;
  74. const unsigned int cNumBodyMutexes = 0;
  75. const unsigned int cMaxBodyPairs = 1024;
  76. const unsigned int cMaxContactConstraints = 1024;
  77. JPC_PhysicsSystem* physics_system = JPC_PhysicsSystem_new();
  78. JPC_PhysicsSystem_Init(
  79. physics_system,
  80. cMaxBodies,
  81. cNumBodyMutexes,
  82. cMaxBodyPairs,
  83. cMaxContactConstraints,
  84. broad_phase_layer_interface,
  85. object_vs_broad_phase_layer_filter,
  86. object_vs_object_layer_filter);
  87. // TODO: register body activation listener
  88. // TODO: register contact listener
  89. JPC_BodyInterface* body_interface = JPC_PhysicsSystem_GetBodyInterface(physics_system);
  90. JPC_BoxShapeSettings* floor_shape_settings = JPC_BoxShapeSettings_new(JPC_Vec3{100.0f, 1.0f, 100.0f});
  91. JPC_ConvexShapeSettings_SetDensity((JPC_ConvexShapeSettings*)floor_shape_settings, 1000.0f);
  92. JPC_Shape* floor_shape;
  93. JPC_String* err;
  94. if (!JPC_ShapeSettings_Create((JPC_ShapeSettings*)floor_shape_settings, &floor_shape, &err)) {
  95. printf("fatal error: %s\n", JPC_String_c_str(err));
  96. // the world is ending, but I guess we can still free memory
  97. JPC_String_delete(err);
  98. exit(1);
  99. }
  100. JPC_BodyCreationSettings floor_settings;
  101. JPC_BodyCreationSettings_default(&floor_settings);
  102. floor_settings.Position = JPC_RVec3{0.0, -1.0, 0.0};
  103. floor_settings.MotionType = JPC_MOTION_TYPE_STATIC;
  104. floor_settings.ObjectLayer = HELLO_OL_NON_MOVING;
  105. floor_settings.Shape = floor_shape;
  106. JPC_Body* floor = JPC_BodyInterface_CreateBody(body_interface, &floor_settings);
  107. JPC_BodyInterface_AddBody(body_interface, JPC_Body_GetID(floor), JPC_ACTIVATION_DONT_ACTIVATE);
  108. JPC_SphereShapeSettings* sphere_shape_settings = JPC_SphereShapeSettings_new(0.5);
  109. JPC_Shape* sphere_shape;
  110. if (!JPC_ShapeSettings_Create((JPC_ShapeSettings*)sphere_shape_settings, &sphere_shape, &err)) {
  111. printf("fatal error: %s\n", JPC_String_c_str(err));
  112. // the world is ending, but I guess we can still free memory
  113. JPC_String_delete(err);
  114. exit(1);
  115. }
  116. JPC_BodyCreationSettings sphere_settings;
  117. JPC_BodyCreationSettings_default(&sphere_settings);
  118. sphere_settings.Position = JPC_RVec3{0.0, 2.0, 0.0};
  119. sphere_settings.MotionType = JPC_MOTION_TYPE_DYNAMIC;
  120. sphere_settings.ObjectLayer = HELLO_OL_MOVING;
  121. sphere_settings.Shape = sphere_shape;
  122. JPC_Body* sphere = JPC_BodyInterface_CreateBody(body_interface, &sphere_settings);
  123. JPC_BodyID sphere_id = JPC_Body_GetID(sphere);
  124. JPC_BodyInterface_AddBody(body_interface, sphere_id, JPC_ACTIVATION_ACTIVATE);
  125. JPC_BodyInterface_SetLinearVelocity(body_interface, sphere_id, JPC_Vec3{0.0, -5.0, 0.0});
  126. // TODO: PhysicsSystem::OptimizeBroadPhase
  127. const float cDeltaTime = 1.0f / 60.0f;
  128. const int cCollisionSteps = 1;
  129. // TODO: Update loop
  130. int step = 0;
  131. while (JPC_BodyInterface_IsActive(body_interface, sphere_id)) {
  132. ++step;
  133. JPC_RVec3 position = JPC_BodyInterface_GetCenterOfMassPosition(body_interface, sphere_id);
  134. JPC_Vec3 velocity = JPC_BodyInterface_GetLinearVelocity(body_interface, sphere_id);
  135. printf("Step %d: Position = (%f, %f, %f), Velocity = (%f, %f, %f)\n", step, position.x, position.y, position.z, velocity.x, velocity.y, velocity.z);
  136. JPC_PhysicsSystem_Update(physics_system, cDeltaTime, cCollisionSteps, temp_allocator, job_system);
  137. }
  138. // TODO: RemoveBody and DestroyBody
  139. JPC_BodyInterface_RemoveBody(body_interface, sphere_id);
  140. JPC_BodyInterface_DestroyBody(body_interface, sphere_id);
  141. JPC_BodyInterface_RemoveBody(body_interface, JPC_Body_GetID(floor));
  142. JPC_BodyInterface_DestroyBody(body_interface, JPC_Body_GetID(floor));
  143. JPC_PhysicsSystem_delete(physics_system);
  144. JPC_BroadPhaseLayerInterface_delete(broad_phase_layer_interface);
  145. JPC_ObjectVsBroadPhaseLayerFilter_delete(object_vs_broad_phase_layer_filter);
  146. JPC_ObjectLayerPairFilter_delete(object_vs_object_layer_filter);
  147. JPC_JobSystemThreadPool_delete(job_system);
  148. JPC_TempAllocatorImpl_delete(temp_allocator);
  149. JPC_UnregisterTypes();
  150. JPC_FactoryDelete();
  151. printf("Hello, world!\n");
  152. }