TriggerComponent.cpp 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  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. #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. ANKI_SCENE_COMPONENT_STATICS(TriggerComponent)
  12. /// The callbacks execute before the TriggerComponent::update
  13. class TriggerComponent::MyPhysicsTriggerProcessContactCallback final : public PhysicsTriggerProcessContactCallback
  14. {
  15. public:
  16. TriggerComponent* m_comp = nullptr;
  17. Bool m_updated = false;
  18. Bool m_enterUpdated = false;
  19. Bool m_insideUpdated = false;
  20. Bool m_exitUpdated = false;
  21. void onTriggerEnter(PhysicsTrigger& trigger, PhysicsFilteredObject& obj)
  22. {
  23. // Clean previous results
  24. if(!m_enterUpdated)
  25. {
  26. m_enterUpdated = true;
  27. m_comp->m_bodiesEnter.destroy(m_comp->m_node->getAllocator());
  28. }
  29. m_updated = true;
  30. m_comp->m_bodiesEnter.emplaceBack(m_comp->m_node->getAllocator(),
  31. static_cast<BodyComponent*>(obj.getUserData()));
  32. }
  33. void onTriggerInside(PhysicsTrigger& trigger, PhysicsFilteredObject& obj)
  34. {
  35. // Clean previous results
  36. if(!m_insideUpdated)
  37. {
  38. m_insideUpdated = true;
  39. m_comp->m_bodiesInside.destroy(m_comp->m_node->getAllocator());
  40. }
  41. m_updated = true;
  42. m_comp->m_bodiesInside.emplaceBack(m_comp->m_node->getAllocator(),
  43. static_cast<BodyComponent*>(obj.getUserData()));
  44. }
  45. void onTriggerExit(PhysicsTrigger& trigger, PhysicsFilteredObject& obj)
  46. {
  47. // Clean previous results
  48. if(!m_exitUpdated)
  49. {
  50. m_exitUpdated = true;
  51. m_comp->m_bodiesExit.destroy(m_comp->m_node->getAllocator());
  52. }
  53. m_updated = true;
  54. m_comp->m_bodiesExit.emplaceBack(m_comp->m_node->getAllocator(),
  55. static_cast<BodyComponent*>(obj.getUserData()));
  56. }
  57. };
  58. TriggerComponent::TriggerComponent(SceneNode* node)
  59. : SceneComponent(node, getStaticClassId())
  60. , m_node(node)
  61. {
  62. ANKI_ASSERT(node);
  63. m_callbacks = m_node->getAllocator().newInstance<MyPhysicsTriggerProcessContactCallback>();
  64. m_callbacks->m_comp = this;
  65. }
  66. TriggerComponent::~TriggerComponent()
  67. {
  68. m_node->getAllocator().deleteInstance(m_callbacks);
  69. m_bodiesEnter.destroy(m_node->getAllocator());
  70. m_bodiesInside.destroy(m_node->getAllocator());
  71. m_bodiesExit.destroy(m_node->getAllocator());
  72. }
  73. void TriggerComponent::setSphereVolumeRadius(F32 radius)
  74. {
  75. m_shape = m_node->getSceneGraph().getPhysicsWorld().newInstance<PhysicsSphere>(radius);
  76. m_trigger = m_node->getSceneGraph().getPhysicsWorld().newInstance<PhysicsTrigger>(m_shape);
  77. m_trigger->setUserData(this);
  78. m_trigger->setContactProcessCallback(m_callbacks);
  79. }
  80. Error TriggerComponent::update(SceneNode& node, Second prevTime, Second crntTime, Bool& updated)
  81. {
  82. updated = m_callbacks->m_updated;
  83. m_callbacks->m_updated = false;
  84. m_callbacks->m_enterUpdated = false;
  85. m_callbacks->m_insideUpdated = false;
  86. m_callbacks->m_exitUpdated = false;
  87. return Error::NONE;
  88. }
  89. } // end namespace anki