/* * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or * its licensors. * * For complete copyright and license terms please see the LICENSE at the root of this * distribution (the "License"). All use of this software is governed by the License, * or, if provided, by the license below or the license accompanying this file. Do not * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * */ // Original file Copyright Crytek GMBH or its affiliates, used under license. #ifndef CRYINCLUDE_EDITOR_MATERIAL_MATERIALMANAGER_H #define CRYINCLUDE_EDITOR_MATERIAL_MATERIALMANAGER_H #pragma once #include "BaseLibraryManager.h" #include "Material.h" #include <AzToolsFramework/AssetBrowser/AssetBrowserBus.h> #include <Include/IEditorMaterialManager.h> #include <AzCore/Asset/AssetCommon.h> #include <AzCore/std/string/wildcard.h> #include <AzFramework/Asset/AssetCatalogBus.h> #include <AzToolsFramework/API/ToolsApplicationAPI.h> #include <AzCore/std/parallel/mutex.h> #include <AzCore/std/parallel/binary_semaphore.h> #include <AzCore/std/parallel/thread.h> class CMaterial; class CMaterialLibrary; class CMaterialHighlighter; namespace AZ { struct Uuid; } namespace AzToolsFramework { namespace AssetBrowser { struct SourceFileOpenerDetails; typedef AZStd::vector<SourceFileOpenerDetails> SourceFileOpenerList; } } enum EHighlightMode { eHighlight_Pick = BIT(0), eHighlight_Breakable = BIT(1), eHighlight_NoSurfaceType = BIT(2), eHighlight_All = 0xFFFFFFFF }; AZ_PUSH_DISABLE_DLL_EXPORT_BASECLASS_WARNING /** Manages all entity prototypes and material libraries. */ class CRYEDIT_API CMaterialManager : public IEditorMaterialManager , public CBaseLibraryManager , public IMaterialManagerListener , protected AzToolsFramework::AssetBrowser::AssetBrowserInteractionNotificationBus::Handler , public AzToolsFramework::AssetBrowser::AssetBrowserModelNotificationBus::Handler , public AzFramework::AssetCatalogEventBus::Handler , public AzToolsFramework::EditorEvents::Bus::Handler { AZ_POP_DISABLE_DLL_EXPORT_BASECLASS_WARNING public: //! Notification callback. typedef Functor0 NotifyCallback; CMaterialManager(CRegistrationContext& regCtx); ~CMaterialManager(); void Set3DEngine(); // Clear all prototypes and material libraries. void ClearAll(); ////////////////////////////////////////////////////////////////////////// // Materials. ////////////////////////////////////////////////////////////////////////// // Loads material. CMaterial* LoadMaterial(const QString& sMaterialName, bool bMakeIfNotFound = true); XmlNodeRef LoadXmlNode(const QString &fullSourcePath, const QString &relativeFilePath); //! Loads a material, avoiding a call to CMaterialManager::MaterialToFilename if the full path is already known CMaterial* LoadMaterialWithFullSourcePath(const QString& relativeFilePath, const QString& fullSourcePath, bool makeIfNotFound = true); virtual CMaterial* LoadMaterial(const char* sMaterialName, bool bMakeIfNotFound = true); virtual void OnRequestMaterial(_smart_ptr<IMaterial> pMaterial); // Creates a new material from a xml node. CMaterial* CreateMaterial(const QString& sMaterialName, const XmlNodeRef& node = XmlNodeRef(), int nMtlFlags = 0, unsigned long nLoadingFlags = 0); virtual CMaterial* CreateMaterial(const char* sMaterialName, const XmlNodeRef& node = XmlNodeRef(), int nMtlFlags = 0, unsigned long nLoadingFlags = 0); // Duplicate material and do nothing more. CMaterial* DuplicateMaterial(const char* newName, CMaterial* pOriginal); // Delete specified material, erases material file, and unassigns from all objects. virtual void DeleteMaterial(CMaterial* pMtl); virtual void RemoveMaterialFromDisk(const char* fileName); //! Export property manager to game. void Export(XmlNodeRef& node); int ExportLib(CMaterialLibrary* pLib, XmlNodeRef& libNode); virtual void SetSelectedItem(IDataBaseItem* pItem); void SetCurrentMaterial(CMaterial* pMtl); //! Get currently active material. CMaterial* GetCurrentMaterial() const; void SetCurrentFolder(const QString& folder); // This material will be highlighted void SetHighlightedMaterial(CMaterial* pMtl); void GetHighlightColor(ColorF* color, float* intensity, int flags); void HighlightedMaterialChanged(CMaterial* pMtl); // highlightMask is a combination of EHighlightMode flags void SetHighlightMask(int highlightMask); int GetHighlightMask() const{ return m_highlightMask; } void SetMarkedMaterials(const std::vector<_smart_ptr<CMaterial> >& markedMaterials); void OnLoadShader(CMaterial* pMaterial); //! Serialize property manager. virtual void Serialize(XmlNodeRef& node, bool bLoading); virtual void SaveAllLibs(); ////////////////////////////////////////////////////////////////////////// // IMaterialManagerListener implementation ////////////////////////////////////////////////////////////////////////// // Called when material manager tries to load a material. virtual void OnCreateMaterial(_smart_ptr<IMaterial> pMaterial); virtual void OnDeleteMaterial(_smart_ptr<IMaterial> pMaterial); virtual bool IsCurrentMaterial(_smart_ptr<IMaterial> pMaterial) const; ////////////////////////////////////////////////////////////////////////// // Convert filename of material file into the name of the material. QString FilenameToMaterial(const QString& filename); // Convert name of the material to the filename. QString MaterialToFilename(const QString& sMaterialName); //! Get the full file path of the source material const AZ::Data::AssetType& GetMaterialAssetType(); ////////////////////////////////////////////////////////////////////////// // Convert 3DEngine IMaterial to Editor's CMaterial pointer. CMaterial* FromIMaterial(_smart_ptr<IMaterial> pMaterial); // Open File selection dialog to create a new material. CMaterial* SelectNewMaterial(int nMtlFlags, const char* sStartPath = NULL); // Synchronize material between 3dsMax and editor. void SyncMaterialEditor(); ////////////////////////////////////////////////////////////////////////// void GotoMaterial(CMaterial* pMaterial); void GotoMaterial(_smart_ptr<IMaterial> pMaterial); // Gather resources from the game material. static void GatherResources(_smart_ptr<IMaterial> pMaterial, CUsedResources& resources); void Command_Create(); void Command_CreateMulti(); void Command_ConvertToMulti(); void Command_Duplicate(); void Command_Merge(); void Command_Delete(); void Command_AssignToSelection(); void Command_ResetSelection(); void Command_SelectAssignedObjects(); void Command_SelectFromObject(); protected: ////////////////////////////////////////////////////////////////////////////////////////////////////// // protected AzToolsFramework::AssetBrowser::AssetBrowserInteractionNotificationBus::Handler void AddSourceFileOpeners(const char* fullSourceFileName, const AZ::Uuid& sourceUUID, AzToolsFramework::AssetBrowser::SourceFileOpenerList& openers) override; ////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////// // public AzToolsFramework::AssetBrowser::AssetBrowserModelNotificationsBus::Handler void EntryAdded(const AzToolsFramework::AssetBrowser::AssetBrowserEntry* entry); ////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////// // AssetCatalogEventBus Functions void OnCatalogAssetChanged(const AZ::Data::AssetId& assetId) override; ////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////// // EditorEventsBus Functions bool SkipEditorStartupUI() override; ////////////////////////////////////////////////////////////////////////////////////////////////////// void SaveDccMaterial(const AZStd::string& relativeDccMaterialPath); bool DccMaterialRequiresSave(const AZStd::string& relativeDccMaterialPath, const AZStd::string& fullSourcePath); void DccMaterialSourceControlCheck(const AZStd::string& relativeDccMaterialPath); void AddDccMaterialPath(const AZStd::string relativeDccMaterialPath); void TickSourceControl(); void QueueSourceControlTick(); // Duplicate the source material and set it as a submaterial of the target material at subMaterialIndex. Returns true if successful. bool DuplicateAsSubMaterialAtIndex(CMaterial* pSourceMaterial, CMaterial* pTargetMaterial, int subMaterialIndex); // Generates a unique variant of the name of the source material to resolve name collisions with the names of the submaterials in the target material. void GenerateUniqueSubmaterialName(const CMaterial* pSourceMaterial, const CMaterial* pTargetMaterial, QString& uniqueSubmaterialName) const; // Open save as dialog for saving materials. bool SelectSaveMaterial(QString& itemName, QString& fullPath, const char* defaultStartPath); void OnEditorNotifyEvent(EEditorNotifyEvent event); virtual CBaseLibraryItem* MakeNewItem(); virtual CBaseLibrary* MakeNewLibrary(); //! Root node where this library will be saved. virtual QString GetRootNodeName(); //! Path to libraries in this manager. virtual QString GetLibsPath(); virtual void ReportDuplicateItem(CBaseLibraryItem* pItem, CBaseLibraryItem* pOldItem); void RegisterCommands(CRegistrationContext& regCtx); void UpdateHighlightedMaterials(); void AddForHighlighting(CMaterial* pMaterial); void RemoveFromHighlighting(CMaterial* pMaterial, int mask); int GetHighlightFlags(CMaterial* pMaterial) const; // For material syncing with 3dsMax. void PickPreviewMaterial(); void InitMatSender(); //! Reloads any registered materials that have been modified by the runtime. void ReloadDirtyMaterials(); protected: QString m_libsPath; // Currently selected (focused) material, in material browser. _smart_ptr<CMaterial> m_pCurrentMaterial; // current selected folder QString m_currentFolder; // List of materials selected in material browser tree. std::vector<_smart_ptr<CMaterial> > m_markedMaterials; // IMaterial is needed to not let 3Dengine release selected IMaterial _smart_ptr<IMaterial> m_pCurrentEngineMaterial; // Paths of .dccmtl that might require saving. They will be fed to // DccMaterialSourceControlCheck() and if saving is required, they // will be added to m_dccMaterialSaveBuffer AZStd::vector<AZStd::string> m_sourceControlBuffer; AZStd::mutex m_sourceControlBufferMutex; AZStd::atomic_bool m_sourceControlFunctionQueued; // Paths of .dccmtl that require saving. These paths have // gone through DccMaterialSourceControlCheck() and will // be saved by the dcc material save thread AZStd::vector<AZStd::string> m_dccMaterialSaveBuffer; AZStd::mutex m_dccMaterialSaveMutex; // Material highlighting _smart_ptr<CMaterial> m_pHighlightMaterial; CMaterialHighlighter* m_pHighlighter; int m_highlightMask; bool m_bHighlightingMaterial; // Only begin processing .dccmtl filepaths once editor is ready // and we can display appropriate error messages bool m_bEditorUiReady; // Only report source control error to the user once, // no need to spam them for every material bool m_bSourceControlErrorReported; class CMaterialSender* m_MatSender; private: CMaterial* LoadMaterialInternal(const QString &materialNameClear, const QString &fullSourcePath, const QString &relativeFilePath, bool bMakeIfNotFound); AZ::Data::AssetType m_materialAssetType; AZ::Data::AssetType m_dccMaterialAssetType; void StartDccMaterialSaveThread(); void DccMaterialSaveThreadFunc(); AZStd::thread m_dccMaterialSaveThread; AZStd::atomic_bool m_joinThreads; AZStd::binary_semaphore m_dccMaterialSaveSemaphore; }; #endif // CRYINCLUDE_EDITOR_MATERIAL_MATERIALMANAGER_H