/* * Copyright (c) Contributors to the Open 3D Engine Project. * For complete copyright and license terms please see the LICENSE at the root of this distribution. * * SPDX-License-Identifier: Apache-2.0 OR MIT * */ #pragma once #include #include #include #include #include #include #include #include #include #include #include namespace MaterialEditor { /** * MaterialDocument provides an API for modifying and saving material document properties. */ class MaterialDocument : public AtomToolsFramework::AtomToolsDocument , public MaterialDocumentRequestBus::Handler , private AZ::TickBus::Handler , private AzToolsFramework::AssetSystemBus::Handler { public: AZ_RTTI(MaterialDocument, "{DBA269AE-892B-415C-8FA1-166B94B0E045}"); AZ_CLASS_ALLOCATOR(MaterialDocument, AZ::SystemAllocator, 0); AZ_DISABLE_COPY(MaterialDocument); MaterialDocument(); virtual ~MaterialDocument(); //////////////////////////////////////////////////////////////////////// // AtomToolsFramework::AtomToolsDocument //////////////////////////////////////////////////////////////////////// const AZStd::any& GetPropertyValue(const AZ::Name& propertyId) const override; const AtomToolsFramework::DynamicProperty& GetProperty(const AZ::Name& propertyId) const override; bool IsPropertyGroupVisible(const AZ::Name& propertyGroupFullName) const override; void SetPropertyValue(const AZ::Name& propertyId, const AZStd::any& value) override; bool Open(AZStd::string_view loadPath) override; bool Reopen() override; bool Save() override; bool SaveAsCopy(AZStd::string_view savePath) override; bool SaveAsChild(AZStd::string_view savePath) override; bool Close() override; bool IsOpen() const override; bool IsModified() const override; bool IsSavable() const override; bool CanUndo() const override; bool CanRedo() const override; bool Undo() override; bool Redo() override; bool BeginEdit() override; bool EndEdit() override; //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// // MaterialDocumentRequestBus::Handler implementation AZ::Data::Asset GetAsset() const override; AZ::Data::Instance GetInstance() const override; const AZ::RPI::MaterialSourceData* GetMaterialSourceData() const override; const AZ::RPI::MaterialTypeSourceData* GetMaterialTypeSourceData() const override; //////////////////////////////////////////////////////////////////////// private: // Predicate for evaluating properties using PropertyFilterFunction = AZStd::function; // Map of document's properties using PropertyMap = AZStd::unordered_map; // Map of raw property values for undo/redo comparison and storage using PropertyValueMap = AZStd::unordered_map; // Map of document's property group visibility flags using PropertyGroupVisibilityMap = AZStd::unordered_map; // Function to be bound for undo and redo using UndoRedoFunction = AZStd::function; // A pair of functions, where first is the undo operation and second is the redo operation using UndoRedoFunctionPair = AZStd::pair; // Container for all of the active undo and redo functions and state using UndoRedoHistory = AZStd::vector; //////////////////////////////////////////////////////////////////////// // AZ::TickBus interface implementation void OnTick(float deltaTime, AZ::ScriptTimePoint time) override; //////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// // AzToolsFramework::AssetSystemBus::Handler overrides... void SourceFileChanged(AZStd::string relativePath, AZStd::string scanFolder, AZ::Uuid sourceUUID) override; ////////////////////////////////////////////////////////////////////////// bool SavePropertiesToSourceData(AZ::RPI::MaterialSourceData& sourceData, PropertyFilterFunction propertyFilter) const; bool OpenInternal(AZStd::string_view loadPath); void Recompile(); void Clear(); void RestorePropertyValues(const PropertyValueMap& propertyValues); struct EditorMaterialFunctorResult { AZStd::unordered_set m_updatedProperties; AZStd::unordered_set m_updatedPropertyGroups; }; // Run editor material functor to update editor metadata. // @param dirtyFlags indicates which properties have changed, and thus which MaterialFunctors need to be run. // @return names for the set of properties and groups that have been changed or need update. EditorMaterialFunctorResult RunEditorMaterialFunctors(AZ::RPI::MaterialPropertyFlags dirtyFlags); // Underlying material asset AZ::Data::Asset m_materialAsset; // Material instance being edited AZ::Data::Instance m_materialInstance; // Set of assets that can trigger a document reload AZStd::unordered_set m_sourceDependencies; // Track if document saved itself last to skip external modification notification bool m_saveTriggeredInternally = false; // If material instance value(s) were modified, do we need to recompile on next tick? bool m_compilePending = false; // Collection of all material's properties PropertyMap m_properties; // Collection of all material's property groups PropertyGroupVisibilityMap m_propertyGroupVisibility; // Material functors that run in editor. See MaterialFunctor.h for details. AZStd::vector> m_editorFunctors; // Source data for material type AZ::RPI::MaterialTypeSourceData m_materialTypeSourceData; // Source data for material AZ::RPI::MaterialSourceData m_materialSourceData; // Variables needed for tracking the undo and redo state of this document // State of property values prior to an edit, used for restoration during undo PropertyValueMap m_propertyValuesBeforeEdit; // Container of undo commands UndoRedoHistory m_undoHistory; // The current position in the undo redo history int m_undoHistoryIndex = 0; AZStd::any m_invalidValue; AtomToolsFramework::DynamicProperty m_invalidProperty; }; } // namespace MaterialEditor