using System; using UnityEngine; [AddComponentMenu("Modifiers/World Path Deform")] public class MegaWorldPathDeform : MegaModifier { public float percent; public float stretch = 1f; public float twist; public float rotate; public MegaAxis axis; public bool flip; public MegaShape path; public bool animate; public float speed = 1f; public float tangent = 1f; [HideInInspector] public Matrix4x4 mat = default(Matrix4x4); public bool UseTwistCurve; public AnimationCurve twistCurve = new AnimationCurve(new Keyframe(0f, 0f), new Keyframe(1f, 1f)); public bool UseStretchCurve; public AnimationCurve stretchCurve = new AnimationCurve(new Keyframe(0f, 1f), new Keyframe(1f, 1f)); public Vector3 Up = Vector3.up; public int curve; public bool usedist; public float distance; public MegaLoopMode loopmode = MegaLoopMode.None; private float usepercent; private float usetan; private float ovlen; public override string ModName() { return "WorldPathDeform"; } public override string GetHelpURL() { return "?page_id=361"; } public override Vector3 Map(int i, Vector3 p) { p = tm.MultiplyPoint3x4(p); float num = 0f; float num3; if (UseStretchCurve) { float num2 = stretchCurve.Evaluate(Mathf.Repeat(p.z * ovlen + usepercent, 1f)) * stretch; num3 = p.z * ovlen * num2 + usepercent; } else { num3 = p.z * ovlen * stretch + usepercent; } Vector3 vector = path.InterpCurve3D(curve, num3, path.normalizedInterp, ref num); Vector3 forward = path.InterpCurve3D(curve, num3 + usetan, path.normalizedInterp); num3 = ((!path.splines[curve].closed) ? Mathf.Clamp01(num3) : Mathf.Repeat(num3, 1f)); Quaternion identity = Quaternion.identity; if (UseTwistCurve) { float num4 = twistCurve.Evaluate(num3) * twist; identity = Quaternion.AngleAxis(num4 + num, Vector3.forward); } else { identity = Quaternion.AngleAxis(twist * num3 + num, Vector3.forward); } forward.x -= vector.x; forward.y -= vector.y; forward.z -= vector.z; Quaternion q = Quaternion.LookRotation(forward, Up) * identity; Matrix4x4 identity2 = Matrix4x4.identity; MegaMatrix.SetTR(ref identity2, vector, q); identity2 = mat * identity2; vector.x = p.x * identity2[0] + p.y * identity2[4] + identity2[12]; vector.y = p.x * identity2[1] + p.y * identity2[5] + identity2[13]; vector.z = p.x * identity2[2] + p.y * identity2[6] + identity2[14]; return vector; } public override void ModStart(MegaModifiers mc) { } public override bool ModLateUpdate(MegaModContext mc) { if (animate) { percent += speed * Time.deltaTime; if (usedist) { distance = percent * 0.01f * path.splines[curve].length; } } return Prepare(mc); } public override bool Prepare(MegaModContext mc) { if (path != null) { if (usedist) { percent = distance / path.splines[curve].length * 100f; } if (curve >= path.splines.Count) { curve = 0; } usepercent = percent / 100f; switch (loopmode) { case MegaLoopMode.Clamp: usepercent = Mathf.Clamp01(usepercent); break; case MegaLoopMode.Loop: usepercent = Mathf.Repeat(usepercent, 1f); break; case MegaLoopMode.PingPong: usepercent = Mathf.PingPong(usepercent, 1f); break; } ovlen = 1f / path.splines[curve].length; usetan = tangent * 0.01f; mat = Matrix4x4.identity; switch (axis) { case MegaAxis.X: MegaMatrix.RotateZ(ref mat, (float)Math.PI / 2f); break; case MegaAxis.Y: MegaMatrix.RotateX(ref mat, -(float)Math.PI / 2f); break; } MegaMatrix.RotateZ(ref mat, (float)Math.PI / 180f * rotate); SetAxis(mat); mat = base.transform.localToWorldMatrix.inverse * path.transform.localToWorldMatrix; return true; } return false; } public override void DrawGizmo(MegaModContext context) { SetTM(); if (Prepare(context)) { Vector3 min = context.bbox.min; Vector3 max = context.bbox.max; if (context.mod.sourceObj != null) { Gizmos.matrix = context.mod.sourceObj.transform.localToWorldMatrix; } else { Gizmos.matrix = base.transform.localToWorldMatrix; } corners[0] = new Vector3(min.x, min.y, min.z); corners[1] = new Vector3(min.x, max.y, min.z); corners[2] = new Vector3(max.x, max.y, min.z); corners[3] = new Vector3(max.x, min.y, min.z); corners[4] = new Vector3(min.x, min.y, max.z); corners[5] = new Vector3(min.x, max.y, max.z); corners[6] = new Vector3(max.x, max.y, max.z); corners[7] = new Vector3(max.x, min.y, max.z); DrawEdge(corners[0], corners[1]); DrawEdge(corners[1], corners[2]); DrawEdge(corners[2], corners[3]); DrawEdge(corners[3], corners[0]); DrawEdge(corners[4], corners[5]); DrawEdge(corners[5], corners[6]); DrawEdge(corners[6], corners[7]); DrawEdge(corners[7], corners[4]); DrawEdge(corners[0], corners[4]); DrawEdge(corners[1], corners[5]); DrawEdge(corners[2], corners[6]); DrawEdge(corners[3], corners[7]); ExtraGizmo(context); } } }