TriggerComponent.cpp 3.0 KB

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