PhysicsObject.h 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  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. /// @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. Atomic<I32>& getRefcount()
  75. {
  76. return m_refcount;
  77. }
  78. HeapAllocator<U8> getAllocator() const;
  79. private:
  80. Bool m_registered = false;
  81. virtual void registerToWorld() = 0;
  82. virtual void unregisterFromWorld() = 0;
  83. private:
  84. Atomic<I32> m_refcount = {0};
  85. PhysicsObjectType m_type;
  86. void* m_userData = nullptr;
  87. };
  88. /// This is a factor that will decide if two filtered objects will be checked for collision.
  89. /// @memberof PhysicsFilteredObject
  90. class PhysicsBroadPhaseFilterCallback
  91. {
  92. public:
  93. virtual Bool needsCollision(const PhysicsFilteredObject& a, const PhysicsFilteredObject& b) = 0;
  94. };
  95. /// A pair of a trigger and a filtered object.
  96. class PhysicsTriggerFilteredPair
  97. {
  98. public:
  99. PhysicsFilteredObject* m_filteredObject = nullptr;
  100. PhysicsTrigger* m_trigger = nullptr;
  101. U64 m_frame = 0;
  102. Bool isAlive() const
  103. {
  104. return m_filteredObject && m_trigger;
  105. }
  106. Bool shouldDelete() const
  107. {
  108. return m_filteredObject == nullptr && m_trigger == nullptr;
  109. }
  110. };
  111. /// A PhysicsObject that takes part into collision detection. Has functionality to filter the broad phase detection.
  112. class PhysicsFilteredObject : public PhysicsObject
  113. {
  114. public:
  115. ANKI_PHYSICS_OBJECT_FRIENDS
  116. PhysicsFilteredObject(PhysicsObjectType type, PhysicsWorld* world)
  117. : PhysicsObject(type, world)
  118. {
  119. }
  120. ~PhysicsFilteredObject();
  121. static Bool classof(const PhysicsObject* obj)
  122. {
  123. return obj->getType() >= PhysicsObjectType::FIRST_FILTERED
  124. && obj->getType() <= PhysicsObjectType::LAST_FILTERED;
  125. }
  126. /// Get the material(s) this object belongs.
  127. PhysicsMaterialBit getMaterialGroup() const
  128. {
  129. return m_materialGroup;
  130. }
  131. /// Set the material(s) this object belongs.
  132. void setMaterialGroup(PhysicsMaterialBit bits)
  133. {
  134. m_materialGroup = bits;
  135. }
  136. /// Get the materials this object collides.
  137. PhysicsMaterialBit getMaterialMask() const
  138. {
  139. return m_materialMask;
  140. }
  141. /// Set the materials this object collides.
  142. void setMaterialMask(PhysicsMaterialBit bit)
  143. {
  144. m_materialMask = bit;
  145. }
  146. /// Get the broadphase callback.
  147. PhysicsBroadPhaseFilterCallback* getPhysicsBroadPhaseFilterCallback() const
  148. {
  149. return m_filter;
  150. }
  151. /// Set the broadphase callback.
  152. void setPhysicsBroadPhaseFilterCallback(PhysicsBroadPhaseFilterCallback* f)
  153. {
  154. m_filter = f;
  155. }
  156. private:
  157. PhysicsMaterialBit m_materialGroup = PhysicsMaterialBit::ALL;
  158. PhysicsMaterialBit m_materialMask = PhysicsMaterialBit::ALL;
  159. PhysicsBroadPhaseFilterCallback* m_filter = nullptr;
  160. static constexpr U32 MAX_TRIGGER_FILTERED_PAIRS = 4;
  161. Array<PhysicsTriggerFilteredPair*, MAX_TRIGGER_FILTERED_PAIRS> m_triggerFilteredPairs = {};
  162. };
  163. /// @}
  164. } // end namespace anki