TerrainWorldComponent.cpp 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  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 <Components/TerrainWorldComponent.h>
  9. #include <AzCore/Asset/AssetManager.h>
  10. #include <AzCore/Asset/AssetManagerBus.h>
  11. #include <AzCore/Component/Entity.h>
  12. #include <AzCore/RTTI/BehaviorContext.h>
  13. #include <AzCore/Serialization/EditContext.h>
  14. #include <AzCore/Serialization/SerializeContext.h>
  15. namespace Terrain
  16. {
  17. AZ::JsonSerializationResult::Result JsonTerrainWorldConfigSerializer::Load(
  18. void* outputValue, [[maybe_unused]] const AZ::Uuid& outputValueTypeId,
  19. const rapidjson::Value& inputValue, AZ::JsonDeserializerContext& context)
  20. {
  21. namespace JSR = AZ::JsonSerializationResult;
  22. auto configInstance = reinterpret_cast<TerrainWorldConfig*>(outputValue);
  23. AZ_Assert(configInstance, "Output value for JsonTerrainWorldConfigSerializer can't be null.");
  24. JSR::ResultCode result(JSR::Tasks::ReadField);
  25. auto arrayFloatToSingleValue = [&](const char* oldName, const char* newName, auto& dataRef, uint32_t index)
  26. {
  27. rapidjson::Value::ConstMemberIterator itr = inputValue.FindMember(oldName);
  28. if (itr != inputValue.MemberEnd() && itr->value.IsArray())
  29. {
  30. dataRef = itr->value.GetArray()[index].GetFloat();
  31. }
  32. else
  33. {
  34. result.Combine(ContinueLoadingFromJsonObjectField(
  35. &dataRef, azrtti_typeid<decltype(dataRef)>(), inputValue, rapidjson::GenericStringRef<char>(newName), context));
  36. }
  37. };
  38. arrayFloatToSingleValue("WorldMin", "MinHeight", configInstance->m_minHeight, 2);
  39. arrayFloatToSingleValue("WorldMax", "MaxHeight", configInstance->m_maxHeight, 2);
  40. arrayFloatToSingleValue("HeightQueryResolution", "HeightQueryResolution", configInstance->m_heightQueryResolution, 0);
  41. result.Combine(ContinueLoadingFromJsonObjectField(
  42. &configInstance->m_surfaceDataQueryResolution, azrtti_typeid<decltype(configInstance->m_surfaceDataQueryResolution)>(),
  43. inputValue, "SurfaceDataQueryResolution", context));
  44. return context.Report(result,
  45. result.GetProcessing() != JSR::Processing::Halted ?
  46. "Successfully loaded TerrainWorldConfig information." :
  47. "Failed to load TerrainWorldConfig information.");
  48. }
  49. AZ_CLASS_ALLOCATOR_IMPL(JsonTerrainWorldConfigSerializer, AZ::SystemAllocator);
  50. void TerrainWorldConfig::Reflect(AZ::ReflectContext* context)
  51. {
  52. if (auto jsonContext = azrtti_cast<AZ::JsonRegistrationContext*>(context))
  53. {
  54. jsonContext->Serializer<JsonTerrainWorldConfigSerializer>()->HandlesType<TerrainWorldConfig>();
  55. }
  56. AZ::SerializeContext* serialize = azrtti_cast<AZ::SerializeContext*>(context);
  57. if (serialize)
  58. {
  59. serialize->Class<TerrainWorldConfig, AZ::ComponentConfig>()
  60. ->Version(4)
  61. ->Field("MinHeight", &TerrainWorldConfig::m_minHeight)
  62. ->Field("MaxHeight", &TerrainWorldConfig::m_maxHeight)
  63. ->Field("HeightQueryResolution", &TerrainWorldConfig::m_heightQueryResolution)
  64. ->Field("SurfaceDataQueryResolution", &TerrainWorldConfig::m_surfaceDataQueryResolution)
  65. ;
  66. AZ::EditContext* edit = serialize->GetEditContext();
  67. if (edit)
  68. {
  69. edit->Class<TerrainWorldConfig>("Terrain World Component", "Data required for the terrain system to run")
  70. ->ClassElement(AZ::Edit::ClassElements::EditorData, "")
  71. ->Attribute(AZ::Edit::Attributes::AppearsInAddComponentMenu, AZStd::vector<AZ::Crc32>({ AZ_CRC_CE("Level") }))
  72. ->Attribute(AZ::Edit::Attributes::Visibility, AZ::Edit::PropertyVisibility::ShowChildrenOnly)
  73. ->Attribute(AZ::Edit::Attributes::AutoExpand, true)
  74. ->DataElement(AZ::Edit::UIHandlers::Default, &TerrainWorldConfig::m_minHeight, "Min Height", "")
  75. ->Attribute(AZ::Edit::Attributes::SoftMin, -1000.0f)
  76. ->Attribute(AZ::Edit::Attributes::SoftMax, 1000.0f)
  77. ->Attribute(AZ::Edit::Attributes::Min, -65536.0f)
  78. ->Attribute(AZ::Edit::Attributes::Max, 65536.0f)
  79. ->Attribute(AZ::Edit::Attributes::ChangeValidate, &TerrainWorldConfig::ValidateHeightMin)
  80. ->DataElement(AZ::Edit::UIHandlers::Default, &TerrainWorldConfig::m_maxHeight, "Max Height", "")
  81. ->Attribute(AZ::Edit::Attributes::SoftMin, -1000.0f)
  82. ->Attribute(AZ::Edit::Attributes::SoftMax, 1000.0f)
  83. ->Attribute(AZ::Edit::Attributes::Min, -65536.0f)
  84. ->Attribute(AZ::Edit::Attributes::Max, 65536.0f)
  85. ->Attribute(AZ::Edit::Attributes::ChangeValidate, &TerrainWorldConfig::ValidateHeightMax)
  86. ->DataElement(
  87. AZ::Edit::UIHandlers::Default, &TerrainWorldConfig::m_heightQueryResolution, "Height Query Resolution (m)", "")
  88. ->Attribute(AZ::Edit::Attributes::Min, 0.1f)
  89. ->DataElement(
  90. AZ::Edit::UIHandlers::Default, &TerrainWorldConfig::m_surfaceDataQueryResolution, "Surface Data Query Resolution (m)", "")
  91. ->Attribute(AZ::Edit::Attributes::Min, 0.1f)
  92. ;
  93. }
  94. }
  95. }
  96. void TerrainWorldComponent::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& services)
  97. {
  98. services.push_back(AZ_CRC_CE("TerrainService"));
  99. }
  100. void TerrainWorldComponent::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& services)
  101. {
  102. services.push_back(AZ_CRC_CE("TerrainService"));
  103. }
  104. void TerrainWorldComponent::GetRequiredServices([[maybe_unused]] AZ::ComponentDescriptor::DependencyArrayType& services)
  105. {
  106. }
  107. void TerrainWorldComponent::Reflect(AZ::ReflectContext* context)
  108. {
  109. TerrainWorldConfig::Reflect(context);
  110. AZ::SerializeContext* serialize = azrtti_cast<AZ::SerializeContext*>(context);
  111. if (serialize)
  112. {
  113. serialize->Class<TerrainWorldComponent, AZ::Component>()
  114. ->Version(0)
  115. ->Field("Configuration", &TerrainWorldComponent::m_configuration)
  116. ;
  117. }
  118. }
  119. TerrainWorldComponent::TerrainWorldComponent(const TerrainWorldConfig& configuration)
  120. : m_configuration(configuration)
  121. {
  122. }
  123. TerrainWorldComponent::~TerrainWorldComponent()
  124. {
  125. }
  126. void TerrainWorldComponent::Activate()
  127. {
  128. // Currently, the Terrain System Component owns the Terrain System instance because the Terrain World component gets recreated
  129. // every time an entity is added or removed to a level. If this ever changes, the Terrain System ownership could move into
  130. // the level component.
  131. TerrainSystemServiceRequestBus::Broadcast(&TerrainSystemServiceRequestBus::Events::Activate);
  132. AzFramework::Terrain::TerrainDataRequestBus::Broadcast(
  133. &AzFramework::Terrain::TerrainDataRequestBus::Events::SetTerrainHeightBounds,
  134. AzFramework::Terrain::FloatRange({ m_configuration.m_minHeight, m_configuration.m_maxHeight }));
  135. AzFramework::Terrain::TerrainDataRequestBus::Broadcast(
  136. &AzFramework::Terrain::TerrainDataRequestBus::Events::SetTerrainHeightQueryResolution, m_configuration.m_heightQueryResolution);
  137. AzFramework::Terrain::TerrainDataRequestBus::Broadcast(
  138. &AzFramework::Terrain::TerrainDataRequestBus::Events::SetTerrainSurfaceDataQueryResolution, m_configuration.m_surfaceDataQueryResolution);
  139. }
  140. void TerrainWorldComponent::Deactivate()
  141. {
  142. TerrainSystemServiceRequestBus::Broadcast(&TerrainSystemServiceRequestBus::Events::Deactivate);
  143. }
  144. bool TerrainWorldComponent::ReadInConfig(const AZ::ComponentConfig* baseConfig)
  145. {
  146. if (auto config = azrtti_cast<const TerrainWorldConfig*>(baseConfig))
  147. {
  148. m_configuration = *config;
  149. return true;
  150. }
  151. return false;
  152. }
  153. bool TerrainWorldComponent::WriteOutConfig(AZ::ComponentConfig* outBaseConfig) const
  154. {
  155. if (auto config = azrtti_cast<TerrainWorldConfig*>(outBaseConfig))
  156. {
  157. *config = m_configuration;
  158. return true;
  159. }
  160. return false;
  161. }
  162. } // namespace Terrain