/* * 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_MANNEQUIN_SEQUENCERTRACK_H #define CRYINCLUDE_EDITOR_MANNEQUIN_SEQUENCERTRACK_H #pragma once #include "ISequencerSystem.h" const int KEY_MENU_CMD_BASE = 1000; template class TSequencerTrack : public CSequencerTrack { public: //! Return number of keys in track. virtual int GetNumKeys() const { return m_keys.size(); } //! Set number of keys in track. //! If needed adds empty keys at end or remove keys from end. virtual void SetNumKeys(int numKeys) { m_keys.resize(numKeys); } //! Remove specified key. virtual void RemoveKey(int num); int CreateKey(float time); int CloneKey(int fromKey); int CopyKey(CSequencerTrack* pFromTrack, int nFromKey); //! Get key at specified location. //! @param key Must be valid pointer to compatible key structure, to be filled with specified key location. virtual void GetKey(int index, CSequencerKey* key) const; virtual const CSequencerKey* GetKey(int index) const; virtual CSequencerKey* GetKey(int index); //! Set key at specified location. //! @param key Must be valid pointer to compatible key structure. virtual void SetKey(int index, CSequencerKey* key); /** Serialize this animation track to XML. Do not override this method, prefer to override SerializeKey. */ virtual bool Serialize(XmlNodeRef& xmlNode, bool bLoading, bool bLoadEmptyTracks = true); virtual bool SerializeSelection(XmlNodeRef& xmlNode, bool bLoading, bool bCopySelected = false, float fTimeOffset = 0); /** Serialize single key of this track. Override this in derived classes. Do not save time attribute, it is already saved in Serialize of the track. */ virtual void SerializeKey(KeyType& key, XmlNodeRef& keyNode, bool bLoading) = 0; protected: //! Sort keys in track (after time of keys was modified). virtual void DoSortKeys(); protected: typedef std::vector Keys; Keys m_keys; }; ////////////////////////////////////////////////////////////////////////// template inline void TSequencerTrack::RemoveKey(int index) { assert(index >= 0 && index < (int)m_keys.size()); m_keys.erase(m_keys.begin() + index); Invalidate(); } ////////////////////////////////////////////////////////////////////////// template inline void TSequencerTrack::GetKey(int index, CSequencerKey* key) const { assert(index >= 0 && index < (int)m_keys.size()); assert(key != 0); *(KeyType*)key = m_keys[index]; } ////////////////////////////////////////////////////////////////////////// template inline const CSequencerKey* TSequencerTrack::GetKey(int index) const { assert(index >= 0 && index < (int)m_keys.size()); return &m_keys[index]; } ////////////////////////////////////////////////////////////////////////// template inline CSequencerKey* TSequencerTrack::GetKey(int index) { assert(index >= 0 && index < (int)m_keys.size()); return &m_keys[index]; } ////////////////////////////////////////////////////////////////////////// template inline void TSequencerTrack::SetKey(int index, CSequencerKey* key) { assert(index >= 0 && index < (int)m_keys.size()); assert(key != 0); m_keys[index] = *(KeyType*)key; Invalidate(); } ////////////////////////////////////////////////////////////////////////// template inline void TSequencerTrack::DoSortKeys() { std::sort(m_keys.begin(), m_keys.end()); } ////////////////////////////////////////////////////////////////////////// template inline bool TSequencerTrack::Serialize(XmlNodeRef& xmlNode, bool bLoading, bool bLoadEmptyTracks) { if (bLoading) { int num = xmlNode->getChildCount(); Range timeRange; int flags = GetFlags(); xmlNode->getAttr("Flags", flags); xmlNode->getAttr("StartTime", timeRange.start); xmlNode->getAttr("EndTime", timeRange.end); SetFlags(flags); SetTimeRange(timeRange); SetNumKeys(num); for (int i = 0; i < num; i++) { XmlNodeRef keyNode = xmlNode->getChild(i); keyNode->getAttr("time", m_keys[i].time); SerializeKey(m_keys[i], keyNode, bLoading); } if ((!num) && (!bLoadEmptyTracks)) { return false; } } else { int num = GetNumKeys(); MakeValid(); xmlNode->setAttr("Flags", GetFlags()); xmlNode->setAttr("StartTime", GetTimeRange().start); xmlNode->setAttr("EndTime", GetTimeRange().end); for (int i = 0; i < num; i++) { XmlNodeRef keyNode = xmlNode->newChild("Key"); keyNode->setAttr("time", m_keys[i].time); SerializeKey(m_keys[i], keyNode, bLoading); } } return true; } ////////////////////////////////////////////////////////////////////////// template inline bool TSequencerTrack::SerializeSelection(XmlNodeRef& xmlNode, bool bLoading, bool bCopySelected, float fTimeOffset) { if (bLoading) { int numCur = GetNumKeys(); int num = xmlNode->getChildCount(); int type; xmlNode->getAttr("TrackType", type); SetNumKeys(num + numCur); for (int i = 0; i < num; i++) { XmlNodeRef keyNode = xmlNode->getChild(i); keyNode->getAttr("time", m_keys[i + numCur].time); m_keys[i + numCur].time += fTimeOffset; SerializeKey(m_keys[i + numCur], keyNode, bLoading); if (bCopySelected) { m_keys[i + numCur].flags |= AKEY_SELECTED; } } SortKeys(); } else { int num = GetNumKeys(); //CheckValid(); for (int i = 0; i < num; i++) { if (!bCopySelected || GetKeyFlags(i) & AKEY_SELECTED) { XmlNodeRef keyNode = xmlNode->newChild("Key"); keyNode->setAttr("time", m_keys[i].time + fTimeOffset); SerializeKey(m_keys[i], keyNode, bLoading); } } } return true; } ////////////////////////////////////////////////////////////////////////// template inline int TSequencerTrack::CreateKey(float time) { KeyType key, akey; int nkey = GetNumKeys(); SetNumKeys(nkey + 1); key.time = time; SetKey(nkey, &key); return nkey; } ////////////////////////////////////////////////////////////////////////// template inline int TSequencerTrack::CloneKey(int fromKey) { KeyType key; GetKey(fromKey, &key); int nkey = GetNumKeys(); SetNumKeys(nkey + 1); SetKey(nkey, &key); return nkey; } ////////////////////////////////////////////////////////////////////////// template inline int TSequencerTrack::CopyKey(CSequencerTrack* pFromTrack, int nFromKey) { KeyType key; pFromTrack->GetKey(nFromKey, &key); int nkey = GetNumKeys(); SetNumKeys(nkey + 1); SetKey(nkey, &key); return nkey; } #endif // CRYINCLUDE_EDITOR_MANNEQUIN_SEQUENCERTRACK_H