EdAnimationCurve.cs 8.9 KB

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