AnimationResource.cpp 6.0 KB

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