MegaWaveMesh.cs 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401
  1. using UnityEngine;
  2. using System.Collections.Generic;
  3. [ExecuteInEditMode]
  4. public class MegaWaveMesh : MonoBehaviour
  5. {
  6. [HideInInspector]
  7. public float offset = 0.0f;
  8. public float Width = 1.0f;
  9. public float Height = 1.0f;
  10. public float Length = 0.0f;
  11. public int WidthSegs = 1;
  12. public bool GenUVs = true;
  13. public bool recalcBounds = false;
  14. public bool recalcNormals = false;
  15. public bool recalcCollider = false;
  16. public float mspeed = 1.0f;
  17. public float flex = 1.0f;
  18. public float amp = 0.0f;
  19. public float wave = 1.0f;
  20. public float phase = 0.0f;
  21. public float mtime = 0.0f;
  22. public float speed = 1.0f;
  23. float dist = 0.0f;
  24. float time = 0.0f;
  25. public float flex1 = 1.0f;
  26. public float amp1 = 0.0f;
  27. public float wave1 = 1.0f;
  28. public float phase1 = 0.0f;
  29. public float mtime1 = 0.0f;
  30. public float speed1 = 1.0f;
  31. float dist1 = 0.0f;
  32. float time1 = 0.0f;
  33. public float flex2 = 1.0f;
  34. public float amp2 = 0.0f;
  35. public float wave2 = 1.0f;
  36. public float phase2 = 0.0f;
  37. public float mtime2 = 0.0f;
  38. public float speed2 = 1.0f;
  39. float dist2 = 0.0f;
  40. float time2 = 0.0f;
  41. public float amount = 1.0f;
  42. [HideInInspector]
  43. public int surfacestart = 0;
  44. [HideInInspector]
  45. public int surfaceend = 1;
  46. [HideInInspector]
  47. public Vector3[] verts;
  48. [HideInInspector]
  49. public Vector2[] uvs;
  50. [HideInInspector]
  51. public int[] tris;
  52. [HideInInspector]
  53. public float surface = 0.0f; // top value for first map
  54. public bool linkOffset = false;
  55. [HideInInspector]
  56. public bool rebuild = true;
  57. Material mat;
  58. public Vector2 UVOffset = Vector2.zero;
  59. public Vector2 UVScale = Vector2.one;
  60. [HideInInspector]
  61. public Mesh mesh;
  62. void Reset()
  63. {
  64. Rebuild();
  65. }
  66. public void Rebuild()
  67. {
  68. MeshFilter mf = GetComponent<MeshFilter>();
  69. if ( mf != null )
  70. {
  71. Mesh mesh1 = mf.sharedMesh; //Utils.GetMesh(gameObject);
  72. if ( mesh1 == null )
  73. {
  74. mesh1 = new Mesh();
  75. mf.sharedMesh = mesh1;
  76. }
  77. mesh = mesh1;
  78. if ( mesh != null )
  79. {
  80. BuildMesh(mesh);
  81. MegaModifyObject mo = GetComponent<MegaModifyObject>();
  82. if ( mo != null )
  83. {
  84. mo.MeshUpdated();
  85. }
  86. }
  87. }
  88. }
  89. public MeshCollider meshCol;
  90. public Mesh colmesh;
  91. public bool smooth = true;
  92. void Update()
  93. {
  94. if ( mesh == null )
  95. Rebuild();
  96. if ( linkOffset )
  97. offset = transform.position.x;
  98. if ( mat == null )
  99. {
  100. MeshRenderer mr = GetComponent<MeshRenderer>();
  101. if ( mr )
  102. mat = mr.sharedMaterial;
  103. }
  104. if ( mat )
  105. {
  106. //float a = Width / mat.mainTexture.width;
  107. Vector3 off = mat.mainTextureOffset;
  108. off.x = offset / Width; // * 2.0f);
  109. mat.mainTextureOffset = off;
  110. }
  111. if ( wave == 0.0f )
  112. wave = 0.0000001f;
  113. if ( wave1 == 0.0f )
  114. wave1 = 0.0000001f;
  115. if ( wave2 == 0.0f )
  116. wave2 = 0.0000001f;
  117. if ( rebuild )
  118. {
  119. BuildMesh(mesh);
  120. }
  121. else
  122. {
  123. UpdateSurface();
  124. mesh.vertices = verts;
  125. if ( recalcNormals )
  126. mesh.RecalculateNormals();
  127. if ( recalcBounds )
  128. mesh.RecalculateBounds();
  129. }
  130. if ( recalcCollider )
  131. {
  132. Rigidbody rb = GetComponent<Rigidbody>();
  133. if ( rb )
  134. {
  135. rb.inertiaTensor = Vector3.one;
  136. rb.inertiaTensorRotation = Quaternion.identity;
  137. }
  138. if ( meshCol == null )
  139. {
  140. meshCol = GetComponent<MeshCollider>();
  141. if ( meshCol == null )
  142. {
  143. meshCol = gameObject.AddComponent<MeshCollider>();
  144. }
  145. }
  146. if ( meshCol != null )
  147. {
  148. if ( colmesh == null )
  149. {
  150. colmesh = new Mesh();
  151. colmesh.Clear();
  152. }
  153. BuildCollider(colmesh);
  154. meshCol.sharedMesh = null;
  155. meshCol.sharedMesh = colmesh;
  156. }
  157. }
  158. if ( Application.isPlaying )
  159. {
  160. mtime += Time.deltaTime * speed * mspeed;
  161. mtime1 += Time.deltaTime * speed1 * mspeed;
  162. mtime2 += Time.deltaTime * speed2 * mspeed;
  163. }
  164. }
  165. Vector3[] colverts;
  166. public float colwidth = 1.0f;
  167. void BuildCollider(Mesh cmesh)
  168. {
  169. bool setris = false;
  170. if ( colverts == null || colverts.Length != verts.Length )
  171. {
  172. colverts = new Vector3[verts.Length];
  173. setris = true;
  174. }
  175. for ( int i = 0; i < surfaceend; i++ )
  176. {
  177. Vector3 p = verts[i];
  178. p.z += colwidth;
  179. colverts[i] = p;
  180. p.z -= 2.0f * colwidth;
  181. colverts[i + surfaceend] = p;
  182. }
  183. colmesh.vertices = colverts;
  184. if ( setris )
  185. {
  186. colmesh.triangles = tris; //coltris;
  187. }
  188. }
  189. void MakeQuad1(int f, int a, int b, int c, int d)
  190. {
  191. tris[f++] = c;
  192. tris[f++] = b;
  193. tris[f++] = a;
  194. tris[f++] = a;
  195. tris[f++] = d;
  196. tris[f++] = c;
  197. }
  198. // Put in utils
  199. int MaxComponent(Vector3 v)
  200. {
  201. if ( Mathf.Abs(v.x) > Mathf.Abs(v.y) )
  202. {
  203. if ( Mathf.Abs(v.x) > Mathf.Abs(v.z) )
  204. return 0;
  205. else
  206. return 2;
  207. }
  208. else
  209. {
  210. if ( Mathf.Abs(v.y) > Mathf.Abs(v.z) )
  211. return 1;
  212. else
  213. return 2;
  214. }
  215. }
  216. static public float WaveFunc(float radius, float t, float amp, float waveLen, float phase) //, float decay)
  217. {
  218. float ang = Mathf.PI * 2.0f * (radius / waveLen + phase);
  219. return amp * Mathf.Sin(ang); // * Mathf.Exp(-decay * Mathf.Abs(radius));
  220. }
  221. static public float WaveFunc1(float radius, float t, float amp, float waveLen, float phase) //, float decay)
  222. {
  223. float ang = Mathf.Repeat(Mathf.PI * 2.0f * (radius / waveLen + phase), Mathf.PI * 2.0f);
  224. if ( ang < Mathf.PI )
  225. return -amp * Mathf.Sin(ang); // * Mathf.Exp(-decay * Mathf.Abs(radius));
  226. return amp * Mathf.Sin(ang); // * Mathf.Exp(-decay * Mathf.Abs(radius));
  227. }
  228. public float Map(Vector3 p)
  229. {
  230. float u = Mathf.Abs(2.0f * p.y / dist);
  231. u = u * u;
  232. p.y = 0.0f;
  233. p.y += amount * flex * WaveFunc(p.x + offset, time, amp, wave, phase + mtime); //, dy);
  234. p.y += amount * flex1 * WaveFunc(p.x + offset, time1, amp1, wave1, phase1 + mtime1); //, dy1);
  235. p.y += amount * flex2 * WaveFunc(p.x + offset, time2, amp2, wave2, phase2 + mtime2); //, dy2);
  236. return p.y + surface;
  237. }
  238. // Update for just the top verts to make quicker
  239. void UpdateSurface()
  240. {
  241. dist = (wave / 10.0f) * 4.0f * 5.0f; //float(numSides);
  242. if ( dist == 0.0f )
  243. dist = 1.0f;
  244. dist1 = (wave1 / 10.0f) * 4.0f * 5.0f; //float(numSides);
  245. if ( dist1 == 0.0f )
  246. dist1 = 1.0f;
  247. dist2 = (wave2 / 10.0f) * 4.0f * 5.0f; //float(numSides);
  248. if ( dist2 == 0.0f )
  249. dist2 = 1.0f;
  250. for ( int i = surfacestart; i < surfaceend; i++ )
  251. verts[i].y = Map(verts[i]);
  252. }
  253. // Only call this on size or seg change
  254. void BuildMesh(Mesh mesh)
  255. {
  256. Width = Mathf.Clamp(Width, 0.0f, float.MaxValue);
  257. Length = Mathf.Clamp(Length, 0.0f, float.MaxValue);
  258. Height = Mathf.Clamp(Height, 0.0f, float.MaxValue);
  259. WidthSegs = Mathf.Clamp(WidthSegs, 1, 200);
  260. Vector3 vb = new Vector3(Width, Height, Length) / 2.0f;
  261. Vector3 va = Vector3.zero;
  262. va.x = -vb.x;
  263. va.y = vb.y;
  264. va.z = vb.z;
  265. float mdx = Width / (float)WidthSegs;
  266. float mdy = Height; // / (float)HeightSegs;
  267. Vector3 p = va;
  268. int numverts = 2 * (WidthSegs + 1);
  269. surfacestart = 0;
  270. surfaceend = WidthSegs + 1;
  271. verts = new Vector3[numverts];
  272. uvs = new Vector2[numverts];
  273. tris = new int[WidthSegs * 2 * 3];
  274. Vector2 uv = Vector2.zero;
  275. int index = 0;
  276. surface = va.y;
  277. p.z = va.z;
  278. p.y = va.y;
  279. p.x = va.x;
  280. for ( int ix = 0; ix <= WidthSegs; ix++ )
  281. {
  282. verts[index] = p;
  283. if ( GenUVs )
  284. {
  285. uv.x = ((p.x + vb.x + UVOffset.x) / Width) * UVScale.x;
  286. uv.y = ((p.y + vb.y + UVOffset.y) / Height) * UVScale.y;
  287. uvs[index] = uv;
  288. }
  289. index++;
  290. p.x += mdx;
  291. }
  292. p.y -= mdy;
  293. p.x = va.x;
  294. for ( int ix = 0; ix <= WidthSegs; ix++ )
  295. {
  296. verts[index] = p;
  297. if ( GenUVs )
  298. {
  299. uv.x = ((p.x + vb.x + UVOffset.x) / Width) * UVScale.x;
  300. uv.y = ((p.y + vb.y + UVOffset.y) / Height) * UVScale.y;
  301. uvs[index] = uv;
  302. }
  303. p.x += mdx;
  304. index++;
  305. }
  306. int f = 0;
  307. int kv = 0; //iz * (WidthSegs + 1) + index;
  308. for ( int ix = 0; ix < WidthSegs; ix++ )
  309. {
  310. MakeQuad1(f, kv, kv + WidthSegs + 1, kv + WidthSegs + 2, kv + 1);
  311. f += 6;
  312. kv++;
  313. }
  314. UpdateSurface();
  315. mesh.Clear();
  316. mesh.subMeshCount = 1;
  317. mesh.vertices = verts;
  318. mesh.uv = uvs;
  319. mesh.SetTriangles(tris, 0);
  320. mesh.RecalculateNormals();
  321. mesh.RecalculateBounds();
  322. }
  323. }