GradientPreviewer.cpp 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  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. #include <AzCore/Component/TransformBus.h>
  9. #include <GradientSignal/Ebuses/GradientPreviewRequestBus.h>
  10. #include <GradientSignal/Editor/GradientPreviewer.h>
  11. #include <LmbrCentral/Shape/ShapeComponentBus.h>
  12. namespace GradientSignal
  13. {
  14. void GradientPreviewer::Reflect(AZ::ReflectContext* context)
  15. {
  16. if (auto serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
  17. {
  18. serializeContext->Class<GradientPreviewer>()
  19. ->Version(0)
  20. ->Field("BoundsEntity", &GradientPreviewer::m_boundsEntityId)
  21. ->Field("PreviewCenter", &GradientPreviewer::m_previewCenter)
  22. ->Field("PreviewExtents", &GradientPreviewer::m_previewExtents)
  23. ->Field("ConstrainToShape", &GradientPreviewer::m_constrainToShape)
  24. ;
  25. if (auto editContext = serializeContext->GetEditContext())
  26. {
  27. editContext
  28. ->Class<GradientPreviewer>("Previewer", "")
  29. ->ClassElement(AZ::Edit::ClassElements::Group, "Preview")
  30. ->Attribute(AZ::Edit::Attributes::Visibility, AZ::Edit::PropertyVisibility::ShowChildrenOnly)
  31. ->UIElement(AZ_CRC_CE("GradientPreviewer"), "Previewer")
  32. ->Attribute(AZ::Edit::Attributes::NameLabelOverride, "")
  33. ->Attribute(AZ_CRC_CE("GradientEntity"), &GradientPreviewer::GetGradientEntityId)
  34. ->ClassElement(AZ::Edit::ClassElements::Group, "Preview Settings")
  35. ->Attribute(AZ::Edit::Attributes::Visibility, &GradientPreviewer::GetPreviewSettingsVisibility)
  36. ->DataElement(AZ::Edit::UIHandlers::Default, &GradientPreviewer::m_boundsEntityId, "Pin Preview to Shape",
  37. "The entity whose shape represents the bounds to render the gradient preview")
  38. ->Attribute(AZ::Edit::Attributes::ChangeNotify, &GradientPreviewer::PreviewSettingsAndSettingsVisibilityChanged)
  39. ->Attribute(AZ::Edit::Attributes::Visibility, &GradientPreviewer::GetPreviewSettingsVisibility)
  40. ->DataElement(AZ::Edit::UIHandlers::Default, &GradientPreviewer::m_previewCenter, "Preview Position",
  41. "Center of the preview bounds")
  42. ->Attribute(AZ::Edit::Attributes::ChangeNotify, &GradientPreviewer::RefreshPreview)
  43. ->Attribute(AZ::Edit::Attributes::Visibility, &GradientPreviewer::GetPreviewPositionVisibility)
  44. ->DataElement(
  45. AZ::Edit::UIHandlers::Default, &GradientPreviewer::m_previewExtents, "Preview Size", "Size of the preview bounds")
  46. ->Attribute(AZ::Edit::Attributes::ChangeNotify, &GradientPreviewer::RefreshPreview)
  47. ->Attribute(AZ::Edit::Attributes::Visibility, &GradientPreviewer::GetPreviewSizeVisibility)
  48. ->DataElement(AZ::Edit::UIHandlers::Default, &GradientPreviewer::m_constrainToShape, "Constrain to Shape",
  49. "If checked, only renders the parts of the gradient inside the component's shape and not its entire bounding box")
  50. ->Attribute(AZ::Edit::Attributes::ChangeNotify, &GradientPreviewer::RefreshPreview)
  51. ->Attribute(AZ::Edit::Attributes::Visibility, &GradientPreviewer::GetPreviewConstrainToShapeVisibility)
  52. ->EndGroup()
  53. ;
  54. }
  55. }
  56. }
  57. void GradientPreviewer::Activate(AZ::EntityId ownerEntityId)
  58. {
  59. m_ownerEntityId = ownerEntityId;
  60. AzToolsFramework::EntitySelectionEvents::Bus::Handler::BusConnect(ownerEntityId);
  61. GradientPreviewContextRequestBus::Handler::BusConnect(ownerEntityId);
  62. RefreshPreview();
  63. }
  64. void GradientPreviewer::Deactivate()
  65. {
  66. // If the preview shouldn't be active, use an invalid entityId
  67. m_ownerEntityId = AZ::EntityId();
  68. AzToolsFramework::EntitySelectionEvents::Bus::Handler::BusDisconnect();
  69. GradientPreviewContextRequestBus::Handler::BusDisconnect();
  70. }
  71. AZ::EntityId GradientPreviewer::GetActiveBoundsEntityId() const
  72. {
  73. if (m_boundsEntityId.IsValid())
  74. {
  75. return m_boundsEntityId;
  76. }
  77. // If there's no bounds entity already set, then default it to the owning entity.
  78. return m_ownerEntityId;
  79. }
  80. bool GradientPreviewer::GetPreviewSettingsVisible() const
  81. {
  82. return m_previewSettingsVisible;
  83. }
  84. void GradientPreviewer::SetPreviewSettingsVisible(bool visible)
  85. {
  86. m_previewSettingsVisible = visible;
  87. }
  88. AZ::u32 GradientPreviewer::GetPreviewSettingsVisibility() const
  89. {
  90. return m_previewSettingsVisible ? AZ::Edit::PropertyVisibility::Show : AZ::Edit::PropertyVisibility::Hide;
  91. }
  92. AZ::u32 GradientPreviewer::GetPreviewPositionVisibility() const
  93. {
  94. return (GetActiveBoundsEntityId().IsValid() || !m_previewSettingsVisible)
  95. ? AZ::Edit::PropertyVisibility::Hide : AZ::Edit::PropertyVisibility::Show;
  96. }
  97. AZ::u32 GradientPreviewer::GetPreviewSizeVisibility() const
  98. {
  99. if (GetActiveBoundsEntityId().IsValid())
  100. {
  101. AZ::Aabb bounds = AZ::Aabb::CreateNull();
  102. LmbrCentral::ShapeComponentRequestsBus::EventResult(
  103. bounds, GetActiveBoundsEntityId(), &LmbrCentral::ShapeComponentRequestsBus::Events::GetEncompassingAabb);
  104. if (bounds.IsValid())
  105. {
  106. return AZ::Edit::PropertyVisibility::Hide;
  107. }
  108. }
  109. return m_previewSettingsVisible ? AZ::Edit::PropertyVisibility::Show : AZ::Edit::PropertyVisibility::Hide;
  110. }
  111. AZ::u32 GradientPreviewer::GetPreviewConstrainToShapeVisibility() const
  112. {
  113. return (GetActiveBoundsEntityId().IsValid() && m_previewSettingsVisible)
  114. ? AZ::Edit::PropertyVisibility::Show : AZ::Edit::PropertyVisibility::Hide;
  115. }
  116. AZ::u32 GradientPreviewer::PreviewSettingsAndSettingsVisibilityChanged() const
  117. {
  118. RefreshPreview();
  119. // We've changed the visibility of one or more properties, so refresh the entire component.
  120. return AZ::Edit::PropertyRefreshLevels::EntireTree;
  121. }
  122. void GradientPreviewer::OnSelected()
  123. {
  124. RefreshPreview();
  125. }
  126. void GradientPreviewer::OnDeselected()
  127. {
  128. RefreshPreview();
  129. }
  130. AZ::EntityId GradientPreviewer::GetPreviewEntity() const
  131. {
  132. return GetActiveBoundsEntityId();
  133. }
  134. void GradientPreviewer::SetPreviewEntity(AZ::EntityId boundsEntityId)
  135. {
  136. m_boundsEntityId = boundsEntityId;
  137. }
  138. AZ::Aabb GradientPreviewer::GetPreviewBounds() const
  139. {
  140. AZ::Vector3 position = m_previewCenter;
  141. // if a shape entity was supplied, attempt to use its shape bounds or position
  142. if (GetActiveBoundsEntityId().IsValid())
  143. {
  144. AZ::Aabb bounds = AZ::Aabb::CreateNull();
  145. LmbrCentral::ShapeComponentRequestsBus::EventResult(
  146. bounds, GetActiveBoundsEntityId(), &LmbrCentral::ShapeComponentRequestsBus::Events::GetEncompassingAabb);
  147. if (bounds.IsValid())
  148. {
  149. return bounds;
  150. }
  151. AZ::TransformBus::EventResult(position, GetActiveBoundsEntityId(), &AZ::TransformBus::Events::GetWorldTranslation);
  152. }
  153. return AZ::Aabb::CreateCenterHalfExtents(position, m_previewExtents / 2.0f);
  154. }
  155. bool GradientPreviewer::GetConstrainToShape() const
  156. {
  157. return m_constrainToShape && GetActiveBoundsEntityId().IsValid();
  158. }
  159. AZ::EntityId GradientPreviewer::GetGradientEntityId() const
  160. {
  161. return m_ownerEntityId;
  162. }
  163. void GradientPreviewer::RefreshPreview() const
  164. {
  165. // Trigger an update just for our specific preview (this means there was a preview-specific change, not an actual configuration
  166. // change)
  167. RefreshPreviews({ m_ownerEntityId });
  168. }
  169. void GradientPreviewer::RefreshPreviews(const AzToolsFramework::EntityIdList& entities)
  170. {
  171. for (auto entityId : entities)
  172. {
  173. GradientSignal::GradientPreviewRequestBus::Event(entityId, &GradientSignal::GradientPreviewRequestBus::Events::Refresh);
  174. }
  175. }
  176. AzToolsFramework::EntityIdList GradientPreviewer::CancelPreviewRendering()
  177. {
  178. AzToolsFramework::EntityIdList entityIds;
  179. AZ::EBusAggregateResults<AZ::EntityId> canceledPreviews;
  180. GradientSignal::GradientPreviewRequestBus::BroadcastResult(
  181. canceledPreviews, &GradientSignal::GradientPreviewRequestBus::Events::CancelRefresh);
  182. // Gather up the EntityIds for any previews that were in progress when we canceled them
  183. for (auto entityId : canceledPreviews.values)
  184. {
  185. if (entityId.IsValid())
  186. {
  187. entityIds.push_back(entityId);
  188. }
  189. }
  190. return entityIds;
  191. }
  192. } // namespace GradientSignal