KeyFrameList.cpp
上传用户:shxiangxiu
上传日期:2007-01-03
资源大小:1101k
文件大小:6k
源码类别:

OpenGL

开发平台:

Visual C++

  1. /////////////////////////////////////////////////////////////////////////////
  2. // KeyFrameList.cpp : implementation file
  3. //
  4. // glOOP (OpenGL Object Oriented Programming library)
  5. // Copyright (c) Craig Fahrnbach 1997, 1998
  6. //
  7. // OpenGL is a registered trademark of Silicon Graphics
  8. //
  9. //
  10. // This program is provided for educational and personal use only and
  11. // is provided without guarantee or warrantee expressed or implied.
  12. //
  13. // Commercial use is strickly prohibited without written permission
  14. // from ImageWare Development.
  15. //
  16. // This program is -not- in the public domain.
  17. //
  18. /////////////////////////////////////////////////////////////////////////////
  19. #include "stdafx.h"
  20. #include "glOOP.h"
  21. #ifdef _DEBUG
  22. #define new DEBUG_NEW
  23. #undef THIS_FILE
  24. static char THIS_FILE[] = __FILE__;
  25. #endif
  26. /////////////////////////////////////////////////////////////////////////////
  27. // CKeyFrameList
  28. //IMPLEMENT_DYNAMIC(CKeyFrameList, CObList)
  29. /////////////////////////////////////////////////////////////////////////////
  30. // CKeyFrameList construction
  31. CKeyFrameList::CKeyFrameList()
  32. {
  33. // TODO: add construction code here,
  34. // Place all significant initialization in InitInstance
  35. }
  36. /////////////////////////////////////////////////////////////////////////////
  37. // CKeyFrameList Destructor
  38. CKeyFrameList::~CKeyFrameList()
  39. {
  40. DeleteAll();
  41. }
  42. /////////////////////////////////////////////////////////////////////////////
  43. // CKeyFrameList function implimentation
  44. void CKeyFrameList::Append(CKeyFrame* pKeyFrame)
  45. {
  46. if (!pKeyFrame)
  47. return;
  48. CObList::AddTail(pKeyFrame);
  49. }
  50. // Add a key value based on the current frame's position
  51. BOOL CKeyFrameList::AddKeyFrame(double time, C3dObject* pObject)
  52. {
  53. if (!pObject)
  54. return FALSE;
  55. // Create new key frame
  56. CKeyFrame* pKeyFrame = new CKeyFrame(time, pObject);
  57. // Add key to list
  58. return AddKeyFrame(pKeyFrame);
  59. }
  60. BOOL CKeyFrameList::AddKeyFrame(CKeyFrame* pNewKeyFrame)
  61. {
  62. if (!pNewKeyFrame)
  63. return FALSE;
  64. // Insert key into list
  65. if (IsEmpty())
  66. {
  67. AddTail(pNewKeyFrame);
  68. return TRUE;
  69. }
  70. // Step through list backward
  71. POSITION pos = GetTailPosition();
  72. ASSERT(pos);
  73. do {
  74. POSITION thispos = pos;
  75. CKeyFrame* pKey = (CKeyFrame*) GetPrev(pos);
  76. if (pKey->m_dTime < pNewKeyFrame->m_dTime)
  77. {
  78. // Insert new key after this one
  79. InsertAfter(thispos, pNewKeyFrame);
  80. return TRUE;
  81. }
  82. if (pKey->m_dTime == pNewKeyFrame->m_dTime)
  83. {
  84. // User has recorded a new key with the same
  85. // time base as pKey, InsertAfter and Remove old.
  86. // Insert new key after this one
  87. InsertAfter(thispos, pNewKeyFrame);
  88. Delete(pKey);
  89. return TRUE;
  90. }
  91. } while (pos);
  92. // Put new key in at start
  93. AddHead(pNewKeyFrame);
  94. return TRUE;
  95. }
  96. void CKeyFrameList::Remove(CKeyFrame* pKeyFrame)
  97. {
  98. if (!pKeyFrame) return;
  99. POSITION pos = CObList::Find(pKeyFrame);
  100. if (pos) {
  101. RemoveAt(pos);
  102. }
  103. }
  104. void CKeyFrameList::Delete(CKeyFrame* pKeyFrame)
  105. {
  106. if (!pKeyFrame) return;
  107. Remove(pKeyFrame);
  108. delete pKeyFrame;
  109. }
  110. void CKeyFrameList::DeleteAll()
  111. {
  112. while (!IsEmpty()) {
  113. CKeyFrame* pKeyFrame = (CKeyFrame*) RemoveHead();
  114. delete pKeyFrame;
  115. }
  116. }
  117. double CKeyFrameList::GetLength()
  118. {
  119. if (IsEmpty()) return 0;
  120. CKeyFrame* pKeyFrame = (CKeyFrame*) GetTail();
  121. ASSERT(pKeyFrame);
  122. return pKeyFrame->m_dTime;
  123. }
  124. CKeyFrame* CKeyFrameList::Find(double dTime)
  125. {
  126. CKeyFrame* pKey = NULL;
  127. // walk the list
  128. POSITION Pos = GetHeadPosition();
  129. while (Pos) {
  130. pKey = GetAt(Pos);
  131. if(pKey->m_dTime == dTime)
  132. return pKey;
  133. pKey = GetNext(Pos);
  134. }
  135. return NULL; // end of list
  136. }
  137. CKeyFrame* CKeyFrameList::FindClosest(double dTime, int *iKeyFrameTime)
  138. {
  139. CKeyFrame* pKey = NULL;
  140. CKeyFrame* pKeyClosest = NULL;
  141. double lowest = LARGE_NUMBER;
  142. // walk the list
  143. POSITION Pos = GetHeadPosition();
  144. while (Pos) {
  145. pKey = GetAt(Pos);
  146. double diff = pKey->m_dTime - dTime;
  147. if(diff < lowest)
  148. pKeyClosest = pKey;
  149. pKey = GetNext(Pos);
  150. }
  151. if(pKeyClosest)
  152. {
  153. if(pKeyClosest->m_dTime < dTime)
  154. *iKeyFrameTime = -1;
  155. if(pKeyClosest->m_dTime == dTime)
  156. *iKeyFrameTime = 0;
  157. if(pKeyClosest->m_dTime > dTime)
  158. *iKeyFrameTime = 1;
  159. }
  160. return pKeyClosest; // end of list
  161. }
  162. CKeyFrame* CKeyFrameList::FindLarger(double dTime)
  163. {
  164. CKeyFrame* pKey = NULL;
  165. CKeyFrame* pKeyLarger = NULL;
  166. double lowest = LARGE_NUMBER;
  167. // walk the list
  168. POSITION Pos = GetHeadPosition();
  169. while (Pos) {
  170. pKey = GetAt(Pos);
  171. double diff = pKey->m_dTime - dTime;
  172. if(diff > 0.0)
  173. {
  174. if(diff < lowest)
  175. {
  176. pKeyLarger = pKey;
  177. lowest = diff;
  178. }
  179. }
  180. pKey = GetNext(Pos);
  181. }
  182. return pKeyLarger; // end of list
  183. }
  184. CKeyFrame* CKeyFrameList::FindSmaller(double dTime)
  185. {
  186. CKeyFrame* pKey = NULL;
  187. CKeyFrame* pKeySmaller = NULL;
  188. double lowest = -LARGE_NUMBER;
  189. // walk the list
  190. POSITION Pos = GetHeadPosition();
  191. while (Pos) {
  192. pKey = GetAt(Pos);
  193. double diff = pKey->m_dTime - dTime;
  194. if(diff < 0.0)
  195. {
  196. if(diff > lowest)
  197. {
  198. pKeySmaller = pKey;
  199. lowest = diff;
  200. }
  201. }
  202. pKey = GetNext(Pos);
  203. }
  204. return pKeySmaller; // end of list
  205. }
  206. void CKeyFrameList::Serialize(CArchive& ar, int iVersion)
  207. {
  208. CString szIndentSave;
  209. CString szBuffer;
  210. if (ar.IsStoring())
  211. {
  212. // Save the Objects' CKeyFrame frames
  213. szBuffer.Format("%stCKeyFrame List {n", szIndent);
  214. ar.WriteString(szBuffer);
  215. // Save the number of keyframes in this list
  216. szBuffer.Format("%sttNumKeyFrames  < %d >n", szIndent, GetNumKeys());
  217. ar.WriteString(szBuffer);
  218. // Save the current indention and indent
  219. // all CAnimation class procedures
  220. szIndentSave = szIndent;
  221. szIndent += _T("tt"); // Add tabs
  222. CKeyFrame* pKey = NULL;
  223. // walk the list
  224. POSITION Pos = GetHeadPosition();
  225. while (Pos) {
  226. pKey = GetAt(Pos);
  227. pKey->Serialize(ar, iVersion);
  228. pKey = GetNext(Pos);
  229. }
  230. // Restore indent position
  231. szIndent = szIndentSave; // restore indent
  232. szBuffer.Format("%st}n", szIndent); // end of CAnimation procedures
  233. ar.WriteString(szBuffer);
  234. }
  235. else
  236. {
  237. // Load all CAnimation procedures
  238. while(ar.ReadString(szBuffer)) {
  239. CKeyFrame* pKey = NULL;
  240. szBuffer.TrimLeft(); // Remove leading white spaces
  241. if(szBuffer.Compare("}") == 0) // end of CAnimKey
  242. break;
  243. if(szBuffer.Compare("CKeyFrame {") == 0) {
  244. pKey = new CKeyFrame(0.0, NULL);
  245. ASSERT(pKey);
  246. pKey->Serialize(ar, iVersion);
  247. Append(pKey);
  248. }
  249. }
  250. }
  251. }