3
0

MaterialDocument.h 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  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/Asset/AssetCommon.h>
  10. #include <AzCore/Component/TickBus.h>
  11. #include <AzCore/RTTI/RTTI.h>
  12. #include <Atom/RPI.Edit/Material/MaterialSourceData.h>
  13. #include <Atom/RPI.Edit/Material/MaterialTypeSourceData.h>
  14. #include <Atom/RPI.Public/Material/Material.h>
  15. #include <Atom/RPI.Reflect/Material/MaterialAsset.h>
  16. #include <AtomToolsFramework/Document/AtomToolsDocument.h>
  17. #include <AtomToolsFramework/DynamicProperty/DynamicPropertyGroup.h>
  18. #include <Document/MaterialDocumentRequestBus.h>
  19. namespace MaterialEditor
  20. {
  21. //! MaterialDocument provides an API for modifying and saving material document properties.
  22. class MaterialDocument
  23. : public AtomToolsFramework::AtomToolsDocument
  24. , public MaterialDocumentRequestBus::Handler
  25. , public AZ::SystemTickBus::Handler
  26. {
  27. public:
  28. AZ_RTTI(MaterialDocument, "{90299628-AD02-4FEB-9527-7278FA2817AD}", AtomToolsFramework::AtomToolsDocument);
  29. AZ_CLASS_ALLOCATOR(MaterialDocument, AZ::SystemAllocator);
  30. AZ_DISABLE_COPY_MOVE(MaterialDocument);
  31. static void Reflect(AZ::ReflectContext* context);
  32. MaterialDocument() = default;
  33. MaterialDocument(const AZ::Crc32& toolId, const AtomToolsFramework::DocumentTypeInfo& documentTypeInfo);
  34. virtual ~MaterialDocument();
  35. // AtomToolsFramework::AtomToolsDocument overrides...
  36. static AtomToolsFramework::DocumentTypeInfo BuildDocumentTypeInfo();
  37. AtomToolsFramework::DocumentObjectInfoVector GetObjectInfo() const override;
  38. bool Open(const AZStd::string& loadPath) override;
  39. bool Save() override;
  40. bool SaveAsCopy(const AZStd::string& savePath) override;
  41. bool SaveAsChild(const AZStd::string& savePath) override;
  42. bool IsModified() const override;
  43. bool CanSaveAsChild() const override;
  44. bool BeginEdit() override;
  45. bool EndEdit() override;
  46. // MaterialDocumentRequestBus::Handler overrides...
  47. AZ::Data::Asset<AZ::RPI::MaterialAsset> GetAsset() const override;
  48. AZ::Data::Instance<AZ::RPI::Material> GetInstance() const override;
  49. const AZ::RPI::MaterialSourceData* GetMaterialSourceData() const override;
  50. const AZ::RPI::MaterialTypeSourceData* GetMaterialTypeSourceData() const override;
  51. void SetPropertyValue(const AZStd::string& propertyId, const AZStd::any& value) override;
  52. const AZStd::any& GetPropertyValue(const AZStd::string& propertyId) const override;
  53. private:
  54. // Predicate for evaluating properties
  55. using PropertyFilterFunction = AZStd::function<bool(const AtomToolsFramework::DynamicProperty&)>;
  56. // Map of raw property values for undo/redo comparison and storage
  57. using PropertyValueMap = AZStd::unordered_map<AZ::Name, AZStd::any>;
  58. // AZ::SystemTickBus overrides...
  59. void OnSystemTick() override;
  60. bool SaveSourceData(AZ::RPI::MaterialSourceData& sourceData, PropertyFilterFunction propertyFilter) const;
  61. // AtomToolsFramework::AtomToolsDocument overrides...
  62. void Clear() override;
  63. bool ReopenRecordState() override;
  64. bool ReopenRestoreState() override;
  65. void Recompile();
  66. bool LoadMaterialSourceData();
  67. bool LoadMaterialTypeSourceData();
  68. void RestorePropertyValues(const PropertyValueMap& propertyValues);
  69. bool AddEditorMaterialFunctors(
  70. const AZStd::vector<AZ::RPI::Ptr<AZ::RPI::MaterialFunctorSourceDataHolder>>& functorSourceDataHolders,
  71. const AZ::RPI::MaterialNameContext& nameContext);
  72. // Run editor material functor to update editor metadata.
  73. // @param dirtyFlags indicates which properties have changed, and thus which MaterialFunctors need to be run.
  74. void RunEditorMaterialFunctors(AZ::RPI::MaterialPropertyFlags dirtyFlags);
  75. // Convert a dynamic property group pointer into generic document object info used to populate the inspector
  76. AtomToolsFramework::DocumentObjectInfo GetObjectInfoFromDynamicPropertyGroup(
  77. const AtomToolsFramework::DynamicPropertyGroup* group) const;
  78. // In order traversal of dynamic property groups
  79. bool TraverseGroups(
  80. AZStd::vector<AZStd::shared_ptr<AtomToolsFramework::DynamicPropertyGroup>>& groups,
  81. AZStd::function<bool(AZStd::shared_ptr<AtomToolsFramework::DynamicPropertyGroup>&)> callback);
  82. // In order traversal of dynamic property groups
  83. bool TraverseGroups(
  84. const AZStd::vector<AZStd::shared_ptr<AtomToolsFramework::DynamicPropertyGroup>>& groups,
  85. AZStd::function<bool(const AZStd::shared_ptr<AtomToolsFramework::DynamicPropertyGroup>&)> callback) const;
  86. // Traverses dynamic property groups to find a property with a specific ID
  87. AtomToolsFramework::DynamicProperty* FindProperty(const AZ::Name& propertyId);
  88. // Traverses dynamic property groups to find a property with a specific ID
  89. const AtomToolsFramework::DynamicProperty* FindProperty(const AZ::Name& propertyId) const;
  90. // Material asset generated from source data, used to get the final values for properties to be assigned to the document
  91. AZ::Data::Asset<AZ::RPI::MaterialAsset> m_materialAsset;
  92. // Material instance is only needed to run editor functors and is assigned directly to the viewport model to reflect real time
  93. // changes to material property values
  94. AZ::Data::Instance<AZ::RPI::Material> m_materialInstance;
  95. // If material instance value(s) were modified, do we need to recompile on next tick?
  96. bool m_compilePending = false;
  97. // Material functors that run in editor. See MaterialFunctor.h for details.
  98. AZStd::vector<AZ::RPI::Ptr<AZ::RPI::MaterialFunctor>> m_editorFunctors;
  99. // Material type source data used to enumerate all properties and populate the document
  100. AZ::RPI::MaterialTypeSourceData m_materialTypeSourceData;
  101. // Material source data with property values that override the material type
  102. AZ::RPI::MaterialSourceData m_materialSourceData;
  103. // State of property values prior to an edit, used for restoration during undo
  104. PropertyValueMap m_propertyValuesBeforeEdit;
  105. // State of property values prior to reopen
  106. PropertyValueMap m_propertyValuesBeforeReopen;
  107. // A container of root level dynamic property groups that represents the reflected, editable data within the document.
  108. // These groups will be mapped to document object info so they can populate and be edited directly in the inspector.
  109. AZStd::vector<AZStd::shared_ptr<AtomToolsFramework::DynamicPropertyGroup>> m_groups;
  110. // Dummy default value returned whenever a property cannot be located
  111. AZStd::any m_invalidValue;
  112. };
  113. } // namespace MaterialEditor