MegaDynamicRipple.cs 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890
  1. using UnityEngine;
  2. [AddComponentMenu("Modifiers/Dynamic Ripple")]
  3. public class MegaDynamicRipple : MegaModifier
  4. {
  5. public MegaAxis axis = MegaAxis.Y;
  6. public int cols = 8;
  7. public int rows = 8;
  8. [HideInInspector]
  9. public float[] buffer1;
  10. [HideInInspector]
  11. public float[] buffer2;
  12. [HideInInspector]
  13. public int[] vertexIndices;
  14. public float damping = 0.999f;
  15. public float WaveHeight = 2.0f;
  16. public float Force = 1.0f;
  17. public float DropsPerSec = 1.0f;
  18. public float speed = 0.5f;
  19. public float[] input;
  20. public float inputdamp = 0.99f;
  21. public float InputForce = 0.1f;
  22. public bool Obstructions = false;
  23. public float[] blockers;
  24. float time = 0.0f;
  25. public float scale = 1.0f;
  26. private bool swapMe = true;
  27. public bool bilinearSample = false;
  28. public override string ModName() { return "Dynamic Ripple"; }
  29. public override string GetHelpURL() { return "?page_id=2395"; }
  30. public Texture2D obTexture;
  31. Collider mycollider;
  32. [ContextMenu("Reset Sim")]
  33. public void ResetGrid()
  34. {
  35. Setup();
  36. }
  37. public void SetObstructions(Texture2D obtex)
  38. {
  39. obTexture = obtex;
  40. if ( blockers == null || blockers.Length != buffer1.Length )
  41. {
  42. blockers = new float[buffer1.Length];
  43. }
  44. if ( obTexture )
  45. {
  46. for ( int y = 0; y < rows; y++ )
  47. {
  48. int yoff = (y * (cols));
  49. float yf = (float)y / (float)rows;
  50. for ( int x = 0; x < cols; x++ )
  51. {
  52. float xf = (float)x / (float)cols;
  53. if ( bilinearSample )
  54. blockers[yoff + x] = obTexture.GetPixelBilinear(xf, yf).grayscale;
  55. else
  56. blockers[yoff + x] = obTexture.GetPixel(x, y).grayscale;
  57. }
  58. }
  59. }
  60. else
  61. {
  62. for ( int i = 0; i < blockers.Length; i++ )
  63. blockers[i] = 1.0f;
  64. }
  65. }
  66. // Float version
  67. public override void Modify(MegaModifiers mc)
  68. {
  69. for ( int i = 0; i < verts.Length; i++ )
  70. {
  71. Vector3 p = verts[i]; //tm.MultiplyPoint3x4(verts[i]);
  72. int vertIndex = vertexIndices[i];
  73. p[vertcomponent] += currentBuffer[vertIndex] * scale; // * 1.0f / Force) * WaveHeight;
  74. sverts[i] = p; //invtm.MultiplyPoint3x4(p);
  75. }
  76. }
  77. public override Vector3 Map(int i, Vector3 p)
  78. {
  79. p = tm.MultiplyPoint3x4(p);
  80. if ( i >= 0 )
  81. {
  82. int vertIndex = vertexIndices[i];
  83. p[vertcomponent] += currentBuffer[vertIndex] * scale; // * 1.0f / Force) * WaveHeight;
  84. }
  85. return invtm.MultiplyPoint3x4(p);
  86. }
  87. public override bool ModLateUpdate(MegaModContext mc)
  88. {
  89. // init
  90. if ( buffer1 == null || rows * cols != buffer1.Length )
  91. {
  92. Setup();
  93. swapMe = false;
  94. currentBuffer = buffer2;
  95. return false;
  96. }
  97. // Update ripples
  98. if ( swapMe )
  99. {
  100. // process the ripples for this frame
  101. processRipples(buffer1, buffer2);
  102. currentBuffer = buffer2;
  103. }
  104. else
  105. {
  106. processRipples(buffer2, buffer1);
  107. currentBuffer = buffer2;
  108. }
  109. swapMe = !swapMe;
  110. return Prepare(mc);
  111. }
  112. float[] currentBuffer;
  113. public override bool Prepare(MegaModContext mc)
  114. {
  115. if ( mycollider == null )
  116. mycollider = GetComponent<Collider>();
  117. return true;
  118. }
  119. // Ripple code
  120. public int vertcomponent = 1;
  121. // Use this for initialization
  122. void Setup()
  123. {
  124. int len = rows * cols;
  125. buffer1 = new float[len];
  126. buffer2 = new float[len];
  127. input = new float[len];
  128. swapMe = false;
  129. currentBuffer = buffer2;
  130. vertexIndices = new int[verts.Length];
  131. SetObstructions(obTexture);
  132. for ( int i = 0; i < len; i++ )
  133. {
  134. buffer1[i] = 0;
  135. buffer2[i] = 0;
  136. }
  137. int xc = 0;
  138. int yc = 1;
  139. Vector3 size = bbox.Size();
  140. if ( size.x == 0.0f )
  141. axis = MegaAxis.X;
  142. if ( size.y == 0.0f )
  143. axis = MegaAxis.Y;
  144. if ( size.z == 0.0f )
  145. axis = MegaAxis.Z;
  146. // this will produce a list of indices that are sorted the way I need them to
  147. // be for the algo to work right
  148. switch ( axis )
  149. {
  150. case MegaAxis.X:
  151. vertcomponent = 0;
  152. xc = 1;
  153. yc = 2;
  154. break;
  155. case MegaAxis.Y:
  156. vertcomponent = 1;
  157. xc = 0;
  158. yc = 2;
  159. break;
  160. case MegaAxis.Z:
  161. vertcomponent = 2;
  162. xc = 0;
  163. yc = 1;
  164. break;
  165. }
  166. for ( int i = 0; i < verts.Length; i++ )
  167. {
  168. float column = ((verts[i][xc] - bbox.min[xc]) / size[xc]);// + 0.5;
  169. float row = ((verts[i][yc] - bbox.min[yc]) / size[yc]);// + 0.5;
  170. if ( column >= 1.0f )
  171. column = 0.999f;
  172. if ( row >= 1.0f )
  173. row = 0.999f;
  174. int ci = (int)(column * (float)(cols));
  175. int ri = (int)(row * (float)(rows));
  176. float position = (ri * (cols)) + ci; // + 0.5f;
  177. vertexIndices[i] = (int)position; //] = i;
  178. }
  179. }
  180. // Normalized position, or even a world and local
  181. void splashAtPoint(int x, int y, float force)
  182. {
  183. int p = ((y * (cols)) + x);
  184. buffer1[p] = force;
  185. buffer1[p - 1] = force * 0.5f;
  186. buffer1[p + 1] = force * 0.5f;
  187. buffer1[p + (cols + 0)] = force * 0.5f;
  188. buffer1[p + (cols + 0) + 1] = force * 0.45f;
  189. buffer1[p + (cols + 0) - 1] = force * 0.45f;
  190. buffer1[p - (cols + 0)] = force * 0.5f;
  191. buffer1[p - (cols + 0) + 1] = force * 0.45f;
  192. buffer1[p - (cols + 0) - 1] = force * 0.45f;
  193. }
  194. void splashAtPoint1(int x, int y, float force)
  195. {
  196. int p = ((y * (cols)) + x);
  197. buffer1[p] = force;
  198. buffer1[p - 1] = force * 0.5f;
  199. buffer1[p + 1] = force * 0.5f;
  200. buffer1[p + (cols + 0)] = force * 0.5f;
  201. buffer1[p + (cols + 0) + 1] = force * 0.45f;
  202. buffer1[p + (cols + 0) - 1] = force * 0.45f;
  203. buffer1[p - (cols + 0)] = force * 0.5f;
  204. buffer1[p - (cols + 0) + 1] = force * 0.45f;
  205. buffer1[p - (cols + 0) - 1] = force * 0.45f;
  206. buffer2[p] = force;
  207. buffer2[p - 1] = force * 0.5f;
  208. buffer2[p + 1] = force * 0.5f;
  209. buffer2[p + (cols + 0)] = force * 0.5f;
  210. buffer2[p + (cols + 0) + 1] = force * 0.45f;
  211. buffer2[p + (cols + 0) - 1] = force * 0.45f;
  212. buffer2[p - (cols + 0)] = force * 0.5f;
  213. buffer2[p - (cols + 0) + 1] = force * 0.45f;
  214. buffer2[p - (cols + 0) - 1] = force * 0.45f;
  215. }
  216. public int wakesize = 1;
  217. public float wakefalloff = 1.0f;
  218. public float wakeforce = 1.0f;
  219. int ipart(float x)
  220. {
  221. return (int)x;
  222. }
  223. int round(float x)
  224. {
  225. return ipart(x + 0.5f);
  226. }
  227. float fpart(float x)
  228. {
  229. return x - (int)x;
  230. }
  231. float rfpart(float x)
  232. {
  233. return 1.0f - fpart(x);
  234. }
  235. void swap(ref float v1, ref float v2)
  236. {
  237. float temp = v1;
  238. v1 = v2;
  239. v2 = temp;
  240. }
  241. void plot(int x, int y, float force)
  242. {
  243. input[x + (y * cols)] = force;
  244. }
  245. void drawLine(float x1, float y1, float x2, float y2, float force)
  246. {
  247. float dx = x2 - x1;
  248. float dy = y2 - y1;
  249. if ( Mathf.Abs(dx) < Mathf.Abs(dy) )
  250. {
  251. swap(ref x1, ref y1);
  252. swap(ref x2, ref y2);
  253. swap(ref dx, ref dy);
  254. }
  255. if ( x2 < x1 )
  256. {
  257. swap(ref x1, ref x2);
  258. swap(ref y1, ref y2);
  259. }
  260. float gradient = dy / dx;
  261. // handle first endpoint
  262. float xend = round(x1);
  263. float yend = y1 + gradient * (xend - x1);
  264. float xgap = rfpart(x1 + 0.5f);
  265. int xpxl1 = (int)xend; // this will be used in the main loop
  266. int ypxl1 = ipart(yend);
  267. plot(xpxl1, ypxl1, rfpart(yend) * xgap * force);
  268. plot(xpxl1, ypxl1 + 1, fpart(yend) * xgap * force);
  269. float intery = yend + gradient; // first y-intersection for the main loop
  270. // handle second endpoint
  271. xend = round(x2);
  272. yend = y2 + gradient * (xend - x2);
  273. xgap = fpart(x2 + 0.5f);
  274. int xpxl2 = (int)xend; // this will be used in the main loop
  275. int ypxl2 = ipart(yend);
  276. plot(xpxl2, ypxl2, rfpart(yend) * xgap * force);
  277. plot(xpxl2, ypxl2 + 1, fpart(yend) * xgap * force);
  278. // main loop
  279. for ( int x = xpxl1 + 1; x < xpxl2 - 1; x++ )
  280. {
  281. plot(x, ipart(intery), rfpart(intery) * force);
  282. plot(x, ipart(intery) + 1, fpart(intery) * force);
  283. intery = intery + gradient;
  284. }
  285. }
  286. void wakeAtPointWu(float x, float y, float force)
  287. {
  288. }
  289. // Add correct amount for position in cell
  290. public void wakeAtPointAdd1(float x, float y, float force)
  291. {
  292. int xi = Mathf.RoundToInt(x) - 1;
  293. int yi = Mathf.RoundToInt(y) - 1;
  294. float[] dists = new float[4];
  295. int index = 0;
  296. int count = 0;
  297. float tdist = 0.0f;
  298. for ( int j = yi; j < yi + 2; j++ )
  299. {
  300. for ( int i = xi; i < xi + 2; i++ )
  301. {
  302. float dx = ((float)i + 0.5f) - x;
  303. float dy = ((float)j + 0.5f) - y;
  304. float dist = Mathf.Sqrt(dx * dx + dy * dy);
  305. if ( dist < 1.0f )
  306. {
  307. tdist += dist;
  308. dists[index] = dist;
  309. count++;
  310. //input[i + (j * cols)] = force * (1.0f - dist);
  311. }
  312. else
  313. dists[index] = 1.0f;
  314. index++;
  315. }
  316. }
  317. index = 0;
  318. for ( int j = yi; j < yi + 2; j++ )
  319. {
  320. for ( int i = xi; i < xi + 2; i++ )
  321. {
  322. if ( j >= 0 && j < rows && i >= 0 && i < cols )
  323. {
  324. if ( dists[index] < 1.0f )
  325. {
  326. input[i + (j * cols)] = force * (dists[index] / tdist); // * (1.0f - dists[index]);
  327. }
  328. }
  329. index++;
  330. }
  331. }
  332. }
  333. void wakeAtPointAdd(int x, int y, float force)
  334. {
  335. int p = ((y * (cols)) + x);
  336. input[p] = force;
  337. }
  338. void wakeAtPoint(int x, int y, float force)
  339. {
  340. int p = ((y * (cols)) + x);
  341. input[p] = force;
  342. input[p - 1] = force * 0.5f;
  343. input[p + 1] = force * 0.5f;
  344. input[p + (cols + 0)] = force * 0.5f;
  345. input[p + (cols + 0) + 1] = force * 0.45f;
  346. input[p + (cols + 0) - 1] = force * 0.45f;
  347. input[p - (cols + 0)] = force * 0.5f;
  348. input[p - (cols + 0) + 1] = force * 0.45f;
  349. input[p - (cols + 0) - 1] = force * 0.45f;
  350. }
  351. void processRipples(float[] source, float[] dest)
  352. {
  353. for ( int y = 1; y < rows - 1; y++ )
  354. {
  355. int yoff = (y * (cols));
  356. for ( int x = 1; x < cols - 1; x++ )
  357. {
  358. input[yoff + x] *= inputdamp;
  359. }
  360. }
  361. if ( Obstructions )
  362. {
  363. for ( int y = 1; y < rows - 1; y++ )
  364. {
  365. int yoff = (y * (cols));
  366. for ( int x = 1; x < cols - 1; x++ )
  367. {
  368. int p = yoff + x;
  369. dest[p] = input[p] + (((source[p - 1] + source[p + 1] + source[p - (cols)] + source[p + (cols)]) * speed) - dest[p]);
  370. dest[p] = dest[p] * damping * blockers[p];
  371. }
  372. }
  373. }
  374. else
  375. {
  376. for ( int y = 1; y < rows - 1; y++ )
  377. {
  378. int yoff = (y * (cols));
  379. for ( int x = 1; x < cols - 1; x++ )
  380. {
  381. int p = yoff + x;
  382. dest[p] = input[p] + (((source[p - 1] + source[p + 1] + source[p - (cols)] + source[p + (cols)]) * speed) - dest[p]);
  383. dest[p] = dest[p] * damping;
  384. }
  385. }
  386. }
  387. }
  388. void Update()
  389. {
  390. if ( buffer1 == null || rows * cols != buffer1.Length )
  391. return;
  392. if ( Application.isPlaying )
  393. time += Time.deltaTime;
  394. int drops = (int)(time * DropsPerSec); //Time.deltaTime
  395. if ( drops > 0 ) //time > DropTime )
  396. {
  397. time = 0.0f;
  398. if ( rows > 8 && cols > 8 )
  399. {
  400. for ( int i = 0; i < drops; i++ )
  401. {
  402. int x = Random.Range(8, cols - 8);
  403. int y = Random.Range(8, rows - 8);
  404. splashAtPoint(x, y, Force * Random.Range(0.1f, 1.0f));
  405. }
  406. }
  407. }
  408. checkInput();
  409. }
  410. // We need to do draw from last pos to new to void gaps
  411. float lastcol = -1.0f;
  412. float lastrow = -1.0f;
  413. bool lastdown = false;
  414. public float GetWaterHeight(Vector3 lpos)
  415. {
  416. if ( currentBuffer == null )
  417. return 0.0f;
  418. float x = (lpos.x - bbox.min.x) / (bbox.max.x - bbox.min.x);
  419. float y = (lpos.y - bbox.min.y) / (bbox.max.y - bbox.min.y);
  420. int xi = (int)(x * cols);
  421. int yi = (int)(y * rows);
  422. if ( xi < 0 || xi >= cols )
  423. return 0.0f;
  424. if ( yi < 0 || yi >= rows )
  425. return 0.0f;
  426. return currentBuffer[(yi * cols) + xi];
  427. }
  428. void checkInput()
  429. {
  430. if ( Input.GetMouseButton(0) )
  431. {
  432. RaycastHit[] hits;
  433. hits = Physics.RaycastAll(Camera.main.ScreenPointToRay(Input.mousePosition));
  434. for ( int i = 0; i < hits.Length; i++ )
  435. {
  436. if ( hits[i].collider.gameObject == gameObject )
  437. {
  438. if ( hits[i].collider is BoxCollider )
  439. {
  440. Vector3 p = gameObject.transform.worldToLocalMatrix.MultiplyPoint(hits[i].point);
  441. BoxCollider bc = (BoxCollider)hits[i].collider;
  442. p -= bc.center;
  443. if ( bc.size.x != 0.0f )
  444. p.x /= bc.size.x;
  445. if ( bc.size.y != 0.0f )
  446. p.y /= bc.size.y;
  447. if ( bc.size.z != 0.0f )
  448. p.z /= bc.size.z;
  449. p.x += 0.5f;
  450. p.y += 0.5f;
  451. p.z += 0.5f;
  452. float column = 0.0f;
  453. float row = 0.0f;
  454. switch ( axis )
  455. {
  456. case MegaAxis.X:
  457. vertcomponent = 0;
  458. column = (p.y) * (cols - 1);
  459. row = p.z * (rows - 1);
  460. break;
  461. case MegaAxis.Y:
  462. column = (p.x) * (cols - 1);
  463. row = p.z * (rows - 1);
  464. break;
  465. case MegaAxis.Z:
  466. column = (p.x) * (cols - 1);
  467. row = p.y * (rows - 1);
  468. break;
  469. }
  470. if ( lastdown )
  471. Line(lastcol, lastrow, column, row);
  472. else
  473. wakeAtPointAdd1((int)column, (int)row, -InputForce);
  474. lastdown = true;
  475. lastrow = row;
  476. lastcol = column;
  477. return;
  478. }
  479. else
  480. {
  481. float column = (1.0f - hits[i].textureCoord.x) * (cols - 1);
  482. float row = hits[i].textureCoord.y * (rows - 1);
  483. if ( lastdown )
  484. Line(lastcol, lastrow, column, row);
  485. else
  486. wakeAtPointAdd1((int)column, (int)row, -InputForce);
  487. lastdown = true;
  488. lastrow = row;
  489. lastcol = column;
  490. return;
  491. }
  492. }
  493. }
  494. }
  495. else
  496. lastdown = false;
  497. }
  498. void checkInput1()
  499. {
  500. if ( Input.GetMouseButton(0) )
  501. {
  502. RaycastHit hit;
  503. if ( Physics.Raycast(Camera.main.ScreenPointToRay(Input.mousePosition), out hit) )
  504. {
  505. if ( hit.collider.gameObject != gameObject )
  506. return;
  507. float column = (1.0f - hit.textureCoord.x) * (cols - 1);
  508. float row = hit.textureCoord.y * (rows - 1);
  509. if ( lastdown )
  510. Line(lastcol, lastrow, column, row);
  511. else
  512. wakeAtPointAdd1((int)column, (int)row, -InputForce);
  513. lastdown = true;
  514. lastrow = row;
  515. lastcol = column;
  516. }
  517. }
  518. else
  519. lastdown = false;
  520. }
  521. void Line(float x0, float y0, float x1, float y1)
  522. {
  523. if ( Mathf.Abs(y1 - y0) > Mathf.Abs(x1 - x0) )
  524. {
  525. int ys = (int)Mathf.Abs(y0 - y1);
  526. float dy = 1.0f;
  527. if ( y1 < y0 )
  528. dy = -1.0f;
  529. float dx = (x1 - x0);
  530. if ( ys > 0 )
  531. dx /= (float)ys;
  532. for ( int y = 0; y <= ys; y++ )
  533. {
  534. wakeAtPointAdd1(x0, y0, -InputForce);
  535. x0 += dx;
  536. y0 += dy;
  537. }
  538. }
  539. else
  540. {
  541. int xs = (int)Mathf.Abs(x0 - x1);
  542. float dx = 1.0f;
  543. if ( x1 < x0 )
  544. dx = -1.0f;
  545. float dy = (y1 - y0);
  546. if ( xs > 0 )
  547. dy /= (float)xs;
  548. for ( int x = 0; x <= xs; x++ )
  549. {
  550. wakeAtPointAdd1(x0, y0, -InputForce);
  551. x0 += dx;
  552. y0 += dy;
  553. }
  554. }
  555. }
  556. public void Line(float x0, float y0, float x1, float y1, float force)
  557. {
  558. if ( Mathf.Abs(y1 - y0) > Mathf.Abs(x1 - x0) )
  559. {
  560. int ys = (int)Mathf.Abs(y0 - y1);
  561. float dy = 1.0f;
  562. if ( y1 < y0 )
  563. dy = -1.0f;
  564. float dx = (x1 - x0);
  565. if ( ys > 0 )
  566. dx /= (float)ys;
  567. for ( int y = 0; y <= ys; y++ )
  568. {
  569. wakeAtPointAdd1(x0, y0, force);
  570. x0 += dx;
  571. y0 += dy;
  572. }
  573. }
  574. else
  575. {
  576. int xs = (int)Mathf.Abs(x0 - x1);
  577. float dx = 1.0f;
  578. if ( x1 < x0 )
  579. dx = -1.0f;
  580. float dy = (y1 - y0);
  581. if ( xs > 0 )
  582. dy /= (float)xs;
  583. for ( int x = 0; x <= xs; x++ )
  584. {
  585. wakeAtPointAdd1(x0, y0, force);
  586. x0 += dx;
  587. y0 += dy;
  588. }
  589. }
  590. }
  591. public void ForceAt(float x, float y, float force)
  592. {
  593. Vector3 lpos = Vector3.zero;
  594. lpos.x = x;
  595. lpos.z = y;
  596. lpos = transform.worldToLocalMatrix.MultiplyPoint(lpos);
  597. x = (lpos.x - bbox.min[xc]) / (bbox.max[xc] - bbox.min[xc]);
  598. y = (lpos.y - bbox.min[yc]) / (bbox.max[yc] - bbox.min[yc]);
  599. int xi = (int)(x * cols);
  600. int yi = (int)(y * rows);
  601. if ( xi < 0 || xi >= cols )
  602. return;
  603. if ( yi < 0 || yi >= rows )
  604. return;
  605. input[(yi * cols) + xi] = force;
  606. }
  607. public void ForceAt(Vector3 p, float force)
  608. {
  609. p = transform.worldToLocalMatrix.MultiplyPoint(p);
  610. BoxCollider bc = (BoxCollider)mycollider;
  611. if ( bc.size.x != 0.0f )
  612. p.x /= bc.size.x;
  613. if ( bc.size.y != 0.0f )
  614. p.y /= bc.size.y;
  615. if ( bc.size.z != 0.0f )
  616. p.z /= bc.size.z;
  617. p.x += 0.5f;
  618. p.y += 0.5f;
  619. p.z += 0.5f;
  620. float column = 0.0f;
  621. float row = 0.0f;
  622. switch ( axis )
  623. {
  624. case MegaAxis.X:
  625. vertcomponent = 0;
  626. column = (p.y) * (cols - 1);
  627. row = p.z * (rows - 1);
  628. break;
  629. case MegaAxis.Y:
  630. column = (p.x) * (cols - 1);
  631. row = p.z * (rows - 1);
  632. break;
  633. case MegaAxis.Z:
  634. column = (p.x) * (cols - 1);
  635. row = p.y * (rows - 1);
  636. break;
  637. }
  638. int xi = (int)column;
  639. int yi = (int)row;
  640. if ( xi < 0 || xi >= cols )
  641. return;
  642. if ( yi < 0 || yi >= rows )
  643. return;
  644. input[(yi * cols) + xi] = force;
  645. }
  646. int xc = 0;
  647. int yc = 0;
  648. void BuildMesh()
  649. {
  650. Vector3 pos = Vector3.zero;
  651. Vector3 last = Vector3.zero;
  652. xc = 0;
  653. yc = 0;
  654. switch ( axis )
  655. {
  656. case MegaAxis.X:
  657. xc = 1;
  658. yc = 2;
  659. break;
  660. case MegaAxis.Y:
  661. xc = 0;
  662. yc = 2;
  663. break;
  664. case MegaAxis.Z:
  665. xc = 0;
  666. yc = 1;
  667. break;
  668. }
  669. for ( int i = 0; i < rows; i++ )
  670. {
  671. pos.z = bbox.min[yc] + ((bbox.max[yc] - bbox.min[yc]) * ((float)i / (float)rows));
  672. for ( int j = 0; j < cols; j++ )
  673. {
  674. pos.x = bbox.min[xc] + ((bbox.max[xc] - bbox.min[xc]) * ((float)j / (float)cols));
  675. pos.y = currentBuffer[(i * cols) + j];
  676. if ( j > 0 )
  677. Gizmos.DrawLine(last, pos);
  678. last = pos;
  679. }
  680. }
  681. for ( int j = 0; j < cols; j++ )
  682. {
  683. pos.x = bbox.min[xc] + ((bbox.max[xc] - bbox.min[xc]) * ((float)j / (float)cols));
  684. for ( int i = 0; i < rows; i++ )
  685. {
  686. pos.z = bbox.min[yc] + ((bbox.max[yc] - bbox.min[yc]) * ((float)i / (float)rows));
  687. pos.y = currentBuffer[(i * cols) + j];
  688. if ( i > 0 )
  689. Gizmos.DrawLine(last, pos);
  690. last = pos;
  691. }
  692. }
  693. }
  694. public override void DrawGizmo(MegaModContext context)
  695. {
  696. Gizmos.color = Color.yellow;
  697. Matrix4x4 gtm = Matrix4x4.identity;
  698. Vector3 pos = gizmoPos;
  699. pos.x = -pos.x;
  700. pos.y = -pos.y;
  701. pos.z = -pos.z;
  702. Vector3 scl = gizmoScale;
  703. scl.x = 1.0f - (scl.x - 1.0f);
  704. scl.y = 1.0f - (scl.y - 1.0f);
  705. gtm.SetTRS(pos, Quaternion.Euler(gizmoRot), scl);
  706. Matrix4x4 tm = Matrix4x4.identity;
  707. switch ( axis )
  708. {
  709. case MegaAxis.X:
  710. MegaMatrix.RotateZ(ref tm, 90.0f * Mathf.Deg2Rad);
  711. break;
  712. case MegaAxis.Z:
  713. MegaMatrix.RotateX(ref tm, 90.0f * Mathf.Deg2Rad);
  714. break;
  715. }
  716. Gizmos.matrix = transform.localToWorldMatrix * gtm * tm;
  717. BuildMesh();
  718. }
  719. }