Spline.cs 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250
  1. using UnityEngine;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. namespace XftWeapon {
  5. public class Spline
  6. {
  7. List<SplineControlPoint> mControlPoints = new List<SplineControlPoint>();
  8. List<SplineControlPoint> mSegments = new List<SplineControlPoint>();
  9. public int Granularity = 20;
  10. public SplineControlPoint this[int index]
  11. {
  12. get
  13. {
  14. if (index > -1 && index < mSegments.Count)
  15. return mSegments[index];
  16. else
  17. return null;
  18. }
  19. }
  20. public List<SplineControlPoint> Segments
  21. {
  22. get
  23. {
  24. return mSegments;
  25. }
  26. }
  27. public List<SplineControlPoint> ControlPoints
  28. {
  29. get
  30. {
  31. return mControlPoints;
  32. }
  33. }
  34. public SplineControlPoint NextControlPoint(SplineControlPoint controlpoint)
  35. {
  36. if (mControlPoints.Count == 0) return null;
  37. int i = controlpoint.ControlPointIndex + 1;
  38. if (i >= mControlPoints.Count)
  39. return null;
  40. else
  41. return mControlPoints[i];
  42. }
  43. public SplineControlPoint PreviousControlPoint(SplineControlPoint controlpoint)
  44. {
  45. if (mControlPoints.Count == 0) return null;
  46. int i = controlpoint.ControlPointIndex - 1;
  47. if (i < 0)
  48. return null;
  49. else
  50. return mControlPoints[i];
  51. }
  52. public Vector3 NextPosition(SplineControlPoint controlpoint)
  53. {
  54. SplineControlPoint seg = NextControlPoint(controlpoint);
  55. if (seg != null)
  56. return seg.Position;
  57. else
  58. return controlpoint.Position;
  59. }
  60. public Vector3 PreviousPosition(SplineControlPoint controlpoint)
  61. {
  62. SplineControlPoint seg = PreviousControlPoint(controlpoint);
  63. if (seg != null)
  64. return seg.Position;
  65. else
  66. return controlpoint.Position;
  67. }
  68. public Vector3 PreviousNormal(SplineControlPoint controlpoint)
  69. {
  70. SplineControlPoint seg = PreviousControlPoint(controlpoint);
  71. if (seg != null)
  72. return seg.Normal;
  73. else
  74. return controlpoint.Normal;
  75. }
  76. public Vector3 NextNormal(SplineControlPoint controlpoint)
  77. {
  78. SplineControlPoint seg = NextControlPoint(controlpoint);
  79. if (seg != null)
  80. return seg.Normal;
  81. else
  82. return controlpoint.Normal;
  83. }
  84. public SplineControlPoint LenToSegment(float t, out float localF)
  85. {
  86. SplineControlPoint seg = null;
  87. t = Mathf.Clamp01(t);
  88. float len = t * mSegments[mSegments.Count - 1].Dist;
  89. int index = 0;
  90. for (index = 0; index < mSegments.Count; index++)
  91. {
  92. if (mSegments[index].Dist >= len)
  93. {
  94. seg = mSegments[index];
  95. break;
  96. }
  97. }
  98. if (index == 0)
  99. {
  100. //skip the first frame.
  101. localF = 0f;
  102. return seg;
  103. }
  104. float PrevLen = 0f;
  105. int prevIdx = seg.SegmentIndex - 1;
  106. SplineControlPoint prevSeg = mSegments[prevIdx];
  107. PrevLen = seg.Dist - prevSeg.Dist;
  108. localF = (len - prevSeg.Dist) / PrevLen;
  109. return prevSeg;
  110. }
  111. public static Vector3 CatmulRom(Vector3 T0, Vector3 P0, Vector3 P1, Vector3 T1, float f)
  112. {
  113. double DT1 = -0.5;
  114. double DT2 = 1.5;
  115. double DT3 = -1.5;
  116. double DT4 = 0.5;
  117. double DE2 = -2.5;
  118. double DE3 = 2;
  119. double DE4 = -0.5;
  120. double DV1 = -0.5;
  121. double DV3 = 0.5;
  122. double FAX = DT1 * T0.x + DT2 * P0.x + DT3 * P1.x + DT4 * T1.x;
  123. double FBX = T0.x + DE2 * P0.x + DE3 * P1.x + DE4 * T1.x;
  124. double FCX = DV1 * T0.x + DV3 * P1.x;
  125. double FDX = P0.x;
  126. double FAY = DT1 * T0.y + DT2 * P0.y + DT3 * P1.y + DT4 * T1.y;
  127. double FBY = T0.y + DE2 * P0.y + DE3 * P1.y + DE4 * T1.y;
  128. double FCY = DV1 * T0.y + DV3 * P1.y;
  129. double FDY = P0.y;
  130. double FAZ = DT1 * T0.z + DT2 * P0.z + DT3 * P1.z + DT4 * T1.z;
  131. double FBZ = T0.z + DE2 * P0.z + DE3 * P1.z + DE4 * T1.z;
  132. double FCZ = DV1 * T0.z + DV3 * P1.z;
  133. double FDZ = P0.z;
  134. float FX = (float)(((FAX * f + FBX) * f + FCX) * f + FDX);
  135. float FY = (float)(((FAY * f + FBY) * f + FCY) * f + FDY);
  136. float FZ = (float)(((FAZ * f + FBZ) * f + FCZ) * f + FDZ);
  137. return new Vector3(FX, FY, FZ);
  138. }
  139. public Vector3 InterpolateByLen(float tl)
  140. {
  141. float localF;
  142. SplineControlPoint seg = LenToSegment(tl, out localF);
  143. return seg.Interpolate(localF);
  144. }
  145. public Vector3 InterpolateNormalByLen(float tl)
  146. {
  147. float localF;
  148. SplineControlPoint seg = LenToSegment(tl, out localF);
  149. return seg.InterpolateNormal(localF);
  150. }
  151. public SplineControlPoint AddControlPoint(Vector3 pos, Vector3 up)
  152. {
  153. SplineControlPoint cp = new SplineControlPoint();
  154. cp.Init(this);
  155. cp.Position = pos;
  156. cp.Normal = up;
  157. mControlPoints.Add(cp);
  158. cp.ControlPointIndex = mControlPoints.Count - 1;
  159. return cp;
  160. }
  161. public void Clear()
  162. {
  163. mControlPoints.Clear();
  164. }
  165. void RefreshDistance()
  166. {
  167. if (mSegments.Count < 1)
  168. return;
  169. mSegments[0].Dist = 0f;
  170. for (int i = 1; i < mSegments.Count; i++)
  171. {
  172. float prevLen = (mSegments[i].Position - mSegments[i - 1].Position).magnitude;
  173. mSegments[i].Dist = mSegments[i - 1].Dist + prevLen;
  174. }
  175. }
  176. public void RefreshSpline()
  177. {
  178. mSegments.Clear();
  179. for (int i = 0; i < mControlPoints.Count; i++)
  180. {
  181. if (mControlPoints[i].IsValid)
  182. {
  183. mSegments.Add(mControlPoints[i]);
  184. mControlPoints[i].SegmentIndex = mSegments.Count - 1;
  185. }
  186. }
  187. RefreshDistance();
  188. }
  189. }
  190. }