FramesArray.cs 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. using System.IO;
  5. namespace VertexAnimationTools_30 {
  6. public class FramesArray {
  7. List<Vector3[]> frames = new List<Vector3[]>();
  8. public bool IsLoop;
  9. public InterpolateModeEnum Interpolation;
  10. public float step {
  11. get {
  12. return 1f / ((float)Count - (IsLoop ? 0 : 1));
  13. }
  14. }
  15. float b1 = 0.166667f;
  16. float b2 = 0.666667f;
  17. float b3 = 0.166667f;
  18. public FramesArray( bool isLoop, InterpolateModeEnum interpolationMode) {
  19. IsLoop = isLoop;
  20. Interpolation = interpolationMode;
  21. }
  22. public FramesArray( int framesCount, int verticesCount, bool isLoop, InterpolateModeEnum interpolationMode) {
  23. for (int i = 0; i<framesCount; i++) {
  24. frames.Add(new Vector3[verticesCount]);
  25. }
  26. IsLoop = isLoop;
  27. Interpolation = interpolationMode;
  28. }
  29. public void AddFrame(Vector3[] vertices) {
  30. frames.Add(vertices);
  31. }
  32. public int Count {
  33. get {
  34. return frames.Count;
  35. }
  36. }
  37. public FramesArray(FramesArray source) {
  38. frames = new List<Vector3[]>(source.frames);
  39. IsLoop = source.IsLoop;
  40. Interpolation = source.Interpolation;
  41. }
  42. public Vector3 this[int frame, int vertex] {
  43. get {
  44. if (IsLoop) {
  45. frame = (int)Mathf.Repeat(frame, Count);
  46. return frames[frame][vertex];
  47. } else {
  48. if (frame < 0) {
  49. Vector3 f0 = frames[0][vertex];
  50. Vector3 f1 = frames[1][vertex];
  51. Vector3 delta = f1 - f0;
  52. return f0 - delta;
  53. }
  54. if (frame >= Count) {
  55. Vector3 l0 = frames[Count - 1][vertex];
  56. Vector3 l1 = frames[Count - 2][vertex];
  57. Vector3 delta = l0 - l1;
  58. return l0 + delta;
  59. }
  60. return frames[frame][vertex];
  61. }
  62. }
  63. set {
  64. if (IsLoop) {
  65. frame = frame % Count;
  66. } else {
  67. frame = Mathf.Clamp(frame, 0, Count);
  68. }
  69. frames[frame][vertex] = value;
  70. }
  71. }
  72. public Vector3 this[float persentage, int vertex] {
  73. get {
  74. int a = Mathf.FloorToInt(persentage / step);
  75. int b = a + 1;
  76. float lv = (persentage - (a * step)) / step;
  77. if (Interpolation == InterpolateModeEnum.Linear) {
  78. return Vector3.Lerp(this[a, vertex], this[b, vertex], lv);
  79. } else {
  80. return HermitePoint(this[a - 1, vertex], this[a, vertex], this[b, vertex], this[b + 1, vertex], lv);
  81. }
  82. }
  83. }
  84. public Vector3[] this[int vertex] {
  85. get {
  86. Vector3[] result = new Vector3[Count];
  87. for (int i = 0; i < result.Length; i++) {
  88. result[i] = this[i, vertex];
  89. }
  90. return result;
  91. }
  92. set {
  93. for (int f = 0; f < value.Length; f++) {
  94. this[f, vertex] = value[f];
  95. }
  96. }
  97. }
  98. public int VerticesCount {
  99. get {
  100. return frames[0].Length;
  101. }
  102. }
  103. Vector3 HermitePoint(Vector3 p0, Vector3 p1, Vector3 p2, Vector3 p3, float s) {
  104. return new Vector3(hermiteInterplation(p0.x, p1.x, p2.x, p3.x, s), hermiteInterplation(p0.y, p1.y, p2.y, p3.y, s), hermiteInterplation(p0.z, p1.z, p2.z, p3.z, s));
  105. }
  106. float hermiteInterplation(float y0, float y1, float y2, float y3, float s) {
  107. float mu2 = s * s;
  108. float mu3 = mu2 * s;
  109. float m0, m1;
  110. float a0, a1, a2, a3;
  111. m0 = (y1 - y0) / 2;
  112. m0 += (y2 - y1) / 2;
  113. m1 = (y2 - y1) / 2;
  114. m1 += (y3 - y2) / 2;
  115. a0 = 2 * mu3 - 3 * mu2 + 1;
  116. a1 = mu3 - 2 * mu2 + s;
  117. a2 = mu3 - mu2;
  118. a3 = -2 * mu3 + 3 * mu2;
  119. return (a0 * y1 + a1 * m0 + a2 * m1 + a3 * y2);
  120. }
  121. public IEnumerable<TaskInfo> SmoothIE(int iterations, float smoothMin, float smoothMax, float easeOffset, float easeLength) {
  122. FramesArray smoothed = new FramesArray(this);
  123. FramesArray temp = new FramesArray(this);
  124. for (int i = 0; i < iterations; i++) {
  125. for (int v = 0; v < smoothed.VerticesCount; v++) {
  126. for (int f = 0; f < smoothed.Count; f++) {
  127. smoothed[f, v] = BPoint(temp[f - 1, v], temp[f, v], temp[f + 1, v], temp[f + 2, v]);
  128. }
  129. }
  130. temp = new FramesArray(smoothed);
  131. yield return new TaskInfo("Smoothing", i / (float)iterations);
  132. }
  133. for (int v = 0; v < smoothed.VerticesCount; v++) {
  134. for (int f = 0; f < Count; f++) {
  135. float pers = (float)f / (float)(Count - 1);
  136. float lv = Extension.SmoothLoopCurve(pers, smoothMin, smoothMax, easeOffset, easeLength);
  137. this[f, v] = Vector3.LerpUnclamped(this[f, v], smoothed[f, v], lv);
  138. }
  139. }
  140. yield return new TaskInfo("Smoothing", 1f);
  141. }
  142. Vector3 BPoint(Vector3 P1, Vector3 P2, Vector3 P3, Vector3 P4) {
  143. return new Vector3(b1 * P1.x + b2 * P2.x + b3 * P3.x, b1 * P1.y + b2 * P2.y + b3 * P3.y, b1 * P1.z + b2 * P2.z + b3 * P3.z);
  144. }
  145. }
  146. }