AnimationResource.cpp 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277
  1. // Copyright (C) 2009-2021, Panagiotis Christopoulos Charitos and contributors.
  2. // All rights reserved.
  3. // Code licensed under the BSD License.
  4. // http://www.anki3d.org/LICENSE
  5. #include <AnKi/Resource/AnimationResource.h>
  6. #include <AnKi/Util/Xml.h>
  7. namespace anki
  8. {
  9. AnimationResource::AnimationResource(ResourceManager* manager)
  10. : ResourceObject(manager)
  11. {
  12. }
  13. AnimationResource::~AnimationResource()
  14. {
  15. for(AnimationChannel& ch : m_channels)
  16. {
  17. ch.destroy(getAllocator());
  18. }
  19. m_channels.destroy(getAllocator());
  20. }
  21. Error AnimationResource::load(const ResourceFilename& filename, Bool async)
  22. {
  23. XmlElement el;
  24. m_startTime = MAX_SECOND;
  25. Second maxTime = MIN_SECOND;
  26. // Document
  27. XmlDocument doc;
  28. ANKI_CHECK(openFileParseXml(filename, doc));
  29. XmlElement rootel;
  30. ANKI_CHECK(doc.getChildElement("animation", rootel));
  31. // Count the number of identity keys. If all of the keys are identities drop a vector
  32. U identPosCount = 0;
  33. U identRotCount = 0;
  34. U identScaleCount = 0;
  35. // <channels>
  36. XmlElement channelsEl;
  37. ANKI_CHECK(rootel.getChildElement("channels", channelsEl));
  38. XmlElement chEl;
  39. ANKI_CHECK(channelsEl.getChildElement("channel", chEl));
  40. U32 channelCount = 0;
  41. ANKI_CHECK(chEl.getSiblingElementsCount(channelCount));
  42. ++channelCount;
  43. if(channelCount == 0)
  44. {
  45. ANKI_RESOURCE_LOGE("Didn't found any channels");
  46. return Error::USER_DATA;
  47. }
  48. m_channels.create(getAllocator(), channelCount);
  49. // For all channels
  50. channelCount = 0;
  51. do
  52. {
  53. AnimationChannel& ch = m_channels[channelCount];
  54. // <name>
  55. CString strtmp;
  56. ANKI_CHECK(chEl.getAttributeText("name", strtmp));
  57. ch.m_name.create(getAllocator(), strtmp);
  58. XmlElement keysEl, keyEl;
  59. // <positionKeys>
  60. ANKI_CHECK(chEl.getChildElementOptional("positionKeys", keysEl));
  61. if(keysEl)
  62. {
  63. ANKI_CHECK(keysEl.getChildElement("key", keyEl));
  64. U32 count = 0;
  65. ANKI_CHECK(keyEl.getSiblingElementsCount(count));
  66. ++count;
  67. ch.m_positions.create(getAllocator(), count);
  68. count = 0;
  69. do
  70. {
  71. AnimationKeyframe<Vec3>& key = ch.m_positions[count++];
  72. // time
  73. ANKI_CHECK(keyEl.getAttributeNumber("time", key.m_time));
  74. m_startTime = min(m_startTime, key.m_time);
  75. maxTime = max(maxTime, key.m_time);
  76. // value
  77. ANKI_CHECK(keyEl.getNumbers(key.m_value));
  78. // Check ident
  79. if(key.m_value == Vec3(0.0))
  80. {
  81. ++identPosCount;
  82. }
  83. // Move to next
  84. ANKI_CHECK(keyEl.getNextSiblingElement("key", keyEl));
  85. } while(keyEl);
  86. }
  87. // <rotationKeys>
  88. ANKI_CHECK(chEl.getChildElementOptional("rotationKeys", keysEl));
  89. if(keysEl)
  90. {
  91. ANKI_CHECK(keysEl.getChildElement("key", keyEl));
  92. U32 count = 0;
  93. ANKI_CHECK(keyEl.getSiblingElementsCount(count));
  94. ++count;
  95. ch.m_rotations.create(getAllocator(), count);
  96. count = 0;
  97. do
  98. {
  99. AnimationKeyframe<Quat>& key = ch.m_rotations[count++];
  100. // time
  101. ANKI_CHECK(keyEl.getAttributeNumber("time", key.m_time));
  102. m_startTime = min(m_startTime, key.m_time);
  103. maxTime = max(maxTime, key.m_time);
  104. // value
  105. ANKI_CHECK(keyEl.getNumbers(key.m_value));
  106. // Check ident
  107. if(key.m_value == Quat::getIdentity())
  108. {
  109. ++identRotCount;
  110. }
  111. // Move to next
  112. ANKI_CHECK(keyEl.getNextSiblingElement("key", keyEl));
  113. } while(keyEl);
  114. }
  115. // <scalingKeys>
  116. ANKI_CHECK(chEl.getChildElementOptional("scalingKeys", keysEl));
  117. if(keysEl)
  118. {
  119. ANKI_CHECK(keysEl.getChildElement("key", keyEl));
  120. U32 count = 0;
  121. ANKI_CHECK(keyEl.getSiblingElementsCount(count));
  122. ++count;
  123. ch.m_scales.create(getAllocator(), count);
  124. count = 0;
  125. do
  126. {
  127. AnimationKeyframe<F32>& key = ch.m_scales[count++];
  128. // time
  129. ANKI_CHECK(keyEl.getAttributeNumber("time", key.m_time));
  130. m_startTime = std::min(m_startTime, key.m_time);
  131. maxTime = std::max(maxTime, key.m_time);
  132. // value
  133. ANKI_CHECK(keyEl.getChildElement("value", el));
  134. ANKI_CHECK(keyEl.getNumber(key.m_value));
  135. // Check ident
  136. if(isZero(key.m_value - 1.0f))
  137. {
  138. ++identScaleCount;
  139. }
  140. // Move to next
  141. ANKI_CHECK(keyEl.getNextSiblingElement("key", keyEl));
  142. } while(keyEl);
  143. }
  144. // Remove identity vectors
  145. if(identPosCount == ch.m_positions.getSize())
  146. {
  147. ch.m_positions.destroy(getAllocator());
  148. }
  149. if(identRotCount == ch.m_rotations.getSize())
  150. {
  151. ch.m_rotations.destroy(getAllocator());
  152. }
  153. if(identScaleCount == ch.m_scales.getSize())
  154. {
  155. ch.m_scales.destroy(getAllocator());
  156. }
  157. // Move to next channel
  158. ++channelCount;
  159. ANKI_CHECK(chEl.getNextSiblingElement("channel", chEl));
  160. } while(chEl);
  161. m_duration = maxTime - m_startTime;
  162. return Error::NONE;
  163. }
  164. void AnimationResource::interpolate(U32 channelIndex, Second time, Vec3& pos, Quat& rot, F32& scale) const
  165. {
  166. pos = Vec3(0.0f);
  167. rot = Quat::getIdentity();
  168. scale = 1.0f;
  169. if(ANKI_UNLIKELY(time < m_startTime))
  170. {
  171. return;
  172. }
  173. // Audjust time
  174. if(time > m_startTime + m_duration)
  175. {
  176. time = mod(time - m_startTime, m_duration) + m_startTime;
  177. }
  178. ANKI_ASSERT(time >= m_startTime && time <= m_startTime + m_duration);
  179. ANKI_ASSERT(channelIndex < m_channels.getSize());
  180. const AnimationChannel& channel = m_channels[channelIndex];
  181. // Position
  182. if(channel.m_positions.getSize() > 1)
  183. {
  184. for(U32 i = 0; i < channel.m_positions.getSize() - 1; ++i)
  185. {
  186. const AnimationKeyframe<Vec3>& left = channel.m_positions[i];
  187. const AnimationKeyframe<Vec3>& right = channel.m_positions[i + 1];
  188. if(time >= left.m_time && time <= right.m_time)
  189. {
  190. const Second u = (time - left.m_time) / (right.m_time - left.m_time);
  191. pos = linearInterpolate(left.m_value, right.m_value, F32(u));
  192. break;
  193. }
  194. }
  195. }
  196. // Rotation
  197. if(channel.m_rotations.getSize() > 1)
  198. {
  199. for(U32 i = 0; i < channel.m_rotations.getSize() - 1; ++i)
  200. {
  201. const AnimationKeyframe<Quat>& left = channel.m_rotations[i];
  202. const AnimationKeyframe<Quat>& right = channel.m_rotations[i + 1];
  203. if(time >= left.m_time && time <= right.m_time)
  204. {
  205. const Second u = (time - left.m_time) / (right.m_time - left.m_time);
  206. rot = left.m_value.slerp(right.m_value, F32(u));
  207. break;
  208. }
  209. }
  210. }
  211. // Scale
  212. if(channel.m_scales.getSize() > 1)
  213. {
  214. for(U32 i = 0; i < channel.m_scales.getSize() - 1; ++i)
  215. {
  216. const AnimationKeyframe<F32>& left = channel.m_scales[i];
  217. const AnimationKeyframe<F32>& right = channel.m_scales[i + 1];
  218. if(time >= left.m_time && time <= right.m_time)
  219. {
  220. const Second u = (time - left.m_time) / (right.m_time - left.m_time);
  221. scale = linearInterpolate(left.m_value, right.m_value, F32(u));
  222. break;
  223. }
  224. }
  225. }
  226. }
  227. } // end namespace anki