MegaFlowCreateFromSplines.cs 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391
  1. using UnityEngine;
  2. using System.Collections.Generic;
  3. public enum MegaFlowModType
  4. {
  5. VelChange,
  6. }
  7. [System.Serializable]
  8. public class MegaFlowModifier
  9. {
  10. public Collider obj;
  11. public MegaFlowModType type = MegaFlowModType.VelChange;
  12. public float amount = 0.0f;
  13. public bool include = true;
  14. public bool show = true;
  15. }
  16. [System.Serializable]
  17. public class MegaFlowSpline
  18. {
  19. public MegaShape shape;
  20. public int curve;
  21. public float velocity = 1.0f;
  22. public float weight = 1.0f;
  23. public float falloffdist = 1.0f;
  24. public AnimationCurve falloffcrv = new AnimationCurve(new Keyframe(0, 1), new Keyframe(1, 0));
  25. public AnimationCurve velcrv = new AnimationCurve(new Keyframe(0, 1), new Keyframe(1, 1));
  26. public AnimationCurve distcrv = new AnimationCurve(new Keyframe(0, 1), new Keyframe(1, 1));
  27. public MegaFlowMode mode = MegaFlowMode.Attract;
  28. public bool include = true;
  29. public int visrings = 20;
  30. public float ringalpha = 0.75f;
  31. public bool show = true;
  32. }
  33. public struct MegaFlowContrib
  34. {
  35. public float dist;
  36. public MegaFlowSpline src;
  37. public Vector3 vel;
  38. public Vector3 delta;
  39. public float alpha;
  40. public float fdist;
  41. }
  42. public enum MegaFlowMode
  43. {
  44. Attract,
  45. Repulse,
  46. Flow,
  47. }
  48. [AddComponentMenu("MegaFlow/Create From Splines")]
  49. [ExecuteInEditMode]
  50. public class MegaFlowCreateFromSplines : MonoBehaviour
  51. {
  52. public Vector3 size = Vector3.one;
  53. public bool square = true;
  54. public int gridx = 32;
  55. public int gridy = 32;
  56. public int gridz = 32;
  57. public List<MegaFlowSpline> splines = new List<MegaFlowSpline>();
  58. public MegaFlow flow;
  59. public int frame = 0;
  60. public Vector3 cellsize = Vector3.one;
  61. Vector3[] cells;
  62. public float velocity = 1.0f;
  63. public float vellen = 1.0f;
  64. public MegaFlowMode emtyspacemode = MegaFlowMode.Attract;
  65. public bool shownotsel = false;
  66. public Gradient velcols;
  67. public float minvel = 0.0f;
  68. public float maxvel = 10.0f;
  69. public Vector3 startval = Vector3.zero;
  70. public List<MegaFlowModifier> modifiers = new List<MegaFlowModifier>();
  71. // Visualization
  72. public MegaFlow preview;
  73. public Texture3D texture;
  74. public float texturescale = 1.0f;
  75. public bool showsplines = false;
  76. public bool showmods = false;
  77. public Vector2 splinepos = Vector2.zero;
  78. public Vector2 modpos = Vector2.zero;
  79. [ContextMenu("Help")]
  80. public void Help()
  81. {
  82. Application.OpenURL("http://www.west-racing.com/mf/?page_id=5904");
  83. }
  84. static Color[] Cols = {
  85. new Color(0.0f, 0.0f, 1.0f, 1.0f),
  86. new Color(0.0f, 1.0f, 1.0f),
  87. new Color(0.0f, 1.0f, 0.0f),
  88. new Color(1.0f, 1.0f, 0.0f),
  89. new Color(1.0f, 0.0f, 0.0f),
  90. };
  91. void Awake()
  92. {
  93. if ( velcols == null )
  94. {
  95. velcols = new Gradient();
  96. GradientColorKey[] keys = new GradientColorKey[5];
  97. for ( int i = 0; i < 5; i++ )
  98. {
  99. keys[i].color = Cols[i];
  100. keys[i].time = (float)i / 4.0f;
  101. }
  102. GradientAlphaKey[] akeys = new GradientAlphaKey[2];
  103. akeys[0].alpha = 1.0f;
  104. akeys[0].time = 0.0f;
  105. akeys[1].alpha = 1.0f;
  106. akeys[1].time = 0.0f;
  107. velcols.SetKeys(keys, akeys);
  108. }
  109. }
  110. public void CreateFlow()
  111. {
  112. int gx = gridx;
  113. int gy = gridy;
  114. int gz = gridz;
  115. if ( square )
  116. {
  117. // find major axis
  118. int axis = 0;
  119. if ( Mathf.Abs(size.x) > Mathf.Abs(size.y) )
  120. {
  121. if ( Mathf.Abs(size.x) > Mathf.Abs(size.z) )
  122. axis = 0;
  123. else
  124. axis = 2;
  125. }
  126. else
  127. {
  128. if ( Mathf.Abs(size.y) > Mathf.Abs(size.z) )
  129. axis = 1;
  130. else
  131. axis = 2;
  132. }
  133. float csize = size[axis] / gridx;
  134. cellsize = new Vector3(csize, csize, csize);
  135. }
  136. else
  137. {
  138. cellsize.x = size.x / gridx;
  139. cellsize.y = size.y / gridy;
  140. cellsize.z = size.z / gridz;
  141. }
  142. gx = (int)(size.x / cellsize.x);
  143. gy = (int)(size.y / cellsize.y);
  144. gz = (int)(size.z / cellsize.z);
  145. cells = new Vector3[gx * gy * gz];
  146. for ( int i = 0; i < cells.Length; i++ )
  147. cells[i] = startval;
  148. Vector3 pos = Vector3.zero;
  149. Vector3 half = cellsize * 0.5f;
  150. Vector3 tan = Vector3.zero;
  151. int kn = 0;
  152. float alpha = 0.0f;
  153. List<MegaFlowContrib> contrib = new List<MegaFlowContrib>();
  154. for ( int z = 0; z < gz; z++ )
  155. {
  156. pos.z = (z * cellsize.z) + half.z;
  157. for ( int y = 0; y < gy; y++ )
  158. {
  159. pos.y = (y * cellsize.y) + half.y;
  160. for ( int x = 0; x < gx; x++ )
  161. {
  162. pos.x = (x * cellsize.x) + half.x;
  163. contrib.Clear();
  164. float nearest = float.MaxValue;
  165. Vector3 neardelta = Vector3.zero;
  166. for ( int i = 0; i < splines.Count; i++ )
  167. {
  168. MegaFlowSpline fs = splines[i];
  169. if ( fs.include )
  170. {
  171. Vector3 np = fs.shape.FindNearestPointWorldShape(pos, 5, ref kn, ref tan, ref alpha);
  172. Vector3 delta = np - pos;
  173. float dist = delta.magnitude;
  174. if ( dist < nearest )
  175. {
  176. nearest = dist;
  177. neardelta = delta;
  178. }
  179. if ( dist < fs.falloffdist )
  180. {
  181. MegaFlowContrib con = new MegaFlowContrib();
  182. con.src = fs;
  183. con.dist = dist;
  184. con.vel = tan * fs.velocity;
  185. con.delta = delta.normalized;
  186. contrib.Add(con);
  187. }
  188. }
  189. }
  190. if ( contrib.Count > 0 )
  191. {
  192. float tweight = 0.0f;
  193. for ( int c = 0; c < contrib.Count; c++ )
  194. tweight += contrib[c].src.weight;
  195. Vector3 vel = cells[(x * gz * gy) + (z * gy) + y]; //Vector3.zero;
  196. for ( int c = 0; c < contrib.Count; c++ )
  197. {
  198. float a = contrib[c].dist / contrib[c].src.falloffdist;
  199. float lerp = contrib[c].src.falloffcrv.Evaluate(a);
  200. switch ( contrib[c].src.mode )
  201. {
  202. case MegaFlowMode.Attract:
  203. vel += Vector3.Lerp(contrib[c].delta, contrib[c].vel, lerp) * velocity * (contrib[c].src.weight / tweight);
  204. break;
  205. case MegaFlowMode.Repulse:
  206. vel += Vector3.Lerp(-contrib[c].delta, contrib[c].vel, lerp) * velocity * (contrib[c].src.weight / tweight);
  207. break;
  208. case MegaFlowMode.Flow:
  209. vel += Vector3.Lerp(Vector3.zero, contrib[c].vel, lerp) * velocity * (contrib[c].src.weight / tweight);
  210. break;
  211. }
  212. }
  213. cells[(x * gz * gy) + (z * gy) + y] = vel;
  214. }
  215. else
  216. {
  217. cells[(x * gz * gy) + (z * gy) + y] = neardelta.normalized * velocity;
  218. }
  219. }
  220. }
  221. }
  222. if ( flow )
  223. {
  224. MegaFlowFrame newf = ScriptableObject.CreateInstance<MegaFlowFrame>();
  225. newf.gridDim2[0] = gx;
  226. newf.gridDim2[1] = gy;
  227. newf.gridDim2[2] = gz;
  228. newf.size = size;
  229. newf.gsize = newf.size;
  230. // griddim should have a name change
  231. newf.spacing.x = newf.size.x / newf.gridDim2[0];
  232. newf.spacing.y = newf.size.y / newf.gridDim2[1];
  233. newf.spacing.z = newf.size.z / newf.gridDim2[2];
  234. newf.oos.x = 1.0f / newf.spacing.x;
  235. newf.oos.y = 1.0f / newf.spacing.y;
  236. newf.oos.z = 1.0f / newf.spacing.z;
  237. newf.vel.AddRange(cells);
  238. flow.AddFrame(newf);
  239. }
  240. }
  241. public void DrawEdge(Vector3 p1, Vector3 p2, int steps)
  242. {
  243. Vector3 last = p1;
  244. Vector3 pos = Vector3.zero;
  245. for ( int i = 1; i <= steps; i++ )
  246. {
  247. pos = p1 + ((p2 - p1) * ((float)i / (float)steps));
  248. if ( (i & 1) == 0 )
  249. Gizmos.color = Color.white;
  250. else
  251. Gizmos.color = Color.black;
  252. Gizmos.DrawLine(last, pos);
  253. last = pos;
  254. }
  255. Gizmos.color = Color.white;
  256. }
  257. public void DrawGizmo()
  258. {
  259. Matrix4x4 offtm = Matrix4x4.TRS(-size * 0.5f, Quaternion.identity, Vector3.one);
  260. Gizmos.matrix = transform.localToWorldMatrix * offtm;
  261. int gx = gridx;
  262. int gy = gridy;
  263. int gz = gridz;
  264. if ( square )
  265. {
  266. // find major axis
  267. int axis = 0;
  268. if ( Mathf.Abs(size.x) > Mathf.Abs(size.y) )
  269. {
  270. if ( Mathf.Abs(size.x) > Mathf.Abs(size.z) )
  271. axis = 0;
  272. else
  273. axis = 2;
  274. }
  275. else
  276. {
  277. if ( Mathf.Abs(size.y) > Mathf.Abs(size.z) )
  278. axis = 1;
  279. else
  280. axis = 2;
  281. }
  282. float csize = size[axis] / gridx;
  283. cellsize = new Vector3(csize, csize, csize);
  284. }
  285. else
  286. {
  287. cellsize.x = size.x / gridx;
  288. cellsize.y = size.y / gridy;
  289. cellsize.z = size.z / gridz;
  290. }
  291. gx = (int)(size.x / cellsize.x);
  292. gy = (int)(size.y / cellsize.y);
  293. gz = (int)(size.z / cellsize.z);
  294. Vector3 min = Vector3.zero;
  295. Vector3 max = size;
  296. Vector3[] corners = new Vector3[8];
  297. corners[0] = new Vector3(min.x, min.y, min.z);
  298. corners[1] = new Vector3(min.x, max.y, min.z);
  299. corners[2] = new Vector3(max.x, max.y, min.z);
  300. corners[3] = new Vector3(max.x, min.y, min.z);
  301. corners[4] = new Vector3(min.x, min.y, max.z);
  302. corners[5] = new Vector3(min.x, max.y, max.z);
  303. corners[6] = new Vector3(max.x, max.y, max.z);
  304. corners[7] = new Vector3(max.x, min.y, max.z);
  305. DrawEdge(corners[2], corners[3], gy);
  306. DrawEdge(corners[3], corners[0], gx);
  307. DrawEdge(corners[4], corners[5], gy);
  308. DrawEdge(corners[5], corners[6], gx);
  309. DrawEdge(corners[6], corners[7], gy);
  310. DrawEdge(corners[7], corners[4], gx);
  311. DrawEdge(corners[0], corners[4], gz);
  312. DrawEdge(corners[0], corners[1], gy);
  313. DrawEdge(corners[1], corners[5], gz);
  314. DrawEdge(corners[2], corners[6], gz);
  315. DrawEdge(corners[3], corners[7], gz);
  316. DrawEdge(corners[1], corners[2], gx);
  317. Gizmos.matrix = Matrix4x4.identity;
  318. }
  319. public Color GetCol(float alpha)
  320. {
  321. return velcols.Evaluate(alpha);
  322. }
  323. }