Files
o3de/Gems/Atom/Tools/MaterialEditor/Code/Source/Document/MaterialDocument.h
T
Guthrie Adams c9c172794e Atom Tools: Document system exposes reflected object data
• This removes a direct dependency on dynamic property groups and data from the document system.
• Added support for names, descriptions, and nesting to dynamic property groups.
• Moved property related functions from base document classes into material editor document classes because dynamic property groups are an implementation detail of the material editor document to support material type flexible data format.
• Change material document to use a table of dynamic property groups instead of a map of properties.
• Added functions to traverse groups and properties.
• This keeps groups and properties organized consistently with the material type file as well as what’s expected in the UI.
• Document data can now be maps directly to the inspector reflective property editors instead of copying one property at a time out of the document and keeping those synchronized.

Signed-off-by: Guthrie Adams <guthadam@amazon.com>
2022-02-03 21:42:27 -06:00

144 lines
6.6 KiB
C++

/*
* 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 <AzCore/Asset/AssetCommon.h>
#include <AzCore/Component/TickBus.h>
#include <AzCore/RTTI/RTTI.h>
#include <Atom/RPI.Edit/Material/MaterialSourceData.h>
#include <Atom/RPI.Edit/Material/MaterialTypeSourceData.h>
#include <Atom/RPI.Public/Material/Material.h>
#include <Atom/RPI.Reflect/Material/MaterialAsset.h>
#include <AtomToolsFramework/Document/AtomToolsDocument.h>
#include <Document/MaterialDocumentRequestBus.h>
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
{
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 overrides...
AZStd::vector<AtomToolsFramework::DocumentObjectInfo> GetObjectInfo() const override;
bool Open(AZStd::string_view loadPath) override;
bool Save() override;
bool SaveAsCopy(AZStd::string_view savePath) override;
bool SaveAsChild(AZStd::string_view savePath) override;
bool IsOpen() const override;
bool IsModified() const override;
bool IsSavable() const override;
bool BeginEdit() override;
bool EndEdit() override;
// MaterialDocumentRequestBus::Handler overrides...
AZ::Data::Asset<AZ::RPI::MaterialAsset> GetAsset() const override;
AZ::Data::Instance<AZ::RPI::Material> GetInstance() const override;
const AZ::RPI::MaterialSourceData* GetMaterialSourceData() const override;
const AZ::RPI::MaterialTypeSourceData* GetMaterialTypeSourceData() const override;
void SetPropertyValue(const AZ::Name& propertyId, const AZStd::any& value) override;
const AZStd::any& GetPropertyValue(const AZ::Name& propertyId) const override;
private:
// Predicate for evaluating properties
using PropertyFilterFunction = AZStd::function<bool(const AtomToolsFramework::DynamicProperty&)>;
// Map of raw property values for undo/redo comparison and storage
using PropertyValueMap = AZStd::unordered_map<AZ::Name, AZStd::any>;
// AZ::TickBus overrides...
void OnTick(float deltaTime, AZ::ScriptTimePoint time) override;
bool SaveSourceData(AZ::RPI::MaterialSourceData& sourceData, PropertyFilterFunction propertyFilter) const;
// AtomToolsFramework::AtomToolsDocument overrides...
void Clear() override;
bool ReopenRecordState() override;
bool ReopenRestoreState() override;
void Recompile();
bool LoadMaterialSourceData();
bool LoadMaterialTypeSourceData();
void RestorePropertyValues(const PropertyValueMap& propertyValues);
bool AddEditorMaterialFunctors(
const AZStd::vector<AZ::RPI::Ptr<AZ::RPI::MaterialFunctorSourceDataHolder>>& functorSourceDataHolders);
// Run editor material functor to update editor metadata.
// @param dirtyFlags indicates which properties have changed, and thus which MaterialFunctors need to be run.
void RunEditorMaterialFunctors(AZ::RPI::MaterialPropertyFlags dirtyFlags);
// Convert a dynamic property group pointer into generic document object info used to populate the inspector
AtomToolsFramework::DocumentObjectInfo GetObjectInfoFromDynamicPropertyGroup(
const AtomToolsFramework::DynamicPropertyGroup* group) const;
// In order traversal of dynamic property groups
bool TraverseGroups(
AZStd::vector<AZStd::shared_ptr<AtomToolsFramework::DynamicPropertyGroup>>& groups,
AZStd::function<bool(AZStd::shared_ptr<AtomToolsFramework::DynamicPropertyGroup>&)> callback);
// In order traversal of dynamic property groups
bool TraverseGroups(
const AZStd::vector<AZStd::shared_ptr<AtomToolsFramework::DynamicPropertyGroup>>& groups,
AZStd::function<bool(const AZStd::shared_ptr<AtomToolsFramework::DynamicPropertyGroup>&)> callback) const;
// Traverses dynamic property groups to find a property with a specific ID
AtomToolsFramework::DynamicProperty* FindProperty(const AZ::Name& propertyId);
// Traverses dynamic property groups to find a property with a specific ID
const AtomToolsFramework::DynamicProperty* FindProperty(const AZ::Name& propertyId) const;
// Material asset generated from source data, used to get the final values for properties to be assigned to the document
AZ::Data::Asset<AZ::RPI::MaterialAsset> m_materialAsset;
// Material instance is only needed to run editor functors and is assigned directly to the viewport model to reflect real time
// changes to material property values
AZ::Data::Instance<AZ::RPI::Material> m_materialInstance;
// If material instance value(s) were modified, do we need to recompile on next tick?
bool m_compilePending = false;
// Material functors that run in editor. See MaterialFunctor.h for details.
AZStd::vector<AZ::RPI::Ptr<AZ::RPI::MaterialFunctor>> m_editorFunctors;
// Material type source data used to enumerate all properties and populate the document
AZ::RPI::MaterialTypeSourceData m_materialTypeSourceData;
// Material source data with property values that override the material type
AZ::RPI::MaterialSourceData m_materialSourceData;
// State of property values prior to an edit, used for restoration during undo
PropertyValueMap m_propertyValuesBeforeEdit;
// State of property values prior to reopen
PropertyValueMap m_propertyValuesBeforeReopen;
// A container of root level dynamic property groups that represents the reflected, editable data within the document.
// These groups will be mapped to document object info so they can populate and be edited directly in the inspector.
AZStd::vector<AZStd::shared_ptr<AtomToolsFramework::DynamicPropertyGroup>> m_groups;
// Dummy default value returned whenever a property cannot be located
AZStd::any m_invalidValue;
};
} // namespace MaterialEditor