AnimationService.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278
  1. //===========================================================================================================================
  2. // Spirenkov Maxim, 2003
  3. //===========================================================================================================================//
  4. //
  5. //===========================================================================================================================
  6. // AnimationService
  7. //============================================================================================
  8. #ifndef _AnimationService_h_
  9. #define _AnimationService_h_
  10. #include "Animation.h"
  11. #include "AnimationProcedural.h"
  12. #include "IAnxEditorServiceAccess.h"
  13. #ifndef STOP_DEBUG
  14. //#define DEBUG_PIX_ENABLE
  15. //#define DEBUG_THREADS
  16. #endif
  17. class IFileService;
  18. //Анимационная сцена
  19. class AnimationScene : public IAnimationScene
  20. {
  21. enum CommandId
  22. {
  23. cmd_empty,
  24. cmd_pause,
  25. cmd_start,
  26. cmd_goto,
  27. cmd_activate_link,
  28. cmd_rand_pos,
  29. };
  30. struct Command
  31. {
  32. word id;
  33. word intData;
  34. const char * strData;
  35. float floatData;
  36. Animation * ani;
  37. };
  38. public:
  39. AnimationScene(AnimationService & s, const char * _cppFile, long _cppLine);
  40. virtual ~AnimationScene();
  41. //Удалить сцену
  42. virtual void Release();
  43. //Принудительное удаление
  44. dword ForceRelease();
  45. //Создать анимацию
  46. virtual IAnimation * Create(const char * path, const char * cppFile, long cppLine);
  47. //Создать пустую анимацию
  48. virtual IAnimation * CreateEmpty(const Bone * skeleton, dword count, const char * cppFile, long cppLine);
  49. //Создать процедурную анимацию
  50. virtual IAnimationProcedural * CreateProcedural(const Bone * skeleton, dword count, const char * cppFile, long cppLine);
  51. //Обновить состояние сцены
  52. void UpdateScene(float dltTime);
  53. //Удалить анимацию из списка
  54. void Delete(Animation * ani);
  55. //Удалить процедурную анимацию из списка
  56. void Delete(AnimationProcedural * ani);
  57. //Установить анимацию на обновление
  58. void SetForUpdate(Animation * ani, bool isUpdate);
  59. public:
  60. void Command_Start(Animation * ani, const char * nameId);
  61. void Command_Goto(Animation * ani, const char * nameId, float blendTime, long clipIndex);
  62. void Command_ActivateLink(Animation * ani, const char * nameId, bool forceApply);
  63. void Command_Pause(Animation * ani, bool isPause);
  64. void Command_RandomizePosition(Animation * ani);
  65. void Command_ClearQueue(const Animation * ani);
  66. #ifndef STOP_DEBUG
  67. //Проверить не отписанный блендер и листенер
  68. void UnregistryCheck(IAniBlendStage * bs, IAnimationListener * lis);
  69. #endif
  70. #ifndef NO_TOOLS
  71. //Создать анимацию основываясь на данных редактора
  72. Animation * Editor_Create(const void * data, dword size);
  73. #endif
  74. private:
  75. AnimationService & service;
  76. //Закреплёные за сценой анимации
  77. array<Animation *> animations;
  78. //Включенные анимации
  79. array<Animation *> updatingAnimations;
  80. //Процедурные анимации, работающие по сильно упрощёной схеме
  81. array<AnimationProcedural *> procedural;
  82. //Буфер отложенных команд
  83. array<Command> commands;
  84. //Происходит ли обновление сцены сейчас
  85. dword isUpdateProcess;
  86. //Исходный Файл в котором был создан объект
  87. const char * cppFile;
  88. //Строка от куда был создан объект
  89. long cppLine;
  90. //Занимаемая всеми анимациями память
  91. dword debugUsageMemory;
  92. };
  93. class AnimationService : public IAnimationService
  94. {
  95. public:
  96. struct AnimationData
  97. {
  98. dword hash;
  99. dword len;
  100. long next;
  101. long prev;
  102. long refCounter;
  103. AnxData * data;
  104. };
  105. //--------------------------------------------------------------------------------------------
  106. //Инициализация
  107. //--------------------------------------------------------------------------------------------
  108. public:
  109. AnimationService();
  110. virtual ~AnimationService();
  111. private:
  112. virtual bool Init();
  113. //Вызываеться перед удалением сервисов
  114. void PreRelease();
  115. //--------------------------------------------------------------------------------------------
  116. //Создание, удаление сцен и анимаций
  117. //--------------------------------------------------------------------------------------------
  118. public:
  119. //Создать анимационные данные из файла
  120. AnxData * Create(const char * path);
  121. //Создать уникальные данные для пустой анимации
  122. AnxData * CreateEmpty(const IAnimationScene::Bone * skeleton, dword count);
  123. //Освободить анимационные данные
  124. void ReleaseData(AnxData * data);
  125. //Создать сцену с анимациями
  126. virtual IAnimationScene * CreateScene(const char * cppFile, long cppLine);
  127. //Удалить анимационную сцену из списка
  128. void ReleaseScene(AnimationScene * scene);
  129. //Получить объем анимации
  130. dword GetAnimationsDataSize();
  131. private:
  132. array<AnimationScene *> scenes; //Сцены
  133. array<AnimationData> anxData; //Загруженные анимационные данные
  134. long firstFreeData; //Первый свободный для использования элемент
  135. string buffer; //Буфер для работы с именами
  136. long entryData[1024]; //Входная таблица для поиска анимаций по имени
  137. //--------------------------------------------------------------------------------------------
  138. //Управление дополнительным потоком
  139. //--------------------------------------------------------------------------------------------
  140. public:
  141. //Добавить анимацию для обсчёта в потоке на следующем кадре
  142. void ThreadAddAnimationToUpdate(Animation * ani);
  143. //Извлечь анимацию из очереди обновления, если невозможно то остановить поток
  144. void ThreadRemoveAnimationToUpdate(Animation * ani);
  145. private:
  146. //Завершить цикл обсчёта матриц
  147. void ThreadStart();
  148. //Завершить поток обсчёта матриц
  149. void ThreadStop();
  150. //Приостановить цикл обсчёта матриц
  151. void ThreadPause();
  152. //Возобновить цикл обсчёта матриц
  153. void ThreadResume();
  154. //Извлечь анимацию из очереди обновления, если невозможно то остановить поток
  155. void ThreadPrepareQueue();
  156. //Поток обновления матриц
  157. static DWORD WINAPI ThreadMatricesUpdater(LPVOID lpParameter);
  158. private:
  159. HANDLE threadUpdater; //Поток апдейта матриц
  160. HANDLE eventProcess; //Событие разрешающее работу апдейтера
  161. HANDLE eventReady; //Событие сигнализирующие состояния потока апдейтера
  162. volatile bool threadWork; //Флаг сигнализирующий работу потока
  163. volatile bool threadPause; //Флаг требующий паузы от потока
  164. CritSection changeIndex; //Секция изменения индекса
  165. //Очередь анимаций для обновления в потоке
  166. array<Animation *> threadAnimationsQueue;
  167. //Индекс текущей обновляемой в сцене анимации
  168. volatile dword threadAnimationIndex;
  169. //Будующая очередь анимаций
  170. array<Animation *> newThreadAnimationsQueue;
  171. //--------------------------------------------------------------------------------------------
  172. //Общее
  173. //--------------------------------------------------------------------------------------------
  174. public:
  175. //Исполнение в конце кадра
  176. virtual void EndFrame(float dltTime);
  177. //Обновить анимационную сцену
  178. virtual void Update(IAnimationScene * scene, float dltTime);
  179. //Получить занимаемую анимацией память
  180. virtual dword GetUsageMemory();
  181. //Разрешён ли трейс об незначительных ошибках
  182. bool IsEnableTrace();
  183. public:
  184. //Разрешено выводить сообщения
  185. bool enableTrace;
  186. //Файловый сервис
  187. IFileService * fs;
  188. //--------------------------------------------------------------------------------------------
  189. //Функции для редактора
  190. //--------------------------------------------------------------------------------------------
  191. #ifndef NO_TOOLS
  192. public:
  193. //В редакторе может быть только однопоточный режим
  194. void Editor_NoThread();
  195. #endif
  196. //--------------------------------------------------------------------------------------------
  197. //Оптимизация, отладка
  198. //--------------------------------------------------------------------------------------------
  199. #ifndef STOP_DEBUG
  200. public:
  201. //Добавить счётчик промахнувшегося вычисления
  202. void AddMissGetBoneMatrices();
  203. //Добавить счётчик промахнувшегося вычисления отдельной кости
  204. void AddMissGetSingleBoneMatrix();
  205. //Добавить счётчик вычисления на дополнительном потоке
  206. void AddThreadUpdateBoneMatricesCounter();
  207. //Проверить не отписанный блендер и листенер
  208. virtual void UnregistryCheck(IAniBlendStage * bs, IAnimationListener * lis);
  209. private:
  210. long missGetBoneMatricesCounter; //Счётчик анимаций обсчитанных в основном потоке
  211. long missGetSingleBoneMatrixCounter; //Счётчик анимаций обсчитанных в основном потоке
  212. long threadUpdateBoneMatricesCounter; //Счётчик анимаций обсчитанных в основном потоке
  213. ICoreStorageLong * bonesCounter; //Переменная для отладочной информации
  214. #endif
  215. dword debugUsageMemory; //Общая занимаемая память
  216. };
  217. #ifndef NO_TOOLS
  218. class AnxEditorServiceAccess : public IAnxEditorServiceAccess
  219. {
  220. public:
  221. //Запретить потоки
  222. virtual void DisableThreads();
  223. //Создать анимацию из памяти
  224. virtual IAnimation * CreateAnimation(IAnimationScene * scene, const void * data, unsigned long size);
  225. };
  226. #endif
  227. //Разрешён ли трейс об незначительных ошибках
  228. __forceinline bool AnimationService::IsEnableTrace()
  229. {
  230. return enableTrace;
  231. }
  232. #endif