TriggerComponent.cpp 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  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();
  27. }
  28. m_updated = true;
  29. m_comp->m_bodiesEnter.emplaceBack(static_cast<BodyComponent*>(obj.getUserData()));
  30. }
  31. void onTriggerInside([[maybe_unused]] PhysicsTrigger& trigger, PhysicsFilteredObject& obj)
  32. {
  33. // Clean previous results
  34. if(!m_insideUpdated)
  35. {
  36. m_insideUpdated = true;
  37. m_comp->m_bodiesInside.destroy();
  38. }
  39. m_updated = true;
  40. m_comp->m_bodiesInside.emplaceBack(static_cast<BodyComponent*>(obj.getUserData()));
  41. }
  42. void onTriggerExit([[maybe_unused]] PhysicsTrigger& trigger, PhysicsFilteredObject& obj)
  43. {
  44. // Clean previous results
  45. if(!m_exitUpdated)
  46. {
  47. m_exitUpdated = true;
  48. m_comp->m_bodiesExit.destroy();
  49. }
  50. m_updated = true;
  51. m_comp->m_bodiesExit.emplaceBack(static_cast<BodyComponent*>(obj.getUserData()));
  52. }
  53. };
  54. TriggerComponent::TriggerComponent(SceneNode* node)
  55. : SceneComponent(node, kClassType)
  56. , m_node(node)
  57. {
  58. ANKI_ASSERT(node);
  59. m_callbacks = newInstance<MyPhysicsTriggerProcessContactCallback>(SceneMemoryPool::getSingleton());
  60. m_callbacks->m_comp = this;
  61. }
  62. TriggerComponent::~TriggerComponent()
  63. {
  64. deleteInstance(SceneMemoryPool::getSingleton(), m_callbacks);
  65. }
  66. void TriggerComponent::setSphereVolumeRadius(F32 radius)
  67. {
  68. // Need to re-create it
  69. m_shape = PhysicsWorld::getSingleton().newInstance<PhysicsSphere>(radius);
  70. m_trigger = PhysicsWorld::getSingleton().newInstance<PhysicsTrigger>(m_shape);
  71. m_trigger->setUserData(this);
  72. m_trigger->setContactProcessCallback(m_callbacks);
  73. m_trigger->setTransform(m_node->getWorldTransform());
  74. }
  75. Error TriggerComponent::update(SceneComponentUpdateInfo& info, Bool& updated)
  76. {
  77. updated = false;
  78. if(m_trigger.isCreated()) [[likely]]
  79. {
  80. updated = m_callbacks->m_updated;
  81. m_callbacks->m_updated = false;
  82. m_callbacks->m_enterUpdated = false;
  83. m_callbacks->m_insideUpdated = false;
  84. m_callbacks->m_exitUpdated = false;
  85. if(info.m_node->movedThisFrame() && m_trigger.isCreated())
  86. {
  87. updated = true;
  88. m_trigger->setTransform(info.m_node->getWorldTransform());
  89. }
  90. }
  91. return Error::kNone;
  92. }
  93. } // end namespace anki