2
0

Common.h 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258
  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/Util/StdTypes.h>
  7. #include <AnKi/Util/Enum.h>
  8. #include <AnKi/Util/Ptr.h>
  9. #include <AnKi/Util/MemoryPool.h>
  10. #include <AnKi/Math.h>
  11. #if ANKI_ASSERTIONS_ENABLED && !defined(JPH_ENABLE_ASSERTS)
  12. # error "See file"
  13. #endif
  14. #if !defined(JPH_DEBUG_RENDERER)
  15. # error "See file"
  16. #endif
  17. #if ANKI_COMPILER_GCC_COMPATIBLE
  18. # pragma GCC diagnostic push
  19. # pragma GCC diagnostic ignored "-Wconversion"
  20. #endif
  21. #include <Jolt/Jolt.h>
  22. #include <Jolt/Physics/Body/Body.h>
  23. #include <Jolt/Physics/Body/BodyCreationSettings.h>
  24. #include <Jolt/Physics/Body/BodyActivationListener.h>
  25. #include <Jolt/Physics/Collision/Shape/BoxShape.h>
  26. #include <Jolt/Physics/Collision/Shape/SphereShape.h>
  27. #include <Jolt/Physics/Collision/Shape/CapsuleShape.h>
  28. #include <Jolt/Physics/Collision/Shape/ScaledShape.h>
  29. #include <Jolt/Physics/Collision/Shape/ConvexHullShape.h>
  30. #include <Jolt/Physics/Collision/Shape/MeshShape.h>
  31. #include <Jolt/Physics/Collision/RayCast.h>
  32. #include <Jolt/Physics/Collision/NarrowPhaseQuery.h>
  33. #include <Jolt/Physics/Collision/CastResult.h>
  34. #include <Jolt/Physics/PhysicsSystem.h>
  35. #include <Jolt/Physics/Constraints/PointConstraint.h>
  36. #include <Jolt/Physics/Constraints/HingeConstraint.h>
  37. #include <Jolt/Physics/Character/CharacterVirtual.h>
  38. #include <Jolt/RegisterTypes.h>
  39. #include <Jolt/Core/JobSystemThreadPool.h>
  40. #if ANKI_COMPILER_GCC_COMPATIBLE
  41. # pragma GCC diagnostic pop
  42. #endif
  43. namespace anki {
  44. #define ANKI_PHYS_LOGI(...) ANKI_LOG("PHYS", kNormal, __VA_ARGS__)
  45. #define ANKI_PHYS_LOGE(...) ANKI_LOG("PHYS", kError, __VA_ARGS__)
  46. #define ANKI_PHYS_LOGW(...) ANKI_LOG("PHYS", kWarning, __VA_ARGS__)
  47. #define ANKI_PHYS_LOGF(...) ANKI_LOG("PHYS", kFatal, __VA_ARGS__)
  48. #define ANKI_PHYSICS_COMMON_FRIENDS \
  49. friend class PhysicsWorld; \
  50. template<typename, typename> \
  51. friend class anki::IntrusivePtr; \
  52. template<typename, typename, typename> \
  53. friend class anki::BlockArray;
  54. class PhysicsMemoryPool : public HeapMemoryPool, public MakeSingleton<PhysicsMemoryPool>
  55. {
  56. template<typename>
  57. friend class anki::MakeSingleton;
  58. private:
  59. PhysicsMemoryPool(AllocAlignedCallback allocCb, void* allocCbUserData)
  60. : HeapMemoryPool(allocCb, allocCbUserData, "PhysicsMemPool")
  61. {
  62. }
  63. ~PhysicsMemoryPool() = default;
  64. };
  65. ANKI_DEFINE_SUBMODULE_UTIL_CONTAINERS(Physics, PhysicsMemoryPool)
  66. enum class PhysicsObjectType : U8
  67. {
  68. kNone,
  69. kCollisionShape,
  70. kBody,
  71. kPlayerController,
  72. kJoint,
  73. kCount
  74. };
  75. ANKI_ENUM_ALLOW_NUMERIC_OPERATIONS(PhysicsObjectType);
  76. /// The base class of all physics objects.
  77. class PhysicsObjectBase
  78. {
  79. template<typename, typename>
  80. friend class IntrusivePtr;
  81. public:
  82. PhysicsObjectBase(const PhysicsObjectBase&) = delete;
  83. PhysicsObjectBase& operator=(const PhysicsObjectBase&) = delete;
  84. PhysicsObjectType getType() const
  85. {
  86. return PhysicsObjectType(m_type);
  87. }
  88. void* getUserData() const
  89. {
  90. return m_userData;
  91. }
  92. void setUserData(void* userData)
  93. {
  94. m_userData = userData;
  95. }
  96. protected:
  97. static constexpr U32 kTypeBits = 5u; ///< 5 is more than enough
  98. static constexpr U32 kMaxBockArrayIndex = kMaxU32 >> kTypeBits;
  99. void* m_userData = nullptr;
  100. mutable Atomic<U32> m_refcount = {0};
  101. U32 m_type : kTypeBits;
  102. U32 m_blockArrayIndex : 32 - kTypeBits = kMaxBockArrayIndex;
  103. PhysicsObjectBase(PhysicsObjectType type)
  104. : m_type(U32(type) & ((1u << kTypeBits) - 1u))
  105. {
  106. ANKI_ASSERT(type < PhysicsObjectType::kCount);
  107. }
  108. void retain() const
  109. {
  110. m_refcount.fetchAdd(1);
  111. }
  112. U32 release() const
  113. {
  114. return m_refcount.fetchSub(1);
  115. }
  116. void setBlockArrayIndex(U32 idx)
  117. {
  118. m_blockArrayIndex = idx & kMaxBockArrayIndex;
  119. }
  120. };
  121. /// The physics layers a PhysicsBody can be.
  122. enum class PhysicsLayer : U8
  123. {
  124. kStatic,
  125. kMoving,
  126. kPlayerController,
  127. kTrigger,
  128. kDebris,
  129. kCount,
  130. kFirst = 0
  131. };
  132. enum class PhysicsLayerBit : U8
  133. {
  134. kNone = 0,
  135. kStatic = 1u << 0u,
  136. kMoving = 1u << 1u,
  137. kPlayerController = 1u << 2u,
  138. kTrigger = 1u << 3u,
  139. kDebris = 1u << 4u,
  140. kAll = kStatic | kMoving | kPlayerController | kTrigger | kDebris
  141. };
  142. ANKI_ENUM_ALLOW_NUMERIC_OPERATIONS(PhysicsLayerBit)
  143. /// Table that shows which layer collides with whom.
  144. inline constexpr Array<PhysicsLayerBit, U32(PhysicsLayer::kCount)> kPhysicsLayerCollisionTable = {
  145. {/* kStatic */ PhysicsLayerBit::kAll & ~(PhysicsLayerBit::kStatic | PhysicsLayerBit::kTrigger),
  146. /* kMoving */ PhysicsLayerBit::kAll & ~(PhysicsLayerBit::kDebris),
  147. /* kPlayerController */ PhysicsLayerBit::kAll & ~(PhysicsLayerBit::kDebris),
  148. /* kTrigger */ PhysicsLayerBit::kAll & ~(PhysicsLayerBit::kStatic | PhysicsLayerBit::kTrigger),
  149. /* kDebris */ PhysicsLayerBit::kStatic}};
  150. #define ANKI_PHYSICS_DEFINE_PTRS(className) \
  151. class className; \
  152. class className##PtrDeleter \
  153. { \
  154. public: \
  155. void operator()(className* ptr); \
  156. }; \
  157. using className##Ptr = IntrusivePtr<className, className##PtrDeleter>;
  158. ANKI_PHYSICS_DEFINE_PTRS(PhysicsCollisionShape)
  159. ANKI_PHYSICS_DEFINE_PTRS(PhysicsBody)
  160. ANKI_PHYSICS_DEFINE_PTRS(PhysicsJoint)
  161. ANKI_PHYSICS_DEFINE_PTRS(PhysicsPlayerController)
  162. #undef ANKI_PHYSICS_DEFINE_PTRS
  163. template<U32 kSize>
  164. class StaticTempAllocator final : public JPH::TempAllocator
  165. {
  166. public:
  167. alignas(JPH_RVECTOR_ALIGNMENT) Array<U8, kSize> m_memory;
  168. U32 m_base = 0;
  169. void* Allocate(U32 size) override
  170. {
  171. ANKI_ASSERT(size);
  172. size = getAlignedRoundUp(JPH_RVECTOR_ALIGNMENT, size);
  173. ANKI_ASSERT(m_base + size <= sizeof(m_memory));
  174. void* out = &m_memory[0] + size;
  175. m_base += size;
  176. return out;
  177. }
  178. void Free([[maybe_unused]] void* address, U32 size) override
  179. {
  180. ANKI_ASSERT(address && size);
  181. size = getAlignedRoundUp(JPH_RVECTOR_ALIGNMENT, size);
  182. ANKI_ASSERT(m_base >= size);
  183. m_base -= size;
  184. }
  185. };
  186. inline JPH::RVec3 toJPH(Vec3 ak)
  187. {
  188. return JPH::RVec3(ak.x, ak.y, ak.z);
  189. }
  190. inline JPH::Quat toJPH(Quat ak)
  191. {
  192. return JPH::Quat(ak.x, ak.y, ak.z, ak.w);
  193. }
  194. inline Vec4 toAnKi(const JPH::Vec4& jph)
  195. {
  196. return Vec4(jph.GetX(), jph.GetY(), jph.GetZ(), jph.GetW());
  197. }
  198. inline Vec3 toAnKi(JPH::Vec3 x)
  199. {
  200. return Vec3(x.GetX(), x.GetY(), x.GetZ());
  201. }
  202. inline Transform toAnKi(const JPH::RMat44& jph)
  203. {
  204. Mat4 m;
  205. for(U32 i = 0; i < 4; ++i)
  206. {
  207. m.setColumn(i, toAnKi(jph.GetColumn4(i)));
  208. }
  209. return Transform(m);
  210. }
  211. } // end namespace anki