MaterialComponentController.h 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  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/Component.h>
  10. #include <AzCore/Component/TickBus.h>
  11. #include <Atom/RPI.Public/Material/Material.h>
  12. #include <AtomLyIntegration/CommonFeatures/Material/MaterialComponentBus.h>
  13. #include <AtomLyIntegration/CommonFeatures/Material/MaterialComponentConfig.h>
  14. namespace AZ
  15. {
  16. namespace Render
  17. {
  18. //! Can be paired with renderable components (MeshComponent for example)
  19. //! to provide material overrides on a per-entity basis.
  20. class MaterialComponentController final
  21. : MaterialComponentRequestBus::Handler
  22. , MaterialConsumerNotificationBus::Handler
  23. , Data::AssetBus::MultiHandler
  24. , SystemTickBus::Handler
  25. {
  26. public:
  27. friend class EditorMaterialComponent;
  28. AZ_CLASS_ALLOCATOR(MaterialComponentController, AZ::SystemAllocator);
  29. AZ_RTTI(MaterialComponentController, "{34AD7ED0-9866-44CD-93B6-E86840214B91}");
  30. static void Reflect(ReflectContext* context);
  31. static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided);
  32. static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible);
  33. static void GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required);
  34. MaterialComponentController() = default;
  35. MaterialComponentController(const MaterialComponentConfig& config);
  36. void Activate(AZ::EntityId entityId);
  37. void Deactivate();
  38. void SetConfiguration(const MaterialComponentConfig& config);
  39. const MaterialComponentConfig& GetConfiguration() const;
  40. //! MaterialComponentRequestBus overrides...
  41. MaterialAssignmentMap GetDefaultMaterialMap() const override;
  42. MaterialAssignmentId FindMaterialAssignmentId(const MaterialAssignmentLodIndex lod, const AZStd::string& label) const override;
  43. AZ::Data::AssetId GetDefaultMaterialAssetId(const MaterialAssignmentId& materialAssignmentId) const override;
  44. AZStd::string GetMaterialLabel(const MaterialAssignmentId& materialAssignmentId) const override;
  45. void SetMaterialMap(const MaterialAssignmentMap& materials) override;
  46. const MaterialAssignmentMap& GetMaterialMap() const override;
  47. void ClearMaterialMap() override;
  48. void ClearMaterialsOnModelSlots() override;
  49. void ClearMaterialsOnLodSlots() override;
  50. void ClearMaterialsOnInvalidSlots() override;
  51. void ClearMaterialsWithMissingAssets() override;
  52. void RepairMaterialsWithMissingAssets() override;
  53. uint32_t RepairMaterialsWithRenamedProperties() override;
  54. void SetMaterialAssetIdOnDefaultSlot(const AZ::Data::AssetId& materialAssetId) override;
  55. const AZ::Data::AssetId GetMaterialAssetIdOnDefaultSlot() const override;
  56. void ClearMaterialAssetIdOnDefaultSlot() override;
  57. void SetMaterialAssetId(const MaterialAssignmentId& materialAssignmentId, const AZ::Data::AssetId& materialAssetId) override;
  58. AZ::Data::AssetId GetMaterialAssetId(const MaterialAssignmentId& materialAssignmentId) const override;
  59. void ClearMaterialAssetId(const MaterialAssignmentId& materialAssignmentId) override;
  60. bool IsMaterialAssetIdOverridden(const MaterialAssignmentId& materialAssignmentId) const override;
  61. bool HasPropertiesOverridden(const MaterialAssignmentId& materialAssignmentId) const override;
  62. void SetPropertyValue(const MaterialAssignmentId& materialAssignmentId, const AZStd::string& propertyName, const AZStd::any& value) override;
  63. AZStd::any GetPropertyValue(const MaterialAssignmentId& materialAssignmentId, const AZStd::string& propertyName) const override;
  64. void ClearPropertyValue(const MaterialAssignmentId& materialAssignmentId, const AZStd::string& propertyName) override;
  65. void ClearPropertyValues(const MaterialAssignmentId& materialAssignmentId) override;
  66. void ClearAllPropertyValues() override;
  67. void SetPropertyValues(
  68. const MaterialAssignmentId& materialAssignmentId, const MaterialPropertyOverrideMap& propertyOverrides) override;
  69. MaterialPropertyOverrideMap GetPropertyValues(const MaterialAssignmentId& materialAssignmentId) const override;
  70. void SetModelUvOverrides(
  71. const MaterialAssignmentId& materialAssignmentId, const AZ::RPI::MaterialModelUvOverrideMap& modelUvOverrides) override;
  72. AZ::RPI::MaterialModelUvOverrideMap GetModelUvOverrides(const MaterialAssignmentId& materialAssignmentId) const override;
  73. //! MaterialConsumerNotificationBus::Handler overrides...
  74. void OnMaterialAssignmentSlotsChanged() override;
  75. private:
  76. AZ_DISABLE_COPY(MaterialComponentController);
  77. //! Data::AssetBus overrides...
  78. void OnAssetReady(Data::Asset<Data::AssetData> asset) override;
  79. void OnAssetReloaded(Data::Asset<Data::AssetData> asset) override;
  80. void OnAssetError(Data::Asset<Data::AssetData> asset) override;
  81. void OnAssetReloadError(Data::Asset<Data::AssetData> asset) override;
  82. // AZ::SystemTickBus overrides...
  83. void OnSystemTick() override;
  84. void LoadMaterials();
  85. void InitializeMaterialInstance(const Data::Asset<Data::AssetData>& asset);
  86. void ReleaseMaterials();
  87. //! Queue applying property overrides to material instances until tick
  88. void QueuePropertyChanges(const MaterialAssignmentId& materialAssignmentId);
  89. //! Queue material instance creation notifications until tick
  90. void QueueMaterialsCreatedNotification();
  91. //! Queue material instance recreation notifications until tick
  92. void QueueMaterialsUpdatedNotification();
  93. //! Queue material reload so that it only occurs once per tick
  94. void QueueLoadMaterials();
  95. //! Converts property overrides storing image asset references into asset IDs. This addresses a problem where image property
  96. //! overrides are lost during prefab serialization and patching. This suboptimal function will be removed once the underlying
  97. //! problem is resolved.
  98. void ConvertAssetsForSerialization();
  99. void ConvertAssetsForSerialization(MaterialPropertyOverrideMap& propertyMap);
  100. AZStd::any ConvertAssetsForSerialization(const AZStd::any& value) const;
  101. void DisplayMissingAssetWarning(Data::Asset<Data::AssetData> asset) const;
  102. EntityId m_entityId;
  103. MaterialComponentConfig m_configuration;
  104. MaterialAssignmentMap m_defaultMaterialMap;
  105. AZStd::unordered_map<AZ::Data::AssetId, AZ::Data::Asset<AZ::RPI::MaterialAsset>> m_uniqueMaterialMap;
  106. AZStd::unordered_set<MaterialAssignmentId> m_materialsWithDirtyProperties;
  107. bool m_queuedMaterialsCreatedNotification = false;
  108. bool m_queuedMaterialsUpdatedNotification = false;
  109. bool m_queuedLoadMaterials = false;
  110. };
  111. } // namespace Render
  112. } // namespace AZ