SplineTrailRenderer.cs 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385
  1. using System;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. public class SplineTrailRenderer : MonoBehaviour
  5. {
  6. public void Clear()
  7. {
  8. this.Init();
  9. }
  10. private void Awake()
  11. {
  12. this.spline = new CatmullRomSpline();
  13. }
  14. private void Start()
  15. {
  16. this.Init();
  17. }
  18. public void Launch(Transform target)
  19. {
  20. this.spline.Launch(target);
  21. this.targetTrans = target;
  22. }
  23. private void Update()
  24. {
  25. if (this.emit)
  26. {
  27. List<Knot> knots = this.spline.knots;
  28. Vector3 position = base.transform.position;
  29. knots[knots.Count - 1].position = position;
  30. knots[knots.Count - 2].position = position;
  31. if (Vector3.Distance(knots[knots.Count - 3].position, position) > this.emissionDistance && Vector3.Distance(knots[knots.Count - 4].position, position) > this.emissionDistance)
  32. {
  33. knots.Add(new Knot(position));
  34. float num = Mathf.Max(this.spline.Length() - 0.1f, 0f);
  35. if (num > this.maxLength && knots.Count > 0)
  36. {
  37. knots.RemoveAt(0);
  38. }
  39. }
  40. }
  41. this.RenderMesh();
  42. this.spline.SetLastPos(this.targetTrans.position);
  43. }
  44. private float GetNoise(float p1, float p2)
  45. {
  46. return 1f - Mathf.PerlinNoise(p1, p2) * 2f;
  47. }
  48. private void RenderMesh()
  49. {
  50. if (this.advancedParameters.nbSegmentToParametrize == 0)
  51. {
  52. this.spline.Parametrize();
  53. }
  54. else
  55. {
  56. this.spline.Parametrize(this.spline.NbSegments - this.advancedParameters.nbSegmentToParametrize, this.spline.NbSegments);
  57. }
  58. float num = Mathf.Max(this.spline.Length() - 0.1f, 0f);
  59. if (this.noiseAmp > 0f)
  60. {
  61. }
  62. int num2 = (int)(1f / this.width * num) + 1 - this.quadOffset;
  63. if (this.allocatedNbQuad < num2)
  64. {
  65. this.Reallocate(num2);
  66. num = Mathf.Max(this.spline.Length() - 0.1f, 0f);
  67. num2 = (int)(1f / this.width * num) + 1 - this.quadOffset;
  68. }
  69. if (this.noiseAmp > 0f)
  70. {
  71. }
  72. int num3 = this.lastStartingQuad;
  73. float num4 = (float)num3 * this.width + (float)this.quadOffset * this.width;
  74. this.maxInstanciedTriCount = Math.Max(this.maxInstanciedTriCount, (num2 - 1) * 6);
  75. CatmullRomSpline.Marker marker = new CatmullRomSpline.Marker();
  76. this.spline.PlaceMarker(marker, num4, null);
  77. Vector3 a = this.spline.GetPosition(marker);
  78. Vector3 vector = this.spline.GetTangent(marker);
  79. Vector3 vector2 = CatmullRomSpline.ComputeBinormal(vector, this.normal);
  80. int num5 = (this.meshDisposition != SplineTrailRenderer.MeshDisposition.Fragmented) ? (num2 - 1) : (num2 - 1);
  81. for (int i = num3; i < num5; i++)
  82. {
  83. float num6 = num4 + this.width;
  84. int num7 = i * 4;
  85. if (num7 > this.vertices.Length - 3)
  86. {
  87. break;
  88. }
  89. int num8 = i * 6;
  90. this.spline.MoveMarker(marker, num6);
  91. Vector3 position = this.spline.GetPosition(marker);
  92. Vector3 tangent = this.spline.GetTangent(marker);
  93. Vector3 vector3 = CatmullRomSpline.ComputeBinormal(tangent, this.normal);
  94. float num9 = this.FadeMultiplier(num4, num);
  95. float num10 = this.FadeMultiplier(num6, num);
  96. float num11 = num9 * this.height;
  97. float num12 = num10 * this.height;
  98. if (this.fadeType == SplineTrailRenderer.FadeType.Alpha || this.fadeType == SplineTrailRenderer.FadeType.None)
  99. {
  100. num11 = ((num9 <= 0f) ? 0f : this.height);
  101. num12 = ((num10 <= 0f) ? 0f : this.height);
  102. }
  103. bool flag = true;
  104. if (this.noiseAmp <= 0f || num11 == 0f || num12 == 0f || i < num3 + 1)
  105. {
  106. flag = false;
  107. }
  108. if (this.meshDisposition == SplineTrailRenderer.MeshDisposition.Continuous)
  109. {
  110. if (flag)
  111. {
  112. float time = Time.time;
  113. Vector3 vector4 = new Vector3(this.GetNoise((float)num7 * this.noiseFrequence, time) * this.noiseAmp, this.GetNoise((float)num7 * this.noiseFrequence + 0.01f, 0f) * this.noiseAmp, 0f);
  114. this.vertices[num7] = base.transform.InverseTransformPoint(a - this.origin + vector2 * (num11 * 0.5f) + Vector3.Project(vector4, vector2));
  115. vector4 = new Vector3(this.GetNoise((float)num7 * this.noiseFrequence + 0.02f, time) * this.noiseAmp, this.GetNoise((float)num7 * this.noiseFrequence + 0.03f, 0f) * this.noiseAmp, 0f);
  116. this.vertices[num7 + 1] = base.transform.InverseTransformPoint(a - this.origin + -vector2 * (num11 * 0.5f) + Vector3.Project(vector4, vector2));
  117. vector4 = new Vector3(this.GetNoise((float)num7 * this.noiseFrequence + 0.04f, time) * this.noiseAmp, this.GetNoise((float)num7 * this.noiseFrequence + 0.05f, 0f) * this.noiseAmp, 0f);
  118. this.vertices[num7 + 2] = base.transform.InverseTransformPoint(position - this.origin + vector3 * (num12 * 0.5f) + Vector3.Project(vector4, vector3));
  119. vector4 = new Vector3(this.GetNoise((float)num7 * this.noiseFrequence + 0.06f, time) * this.noiseAmp, this.GetNoise((float)num7 * this.noiseFrequence + 0.07f, 0f) * this.noiseAmp, 0f);
  120. this.vertices[num7 + 3] = base.transform.InverseTransformPoint(position - this.origin + -vector3 * (num12 * 0.5f) + Vector3.Project(vector4, vector3));
  121. }
  122. else
  123. {
  124. this.vertices[num7] = base.transform.InverseTransformPoint(a - this.origin + vector2 * (num11 * 0.5f));
  125. this.vertices[num7 + 1] = base.transform.InverseTransformPoint(a - this.origin + -vector2 * (num11 * 0.5f));
  126. this.vertices[num7 + 2] = base.transform.InverseTransformPoint(position - this.origin + vector3 * (num12 * 0.5f));
  127. this.vertices[num7 + 3] = base.transform.InverseTransformPoint(position - this.origin + -vector3 * (num12 * 0.5f));
  128. }
  129. this.uv[num7] = new Vector2(num4 / this.height, 1f);
  130. this.uv[num7 + 1] = new Vector2(num4 / this.height, 0f);
  131. this.uv[num7 + 2] = new Vector2(num6 / this.height, 1f);
  132. this.uv[num7 + 3] = new Vector2(num6 / this.height, 0f);
  133. }
  134. else
  135. {
  136. Vector3 a2 = a + vector * this.width * -0.5f - this.origin;
  137. this.vertices[num7] = base.transform.InverseTransformPoint(a2 + vector2 * (num11 * 0.5f));
  138. this.vertices[num7 + 1] = base.transform.InverseTransformPoint(a2 + -vector2 * (num11 * 0.5f));
  139. this.vertices[num7 + 2] = base.transform.InverseTransformPoint(a2 + vector * this.width + vector2 * (num11 * 0.5f));
  140. this.vertices[num7 + 3] = base.transform.InverseTransformPoint(a2 + vector * this.width + -vector2 * (num11 * 0.5f));
  141. this.uv[num7] = new Vector2(0f, 1f);
  142. this.uv[num7 + 1] = new Vector2(0f, 0f);
  143. this.uv[num7 + 2] = new Vector2(1f, 1f);
  144. this.uv[num7 + 3] = new Vector2(1f, 0f);
  145. }
  146. this.triangles[num8] = num7;
  147. this.triangles[num8 + 1] = num7 + 1;
  148. this.triangles[num8 + 2] = num7 + 2;
  149. this.triangles[num8 + 3] = num7 + 2;
  150. this.triangles[num8 + 4] = num7 + 1;
  151. this.triangles[num8 + 5] = num7 + 3;
  152. this.colors[num7] = this.vertexColor;
  153. this.colors[num7 + 1] = this.vertexColor;
  154. this.colors[num7 + 2] = this.vertexColor;
  155. this.colors[num7 + 3] = this.vertexColor;
  156. if (this.fadeType == SplineTrailRenderer.FadeType.Alpha || this.fadeType == SplineTrailRenderer.FadeType.Both)
  157. {
  158. if (i < num3 + 10)
  159. {
  160. this.colors[num7].a = 0f;
  161. this.colors[num7 + 1].a = 0f;
  162. this.colors[num7 + 2].a = 0f;
  163. this.colors[num7 + 3].a = 0f;
  164. }
  165. else
  166. {
  167. Color[] array = this.colors;
  168. int num13 = num7;
  169. array[num13].a = array[num13].a * num9;
  170. Color[] array2 = this.colors;
  171. int num14 = num7 + 1;
  172. array2[num14].a = array2[num14].a * num9;
  173. Color[] array3 = this.colors;
  174. int num15 = num7 + 2;
  175. array3[num15].a = array3[num15].a * num10;
  176. Color[] array4 = this.colors;
  177. int num16 = num7 + 3;
  178. array4[num16].a = array4[num16].a * num10;
  179. }
  180. }
  181. a = position;
  182. vector = tangent;
  183. vector2 = vector3;
  184. num4 = num6;
  185. }
  186. for (int j = (num2 - 1) * 6; j < this.maxInstanciedTriCount; j++)
  187. {
  188. if (j < this.triangles.Length)
  189. {
  190. this.triangles[j] = 0;
  191. }
  192. }
  193. this.lastStartingQuad = ((this.advancedParameters.lengthToRedraw != 0f) ? Math.Max(0, num2 - ((int)(this.advancedParameters.lengthToRedraw / this.width) + 5)) : Math.Max(0, num2 - ((int)(this.maxLength / this.width) + 5)));
  194. this.mesh.Clear();
  195. this.mesh.vertices = this.vertices;
  196. this.mesh.uv = this.uv;
  197. this.mesh.triangles = this.triangles;
  198. this.mesh.colors = this.colors;
  199. this.mesh.normals = this.normals;
  200. }
  201. private void OnDrawGizmos()
  202. {
  203. if (this.advancedParameters == null || this.spline == null || this.debugDrawSpline)
  204. {
  205. }
  206. }
  207. private void Init()
  208. {
  209. this.origin = Vector3.zero;
  210. this.mesh = base.GetComponent<MeshFilter>().mesh;
  211. this.mesh.MarkDynamic();
  212. this.allocatedNbQuad = this.advancedParameters.baseNbQuad;
  213. this.maxInstanciedTriCount = 0;
  214. this.lastStartingQuad = 0;
  215. this.quadOffset = 0;
  216. this.vertices = new Vector3[this.advancedParameters.baseNbQuad * 4];
  217. this.triangles = new int[this.advancedParameters.baseNbQuad * 6];
  218. this.uv = new Vector2[this.advancedParameters.baseNbQuad * 4];
  219. this.colors = new Color[this.advancedParameters.baseNbQuad * 4];
  220. this.normals = new Vector3[this.advancedParameters.baseNbQuad * 4];
  221. if (this.normal == Vector3.zero)
  222. {
  223. this.normal = (base.transform.position - Camera.main.transform.position).normalized;
  224. }
  225. for (int i = 0; i < this.normals.Length; i++)
  226. {
  227. this.normals[i] = this.normal;
  228. }
  229. this.spline.Clear();
  230. List<Knot> knots = this.spline.knots;
  231. Vector3 position = base.transform.position;
  232. knots.Add(new Knot(position));
  233. knots.Add(new Knot(position));
  234. knots.Add(new Knot(position));
  235. knots.Add(new Knot(position));
  236. knots.Add(new Knot(position));
  237. }
  238. private void Reallocate(int nbQuad)
  239. {
  240. if (this.advancedParameters.shiftMeshData && this.lastStartingQuad > 0)
  241. {
  242. int num = 0;
  243. for (int i = this.lastStartingQuad; i < nbQuad; i++)
  244. {
  245. this.vertices[num] = this.vertices[i];
  246. this.triangles[num] = this.triangles[i];
  247. this.uv[num] = this.uv[i];
  248. this.colors[num] = this.colors[i];
  249. this.normals[num] = this.normals[i];
  250. num++;
  251. }
  252. this.quadOffset += this.lastStartingQuad;
  253. this.lastStartingQuad = 0;
  254. }
  255. if (this.allocatedNbQuad < nbQuad - this.quadOffset)
  256. {
  257. if ((this.allocatedNbQuad + this.advancedParameters.nbQuadIncrement) * 4 > 65000)
  258. {
  259. this.Clear();
  260. return;
  261. }
  262. this.allocatedNbQuad += this.advancedParameters.nbQuadIncrement;
  263. Vector3[] array = new Vector3[this.allocatedNbQuad * 4];
  264. int[] array2 = new int[this.allocatedNbQuad * 6];
  265. Vector2[] array3 = new Vector2[this.allocatedNbQuad * 4];
  266. Color[] array4 = new Color[this.allocatedNbQuad * 4];
  267. Vector3[] array5 = new Vector3[this.allocatedNbQuad * 4];
  268. this.vertices.CopyTo(array, 0);
  269. this.triangles.CopyTo(array2, 0);
  270. this.uv.CopyTo(array3, 0);
  271. this.colors.CopyTo(array4, 0);
  272. this.normals.CopyTo(array5, 0);
  273. this.vertices = array;
  274. this.triangles = array2;
  275. this.uv = array3;
  276. this.colors = array4;
  277. this.normals = array5;
  278. }
  279. }
  280. private float FadeMultiplier(float distance, float length)
  281. {
  282. float a = Mathf.Clamp01((distance - Mathf.Max(length - this.maxLength, 0f)) / this.fadeLengthBegin);
  283. float b = Mathf.Clamp01((length - distance) / this.fadeLengthEnd);
  284. return Mathf.Min(a, b);
  285. }
  286. public bool emit = true;
  287. public float emissionDistance = 1f;
  288. public float height = 1f;
  289. public float width = 0.2f;
  290. public Color vertexColor = Color.white;
  291. public Vector3 normal = new Vector3(0f, 0f, 1f);
  292. public SplineTrailRenderer.MeshDisposition meshDisposition;
  293. public SplineTrailRenderer.FadeType fadeType;
  294. public float fadeLengthBegin = 5f;
  295. public float fadeLengthEnd = 5f;
  296. public float maxLength = 50f;
  297. public float noiseAmp;
  298. public float noiseFrequence = 0.01f;
  299. public bool debugDrawSpline;
  300. private SplineTrailRenderer.AdvancedParameters advancedParameters = new SplineTrailRenderer.AdvancedParameters();
  301. [HideInInspector]
  302. public CatmullRomSpline spline;
  303. private const int NbVertexPerQuad = 4;
  304. private const int NbTriIndexPerQuad = 6;
  305. private Vector3[] vertices;
  306. private int[] triangles;
  307. private Vector2[] uv;
  308. private Color[] colors;
  309. private Vector3[] normals;
  310. private Vector3 origin;
  311. private int maxInstanciedTriCount;
  312. private Mesh mesh;
  313. private int allocatedNbQuad;
  314. private int lastStartingQuad;
  315. private int quadOffset;
  316. private Transform targetTrans;
  317. public enum MeshDisposition
  318. {
  319. Continuous,
  320. Fragmented
  321. }
  322. public enum FadeType
  323. {
  324. None,
  325. MeshShrinking,
  326. Alpha,
  327. Both
  328. }
  329. public class AdvancedParameters
  330. {
  331. public int baseNbQuad = 500;
  332. public int nbQuadIncrement = 200;
  333. public int nbSegmentToParametrize = 3;
  334. public float lengthToRedraw;
  335. public bool shiftMeshData;
  336. }
  337. }