TriggerComponent.cpp 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. // Copyright (C) 2009-2023, Panagiotis Christopoulos Charitos and contributors.
  2. // All rights reserved.
  3. // Code licensed under the BSD License.
  4. // http://www.anki3d.org/LICENSE
  5. #include <AnKi/Scene/Components/TriggerComponent.h>
  6. #include <AnKi/Scene/SceneNode.h>
  7. #include <AnKi/Scene/SceneGraph.h>
  8. #include <AnKi/Physics/PhysicsCollisionShape.h>
  9. #include <AnKi/Physics/PhysicsWorld.h>
  10. namespace anki {
  11. /// The callbacks execute before the TriggerComponent::update
  12. class TriggerComponent::MyPhysicsTriggerProcessContactCallback final : public PhysicsTriggerProcessContactCallback
  13. {
  14. public:
  15. TriggerComponent* m_comp = nullptr;
  16. Bool m_updated = false;
  17. Bool m_enterUpdated = false;
  18. Bool m_insideUpdated = false;
  19. Bool m_exitUpdated = false;
  20. void onTriggerEnter([[maybe_unused]] PhysicsTrigger& trigger, PhysicsFilteredObject& obj)
  21. {
  22. // Clean previous results
  23. if(!m_enterUpdated)
  24. {
  25. m_enterUpdated = true;
  26. m_comp->m_bodiesEnter.destroy(m_comp->m_node->getMemoryPool());
  27. }
  28. m_updated = true;
  29. m_comp->m_bodiesEnter.emplaceBack(m_comp->m_node->getMemoryPool(),
  30. static_cast<BodyComponent*>(obj.getUserData()));
  31. }
  32. void onTriggerInside([[maybe_unused]] PhysicsTrigger& trigger, PhysicsFilteredObject& obj)
  33. {
  34. // Clean previous results
  35. if(!m_insideUpdated)
  36. {
  37. m_insideUpdated = true;
  38. m_comp->m_bodiesInside.destroy(m_comp->m_node->getMemoryPool());
  39. }
  40. m_updated = true;
  41. m_comp->m_bodiesInside.emplaceBack(m_comp->m_node->getMemoryPool(),
  42. static_cast<BodyComponent*>(obj.getUserData()));
  43. }
  44. void onTriggerExit([[maybe_unused]] PhysicsTrigger& trigger, PhysicsFilteredObject& obj)
  45. {
  46. // Clean previous results
  47. if(!m_exitUpdated)
  48. {
  49. m_exitUpdated = true;
  50. m_comp->m_bodiesExit.destroy(m_comp->m_node->getMemoryPool());
  51. }
  52. m_updated = true;
  53. m_comp->m_bodiesExit.emplaceBack(m_comp->m_node->getMemoryPool(),
  54. static_cast<BodyComponent*>(obj.getUserData()));
  55. }
  56. };
  57. TriggerComponent::TriggerComponent(SceneNode* node)
  58. : SceneComponent(node, getStaticClassId())
  59. , m_node(node)
  60. {
  61. ANKI_ASSERT(node);
  62. m_callbacks = newInstance<MyPhysicsTriggerProcessContactCallback>(m_node->getMemoryPool());
  63. m_callbacks->m_comp = this;
  64. }
  65. TriggerComponent::~TriggerComponent()
  66. {
  67. deleteInstance(m_node->getMemoryPool(), m_callbacks);
  68. m_bodiesEnter.destroy(m_node->getMemoryPool());
  69. m_bodiesInside.destroy(m_node->getMemoryPool());
  70. m_bodiesExit.destroy(m_node->getMemoryPool());
  71. }
  72. void TriggerComponent::setSphereVolumeRadius(F32 radius)
  73. {
  74. // Need to re-create it
  75. m_shape = PhysicsWorld::getSingleton().newInstance<PhysicsSphere>(radius);
  76. m_trigger = PhysicsWorld::getSingleton().newInstance<PhysicsTrigger>(m_shape);
  77. m_trigger->setUserData(this);
  78. m_trigger->setContactProcessCallback(m_callbacks);
  79. m_trigger->setTransform(m_node->getWorldTransform());
  80. }
  81. Error TriggerComponent::update(SceneComponentUpdateInfo& info, Bool& updated)
  82. {
  83. updated = false;
  84. if(m_trigger.isCreated()) [[likely]]
  85. {
  86. updated = m_callbacks->m_updated;
  87. m_callbacks->m_updated = false;
  88. m_callbacks->m_enterUpdated = false;
  89. m_callbacks->m_insideUpdated = false;
  90. m_callbacks->m_exitUpdated = false;
  91. if(info.m_node->movedThisFrame() && m_trigger.isCreated())
  92. {
  93. updated = true;
  94. m_trigger->setTransform(info.m_node->getWorldTransform());
  95. }
  96. }
  97. return Error::kNone;
  98. }
  99. } // end namespace anki