MegaTreeBend.cs 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. 
  2. using UnityEngine;
  3. [AddComponentMenu("Modifiers/Tree Bend")]
  4. public class MegaTreeBend : MegaModifier
  5. {
  6. public float fBendScale = 1.0f;
  7. public Vector3 vWind = Vector3.zero;
  8. public float WindDir = 0.0f;
  9. public float WindSpeed = 0.0f;
  10. Vector2 waveIn = Vector2.zero;
  11. Vector2 waves = Vector2.zero;
  12. public override string ModName() { return "Tree Bend"; }
  13. public override string GetHelpURL() { return "?page_id=41"; }
  14. float frac(float val)
  15. {
  16. int v = (int)val;
  17. return val - v;
  18. }
  19. Vector2 smoothCurve(Vector2 x)
  20. {
  21. x.x = x.x * x.x * (3.0f - 2.0f * x.x);
  22. x.y = x.y * x.y * (3.0f - 2.0f * x.y);
  23. return x;
  24. }
  25. Vector2 triangleWave(Vector2 x)
  26. {
  27. x.x = Mathf.Abs(frac(x.x + 0.5f) * 2.0f - 1.0f);
  28. x.y = Mathf.Abs(frac(x.y + 0.5f) * 2.0f - 1.0f);
  29. return x;
  30. }
  31. Vector2 smoothTriangleWave(Vector2 x)
  32. {
  33. return smoothCurve(triangleWave(x));
  34. }
  35. float windTurbulence(float bbPhase, float frequency, float strength)
  36. {
  37. // We create the input value for wave generation from the frequency and phase.
  38. waveIn.x = bbPhase + frequency;
  39. waveIn.y = bbPhase + frequency;
  40. // We use two square waves to generate the effect which
  41. // is then scaled by the overall strength.
  42. waves.x = (frac(waveIn.x * 1.975f) * 2.0f - 1.0f);
  43. waves.y = (frac(waveIn.y * 0.793f) * 2.0f - 1.0f);
  44. waves = smoothTriangleWave(waves);
  45. // Sum up the two waves into a single wave.
  46. return (waves.x + waves.y) * strength;
  47. }
  48. Vector2 windEffect(float bbPhase, Vector2 windDirection, float gustLength, float gustFrequency, float gustStrength, float turbFrequency, float turbStrength)
  49. {
  50. // Calculate the ambient wind turbulence.
  51. float turbulence = windTurbulence(bbPhase, turbFrequency, turbStrength);
  52. // We simulate the overall gust via a sine wave.
  53. float gustPhase = Mathf.Clamp01(Mathf.Sin((bbPhase - gustFrequency) / gustLength));
  54. float gustOffset = (gustPhase * gustStrength) + ((0.2f + gustPhase) * turbulence);
  55. // Return the final directional wind effect.
  56. return gustOffset * windDirection;
  57. }
  58. // Virtual method for all mods
  59. public override void SetValues(MegaModifier mod)
  60. {
  61. //MegaTreeBend bm = (MegaTreeBend)mod;
  62. }
  63. public override Vector3 Map(int i, Vector3 p)
  64. {
  65. p = tm.MultiplyPoint3x4(p); // tm may have an offset gizmo etc
  66. float fLength = p.magnitude;
  67. float fBF = p.y * fBendScale;
  68. fBF += 1.0f;
  69. fBF *= fBF;
  70. fBF = fBF * fBF - fBF;
  71. Vector3 vNewPos = p;
  72. vNewPos.x += vWind.x * fBF;
  73. vNewPos.z += vWind.y * fBF;
  74. p = vNewPos.normalized * fLength;
  75. p = invtm.MultiplyPoint3x4(p);
  76. return p;
  77. }
  78. public override bool ModLateUpdate(MegaModContext mc)
  79. {
  80. return Prepare(mc);
  81. }
  82. public override bool Prepare(MegaModContext mc)
  83. {
  84. vWind.x = Mathf.Sin(WindDir * Mathf.Deg2Rad) * WindSpeed;
  85. vWind.y = Mathf.Cos(WindDir * Mathf.Deg2Rad) * WindSpeed;
  86. return true;
  87. }
  88. }