TerrainMacroMaterialBus.h 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  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 <AzCore/Component/ComponentBus.h>
  10. #include <AzCore/EBus/EBus.h>
  11. #include <AzCore/Math/Vector2.h>
  12. #include <AzCore/Math/Aabb.h>
  13. #include <AzCore/Math/Color.h>
  14. #include <Atom/RHI.Reflect/Size.h>
  15. #include <Atom/RPI.Reflect/Image/Image.h>
  16. namespace Terrain
  17. {
  18. struct MacroMaterialData final
  19. {
  20. AZ_TYPE_INFO(MacroMaterialData, "{DC68E20A-3251-4E4E-8BC7-F6A2521FEF46}");
  21. static void Reflect(AZ::ReflectContext* context);
  22. AZ::EntityId m_entityId;
  23. AZ::Aabb m_bounds = AZ::Aabb::CreateNull();
  24. AZ::Data::Instance<AZ::RPI::Image> m_colorImage;
  25. AZ::Data::Instance<AZ::RPI::Image> m_normalImage;
  26. bool m_normalFlipX{ false };
  27. bool m_normalFlipY{ false };
  28. float m_normalFactor{ 0.0f };
  29. int32_t m_priority{ 0 };
  30. };
  31. /**
  32. * Request terrain macro material data.
  33. */
  34. class TerrainMacroMaterialRequests
  35. : public AZ::ComponentBus
  36. {
  37. public:
  38. static void Reflect(AZ::ReflectContext* context);
  39. ////////////////////////////////////////////////////////////////////////
  40. // EBusTraits
  41. using MutexType = AZStd::recursive_mutex;
  42. ////////////////////////////////////////////////////////////////////////
  43. virtual ~TerrainMacroMaterialRequests() = default;
  44. //! Get the terrain macro material and the region that it covers.
  45. virtual MacroMaterialData GetTerrainMacroMaterialData() = 0;
  46. //! Get the macro color image size in pixels
  47. //! @return Number of pixels in the image width, height, and depth
  48. virtual AZ::RHI::Size GetMacroColorImageSize() const
  49. {
  50. return { 0, 0, 0 };
  51. }
  52. //! Get the number of macro color pixels per meter in world space.
  53. //! @return The number of pixels in the X and Y direction in one world space meter.
  54. virtual AZ::Vector2 GetMacroColorImagePixelsPerMeter() const
  55. {
  56. return AZ::Vector2(0.0f, 0.0f);
  57. }
  58. };
  59. using TerrainMacroMaterialRequestBus = AZ::EBus<TerrainMacroMaterialRequests>;
  60. /**
  61. * Notifications for when the terrain macro material data changes.
  62. */
  63. class TerrainMacroMaterialNotifications : public AZ::EBusTraits
  64. {
  65. public:
  66. //! Allow multiple listeners to the notification bus.
  67. static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Multiple;
  68. //! Notifications are broadcast to everyone and don't require subscribing to a specific ID or address.
  69. //! This is because the systems that care about this information wouldn't know which entity IDs to listen to until after
  70. //! it received a "macro material created" event, which is one of the events sent out on this bus.
  71. //! So instead, all the events include which entity ID they affect, but don't require subscribing to specific entity IDs.
  72. static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single;
  73. //////////////////////////////////////////////////////////////////////////
  74. //! Notify any listeners that a new macro material has been created.
  75. //! @param macroMaterialEntity The Entity ID for the entity containing the macro material.
  76. //! @param macroMaterial The data for the newly-created macro material.
  77. virtual void OnTerrainMacroMaterialCreated(
  78. [[maybe_unused]] AZ::EntityId macroMaterialEntity,
  79. [[maybe_unused]] const MacroMaterialData& macroMaterial)
  80. {
  81. }
  82. //! Notify any listeners that the macro material data changed.
  83. //! @param macroMaterialEntity The Entity ID for the entity containing the macro material.
  84. //! @param macroMaterial The data for the changed macro material. (This data contains the new changes)
  85. virtual void OnTerrainMacroMaterialChanged(
  86. [[maybe_unused]] AZ::EntityId macroMaterialEntity, [[maybe_unused]] const MacroMaterialData& macroMaterial)
  87. {
  88. }
  89. //! Notify any listeners that the region affected by the macro material has changed (presumably by moving the transform or the box)
  90. //! @param macroMaterialEntity The Entity ID for the entity containing the macro material.
  91. //! @param oldRegion The previous region covered by the macro material.
  92. //! @param newRegion The new region covered by the macro material.
  93. virtual void OnTerrainMacroMaterialRegionChanged(
  94. [[maybe_unused]] AZ::EntityId macroMaterialEntity,
  95. [[maybe_unused]] const AZ::Aabb& oldRegion,
  96. [[maybe_unused]] const AZ::Aabb& newRegion)
  97. {
  98. }
  99. //! Notify any listeners that the macro material has been destroyed.
  100. //! @param macroMaterialEntity The Entity ID for the entity containing the macro material.
  101. virtual void OnTerrainMacroMaterialDestroyed([[maybe_unused]] AZ::EntityId macroMaterialEntity)
  102. {
  103. }
  104. };
  105. using TerrainMacroMaterialNotificationBus = AZ::EBus<TerrainMacroMaterialNotifications>;
  106. class ImageTileBuffer;
  107. using PixelIndex = AZStd::pair<int16_t, int16_t>;
  108. //! EBus that can be used to modify the image data for a Terrain Macro Color texture.
  109. //! The following APIs are the low-level image modification APIs that enable image modifications at the per-pixel level.
  110. class TerrainMacroColorModifications : public AZ::ComponentBus
  111. {
  112. public:
  113. // Overrides the default AZ::EBusTraits handler policy to allow only one listener per entity.
  114. static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Single;
  115. //! Start an image modification session.
  116. //! This will create a modification buffer that contains an uncompressed copy of the current macro color image data.
  117. virtual void StartMacroColorImageModification() = 0;
  118. //! Finish an image modification session.
  119. //! Clean up any helper structures used during image modification.
  120. virtual void EndMacroColorImageModification() = 0;
  121. //! Given a list of world positions, return a list of pixel indices into the image.
  122. //! @param positions The list of world positions to query
  123. //! @param outIndices [out] The list of output PixelIndex values giving the (x,y) pixel coordinates for each world position.
  124. virtual void GetMacroColorPixelIndicesForPositions(
  125. AZStd::span<const AZ::Vector3> positions, AZStd::span<PixelIndex> outIndices) const = 0;
  126. //! Get the image pixel values at a list of positions.
  127. //! @param positions The list of world positions to query
  128. //! @param outValues [out] The list of output values. This list is expected to be the same size as the positions list.
  129. virtual void GetMacroColorPixelValuesByPosition(AZStd::span<const AZ::Vector3> positions, AZStd::span<AZ::Color> outValues) const = 0;
  130. //! Get the image pixel values at a list of pixel indices.
  131. //! @param positions The list of pixel indices to query
  132. //! @param outValues [out] The list of output values. This list is expected to be the same size as the positions list.
  133. virtual void GetMacroColorPixelValuesByPixelIndex(AZStd::span<const PixelIndex> indices, AZStd::span<AZ::Color> outValues) const = 0;
  134. //! Start a series of pixel modifications.
  135. //! This will track all of the pixels modified so that they can be updated once at the end.
  136. virtual void StartMacroColorPixelModifications() = 0;
  137. //! End a series of pixel modifications.
  138. //! This will notify that the series of pixel modifications have ended, so buffer refreshes can now happen.
  139. virtual void EndMacroColorPixelModifications() = 0;
  140. //! Given a list of pixel indices, set those pixels to the given values.
  141. //! @param indicdes The list of pixel indices to set the values for.
  142. //! @param values The list of values to set. This list is expected to be the same size as the positions list.
  143. virtual void SetMacroColorPixelValuesByPixelIndex(AZStd::span<const PixelIndex> indices, AZStd::span<const AZ::Color> values) = 0;
  144. };
  145. using TerrainMacroColorModificationBus = AZ::EBus<TerrainMacroColorModifications>;
  146. //! EBus that notifies about the current state of Terrain Macro Color modifications
  147. class TerrainMacroColorModificationNotifications : public AZ::ComponentBus
  148. {
  149. public:
  150. //! Notify any listeners that a brush stroke has started on the macro color image.
  151. virtual void OnTerrainMacroColorBrushStrokeBegin() {}
  152. //! Notify any listeners that a brush stroke has ended on the macro color image.
  153. //! @param changedDataBuffer A pointer to the ImageTileBuffer containing the changed data. The buffer will be deleted
  154. //! after this notification unless a listener keeps a copy of the pointer (for undo/redo, for example).
  155. //! @param dirtyRegion The AABB defining the world space region affected by the brush stroke.
  156. virtual void OnTerrainMacroColorBrushStrokeEnd(
  157. [[maybe_unused]] AZStd::shared_ptr<ImageTileBuffer> changedDataBuffer, [[maybe_unused]] const AZ::Aabb& dirtyRegion)
  158. {
  159. }
  160. };
  161. using TerrainMacroColorModificationNotificationBus = AZ::EBus<TerrainMacroColorModificationNotifications>;
  162. }