PhysicsObject.h 4.1 KB

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