MegaWorldPathDeform.cs 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. using UnityEngine;
  2. using System.IO;
  3. public enum MegaLoopMode
  4. {
  5. Loop,
  6. Clamp,
  7. PingPong,
  8. None,
  9. }
  10. [AddComponentMenu("Modifiers/World Path Deform")]
  11. public class MegaWorldPathDeform : MegaModifier
  12. {
  13. public float percent = 0.0f;
  14. public float stretch = 1.0f;
  15. public float twist = 0.0f;
  16. public float rotate = 0.0f;
  17. public MegaAxis axis = MegaAxis.X;
  18. public bool flip = false;
  19. public MegaShape path = null;
  20. public bool animate = false;
  21. public float speed = 1.0f;
  22. public float tangent = 1.0f;
  23. [HideInInspector]
  24. public Matrix4x4 mat = new Matrix4x4();
  25. public bool UseTwistCurve = false;
  26. public AnimationCurve twistCurve = new AnimationCurve(new Keyframe(0, 0), new Keyframe(1, 1));
  27. public bool UseStretchCurve = false;
  28. public AnimationCurve stretchCurve = new AnimationCurve(new Keyframe(0, 1), new Keyframe(1, 1));
  29. public override string ModName() { return "WorldPathDeform"; }
  30. public override string GetHelpURL() { return "?page_id=361"; }
  31. public Vector3 Up = Vector3.up;
  32. public int curve = 0;
  33. public bool usedist = false;
  34. public float distance = 0.0f;
  35. public MegaLoopMode loopmode = MegaLoopMode.None;
  36. float usepercent;
  37. float usetan;
  38. float ovlen;
  39. public override Vector3 Map(int i, Vector3 p)
  40. {
  41. p = tm.MultiplyPoint3x4(p); // Dont need either, so saving 3 vector mat mults but gaining a mat mult
  42. float alpha;
  43. float tws = 0.0f;
  44. if ( UseStretchCurve )
  45. {
  46. float str = stretchCurve.Evaluate(Mathf.Repeat(p.z * ovlen + usepercent, 1.0f)) * stretch;
  47. alpha = (p.z * ovlen * str) + usepercent; //(percent / 100.0f); // can precalc this
  48. }
  49. else
  50. alpha = (p.z * ovlen * stretch) + usepercent; //(percent / 100.0f); // can precalc this
  51. Vector3 ps = path.InterpCurve3D(curve, alpha, path.normalizedInterp, ref tws); // - start;
  52. Vector3 ps1 = path.InterpCurve3D(curve, alpha + usetan, path.normalizedInterp); // - start;
  53. if ( path.splines[curve].closed )
  54. alpha = Mathf.Repeat(alpha, 1.0f);
  55. else
  56. alpha = Mathf.Clamp01(alpha);
  57. Quaternion tw = Quaternion.identity;
  58. if ( UseTwistCurve )
  59. {
  60. float twst = twistCurve.Evaluate(alpha) * twist;
  61. tw = Quaternion.AngleAxis(twst + tws, Vector3.forward);
  62. }
  63. else
  64. tw = Quaternion.AngleAxis((twist * alpha) + tws, Vector3.forward);
  65. ps1.x -= ps.x;
  66. ps1.y -= ps.y;
  67. ps1.z -= ps.z;
  68. Quaternion rotation = Quaternion.LookRotation(ps1, Up) * tw;
  69. Matrix4x4 wtm = Matrix4x4.identity;
  70. MegaMatrix.SetTR(ref wtm, ps, rotation);
  71. wtm = mat * wtm;
  72. ps.x = (p.x * wtm[0]) + (p.y * wtm[4]) + wtm[12];
  73. ps.y = (p.x * wtm[1]) + (p.y * wtm[5]) + wtm[13];
  74. ps.z = (p.x * wtm[2]) + (p.y * wtm[6]) + wtm[14];
  75. return ps; //wtm.MultiplyPoint3x4(p);
  76. }
  77. public override void ModStart(MegaModifiers mc)
  78. {
  79. }
  80. public override bool ModLateUpdate(MegaModContext mc)
  81. {
  82. if ( animate )
  83. {
  84. if ( Application.isPlaying )
  85. percent += speed * Time.deltaTime;
  86. if ( usedist )
  87. distance = percent * 0.01f * path.splines[curve].length;
  88. }
  89. return Prepare(mc);
  90. }
  91. public override bool Prepare(MegaModContext mc)
  92. {
  93. if ( path != null )
  94. {
  95. if ( usedist )
  96. percent = distance / path.splines[curve].length * 100.0f;
  97. if ( curve >= path.splines.Count )
  98. curve = 0;
  99. usepercent = percent / 100.0f;
  100. switch ( loopmode )
  101. {
  102. case MegaLoopMode.Clamp: usepercent = Mathf.Clamp01(usepercent); break;
  103. case MegaLoopMode.Loop: usepercent = Mathf.Repeat(usepercent, 1.0f); break;
  104. case MegaLoopMode.PingPong: usepercent = Mathf.PingPong(usepercent, 1.0f); break;
  105. }
  106. ovlen = (1.0f / path.splines[curve].length); // * stretch;
  107. usetan = (tangent * 0.01f);
  108. mat = Matrix4x4.identity;
  109. switch ( axis )
  110. {
  111. case MegaAxis.X: MegaMatrix.RotateZ(ref mat, Mathf.PI * 0.5f); break;
  112. case MegaAxis.Y: MegaMatrix.RotateX(ref mat, -Mathf.PI * 0.5f); break;
  113. case MegaAxis.Z: break;
  114. }
  115. MegaMatrix.RotateZ(ref mat, Mathf.Deg2Rad * rotate);
  116. SetAxis(mat);
  117. mat = transform.localToWorldMatrix.inverse * path.transform.localToWorldMatrix;
  118. return true;
  119. }
  120. return false;
  121. }
  122. public override void DrawGizmo(MegaModContext context)
  123. {
  124. SetTM();
  125. if ( !Prepare(context) )
  126. return;
  127. Vector3 min = context.bbox.min;
  128. Vector3 max = context.bbox.max;
  129. if ( context.mod.sourceObj != null )
  130. Gizmos.matrix = context.mod.sourceObj.transform.localToWorldMatrix;
  131. else
  132. Gizmos.matrix = transform.localToWorldMatrix;
  133. corners[0] = new Vector3(min.x, min.y, min.z);
  134. corners[1] = new Vector3(min.x, max.y, min.z);
  135. corners[2] = new Vector3(max.x, max.y, min.z);
  136. corners[3] = new Vector3(max.x, min.y, min.z);
  137. corners[4] = new Vector3(min.x, min.y, max.z);
  138. corners[5] = new Vector3(min.x, max.y, max.z);
  139. corners[6] = new Vector3(max.x, max.y, max.z);
  140. corners[7] = new Vector3(max.x, min.y, max.z);
  141. DrawEdge(corners[0], corners[1]);
  142. DrawEdge(corners[1], corners[2]);
  143. DrawEdge(corners[2], corners[3]);
  144. DrawEdge(corners[3], corners[0]);
  145. DrawEdge(corners[4], corners[5]);
  146. DrawEdge(corners[5], corners[6]);
  147. DrawEdge(corners[6], corners[7]);
  148. DrawEdge(corners[7], corners[4]);
  149. DrawEdge(corners[0], corners[4]);
  150. DrawEdge(corners[1], corners[5]);
  151. DrawEdge(corners[2], corners[6]);
  152. DrawEdge(corners[3], corners[7]);
  153. ExtraGizmo(context);
  154. }
  155. }