PhysicsWorld.h 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. // Copyright (C) 2009-present, Panagiotis Christopoulos Charitos and contributors.
  2. // All rights reserved.
  3. // Code licensed under the BSD License.
  4. // http://www.anki3d.org/LICENSE
  5. #pragma once
  6. #include <AnKi/Physics/Common.h>
  7. #include <AnKi/Physics/PhysicsCollisionShape.h>
  8. #include <AnKi/Physics/PhysicsBody.h>
  9. #include <AnKi/Physics/PhysicsJoint.h>
  10. #include <AnKi/Physics/PhysicsPlayerController.h>
  11. #include <AnKi/Util/BlockArray.h>
  12. namespace anki {
  13. /// @addtogroup physics
  14. /// @{
  15. /// @memberof PhysicsWorld
  16. class RayHitResult
  17. {
  18. public:
  19. PhysicsObjectBase* m_object = nullptr;
  20. Vec3 m_normal; ///< In world space.
  21. Vec3 m_hitPosition; ///< In world space.
  22. };
  23. /// @memberof PhysicsWorld
  24. class PhysicsDebugDrawerInterface
  25. {
  26. public:
  27. /// The implementer is responsible of batching lines together.
  28. virtual void drawLines(ConstWeakArray<Vec3> lines, Array<U8, 4> color) = 0;
  29. };
  30. /// The master container for all physics related stuff.
  31. /// The newXXX methods are thread-safe between themselves and the dereference of the pointers. Every other method is not thread-safe.
  32. class PhysicsWorld : public MakeSingleton<PhysicsWorld>
  33. {
  34. template<typename>
  35. friend class anki::MakeSingleton;
  36. friend class PhysicsCollisionShapePtrDeleter;
  37. friend class PhysicsBodyPtrDeleter;
  38. friend class PhysicsBody;
  39. friend class PhysicsPlayerController;
  40. friend class PhysicsPlayerControllerPtrDeleter;
  41. friend class PhysicsJointPtrDeleter;
  42. public:
  43. Error init(AllocAlignedCallback allocCb, void* allocCbData);
  44. PhysicsCollisionShapePtr newSphereCollisionShape(F32 radius);
  45. PhysicsCollisionShapePtr newBoxCollisionShape(Vec3 extend);
  46. PhysicsCollisionShapePtr newCapsuleCollisionShape(F32 height, F32 radius); ///< Capsule axis is in Y.
  47. PhysicsCollisionShapePtr newConvexHullShape(ConstWeakArray<Vec3> positions);
  48. PhysicsCollisionShapePtr newStaticMeshShape(ConstWeakArray<Vec3> positions, ConstWeakArray<U32> indices);
  49. PhysicsBodyPtr newPhysicsBody(const PhysicsBodyInitInfo& init);
  50. PhysicsJointPtr newPointJoint(PhysicsBody* body1, PhysicsBody* body2, const Vec3& pivot);
  51. /// @param pivot Gives the origin and rotation of the hinge. The hinge rotats in the X axis of the transform.
  52. PhysicsJointPtr newHingeJoint(PhysicsBody* body1, PhysicsBody* body2, const Transform& pivot);
  53. PhysicsPlayerControllerPtr newPlayerController(const PhysicsPlayerControllerInitInfo& init);
  54. void update(Second dt);
  55. /// Returns the closest hit.
  56. Bool castRayClosestHit(const Vec3& rayStart, const Vec3& rayEnd, PhysicsLayerBit layers, RayHitResult& result);
  57. /// Executes a callback for all hits found.
  58. template<typename TFunc>
  59. Bool castRayAllHits(const Vec3& rayStart, const Vec3& rayEnd, PhysicsLayerBit layers, TFunc func)
  60. {
  61. PhysicsDynamicArray<RayHitResult> results;
  62. const Bool success = castRayAllHits(rayStart, rayEnd, layers, results);
  63. if(success)
  64. {
  65. for(RayHitResult& res : results)
  66. {
  67. func(res);
  68. }
  69. }
  70. return success;
  71. }
  72. void debugDraw(PhysicsDebugDrawerInterface& interface);
  73. private:
  74. class MyBodyActivationListener;
  75. class MyContactListener;
  76. class MyDebugRenderer;
  77. template<typename T, U32 kElementsPerBlock>
  78. class ObjArray
  79. {
  80. public:
  81. PhysicsBlockArray<T, BlockArrayConfig<kElementsPerBlock>> m_array;
  82. Mutex m_mtx;
  83. };
  84. class Contact
  85. {
  86. public:
  87. PhysicsBody* m_trigger;
  88. PhysicsObjectBase* m_receiver;
  89. };
  90. ClassWrapper<JPH::PhysicsSystem> m_jphPhysicsSystem;
  91. ClassWrapper<JPH::JobSystemThreadPool> m_jobSystem;
  92. ClassWrapper<JPH::TempAllocatorImpl> m_tempAllocator;
  93. ObjArray<PhysicsCollisionShape, 32> m_collisionShapes;
  94. ObjArray<PhysicsBody, 64> m_bodies;
  95. ObjArray<PhysicsJoint, 16> m_joints;
  96. ObjArray<PhysicsPlayerController, 8> m_characters;
  97. DynamicArray<Contact> m_insertedContacts;
  98. DynamicArray<Contact> m_deletedContacts;
  99. Mutex m_insertedContactsMtx;
  100. Mutex m_deletedContactsMtx;
  101. Bool m_optimizeBroadphase = true;
  102. static MyBodyActivationListener m_bodyActivationListener;
  103. static MyContactListener m_contactListener;
  104. PhysicsWorld();
  105. ~PhysicsWorld();
  106. template<typename TJPHCollisionShape, typename... TArgs>
  107. PhysicsCollisionShapePtr newCollisionShape(TArgs&&... args);
  108. template<typename TJPHJoint, typename... TArgs>
  109. PhysicsJointPtr newJoint(PhysicsBody* body1, PhysicsBody* body2, TArgs&&... args);
  110. PhysicsCollisionShapePtr newScaleCollisionObject(const Vec3& scale, PhysicsCollisionShape* baseShape);
  111. RayHitResult jphToAnKi(const JPH::RRayCast& ray, const JPH::RayCastResult& hit);
  112. Bool castRayAllHitsInternal(const Vec3& rayStart, const Vec3& rayEnd, PhysicsLayerBit layers, PhysicsDynamicArray<RayHitResult>& results);
  113. };
  114. /// @}
  115. } // end namespace anki