SlopeAlignmentModifierComponent.cpp 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  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 "SlopeAlignmentModifierComponent.h"
  9. #include <AzCore/Component/Entity.h>
  10. #include <AzCore/Math/Matrix3x3.h>
  11. #include <AzCore/RTTI/BehaviorContext.h>
  12. #include <AzCore/Serialization/EditContext.h>
  13. #include <AzCore/Serialization/SerializeContext.h>
  14. #include <Vegetation/Descriptor.h>
  15. #include <GradientSignal/Ebuses/GradientRequestBus.h>
  16. #include <Vegetation/InstanceData.h>
  17. #include <AzCore/Debug/Profiler.h>
  18. #include <VegetationProfiler.h>
  19. namespace Vegetation
  20. {
  21. void SlopeAlignmentModifierConfig::Reflect(AZ::ReflectContext* context)
  22. {
  23. AZ::SerializeContext* serialize = azrtti_cast<AZ::SerializeContext*>(context);
  24. if (serialize)
  25. {
  26. serialize->Class<SlopeAlignmentModifierConfig, AZ::ComponentConfig>()
  27. ->Version(0)
  28. ->Field("AllowOverrides", &SlopeAlignmentModifierConfig::m_allowOverrides)
  29. ->Field("RangeMin", &SlopeAlignmentModifierConfig::m_rangeMin)
  30. ->Field("RangeMax", &SlopeAlignmentModifierConfig::m_rangeMax)
  31. ->Field("Gradient", &SlopeAlignmentModifierConfig::m_gradientSampler)
  32. ;
  33. AZ::EditContext* edit = serialize->GetEditContext();
  34. if (edit)
  35. {
  36. edit->Class<SlopeAlignmentModifierConfig>(
  37. "Vegetation Slope Alignment Modifier", "")
  38. ->ClassElement(AZ::Edit::ClassElements::EditorData, "")
  39. ->Attribute(AZ::Edit::Attributes::Visibility, AZ::Edit::PropertyVisibility::ShowChildrenOnly)
  40. ->Attribute(AZ::Edit::Attributes::AutoExpand, true)
  41. ->DataElement(AZ::Edit::UIHandlers::CheckBox, &SlopeAlignmentModifierConfig::m_allowOverrides, "Allow Per-Item Overrides", "Allow per-descriptor parameters to override component parameters.")
  42. ->DataElement(AZ::Edit::UIHandlers::Slider, &SlopeAlignmentModifierConfig::m_rangeMin, "Alignment Coefficient Min", "Minimum slope alignment coefficient.")
  43. ->Attribute(AZ::Edit::Attributes::Min, 0.0f)
  44. ->Attribute(AZ::Edit::Attributes::Max, 1.0f)
  45. ->DataElement(AZ::Edit::UIHandlers::Slider, &SlopeAlignmentModifierConfig::m_rangeMax, "Alignment Coefficient Max", "Maximum slope alignment coefficient.")
  46. ->Attribute(AZ::Edit::Attributes::Min, 0.0f)
  47. ->Attribute(AZ::Edit::Attributes::Max, 1.0f)
  48. ->DataElement(0, &SlopeAlignmentModifierConfig::m_gradientSampler, "Gradient", "Gradient used as blend factor to lerp between ranges.")
  49. ;
  50. }
  51. }
  52. if (auto behaviorContext = azrtti_cast<AZ::BehaviorContext*>(context))
  53. {
  54. behaviorContext->Class<SlopeAlignmentModifierConfig>()
  55. ->Attribute(AZ::Script::Attributes::Category, "Vegetation")
  56. ->Constructor()
  57. ->Property("allowOverrides", BehaviorValueProperty(&SlopeAlignmentModifierConfig::m_allowOverrides))
  58. ->Property("rangeMin", BehaviorValueProperty(&SlopeAlignmentModifierConfig::m_rangeMin))
  59. ->Property("rangeMax", BehaviorValueProperty(&SlopeAlignmentModifierConfig::m_rangeMax))
  60. ->Property("gradientSampler", BehaviorValueProperty(&SlopeAlignmentModifierConfig::m_gradientSampler))
  61. ;
  62. }
  63. }
  64. void SlopeAlignmentModifierComponent::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& services)
  65. {
  66. services.push_back(AZ_CRC_CE("VegetationModifierService"));
  67. services.push_back(AZ_CRC_CE("VegetationAlignmentModifierService"));
  68. }
  69. void SlopeAlignmentModifierComponent::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& services)
  70. {
  71. services.push_back(AZ_CRC_CE("VegetationAlignmentModifierService"));
  72. }
  73. void SlopeAlignmentModifierComponent::GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& services)
  74. {
  75. services.push_back(AZ_CRC_CE("VegetationAreaService"));
  76. }
  77. void SlopeAlignmentModifierComponent::Reflect(AZ::ReflectContext* context)
  78. {
  79. SlopeAlignmentModifierConfig::Reflect(context);
  80. AZ::SerializeContext* serialize = azrtti_cast<AZ::SerializeContext*>(context);
  81. if (serialize)
  82. {
  83. serialize->Class<SlopeAlignmentModifierComponent, AZ::Component>()
  84. ->Version(0)
  85. ->Field("Configuration", &SlopeAlignmentModifierComponent::m_configuration)
  86. ;
  87. }
  88. if (auto behaviorContext = azrtti_cast<AZ::BehaviorContext*>(context))
  89. {
  90. behaviorContext->Constant("SlopeAlignmentModifierComponentTypeId", BehaviorConstant(SlopeAlignmentModifierComponentTypeId));
  91. behaviorContext->Class<SlopeAlignmentModifierComponent>()->RequestBus("SlopeAlignmentModifierRequestBus");
  92. behaviorContext->EBus<SlopeAlignmentModifierRequestBus>("SlopeAlignmentModifierRequestBus")
  93. ->Attribute(AZ::Script::Attributes::Category, "Vegetation")
  94. ->Event("GetAllowOverrides", &SlopeAlignmentModifierRequestBus::Events::GetAllowOverrides)
  95. ->Event("SetAllowOverrides", &SlopeAlignmentModifierRequestBus::Events::SetAllowOverrides)
  96. ->VirtualProperty("AllowOverrides", "GetAllowOverrides", "SetAllowOverrides")
  97. ->Event("GetRangeMin", &SlopeAlignmentModifierRequestBus::Events::GetRangeMin)
  98. ->Event("SetRangeMin", &SlopeAlignmentModifierRequestBus::Events::SetRangeMin)
  99. ->VirtualProperty("RangeMin", "GetRangeMin", "SetRangeMin")
  100. ->Event("GetRangeMax", &SlopeAlignmentModifierRequestBus::Events::GetRangeMax)
  101. ->Event("SetRangeMax", &SlopeAlignmentModifierRequestBus::Events::SetRangeMax)
  102. ->VirtualProperty("RangeMax", "GetRangeMax", "SetRangeMax")
  103. ->Event("GetGradientSampler", &SlopeAlignmentModifierRequestBus::Events::GetGradientSampler)
  104. ;
  105. }
  106. }
  107. SlopeAlignmentModifierComponent::SlopeAlignmentModifierComponent(const SlopeAlignmentModifierConfig& configuration)
  108. : m_configuration(configuration)
  109. {
  110. }
  111. void SlopeAlignmentModifierComponent::Activate()
  112. {
  113. m_dependencyMonitor.Reset();
  114. m_dependencyMonitor.ConnectOwner(GetEntityId());
  115. m_dependencyMonitor.ConnectDependencies({ m_configuration.m_gradientSampler.m_gradientId });
  116. ModifierRequestBus::Handler::BusConnect(GetEntityId());
  117. SlopeAlignmentModifierRequestBus::Handler::BusConnect(GetEntityId());
  118. }
  119. void SlopeAlignmentModifierComponent::Deactivate()
  120. {
  121. m_dependencyMonitor.Reset();
  122. ModifierRequestBus::Handler::BusDisconnect();
  123. SlopeAlignmentModifierRequestBus::Handler::BusDisconnect();
  124. }
  125. bool SlopeAlignmentModifierComponent::ReadInConfig(const AZ::ComponentConfig* baseConfig)
  126. {
  127. if (auto config = azrtti_cast<const SlopeAlignmentModifierConfig*>(baseConfig))
  128. {
  129. m_configuration = *config;
  130. return true;
  131. }
  132. return false;
  133. }
  134. bool SlopeAlignmentModifierComponent::WriteOutConfig(AZ::ComponentConfig* outBaseConfig) const
  135. {
  136. if (auto config = azrtti_cast<SlopeAlignmentModifierConfig*>(outBaseConfig))
  137. {
  138. *config = m_configuration;
  139. return true;
  140. }
  141. return false;
  142. }
  143. void SlopeAlignmentModifierComponent::Execute(InstanceData& instanceData) const
  144. {
  145. AZ_PROFILE_FUNCTION(Vegetation);
  146. const bool useOverrides = m_configuration.m_allowOverrides && instanceData.m_descriptorPtr && instanceData.m_descriptorPtr->m_surfaceAlignmentOverrideEnabled;
  147. const float min = useOverrides ? instanceData.m_descriptorPtr->m_surfaceAlignmentMin : m_configuration.m_rangeMin;
  148. const float max = useOverrides ? instanceData.m_descriptorPtr->m_surfaceAlignmentMax : m_configuration.m_rangeMax;
  149. const GradientSignal::GradientSampleParams sampleParams(instanceData.m_position);
  150. const float factor = m_configuration.m_gradientSampler.GetValue(sampleParams) * (max - min) + min;
  151. AZ::Vector3 r = AZ::Vector3(-1.0f, 0.0f, 0.0f);
  152. AZ::Vector3 f = AZ::Vector3(0.0f, 1.0f, 0.0f);
  153. AZ::Vector3 u = AZ::Vector3(0.0f, 0.0f, 1.0f);
  154. u = u.Lerp(instanceData.m_normal, factor);
  155. u.Normalize();
  156. f = r.Cross(u);
  157. f.Normalize();
  158. r = f.Cross(u);
  159. r.Normalize();
  160. instanceData.m_alignment = AZ::Quaternion::CreateFromMatrix3x3(AZ::Matrix3x3::CreateFromColumns(r, f, u));
  161. }
  162. bool SlopeAlignmentModifierComponent::GetAllowOverrides() const
  163. {
  164. return m_configuration.m_allowOverrides;
  165. }
  166. void SlopeAlignmentModifierComponent::SetAllowOverrides(bool value)
  167. {
  168. m_configuration.m_allowOverrides = value;
  169. LmbrCentral::DependencyNotificationBus::Event(GetEntityId(), &LmbrCentral::DependencyNotificationBus::Events::OnCompositionChanged);
  170. }
  171. float SlopeAlignmentModifierComponent::GetRangeMin() const
  172. {
  173. return m_configuration.m_rangeMin;
  174. }
  175. void SlopeAlignmentModifierComponent::SetRangeMin(float rangeMin)
  176. {
  177. m_configuration.m_rangeMin = rangeMin;
  178. LmbrCentral::DependencyNotificationBus::Event(GetEntityId(), &LmbrCentral::DependencyNotificationBus::Events::OnCompositionChanged);
  179. }
  180. float SlopeAlignmentModifierComponent::GetRangeMax() const
  181. {
  182. return m_configuration.m_rangeMax;
  183. }
  184. void SlopeAlignmentModifierComponent::SetRangeMax(float rangeMax)
  185. {
  186. m_configuration.m_rangeMax = rangeMax;
  187. LmbrCentral::DependencyNotificationBus::Event(GetEntityId(), &LmbrCentral::DependencyNotificationBus::Events::OnCompositionChanged);
  188. }
  189. GradientSignal::GradientSampler& SlopeAlignmentModifierComponent::GetGradientSampler()
  190. {
  191. return m_configuration.m_gradientSampler;
  192. }
  193. }