RecastNavigationMeshComponentController.h 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. /*
  2. * Copyright (c) Contributors to the Open 3D Engine Project.
  3. * For complete copyright and license terms please see the LICENSE at the root of this distribution.
  4. *
  5. * SPDX-License-Identifier: Apache-2.0 OR MIT
  6. *
  7. */
  8. #pragma once
  9. #include <Recast.h>
  10. #include <AzCore/Component/Component.h>
  11. #include <AzCore/Component/EntityId.h>
  12. #include <AzCore/EBus/ScheduledEvent.h>
  13. #include <AzCore/Task/TaskDescriptor.h>
  14. #include <AzCore/Task/TaskExecutor.h>
  15. #include <AzCore/Task/TaskGraph.h>
  16. #include <RecastNavigation/RecastHelpers.h>
  17. #include <Misc/RecastNavigationDebugDraw.h>
  18. #include <Misc/RecastNavigationMeshConfig.h>
  19. #include <RecastNavigation/RecastNavigationMeshBus.h>
  20. namespace RecastNavigation
  21. {
  22. //! Common navigation mesh logic for Recast navigation components. Recommended use is as a base class.
  23. //! The method provided are not thread-safe. Use the mutex from @m_navObject to synchronize as necessary at the higher level.
  24. class RecastNavigationMeshComponentController
  25. : public RecastNavigationMeshRequestBus::Handler
  26. {
  27. friend class EditorRecastNavigationMeshComponent;
  28. public:
  29. AZ_CLASS_ALLOCATOR(RecastNavigationMeshComponentController, AZ::SystemAllocator);
  30. AZ_RTTI(RecastNavigationMeshComponentController, "{D34CD5E0-8C29-4545-8734-9C7A92F03740}");
  31. RecastNavigationMeshComponentController();
  32. explicit RecastNavigationMeshComponentController(const RecastNavigationMeshConfig& config);
  33. ~RecastNavigationMeshComponentController() override = default;
  34. void Activate(const AZ::EntityComponentIdPair& entityComponentIdPair);
  35. void Deactivate();
  36. void SetConfiguration(const RecastNavigationMeshConfig& config);
  37. const RecastNavigationMeshConfig& GetConfiguration() const;
  38. static void Reflect(AZ::ReflectContext* context);
  39. static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided);
  40. static void GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required);
  41. static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible);
  42. //! Allocates and initializes Recast navigation mesh into @m_navMesh.
  43. //! @param meshEntityId the entity's positions will be used as the center of the navigation mesh.
  44. //! @return true if the navigation mesh object was successfully created.
  45. bool CreateNavigationMesh(AZ::EntityId meshEntityId);
  46. //! Given a Recast data add a tile to the navigation mesh @m_navMesh.
  47. //! @param navigationTileData the raw data of a Recast tile
  48. //! @return true if successful.
  49. bool AttachNavigationTileToMesh(NavigationTileData& navigationTileData);
  50. //! Given a set of geometry and configuration create a Recast tile that can be attached using @AttachNavigationTileToMesh.
  51. //! @param geom A set of geometry, triangle data.
  52. //! @param meshConfig Recast navigation mesh configuration.
  53. //! @param context Recast context object, @rcContext.
  54. //! @returns the tile data that can be attached to the navigation mesh using @AttachNavigationTileToMesh
  55. NavigationTileData CreateNavigationTile(TileGeometry* geom, const RecastNavigationMeshConfig& meshConfig, rcContext* context);
  56. //! Creates a task graph with tasks to process received tile data.
  57. //! @param config navigation mesh configuration to apply to the tile data
  58. //! @param sendNotificationEvent once all the tiles are processed and added to the navigation update notify on the main thread
  59. void ReceivedAllNewTilesImpl(const RecastNavigationMeshConfig& config, AZ::ScheduledEvent& sendNotificationEvent);
  60. //! RecastNavigationRequestBus overrides ...
  61. //! @{
  62. bool UpdateNavigationMeshBlockUntilCompleted() override;
  63. bool UpdateNavigationMeshAsync() override;
  64. AZStd::shared_ptr<NavMeshQuery> GetNavigationObject() override;
  65. //! @}
  66. protected:
  67. AZ::EntityComponentIdPair m_entityComponentIdPair;
  68. //! In-game navigation mesh configuration.
  69. RecastNavigationMeshConfig m_configuration;
  70. void OnSendNotificationTick();
  71. //! Tick event to notify on navigation mesh updates from the main thread.
  72. //! This is often needed for script environment, such as Script Canvas.
  73. AZ::ScheduledEvent m_sendNotificationEvent{ [this]() { OnSendNotificationTick(); }, AZ::Name("RecastNavigationMeshUpdated") };
  74. bool IsDebugDrawEnabled() const;
  75. //! If debug draw was specified, then this call will be invoked every frame.
  76. void OnDebugDrawTick();
  77. //! Tick event for the optional debug draw.
  78. AZ::ScheduledEvent m_tickEvent{ [this]() { OnDebugDrawTick(); }, AZ::Name("RecastNavigationDebugViewTick") };
  79. void OnReceivedAllNewTiles();
  80. //! Tick event to notify on navigation mesh updates from the main thread.
  81. //! This is often needed for script environment, such as Script Canvas.
  82. AZ::ScheduledEvent m_receivedAllNewTilesEvent{ [this]() { OnReceivedAllNewTiles(); }, AZ::Name("RecastNavigationReceivedTiles") };
  83. void OnTileProcessedEvent(AZStd::shared_ptr<TileGeometry> tile);
  84. //! Debug draw object for Recast navigation mesh.
  85. RecastNavigationDebugDraw m_customDebugDraw;
  86. //! Recast logging functionality and other optional tools.
  87. AZStd::unique_ptr<rcContext> m_context;
  88. //! Recast navigation objects.
  89. AZStd::shared_ptr<NavMeshQuery> m_navObject;
  90. AZStd::vector<AZStd::shared_ptr<TileGeometry>> m_tilesToBeProcessed;
  91. AZStd::recursive_mutex m_tileProcessingMutex;
  92. //! A way to check if we should stop tile processing (because we might be deactivating, for example).
  93. AZStd::atomic<bool> m_shouldProcessTiles{ true };
  94. //! Task graph objects to process tile geometry into Recast tiles.
  95. AZ::TaskGraph m_taskGraph{ "RecastNavigation Tile Processing" };
  96. AZ::TaskExecutor m_taskExecutor;
  97. AZStd::unique_ptr<AZ::TaskGraphEvent> m_taskGraphEvent;
  98. AZ::TaskDescriptor m_taskDescriptor{ "Processing Tiles", "Recast Navigation" };
  99. //! If true, an update operation is in progress.
  100. AZStd::atomic<bool> m_updateInProgress{ false };
  101. };
  102. } // namespace RecastNavigation