PhysicsObject.h 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. // Copyright (C) 2009-2022, 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/Util/List.h>
  8. namespace anki {
  9. /// @addtogroup physics
  10. /// @{
  11. /// Type of the physics object.
  12. enum class PhysicsObjectType : U8
  13. {
  14. COLLISION_SHAPE,
  15. JOINT,
  16. BODY,
  17. PLAYER_CONTROLLER,
  18. TRIGGER,
  19. COUNT,
  20. FIRST = 0,
  21. LAST = COUNT - 1,
  22. FIRST_FILTERED = BODY,
  23. LAST_FILTERED = TRIGGER,
  24. };
  25. ANKI_ENUM_ALLOW_NUMERIC_OPERATIONS(PhysicsObjectType)
  26. #define ANKI_PHYSICS_OBJECT_FRIENDS \
  27. friend class PhysicsWorld; \
  28. friend class PhysicsPtrDeleter; \
  29. template<typename T, typename TDeleter> \
  30. friend class IntrusivePtr;
  31. #define ANKI_PHYSICS_OBJECT(type) \
  32. ANKI_PHYSICS_OBJECT_FRIENDS \
  33. public: \
  34. static constexpr PhysicsObjectType CLASS_TYPE = type; \
  35. \
  36. private:
  37. /// Base of all physics objects.
  38. class PhysicsObject : public IntrusiveListEnabled<PhysicsObject>
  39. {
  40. ANKI_PHYSICS_OBJECT_FRIENDS
  41. public:
  42. PhysicsObject(PhysicsObjectType type, PhysicsWorld* world)
  43. : m_world(world)
  44. , m_type(type)
  45. {
  46. ANKI_ASSERT(m_world);
  47. }
  48. virtual ~PhysicsObject()
  49. {
  50. ANKI_ASSERT(!m_registered);
  51. }
  52. PhysicsObjectType getType() const
  53. {
  54. return m_type;
  55. }
  56. void setUserData(void* ud)
  57. {
  58. m_userData = ud;
  59. }
  60. void* getUserData() const
  61. {
  62. return m_userData;
  63. }
  64. protected:
  65. PhysicsWorld* m_world = nullptr;
  66. PhysicsWorld& getWorld()
  67. {
  68. return *m_world;
  69. }
  70. const PhysicsWorld& getWorld() const
  71. {
  72. return *m_world;
  73. }
  74. void retain() const
  75. {
  76. m_refcount.fetchAdd(1);
  77. }
  78. I32 release() const
  79. {
  80. return m_refcount.fetchSub(1);
  81. }
  82. HeapAllocator<U8> getAllocator() const;
  83. private:
  84. Bool m_registered = false;
  85. virtual void registerToWorld() = 0;
  86. virtual void unregisterFromWorld() = 0;
  87. private:
  88. mutable Atomic<I32> m_refcount = {0};
  89. PhysicsObjectType m_type;
  90. void* m_userData = nullptr;
  91. };
  92. /// This is a factor that will decide if two filtered objects will be checked for collision.
  93. /// @memberof PhysicsFilteredObject
  94. class PhysicsBroadPhaseFilterCallback
  95. {
  96. public:
  97. virtual Bool needsCollision(const PhysicsFilteredObject& a, const PhysicsFilteredObject& b) = 0;
  98. };
  99. /// A pair of a trigger and a filtered object.
  100. class PhysicsTriggerFilteredPair
  101. {
  102. public:
  103. PhysicsFilteredObject* m_filteredObject = nullptr;
  104. PhysicsTrigger* m_trigger = nullptr;
  105. U64 m_frame = 0;
  106. Bool isAlive() const
  107. {
  108. return m_filteredObject && m_trigger;
  109. }
  110. Bool shouldDelete() const
  111. {
  112. return m_filteredObject == nullptr && m_trigger == nullptr;
  113. }
  114. };
  115. /// A PhysicsObject that takes part into collision detection. Has functionality to filter the broad phase detection.
  116. class PhysicsFilteredObject : public PhysicsObject
  117. {
  118. public:
  119. ANKI_PHYSICS_OBJECT_FRIENDS
  120. PhysicsFilteredObject(PhysicsObjectType type, PhysicsWorld* world)
  121. : PhysicsObject(type, world)
  122. {
  123. }
  124. ~PhysicsFilteredObject();
  125. static Bool classof(const PhysicsObject* obj)
  126. {
  127. return obj->getType() >= PhysicsObjectType::FIRST_FILTERED
  128. && obj->getType() <= PhysicsObjectType::LAST_FILTERED;
  129. }
  130. /// Get the material(s) this object belongs.
  131. PhysicsMaterialBit getMaterialGroup() const
  132. {
  133. return m_materialGroup;
  134. }
  135. /// Set the material(s) this object belongs.
  136. void setMaterialGroup(PhysicsMaterialBit bits)
  137. {
  138. m_materialGroup = bits;
  139. }
  140. /// Get the materials this object collides.
  141. PhysicsMaterialBit getMaterialMask() const
  142. {
  143. return m_materialMask;
  144. }
  145. /// Set the materials this object collides.
  146. void setMaterialMask(PhysicsMaterialBit bit)
  147. {
  148. m_materialMask = bit;
  149. }
  150. /// Get the broadphase callback.
  151. PhysicsBroadPhaseFilterCallback* getPhysicsBroadPhaseFilterCallback() const
  152. {
  153. return m_filter;
  154. }
  155. /// Set the broadphase callback.
  156. void setPhysicsBroadPhaseFilterCallback(PhysicsBroadPhaseFilterCallback* f)
  157. {
  158. m_filter = f;
  159. }
  160. private:
  161. PhysicsMaterialBit m_materialGroup = PhysicsMaterialBit::ALL;
  162. PhysicsMaterialBit m_materialMask = PhysicsMaterialBit::ALL;
  163. PhysicsBroadPhaseFilterCallback* m_filter = nullptr;
  164. static constexpr U32 MAX_TRIGGER_FILTERED_PAIRS = 4;
  165. Array<PhysicsTriggerFilteredPair*, MAX_TRIGGER_FILTERED_PAIRS> m_triggerFilteredPairs = {};
  166. };
  167. /// @}
  168. } // end namespace anki