/* * 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_CRYACTION_MANNEQUIN_ANIMATIONDATABASEMANAGER_H #define CRYINCLUDE_CRYACTION_MANNEQUIN_ANIMATIONDATABASEMANAGER_H #pragma once #include "AnimationDatabase.h" #include "ICryMannequinEditor.h" #include #include "IResourceManager.h" class CAnimationDatabaseLibrary { public: typedef const CAnimationDatabase* THandle; CAnimationDatabaseLibrary(); ~CAnimationDatabaseLibrary(); void Insert(uint32 nCrc, CAnimationDatabase* pDb); public: THandle LoadResource(const char* name, uint32 nFlags); THandle TryOpenResource(const char* name, uint32 nFlags); void CreateResource(THandle& hdlOut, const char* name, uint32 nFlags); void PublishResource(THandle& hdlOut); protected: typedef std::map TAnimDatabaseList; protected: bool LoadDatabase(const XmlNodeRef& xmlNode, CAnimationDatabase& animDB, bool recursive); bool LoadDatabaseDefinitions(const XmlNodeRef& root, const char* filename, const CTagDefinition** ppFragDefs, const CTagDefinition** ppTagDefs); void LoadDatabaseData ( CAnimationDatabase& animDB, const XmlNodeRef root, const CTagDefinition& fragIDs, const CTagDefinition& tagIDs, const TagState& adbFilter, bool recursive, CAnimationDatabase::SSubADB* subAnimDB = NULL ); void AnimEntryToXML(XmlNodeRef outNode, const SAnimationEntry& animEntry, const char* name) const; bool XMLToAnimEntry(SAnimationEntry& animEntry, XmlNodeRef root) const; bool XMLToFragment(CFragment& fragment, XmlNodeRef root, bool transition) const; void FragmentToXML(XmlNodeRef outNode, const CFragment* fragment, bool transition) const; void ProceduralToXml(XmlNodeRef pOutNode, const SProceduralEntry& proceduralEntry) const; bool XmlToProcedural(XmlNodeRef pInNode, SProceduralEntry& outProceduralEntry) const; void XMLToBlend(SAnimBlend& animBlend, XmlNodeRef xmlBlend) const; void BlendToXML(XmlNodeRef outNode, const SAnimBlend& animBlend, const char* name) const; private: CAnimationDatabaseLibrary(const CAnimationDatabaseLibrary&); CAnimationDatabaseLibrary& operator = (const CAnimationDatabaseLibrary&); protected: TAnimDatabaseList m_databases; CTagDefinition m_animFlags; CTagDefinition m_transitionFlags; }; class CAnimationTagDefLibrary { public: typedef const CTagDefinition* THandle; CAnimationTagDefLibrary(); ~CAnimationTagDefLibrary(); void Insert(uint32 nCrc, CTagDefinition* pDef); public: THandle LoadResource(const char* name, uint32 nFlags); THandle TryOpenResource(const char* name, uint32 nFlags); void CreateResource(THandle& hdlOut, const char* name, uint32 nFlags); void PublishResource(THandle& hdlOut); protected: typedef std::map TTagDefList; private: CAnimationTagDefLibrary(const CAnimationTagDefLibrary&); CAnimationTagDefLibrary& operator = (const CAnimationTagDefLibrary&); protected: TTagDefList m_tagDefs; }; class CAnimationControllerDefLibrary { public: typedef const SControllerDef* THandle; CAnimationControllerDefLibrary(); ~CAnimationControllerDefLibrary(); void Insert(uint32 nCrc32, SControllerDef* pDef); public: THandle LoadResource(const char* name, uint32 nFlags); THandle TryOpenResource(const char* name, uint32 nFlags); void CreateResource(THandle& hdlOut, const char* name, uint32 nFlags); void PublishResource(THandle& hdlOut); protected: typedef std::map TControllerDefList; protected: SControllerDef* LoadControllerDef(const XmlNodeRef& xmlNode, const char* context); private: CAnimationControllerDefLibrary(const CAnimationControllerDefLibrary&); CAnimationControllerDefLibrary& operator = (const CAnimationControllerDefLibrary&); protected: TControllerDefList m_controllerDefs; CTagDefinition m_fragmentFlags; }; class CAnimationDatabaseManager : public IAnimationDatabaseManager , public IMannequinEditorManager , protected CAnimationDatabaseLibrary , protected CAnimationTagDefLibrary , protected CAnimationControllerDefLibrary { public: CAnimationDatabaseManager(); ~CAnimationDatabaseManager(); virtual int GetTotalDatabases() const { return m_databases.size(); } virtual const IAnimationDatabase* GetDatabase(int idx) const { for (TAnimDatabaseList::const_iterator iter = m_databases.begin(); iter != m_databases.end(); ++iter) { if (idx-- == 0) { return iter->second; } } return NULL; } const IAnimationDatabase* Load(const char* filename); const SControllerDef* LoadControllerDef(const char* filename); const CTagDefinition* LoadTagDefs(const char* filename, bool isTags); const IAnimationDatabase* FindDatabase(const uint32 crcFilename) const; const SControllerDef* FindControllerDef(const uint32 crcFilename) const; const SControllerDef* FindControllerDef(const char* filename) const; const CTagDefinition* FindTagDef(const uint32 crcFilename) const; const CTagDefinition* FindTagDef(const char* filename) const; IAnimationDatabase* Create(const char* filename, const char* defFilename); CTagDefinition* CreateTagDefinition(const char* filename); void ReloadAll(); void UnloadAll(); // IMannequinEditorManager void GetAffectedFragmentsString(const CTagDefinition* pQueryTagDef, TagID tagID, char* buffer, int bufferSize); void ApplyTagDefChanges(const CTagDefinition* pOriginal, CTagDefinition* pModified); void RenameTag(const CTagDefinition* pOriginal, int32 tagCRC, const char* newName); void RenameTagGroup(const CTagDefinition* pOriginal, int32 tagGroupCRC, const char* newName); void GetIncludedTagDefs(const CTagDefinition* pQueriedTagDef, DynArray& tagDefs) const; EModifyFragmentIdResult CreateFragmentID(const CTagDefinition& fragmentIds, const char* szFragmentIdName); EModifyFragmentIdResult RenameFragmentID(const CTagDefinition& fragmentIds, FragmentID fragmentID, const char* szFragmentIdName); EModifyFragmentIdResult DeleteFragmentID(const CTagDefinition& fragmentIds, FragmentID fragmentID); bool SetFragmentTagDef(const CTagDefinition& fragmentIds, FragmentID fragmentID, const CTagDefinition* pFragTagDefs); void SetFragmentDef(const SControllerDef& controllerDef, FragmentID fragmentID, const SFragmentDef& fragmentDef); void SaveDatabasesSnapshot(SSnapshotCollection& snapshotCollection) const; void LoadDatabasesSnapshot(const SSnapshotCollection& snapshotCollection); void GetLoadedTagDefs(DynArray& tagDefs); void GetLoadedDatabases(DynArray& animDatabases) const; void GetLoadedControllerDefs(DynArray& controllerDefs) const; void SaveAll(IMannequinWriter* pWriter) const; void RevertDatabase(const char* szFilename); void RevertControllerDef(const char* szFilename); void RevertTagDef(const char* szFilename); bool DeleteFragmentEntry(IAnimationDatabase* pDatabase, FragmentID fragmentID, const SFragTagState& tagState, uint32 optionIdx, bool logWarning); bool DeleteFragmentEntries(IAnimationDatabase* pDatabase, FragmentID fragmentID, const SFragTagState& tagState, const std::vector& optionIndices, bool logWarning); uint32 AddFragmentEntry(IAnimationDatabase* pDatabase, FragmentID fragmentID, const SFragTagState& tagState, const CFragment& fragment); void SetFragmentEntry(IAnimationDatabase* pDatabase, FragmentID fragmentID, const SFragTagState& tagState, uint32 optionIdx, const CFragment& fragment); bool IsFileUsedByControllerDef(const SControllerDef& controllerDef, const char* szFilename) const; void RegisterListener(IMannequinEditorListener* pListener); void UnregisterListener(IMannequinEditorListener* pListener); void AddSubADBFragmentFilter(IAnimationDatabase* pDatabase, const char* szSubADBFilename, FragmentID fragmentID); void RemoveSubADBFragmentFilter(IAnimationDatabase* pDatabase, const char* szSubADBFilename, FragmentID fragmentID); uint32 GetSubADBFragmentFilterCount(const IAnimationDatabase* pDatabase, const char* szSubADBFilename) const; FragmentID GetSubADBFragmentFilter(const IAnimationDatabase* pDatabase, const char* szSubADBFilename, uint32 index) const; void SetSubADBTagFilter(IAnimationDatabase* pDatabase, const char* szSubADBFilename, TagState tagState); TagState GetSubADBTagFilter(const IAnimationDatabase* pDatabase, const char* szSubADBFilename) const; void SetBlend(IAnimationDatabase* pDatabase, FragmentID fragmentIDFrom, FragmentID fragmentIDTo, const SFragTagState& tagFrom, const SFragTagState& tagTo, SFragmentBlendUid blendUid, const SFragmentBlend& fragBlend); SFragmentBlendUid AddBlend(IAnimationDatabase* pDatabase, FragmentID fragmentIDFrom, FragmentID fragmentIDTo, const SFragTagState& tagFrom, const SFragTagState& tagTo, const SFragmentBlend& fragBlend); void DeleteBlend(IAnimationDatabase* pDatabase, FragmentID fragmentIDFrom, FragmentID fragmentIDTo, const SFragTagState& tagFrom, const SFragTagState& tagTo, SFragmentBlendUid blendUid); void GetFragmentBlends(const IAnimationDatabase* pDatabase, SEditorFragmentBlendID::TEditorFragmentBlendIDArray& outBlendIDs) const; void GetFragmentBlendVariants(const IAnimationDatabase* pDatabase, const FragmentID fragmentIDFrom, const FragmentID fragmentIDTo, SEditorFragmentBlendVariant::TEditorFragmentBlendVariantArray& outVariants) const; void GetFragmentBlend(const IAnimationDatabase* pIDatabase, const FragmentID fragmentIDFrom, const FragmentID fragmentIDTo, const SFragTagState& tagFrom, const SFragTagState& tagTo, const SFragmentBlendUid& blendUid, SFragmentBlend& outFragmentBlend) const; // ~IMannequinEditorManager private: CAnimationDatabaseManager(const CAnimationDatabaseManager&); CAnimationDatabaseManager& operator = (const CAnimationDatabaseManager&); //--- used for saving struct SSaveState { string m_sFileName; bool m_bSavedByTags; // Otherwise saved by ID... tags is higher priority; SSaveState () : m_sFileName() , m_bSavedByTags(false) {} }; typedef std::vector < SSaveState > TSaveStateList; struct SFragmentSaveEntry { TSaveStateList vSaveStates; }; typedef std::vector < SFragmentSaveEntry > TFragmentSaveList; struct SFragmentBlendSaveEntry { TSaveStateList vSaveStates; }; typedef std::map TFragmentBlendSaveDatabase; void Save(const IAnimationDatabase& iAnimDB, const char* databaseName) const; XmlNodeRef SaveDatabase ( const CAnimationDatabase& animDB, const CAnimationDatabase::SSubADB* subAnimDB, const TFragmentSaveList& vFragSaveList, const TFragmentBlendSaveDatabase& mBlendSaveDatabase, bool flatten = false ) const; void ReloadDatabase(IAnimationDatabase* pDatabase); void RemoveDataFromParent(CAnimationDatabase* parentADB, const CAnimationDatabase::SSubADB* subADB); void ClearDatabase(CAnimationDatabase* pDatabase); void Compress(CAnimationDatabase& animDB); XmlNodeRef SaveControllerDef(const SControllerDef& controllerDef) const; void ReloadControllerDef(SControllerDef* pControllerDef); void ReloadTagDefinition(CTagDefinition* pTagDefinition); void FindRootSubADB(const CAnimationDatabase& animDB, const CAnimationDatabase::SSubADB* pSubADB, FragmentID fragID, TagState tagState, string& outRootADB) const; std::vector FindImpactedDatabases(const CAnimationDatabase* pWorkingDatabase, FragmentID fragId, TagState globalTags) const; bool HasAncestor(const CAnimationDatabase& database, const string& ancestorName) const; bool HasAncestor(const CAnimationDatabase::SSubADB& database, const string& ancestorName) const; void PrepareSave (const CAnimationDatabase& animDB, const CAnimationDatabase::SSubADB* subAnimDB, TFragmentSaveList& vFragSaveList, TFragmentBlendSaveDatabase& mBlendSaveDatabase) const; bool FragmentMatches(uint32 fragCRC, const TagState& tagState, const CAnimationDatabase::SSubADB& subAnimDB, bool& bTagMatchFound) const; bool TransitionMatches(uint32 fragCRCFrom, uint32 fragCRCTo, const TagState& tagStateFrom, const TagState& tagStateTo, const CTagDefinition& parentTagDefs, const CAnimationDatabase::SSubADB& subAnimDB, bool& bTagMatchFound) const; bool CanSaveFragmentID(FragmentID fragID, const CAnimationDatabase& animDB, const CAnimationDatabase::SSubADB* subAnimDB) const; bool ShouldSaveFragment(FragmentID fragID, const TagState& tagState, const CAnimationDatabase& animDB, const CAnimationDatabase::SSubADB* subAnimDB, bool& bTagMatchFound) const; bool ShouldSaveTransition ( FragmentID fragIDFrom, FragmentID fragIDTo, const TagState& tagStateFrom, const TagState& tagStateTo, const CAnimationDatabase& animDB, const CAnimationDatabase::SSubADB* subAnimDB, bool& bTagMatchFound ) const; void RevertSubADB (const char* szFilename, CAnimationDatabase* animDB, const CAnimationDatabase::SSubADB& subADB); void SaveSubADB ( IMannequinWriter* pWriter, const CAnimationDatabase& animationDatabase, const CAnimationDatabase::SSubADB& subADB, const TFragmentSaveList& vFragSaveList, const TFragmentBlendSaveDatabase& mBlendSaveDatabase ) const; void SaveSubADB (const CAnimationDatabase& animDB, const CAnimationDatabase::SSubADB& subAnimDB, const TFragmentSaveList& vFragSaveList, const TFragmentBlendSaveDatabase& mBlendSaveDatabase) const; void SaveDatabase(IMannequinWriter* pWriter, const IAnimationDatabase* pAnimationDatabase) const; void SaveControllerDef(IMannequinWriter* pWriter, const SControllerDef* pControllerDef) const; void SaveTagDefinition(IMannequinWriter* pWriter, const CTagDefinition* pTagDefinition) const; void NotifyListenersTagDefinitionChanged(const CTagDefinition& tagDef); void ReconcileSubDatabases(const CAnimationDatabase* pSourceDatabase); void ReconcileSubDatabase(const CAnimationDatabase* pSourceDatabase, CAnimationDatabase* pTargetSubDatabase); private: static CAnimationDatabaseManager* s_Instance; typedef CListenerSet TEditorListenerSet; TEditorListenerSet m_editorListenerSet; }; #endif // CRYINCLUDE_CRYACTION_MANNEQUIN_ANIMATIONDATABASEMANAGER_H