2
0

phys_jolt.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346
  1. #include "phys_jolt.h"
  2. #include <Jolt/Jolt.h>
  3. #include <Jolt/RegisterTypes.h>
  4. #include <Jolt/Core/Factory.h>
  5. #include <Jolt/Core/TempAllocator.h>
  6. #include <Jolt/Core/JobSystemThreadPool.h>
  7. #include <Jolt/Physics/PhysicsSettings.h>
  8. #include <Jolt/Physics/PhysicsSystem.h>
  9. #include <Jolt/Physics/Collision/Shape/BoxShape.h>
  10. #include <Jolt/Physics/Collision/Shape/SphereShape.h>
  11. #include <Jolt/Physics/Collision/Shape/MeshShape.h>
  12. #include <Jolt/Physics/Collision/Shape/ConvexHullShape.h>
  13. #include <Jolt/Physics/Collision/Shape/HeightFieldShape.h>
  14. #include <Jolt/Physics/Body/BodyCreationSettings.h>
  15. #include <Jolt/Physics/Body/MotionQuality.h>
  16. #include <kinc/math/vector.h>
  17. #include <kinc/math/quaternion.h>
  18. #include "iron_array.h"
  19. JPH_SUPPRESS_WARNINGS
  20. using namespace JPH;
  21. using namespace JPH::literals;
  22. PhysicsSystem *physics_system;
  23. TempAllocatorImpl *temp_allocator;
  24. JobSystemThreadPool *job_system;
  25. physics_pair_t ppair;
  26. static void TraceImpl(const char *inFMT, ...) {
  27. }
  28. namespace Layers {
  29. static constexpr ObjectLayer NON_MOVING = 0;
  30. static constexpr ObjectLayer MOVING = 1;
  31. static constexpr ObjectLayer NUM_LAYERS = 2;
  32. };
  33. class ObjectLayerPairFilterImpl : public ObjectLayerPairFilter {
  34. public:
  35. virtual bool ShouldCollide(ObjectLayer inObject1, ObjectLayer inObject2) const override {
  36. switch (inObject1) {
  37. case Layers::NON_MOVING:
  38. return inObject2 == Layers::MOVING;
  39. case Layers::MOVING:
  40. return true;
  41. default:
  42. return false;
  43. }
  44. }
  45. };
  46. namespace BroadPhaseLayers {
  47. static constexpr BroadPhaseLayer NON_MOVING(0);
  48. static constexpr BroadPhaseLayer MOVING(1);
  49. static constexpr uint NUM_LAYERS(2);
  50. };
  51. class BPLayerInterfaceImpl final : public BroadPhaseLayerInterface {
  52. public:
  53. BPLayerInterfaceImpl() {
  54. mObjectToBroadPhase[Layers::NON_MOVING] = BroadPhaseLayers::NON_MOVING;
  55. mObjectToBroadPhase[Layers::MOVING] = BroadPhaseLayers::MOVING;
  56. }
  57. virtual uint GetNumBroadPhaseLayers() const override {
  58. return BroadPhaseLayers::NUM_LAYERS;
  59. }
  60. virtual BroadPhaseLayer GetBroadPhaseLayer(ObjectLayer inLayer) const override {
  61. return mObjectToBroadPhase[inLayer];
  62. }
  63. #if defined(JPH_EXTERNAL_PROFILE) || defined(JPH_PROFILE_ENABLED)
  64. virtual const char *GetBroadPhaseLayerName(BroadPhaseLayer inLayer) const override {
  65. return "";
  66. }
  67. #endif
  68. BroadPhaseLayer mObjectToBroadPhase[Layers::NUM_LAYERS];
  69. };
  70. class ObjectVsBroadPhaseLayerFilterImpl : public ObjectVsBroadPhaseLayerFilter {
  71. public:
  72. virtual bool ShouldCollide(ObjectLayer inLayer1, BroadPhaseLayer inLayer2) const override {
  73. switch (inLayer1) {
  74. case Layers::NON_MOVING:
  75. return inLayer2 == BroadPhaseLayers::MOVING;
  76. case Layers::MOVING:
  77. return true;
  78. default:
  79. return false;
  80. }
  81. }
  82. };
  83. class MyContactListener : public ContactListener {
  84. public:
  85. virtual ValidateResult OnContactValidate(const Body &inBody1, const Body &inBody2, RVec3Arg inBaseOffset, const CollideShapeResult &inCollisionResult) override {
  86. return ValidateResult::AcceptAllContactsForThisBodyPair;
  87. }
  88. virtual void OnContactAdded(const Body &inBody1, const Body &inBody2, const ContactManifold &inManifold, ContactSettings &ioSettings) override {
  89. }
  90. virtual void OnContactPersisted(const Body &inBody1, const Body &inBody2, const ContactManifold &inManifold, ContactSettings &ioSettings) override {
  91. ppair.pos_a_x = inManifold.GetWorldSpaceContactPointOn1(0).GetX();
  92. ppair.pos_a_y = inManifold.GetWorldSpaceContactPointOn1(0).GetY();
  93. ppair.pos_a_z = inManifold.GetWorldSpaceContactPointOn1(0).GetZ();
  94. }
  95. virtual void OnContactRemoved(const SubShapeIDPair &inSubShapePair) override {
  96. ppair.pos_a_x = ppair.pos_a_y = ppair.pos_a_z = 0;
  97. }
  98. };
  99. typedef enum {
  100. physics_shape_BOX = 0,
  101. physics_shape_SPHERE = 1,
  102. physics_shape_HULL = 2,
  103. physics_shape_TERRAIN = 3,
  104. physics_shape_MESH = 4,
  105. } physics_shape_t;
  106. BPLayerInterfaceImpl broad_phase_layer_interface;
  107. ObjectVsBroadPhaseLayerFilterImpl object_vs_broadphase_layer_filter;
  108. ObjectLayerPairFilterImpl object_vs_object_layer_filter;
  109. void _jolt_world_create() {
  110. RegisterDefaultAllocator();
  111. Trace = TraceImpl;
  112. Factory::sInstance = new Factory();
  113. RegisterTypes();
  114. temp_allocator = new TempAllocatorImpl(10 * 1024 * 1024);
  115. // job_system = new JobSystemThreadPool(cMaxPhysicsJobs, cMaxPhysicsBarriers, thread::hardware_concurrency() - 1);
  116. job_system = new JobSystemThreadPool(cMaxPhysicsJobs, cMaxPhysicsBarriers, 0);
  117. const uint cMaxBodies = 1024;
  118. const uint cNumBodyMutexes = 0;
  119. const uint cMaxBodyPairs = 1024;
  120. const uint cMaxContactConstraints = 1024;
  121. physics_system = new PhysicsSystem();
  122. physics_system->Init(cMaxBodies, cNumBodyMutexes, cMaxBodyPairs, cMaxContactConstraints,
  123. broad_phase_layer_interface, object_vs_broadphase_layer_filter, object_vs_object_layer_filter);
  124. MyContactListener *contact_listener = new MyContactListener();
  125. physics_system->SetContactListener(contact_listener);
  126. physics_system->SetGravity(Vec3(0.0, 0.0, -9.81));
  127. }
  128. void _jolt_world_update() {
  129. #ifdef is_forge
  130. const int cCollisionSteps = 2;
  131. #else
  132. const int cCollisionSteps = 1;
  133. #endif
  134. const float cDeltaTime = 1.0f / 60.0f;
  135. physics_system->Update(cDeltaTime, cCollisionSteps, temp_allocator, job_system);
  136. }
  137. void _jolt_world_destroy() {
  138. // body_interface.RemoveBody(sphere_id);
  139. // body_interface.DestroyBody(sphere_id);
  140. // body_interface.RemoveBody(floor->GetID());
  141. // body_interface.DestroyBody(floor->GetID());
  142. UnregisterTypes();
  143. delete Factory::sInstance;
  144. Factory::sInstance = nullptr;
  145. }
  146. void *_jolt_body_create(int shape, float mass, float dimx, float dimy, float dimz, float x, float y, float z, void *f32a_triangles) {
  147. BodyInterface &body_interface = physics_system->GetBodyInterface();
  148. Body *body;
  149. ShapeSettings::ShapeResult result;
  150. // float convex_radius = 0.05f;
  151. float convex_radius = 0.0f;
  152. // if (convex_radius > 0.0) {
  153. // if (dimx <= 0.2) dimx = 0.21;
  154. // if (dimy <= 0.2) dimy = 0.21;
  155. // if (dimz <= 0.2) dimz = 0.21;
  156. // }
  157. if (shape == physics_shape_BOX) {
  158. BoxShapeSettings shape_settings(RVec3(dimx / 2.0, dimy / 2.0, dimz / 2.0), convex_radius);
  159. shape_settings.SetEmbedded();
  160. result = shape_settings.Create();
  161. }
  162. else if (shape == physics_shape_SPHERE) {
  163. SphereShapeSettings shape_settings(dimx / 2.0);
  164. shape_settings.SetEmbedded();
  165. result = shape_settings.Create();
  166. }
  167. else if (shape == physics_shape_HULL) {
  168. f32_array_t *f32a = (f32_array_t *)f32a_triangles;
  169. JPH::Array<JPH::Vec3> points;
  170. points.reserve(f32a->length / 3);
  171. for (int i = 0; i < f32a->length / 9; ++i) {
  172. Vec3 v1(f32a->buffer[i * 9 ], f32a->buffer[i * 9 + 1], f32a->buffer[i * 9 + 2]);
  173. Vec3 v2(f32a->buffer[i * 9 + 3], f32a->buffer[i * 9 + 4], f32a->buffer[i * 9 + 5]);
  174. Vec3 v3(f32a->buffer[i * 9 + 6], f32a->buffer[i * 9 + 7], f32a->buffer[i * 9 + 8]);
  175. points.push_back(v1);
  176. points.push_back(v2);
  177. points.push_back(v3);
  178. }
  179. ConvexHullShapeSettings shape_settings(points, convex_radius);
  180. shape_settings.SetEmbedded();
  181. result = shape_settings.Create();
  182. }
  183. else if (shape == physics_shape_TERRAIN) {
  184. f32_array_t *f32a = (f32_array_t *)f32a_triangles;
  185. // HeightFieldShapeSettings shape_settings();
  186. // shape_settings.SetEmbedded();
  187. // result = shape_settings.Create();
  188. }
  189. else {
  190. // Mesh
  191. f32_array_t *f32a = (f32_array_t *)f32a_triangles;
  192. TriangleList triangles;
  193. triangles.reserve(f32a->length / 9);
  194. for (int i = 0; i < f32a->length / 9; ++i) {
  195. Float3 v1(f32a->buffer[i * 9 ], f32a->buffer[i * 9 + 1], f32a->buffer[i * 9 + 2]);
  196. Float3 v2(f32a->buffer[i * 9 + 3], f32a->buffer[i * 9 + 4], f32a->buffer[i * 9 + 5]);
  197. Float3 v3(f32a->buffer[i * 9 + 6], f32a->buffer[i * 9 + 7], f32a->buffer[i * 9 + 8]);
  198. triangles.push_back(Triangle(v1, v2, v3));
  199. }
  200. MeshShapeSettings shape_settings(triangles);
  201. shape_settings.SetEmbedded();
  202. result = shape_settings.Create();
  203. }
  204. ShapeRefC shape_c = result.Get();
  205. BodyCreationSettings settings(shape_c, RVec3(x, y, z), Quat::sIdentity(), mass == 0 ? EMotionType::Static : EMotionType::Dynamic,
  206. mass == 0 ? Layers::NON_MOVING : Layers::MOVING);
  207. #ifdef is_forge
  208. settings.mAllowSleeping = false;
  209. #endif
  210. // if (ccd) {
  211. if (shape != physics_shape_MESH) {
  212. settings.mMotionQuality = EMotionQuality::LinearCast;
  213. MassProperties mass_prop;
  214. mass_prop.ScaleToMass(mass);
  215. settings.mMassPropertiesOverride = mass_prop;
  216. settings.mOverrideMassProperties = EOverrideMassProperties::CalculateInertia;
  217. }
  218. body = body_interface.CreateBody(settings);
  219. body_interface.AddBody(body->GetID(), EActivation::Activate);
  220. return body;
  221. }
  222. void _jolt_body_apply_impulse(void *b, float x, float y, float z) {
  223. BodyInterface &body_interface = physics_system->GetBodyInterface();
  224. Body *body = (Body *)b;
  225. body_interface.AddImpulse(body->GetID(), Vec3(x, y, z));
  226. }
  227. void _jolt_body_get_pos(void *b, void *p) {
  228. BodyInterface &body_interface = physics_system->GetBodyInterface();
  229. Body *body = (Body *)b;
  230. RVec3 position = body_interface.GetCenterOfMassPosition(body->GetID());
  231. kinc_vector4_t *v = (kinc_vector4_t *)p;
  232. v->x = position.GetX();
  233. v->y = position.GetY();
  234. v->z = position.GetZ();
  235. }
  236. void _jolt_body_get_rot(void *b, void *r) {
  237. BodyInterface &body_interface = physics_system->GetBodyInterface();
  238. Body *body = (Body *)b;
  239. Quat rotation = body_interface.GetRotation(body->GetID());
  240. kinc_quaternion_t *q = (kinc_quaternion_t *)r;
  241. q->x = rotation.GetX();
  242. q->y = rotation.GetY();
  243. q->z = rotation.GetZ();
  244. q->w = rotation.GetW();
  245. }
  246. void _jolt_body_sync_transform(void *b, vec4_t p, quat_t r) {
  247. BodyInterface &body_interface = physics_system->GetBodyInterface();
  248. Body *body = (Body *)b;
  249. body_interface.SetPositionAndRotation(body->GetID(), RVec3(p.x, p.y, p.z), Quat(r.x, r.y, r.z, r.w), EActivation::Activate);
  250. body_interface.SetLinearVelocity(body->GetID(), RVec3(0, 0, 0));
  251. body_interface.SetAngularVelocity(body->GetID(), RVec3(0, 0, 0));
  252. }
  253. void _jolt_body_remove(void *b) {
  254. BodyInterface &body_interface = physics_system->GetBodyInterface();
  255. Body *body = (Body *)b;
  256. body_interface.RemoveBody(body->GetID());
  257. }
  258. extern "C" {
  259. void jolt_world_create() {
  260. _jolt_world_create();
  261. }
  262. void jolt_world_update() {
  263. _jolt_world_update();
  264. }
  265. physics_pair_t *jolt_world_get_contact_pairs() {
  266. return &ppair;
  267. }
  268. void jolt_world_destroy() {
  269. _jolt_world_destroy();
  270. }
  271. void *jolt_body_create(int shape, float mass, float dimx, float dimy, float dimz, float x, float y, float z, void *f32a_triangles) {
  272. return _jolt_body_create(shape, mass, dimx, dimy, dimz, x, y, z, f32a_triangles);
  273. }
  274. void jolt_body_apply_impulse(void *body, float x, float y, float z) {
  275. _jolt_body_apply_impulse(body, x, y, z);
  276. }
  277. void jolt_body_get_pos(void *b, void *p) {
  278. _jolt_body_get_pos(b, p);
  279. }
  280. void jolt_body_get_rot(void *b, void *r) {
  281. _jolt_body_get_rot(b, r);
  282. }
  283. void jolt_body_sync_transform(void *b, vec4_t p, quat_t r) {
  284. _jolt_body_sync_transform(b, p, r);
  285. }
  286. void jolt_body_remove(void *b) {
  287. _jolt_body_remove(b);
  288. }
  289. }