EdAnimationCurve.cs 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260
  1. //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
  2. //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
  3. using System;
  4. using BansheeEngine;
  5. namespace BansheeEditor
  6. {
  7. internal enum TangentMode
  8. {
  9. Auto = 0,
  10. Free = 1 << 0,
  11. InAuto = 1 << 1,
  12. OutAuto = 1 << 2,
  13. InFree = 1 << 3,
  14. OutFree = 1 << 4,
  15. InLinear = 1 << 5,
  16. OutLinear = 1 << 6,
  17. InStep = 1 << 7,
  18. OutStep = 1 << 8
  19. }
  20. internal class EdAnimationCurve
  21. {
  22. private AnimationCurve native;
  23. private TangentMode[] tangentModes;
  24. public AnimationCurve Native
  25. {
  26. get { return native; }
  27. }
  28. public TangentMode[] TangentModes
  29. {
  30. get { return tangentModes; }
  31. }
  32. internal EdAnimationCurve()
  33. {
  34. KeyFrame[] keyframes = new KeyFrame[0];
  35. native = new AnimationCurve(keyframes);
  36. tangentModes = new TangentMode[0];
  37. }
  38. // Tangent modes should match number of curve keyframes
  39. internal EdAnimationCurve(AnimationCurve native, TangentMode[] tangentModes)
  40. {
  41. this.native = native;
  42. KeyFrame[] keyFrames = native.KeyFrames;
  43. this.tangentModes = new TangentMode[keyFrames.Length];
  44. if (tangentModes != null)
  45. {
  46. int numTangents = Math.Min(keyFrames.Length, tangentModes.Length);
  47. Array.Copy(tangentModes, this.tangentModes, numTangents);
  48. }
  49. UpdateTangents(keyFrames, this.tangentModes);
  50. }
  51. internal void AddKeyframe(float time, float value)
  52. {
  53. AddKeyframe(time, value, TangentMode.Auto);
  54. }
  55. internal void AddKeyframe(float time, float value, TangentMode tangentMode)
  56. {
  57. KeyFrame[] existingKeyFrames = native.KeyFrames;
  58. KeyFrame[] newKeyFrames = new KeyFrame[existingKeyFrames.Length + 1];
  59. newKeyFrames[newKeyFrames.Length - 1].time = float.PositiveInfinity;
  60. TangentMode[] newTangentModes = new TangentMode[tangentModes.Length + 1];
  61. int insertIdx = existingKeyFrames.Length;
  62. for (int i = 0; i < existingKeyFrames.Length; i++)
  63. {
  64. if (time < existingKeyFrames[i].time)
  65. {
  66. insertIdx = i;
  67. break;
  68. }
  69. }
  70. Array.Copy(existingKeyFrames, newKeyFrames, insertIdx);
  71. Array.Copy(tangentModes, newTangentModes, insertIdx);
  72. KeyFrame keyFrame = new KeyFrame();
  73. keyFrame.time = time;
  74. keyFrame.value = value;
  75. newKeyFrames[insertIdx] = keyFrame;
  76. newTangentModes[insertIdx] = tangentMode;
  77. if (insertIdx < existingKeyFrames.Length)
  78. {
  79. int remaining = existingKeyFrames.Length - insertIdx;
  80. Array.Copy(existingKeyFrames, insertIdx, newKeyFrames, insertIdx + 1, remaining);
  81. Array.Copy(tangentModes, insertIdx, newTangentModes, insertIdx + 1, remaining);
  82. }
  83. UpdateTangents(newKeyFrames, newTangentModes);
  84. tangentModes = newTangentModes;
  85. native.KeyFrames = newKeyFrames;
  86. }
  87. internal void RemoveKeyframe(int index)
  88. {
  89. KeyFrame[] existingKeyFrames = native.KeyFrames;
  90. if (index < 0 || index >= existingKeyFrames.Length)
  91. return;
  92. KeyFrame[] newKeyFrames = new KeyFrame[existingKeyFrames.Length - 1];
  93. TangentMode[] newTangentModes = new TangentMode[tangentModes.Length - 1];
  94. Array.Copy(existingKeyFrames, newKeyFrames, index);
  95. Array.Copy(tangentModes, newTangentModes, index);
  96. if (index < newKeyFrames.Length)
  97. {
  98. int remaining = newKeyFrames.Length - index;
  99. Array.Copy(existingKeyFrames, index + 1, newKeyFrames, index, remaining);
  100. Array.Copy(tangentModes, index + 1, newTangentModes, index, remaining);
  101. }
  102. UpdateTangents(newKeyFrames, newTangentModes);
  103. tangentModes = newTangentModes;
  104. native.KeyFrames = newKeyFrames;
  105. }
  106. internal void SetTangentMode(int index, TangentMode mode)
  107. {
  108. if (index < 0 || index >= tangentModes.Length)
  109. return;
  110. tangentModes[index] = mode;
  111. KeyFrame[] keyFrames = native.KeyFrames;
  112. UpdateTangents(keyFrames, tangentModes);
  113. native.KeyFrames = keyFrames;
  114. }
  115. private void UpdateTangents(KeyFrame[] keyFrames, TangentMode[] tangentModes)
  116. {
  117. if (keyFrames.Length == 0)
  118. return;
  119. if (keyFrames.Length == 1)
  120. {
  121. keyFrames[0].inTangent = 0.0f;
  122. keyFrames[0].outTangent = 0.0f;
  123. return;
  124. }
  125. // First keyframe
  126. {
  127. KeyFrame keyThis = keyFrames[0];
  128. KeyFrame keyNext = keyFrames[1];
  129. keyThis.inTangent = 0.0f;
  130. TangentMode tangentMode = tangentModes[0];
  131. if (tangentMode == TangentMode.Auto || tangentMode == TangentMode.OutAuto || tangentMode == TangentMode.OutLinear)
  132. {
  133. float diff = keyNext.time - keyThis.time;
  134. keyThis.outTangent = (keyNext.value - keyThis.value) / diff;
  135. }
  136. else if (tangentMode == TangentMode.OutStep)
  137. {
  138. keyThis.outTangent = float.PositiveInfinity;
  139. }
  140. keyFrames[0] = keyThis;
  141. }
  142. // Inner keyframes
  143. for(int i = 1; i < keyFrames.Length - 1; i++)
  144. {
  145. KeyFrame keyPrev = keyFrames[i - 1];
  146. KeyFrame keyThis = keyFrames[i];
  147. KeyFrame keyNext = keyFrames[i + 1];
  148. keyThis.inTangent = 0.0f;
  149. TangentMode tangentMode = tangentModes[i];
  150. if (tangentMode == TangentMode.Auto) // Both automatic
  151. {
  152. float diff = keyNext.time - keyPrev.time;
  153. keyThis.outTangent = (keyNext.value - keyPrev.value) / diff;
  154. keyThis.inTangent = keyThis.outTangent;
  155. }
  156. else if (tangentMode == TangentMode.Free) // Both free
  157. {
  158. keyThis.inTangent = keyThis.outTangent;
  159. }
  160. else // Different per-tangent modes
  161. {
  162. // In tangent
  163. if (tangentMode.HasFlag(TangentMode.InAuto))
  164. {
  165. float diff = keyNext.time - keyPrev.time;
  166. keyThis.inTangent = (keyNext.value - keyPrev.value) / diff;
  167. }
  168. else if (tangentMode.HasFlag(TangentMode.InLinear))
  169. {
  170. float diff = keyThis.time - keyPrev.time;
  171. keyThis.inTangent = (keyThis.value - keyPrev.value) / diff;
  172. }
  173. else if (tangentMode.HasFlag(TangentMode.InStep))
  174. {
  175. keyThis.inTangent = float.PositiveInfinity;
  176. }
  177. // Out tangent
  178. if (tangentMode.HasFlag(TangentMode.OutAuto))
  179. {
  180. float diff = keyNext.time - keyPrev.time;
  181. keyThis.outTangent = (keyNext.value - keyPrev.value) / diff;
  182. }
  183. else if (tangentMode.HasFlag(TangentMode.OutLinear))
  184. {
  185. float diff = keyNext.time - keyThis.time;
  186. keyThis.outTangent = (keyNext.value - keyThis.value) / diff;
  187. }
  188. else if (tangentMode.HasFlag(TangentMode.OutStep))
  189. {
  190. keyThis.outTangent = float.PositiveInfinity;
  191. }
  192. }
  193. keyFrames[i] = keyThis;
  194. }
  195. // Last keyframe
  196. {
  197. KeyFrame keyThis = keyFrames[keyFrames.Length - 1];
  198. KeyFrame keyPrev = keyFrames[keyFrames.Length - 2];
  199. keyThis.outTangent = 0.0f;
  200. TangentMode tangentMode = tangentModes[tangentModes.Length - 1];
  201. if (tangentMode == TangentMode.Auto || tangentMode == TangentMode.InAuto || tangentMode == TangentMode.InLinear)
  202. {
  203. float diff = keyThis.time - keyPrev.time;
  204. keyThis.inTangent = (keyThis.value - keyPrev.value) / diff;
  205. }
  206. else if (tangentMode == TangentMode.InStep)
  207. {
  208. keyThis.inTangent = float.PositiveInfinity;
  209. }
  210. keyFrames[keyFrames.Length - 1] = keyThis;
  211. }
  212. }
  213. }
  214. }