#if !defined(KEY_H) #define KEY_H #pragma warning(disable:4786) // don't warn about browse name overflow. #include #include #include #include #include "z3dmath.h" typedef std::map< unsigned long, vector3, std::less > VectorKeyList; typedef std::map< unsigned long, quaternion, std::less > QuaternionKeyList; typedef std::map< unsigned long, float, std::less > FloatKeyList; typedef std::map< unsigned long, color, std::less > ColorKeyList; template class CKeyList { protected: KeyList m_lstKey; typename KeyList::iterator Lower, Upper; unsigned long dwLower, dwUpper; public: CKeyList(void) { } ~CKeyList(void) { } typename KeyList::iterator Begin(void) { return m_lstKey.begin(); } typename KeyList::iterator End(void) { return m_lstKey.end(); } template void SetKey(unsigned long dwFrame, NewData &Data) { m_lstKey[dwFrame] = Data; } template BOOL Find(unsigned long dwFrame, NewData &Data) { if(m_lstKey.empty()) return FALSE; Lower = m_lstKey.find(dwFrame); if(Lower == m_lstKey.end()) { Lower = m_lstKey.lower_bound(dwFrame); if(Lower != m_lstKey.begin()) { Lower--; } Data = ((*Lower).second); return FALSE; } Data = ((*Lower).second); return TRUE; } BOOL Find(unsigned long dwFrame) { if(m_lstKey.empty()) return FALSE; Lower = m_lstKey.find(dwFrame); if(Lower == m_lstKey.end()) return FALSE; else return TRUE; } void Erase(unsigned long dwFrame) { Lower = m_lstKey.find(dwFrame); m_lstKey.erase(Lower); } template void Load(FILE *fp, DataType &Data) { unsigned short frame; dwLower = 0; fread(&dwLower, 2, 1, fp); for(dwUpper = 0; dwUpper < dwLower; dwUpper++) { fread(&frame, 2, 1, fp); fread(&Data, sizeof(Data), 1, fp); m_lstKey[frame] = Data; } } void Save(FILE *fp) { dwLower = m_lstKey.size(); fwrite(&dwLower, 2, 1, fp); for(Lower = m_lstKey.begin(); Lower != m_lstKey.end(); Lower++) { fwrite(&((*Lower).first), 2, 1, fp); fwrite(&((*Lower).second), sizeof((*Lower).second), 1, fp); } } BOOL InterpolationQ(float fFrame, quaternion &Data) { quaternion rdLower, rdUpper; if(m_lstKey.empty()) return FALSE; Lower = Upper = m_lstKey.lower_bound(ceilf(fFrame)); if(Upper == m_lstKey.begin()) { Upper = Lower; Upper++; } else { Lower--; } dwLower = (*Lower).first; rdLower = (*Lower).second; if(Upper != m_lstKey.end()) { dwUpper = (*Upper).first; rdUpper = (*Upper).second; z3d::QuaternionSlerp(Data, rdLower, rdUpper, 1.0f / (dwUpper - dwLower) * (fFrame - dwLower)); } else { Data = rdLower; } return TRUE; } BOOL InterpolationC(float fFrame, color &Data) { color rdLower, rdUpper; if(m_lstKey.empty()) return FALSE; Lower = Upper = m_lstKey.lower_bound(ceilf(fFrame)); if(Upper == m_lstKey.begin()) { Upper = Lower; Upper++; } else { Lower--; } dwLower = (*Lower).first; rdLower = (*Lower).second; if(Upper != m_lstKey.end()) { dwUpper = (*Upper).first; rdUpper = (*Upper).second; Data = color::Interpolation(rdLower, rdUpper, 1.0f / (dwUpper - dwLower) * (fFrame - dwLower)); } else { Data = rdLower; } return TRUE; } template BOOL Interpolation(float fFrame, RetData &Data) { RetData rdLower, rdUpper; if(m_lstKey.empty()) return FALSE; Lower = Upper = m_lstKey.lower_bound(ceilf(fFrame)); if(Upper == m_lstKey.begin()) { Upper = Lower; Upper++; } else { Lower--; } dwLower = (*Lower).first; rdLower = (*Lower).second; if(Upper != m_lstKey.end()) { dwUpper = (*Upper).first; rdUpper = (*Upper).second; Data = (((rdUpper - rdLower) / (dwUpper - dwLower)) * (fFrame - dwLower)) + rdLower; } else { Data = rdLower; } return TRUE; } }; template inline void SetKey(unsigned long dwFrame, KeyList &lstKey, Data NewData) { lstKey.SetKey(dwFrame, NewData); } #endif // !defined(KEY_H)