EditorTerrainPhysicsColliderComponent.cpp 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  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 <EditorComponents/EditorTerrainPhysicsColliderComponent.h>
  9. #include <AzCore/Serialization/SerializeContext.h>
  10. #include <AzCore/Serialization/EditContext.h>
  11. #include <AzFramework/Physics/Material/PhysicsMaterialManager.h>
  12. namespace Terrain
  13. {
  14. static AZ::Data::AssetId GetDefaultPhysicsMaterialAssetId()
  15. {
  16. // Used for Edit Context.
  17. // When the physics material asset property doesn't have an asset assigned it
  18. // will show "(default)" to indicate that the default material will be used.
  19. if (auto* materialManager = AZ::Interface<Physics::MaterialManager>::Get())
  20. {
  21. if (AZStd::shared_ptr<Physics::Material> defaultMaterial = materialManager->GetDefaultMaterial())
  22. {
  23. return defaultMaterial->GetMaterialAsset().GetId();
  24. }
  25. }
  26. return {};
  27. }
  28. void EditorTerrainPhysicsColliderComponent::Reflect(AZ::ReflectContext* context)
  29. {
  30. if (auto serialize = azrtti_cast<AZ::SerializeContext*>(context))
  31. {
  32. serialize->Class<EditorTerrainPhysicsColliderComponent, AzToolsFramework::Components::EditorComponentBase>()
  33. ->Version(1)
  34. ->Field("Configuration", &EditorTerrainPhysicsColliderComponent::m_configuration)
  35. ;
  36. if (auto edit = serialize->GetEditContext())
  37. {
  38. edit->Class<TerrainPhysicsSurfaceMaterialMapping>(
  39. "Terrain Surface Material Mapping", "Mapping between a surface and a physics material.")
  40. ->ClassElement(AZ::Edit::ClassElements::EditorData, "")
  41. ->Attribute(AZ::Edit::Attributes::AutoExpand, true)
  42. ->Attribute(AZ::Edit::Attributes::Visibility, AZ::Edit::PropertyVisibility::Show)
  43. ->DataElement(
  44. AZ::Edit::UIHandlers::ComboBox, &TerrainPhysicsSurfaceMaterialMapping::m_surfaceTag, "Surface Tag",
  45. "Surface type to map to a physics material.")
  46. ->Attribute(AZ::Edit::Attributes::EnumValues, &TerrainPhysicsSurfaceMaterialMapping::BuildSelectableTagList)
  47. ->DataElement(AZ::Edit::UIHandlers::Default, &TerrainPhysicsSurfaceMaterialMapping::m_materialAsset, "Material Asset", "")
  48. ->Attribute(AZ::Edit::Attributes::DefaultAsset, &GetDefaultPhysicsMaterialAssetId)
  49. ->Attribute(AZ_CRC_CE("EditButton"), "")
  50. ->Attribute(AZ_CRC_CE("EditDescription"), "Open in Asset Editor")
  51. ->Attribute(AZ_CRC_CE("DisableEditButtonWhenNoAssetSelected"), true)
  52. ;
  53. edit->Class<TerrainPhysicsColliderConfig>(
  54. "Terrain Physics Collider Component",
  55. "Provides terrain data to a physics collider with configurable surface mappings.")
  56. ->ClassElement(AZ::Edit::ClassElements::EditorData, "")
  57. ->Attribute(AZ::Edit::Attributes::Visibility, AZ::Edit::PropertyVisibility::ShowChildrenOnly)
  58. ->Attribute(AZ::Edit::Attributes::AutoExpand, true)
  59. ->DataElement(AZ::Edit::UIHandlers::Default, &TerrainPhysicsColliderConfig::m_defaultMaterialAsset,
  60. "Default Surface Physics Material", "Select a material to be used by unmapped surfaces by default")
  61. ->Attribute(AZ::Edit::Attributes::DefaultAsset, &GetDefaultPhysicsMaterialAssetId)
  62. ->Attribute(AZ_CRC_CE("EditButton"), "")
  63. ->Attribute(AZ_CRC_CE("EditDescription"), "Open in Asset Editor")
  64. ->Attribute(AZ_CRC_CE("DisableEditButtonWhenNoAssetSelected"), true)
  65. ->DataElement(
  66. AZ::Edit::UIHandlers::Default, &TerrainPhysicsColliderConfig::m_surfaceMaterialMappings,
  67. "Surface to Material Mappings", "Maps surfaces to physics materials")
  68. ;
  69. edit->Class<EditorTerrainPhysicsColliderComponent>(
  70. EditorTerrainPhysicsColliderComponent::s_componentName,
  71. EditorTerrainPhysicsColliderComponent::s_componentDescription)
  72. ->ClassElement(AZ::Edit::ClassElements::EditorData, "")
  73. ->Attribute(AZ::Edit::Attributes::Icon, EditorTerrainPhysicsColliderComponent::s_icon)
  74. ->Attribute(AZ::Edit::Attributes::HelpPageURL, "https://docs.o3de.org/docs/user-guide/components/reference/terrain/terrain-physics-collider/")
  75. ->Attribute(AZ::Edit::Attributes::ViewportIcon, EditorTerrainPhysicsColliderComponent::s_viewportIcon)
  76. ->Attribute(AZ::Edit::Attributes::HelpPageURL, EditorTerrainPhysicsColliderComponent::s_helpUrl)
  77. ->Attribute(AZ::Edit::Attributes::Category, EditorTerrainPhysicsColliderComponent::s_categoryName)
  78. ->Attribute(AZ::Edit::Attributes::AppearsInAddComponentMenu, AZ_CRC_CE("Game"))
  79. ->Attribute(AZ::Edit::Attributes::AutoExpand, true)
  80. ->DataElement(AZ::Edit::UIHandlers::Default, &EditorTerrainPhysicsColliderComponent::m_configuration, "Config", "Terrain Physics Collider configuration")
  81. ->Attribute(AZ::Edit::Attributes::Visibility, AZ::Edit::PropertyVisibility::ShowChildrenOnly)
  82. ->Attribute(AZ::Edit::Attributes::ChangeNotify, &EditorTerrainPhysicsColliderComponent::ConfigurationChanged);
  83. ;
  84. }
  85. }
  86. }
  87. void EditorTerrainPhysicsColliderComponent::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& services)
  88. {
  89. services.push_back(AZ_CRC_CE("PhysicsHeightfieldProviderService"));
  90. }
  91. void EditorTerrainPhysicsColliderComponent::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& services)
  92. {
  93. services.push_back(AZ_CRC_CE("PhysicsHeightfieldProviderService"));
  94. }
  95. void EditorTerrainPhysicsColliderComponent::GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& services)
  96. {
  97. services.push_back(AZ_CRC_CE("AxisAlignedBoxShapeService"));
  98. }
  99. void EditorTerrainPhysicsColliderComponent::GetDependentServices(AZ::ComponentDescriptor::DependencyArrayType& services)
  100. {
  101. // If any of the following appear on the same entity as this one, they should get activated first as their data will
  102. // affect this component.
  103. services.push_back(AZ_CRC_CE("TerrainAreaService"));
  104. services.push_back(AZ_CRC_CE("TerrainHeightProviderService"));
  105. services.push_back(AZ_CRC_CE("TerrainSurfaceProviderService"));
  106. }
  107. void EditorTerrainPhysicsColliderComponent::Init()
  108. {
  109. m_component.Init();
  110. }
  111. void EditorTerrainPhysicsColliderComponent::Activate()
  112. {
  113. UpdateConfigurationTagProvider();
  114. m_component.SetEntity(GetEntity());
  115. m_component.UpdateConfiguration(m_configuration);
  116. m_component.Activate();
  117. AzToolsFramework::Components::EditorComponentBase::Activate();
  118. }
  119. void EditorTerrainPhysicsColliderComponent::Deactivate()
  120. {
  121. AzToolsFramework::Components::EditorComponentBase::Deactivate();
  122. m_component.Deactivate();
  123. // remove the entity association, in case the parent component is being removed, otherwise the component will be reactivated
  124. m_component.SetEntity(nullptr);
  125. }
  126. void EditorTerrainPhysicsColliderComponent::BuildGameEntity(AZ::Entity* gameEntity)
  127. {
  128. gameEntity->AddComponent(aznew TerrainPhysicsColliderComponent(m_configuration));
  129. }
  130. AZStd::unordered_set<SurfaceData::SurfaceTag> EditorTerrainPhysicsColliderComponent::GetSurfaceTagsInUse() const
  131. {
  132. AZStd::unordered_set<SurfaceData::SurfaceTag> tagsInUse;
  133. for (const TerrainPhysicsSurfaceMaterialMapping& mapping : m_configuration.m_surfaceMaterialMappings)
  134. {
  135. tagsInUse.insert(mapping.m_surfaceTag);
  136. }
  137. return AZStd::move(tagsInUse);
  138. }
  139. AZ::u32 EditorTerrainPhysicsColliderComponent::ConfigurationChanged()
  140. {
  141. m_component.UpdateConfiguration(m_configuration);
  142. UpdateConfigurationTagProvider();
  143. return AZ::Edit::PropertyRefreshLevels::None;
  144. }
  145. void EditorTerrainPhysicsColliderComponent::UpdateConfigurationTagProvider()
  146. {
  147. for (TerrainPhysicsSurfaceMaterialMapping& mapping : m_configuration.m_surfaceMaterialMappings)
  148. {
  149. mapping.SetTagListProvider(this);
  150. }
  151. }
  152. AZStd::vector<AZStd::pair<AZ::u32, AZStd::string>> TerrainPhysicsSurfaceMaterialMapping::BuildSelectableTagList() const
  153. {
  154. return AZStd::move(Terrain::BuildSelectableTagList(m_tagListProvider, m_surfaceTag));
  155. }
  156. void TerrainPhysicsSurfaceMaterialMapping::SetTagListProvider(const EditorSurfaceTagListProvider* tagListProvider)
  157. {
  158. m_tagListProvider = tagListProvider;
  159. }
  160. }