319 lines
7.8 KiB
C#
319 lines
7.8 KiB
C#
using System;
|
|
using UnityEngine;
|
|
|
|
[AddComponentMenu("Modifiers/Path Deform")]
|
|
public class MegaPathDeform : 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 bool drawpath;
|
|
|
|
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 Vector3 start;
|
|
|
|
private Quaternion tw = Quaternion.identity;
|
|
|
|
private float usepercent;
|
|
|
|
private float usetan;
|
|
|
|
private float ovlen;
|
|
|
|
public override string ModName()
|
|
{
|
|
return "PathDeform";
|
|
}
|
|
|
|
public override string GetHelpURL()
|
|
{
|
|
return "?page_id=273";
|
|
}
|
|
|
|
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) - start;
|
|
Vector3 vector2 = path.InterpCurve3D(curve, num3 + usetan, path.normalizedInterp) - start;
|
|
num3 = ((!path.splines[curve].closed) ? Mathf.Clamp01(num3) : Mathf.Repeat(num3, 1f));
|
|
if (UseTwistCurve)
|
|
{
|
|
float num4 = twistCurve.Evaluate(num3) * twist;
|
|
tw = Quaternion.AngleAxis(num4 + num, Vector3.forward);
|
|
}
|
|
else
|
|
{
|
|
tw = Quaternion.AngleAxis(num + twist * num3, Vector3.forward);
|
|
}
|
|
Vector3 forward = vector2 - vector;
|
|
Quaternion q = Quaternion.LookRotation(forward, Up) * tw;
|
|
Matrix4x4 identity = Matrix4x4.identity;
|
|
MegaMatrix.SetTR(ref identity, vector, q);
|
|
identity = mat * identity;
|
|
p.z = 0f;
|
|
return identity.MultiplyPoint3x4(p);
|
|
}
|
|
|
|
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 (curve >= path.splines.Count)
|
|
{
|
|
curve = 0;
|
|
}
|
|
if (usedist)
|
|
{
|
|
percent = distance / path.splines[curve].length * 100f;
|
|
}
|
|
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;
|
|
MegaAxis megaAxis = axis;
|
|
if (megaAxis == MegaAxis.Z)
|
|
{
|
|
MegaMatrix.RotateX(ref mat, -(float)Math.PI / 2f);
|
|
}
|
|
MegaMatrix.RotateZ(ref mat, (float)Math.PI / 180f * rotate);
|
|
SetAxis(mat);
|
|
start = path.splines[curve].knots[0].p;
|
|
Vector3 vector = path.InterpCurve3D(0, 0.01f, path.normalizedInterp);
|
|
Vector3 vector2 = Vector3.zero;
|
|
switch (axis)
|
|
{
|
|
case MegaAxis.X:
|
|
vector2 = Vector3.left;
|
|
break;
|
|
case MegaAxis.Y:
|
|
vector2 = Vector3.back;
|
|
break;
|
|
case MegaAxis.Z:
|
|
vector2 = Vector3.up;
|
|
break;
|
|
}
|
|
Quaternion identity = Quaternion.identity;
|
|
if (flip)
|
|
{
|
|
vector2 = -vector2;
|
|
}
|
|
identity = Quaternion.FromToRotation(vector - start, vector2);
|
|
mat.SetTRS(Vector3.zero, identity, Vector3.one);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
public void OnDrawGizmos()
|
|
{
|
|
if (drawpath)
|
|
{
|
|
Display(this);
|
|
}
|
|
}
|
|
|
|
private void Display(MegaPathDeform pd)
|
|
{
|
|
if (!(pd.path != null))
|
|
{
|
|
return;
|
|
}
|
|
pd.mat = Matrix4x4.identity;
|
|
Vector3 p = pd.path.splines[curve].knots[0].p;
|
|
Vector3 vector = pd.path.InterpCurve3D(curve, 0.01f, pd.path.normalizedInterp);
|
|
Vector3 vector2 = Vector3.zero;
|
|
switch (axis)
|
|
{
|
|
case MegaAxis.X:
|
|
vector2 = Vector3.left;
|
|
break;
|
|
case MegaAxis.Y:
|
|
vector2 = Vector3.back;
|
|
break;
|
|
case MegaAxis.Z:
|
|
vector2 = Vector3.up;
|
|
break;
|
|
}
|
|
Quaternion identity = Quaternion.identity;
|
|
if (flip)
|
|
{
|
|
vector2 = -vector2;
|
|
}
|
|
identity = Quaternion.FromToRotation(vector - p, vector2);
|
|
pd.mat.SetTRS(Vector3.zero, identity, Vector3.one);
|
|
Matrix4x4 matrix4x = pd.transform.localToWorldMatrix * pd.mat;
|
|
for (int i = 0; i < pd.path.splines.Count; i++)
|
|
{
|
|
float num = pd.path.stepdist * 0.1f;
|
|
if (num < 0.01f)
|
|
{
|
|
num = 0.01f;
|
|
}
|
|
float num2 = pd.path.splines[i].length / (pd.path.splines[i].length / num);
|
|
int num3 = 0;
|
|
int k = -1;
|
|
int k2 = -1;
|
|
Vector3 point = pd.path.splines[i].Interpolate(0f, pd.path.normalizedInterp, ref k2) - p;
|
|
for (float num4 = num2; num4 < pd.path.splines[i].length; num4 += num2)
|
|
{
|
|
float alpha = num4 / pd.path.splines[i].length;
|
|
Vector3 vector3 = pd.path.splines[i].Interpolate(alpha, pd.path.normalizedInterp, ref k) - p;
|
|
if ((num3 & 1) == 1)
|
|
{
|
|
Gizmos.color = pd.path.col1;
|
|
}
|
|
else
|
|
{
|
|
Gizmos.color = pd.path.col2;
|
|
}
|
|
if (k != k2)
|
|
{
|
|
for (k2++; k2 <= k; k2++)
|
|
{
|
|
Gizmos.DrawLine(matrix4x.MultiplyPoint(point), matrix4x.MultiplyPoint(pd.path.splines[i].knots[k2].p - p));
|
|
point = pd.path.splines[i].knots[k2].p - p;
|
|
}
|
|
}
|
|
k2 = k;
|
|
Gizmos.DrawLine(matrix4x.MultiplyPoint(point), matrix4x.MultiplyPoint(vector3));
|
|
num3++;
|
|
point = vector3;
|
|
}
|
|
if ((num3 & 1) == 1)
|
|
{
|
|
Gizmos.color = pd.path.col1;
|
|
}
|
|
else
|
|
{
|
|
Gizmos.color = pd.path.col2;
|
|
}
|
|
if (pd.path.splines[i].closed)
|
|
{
|
|
Vector3 point2 = pd.path.splines[i].Interpolate(0f, pd.path.normalizedInterp, ref k) - p;
|
|
Gizmos.DrawLine(matrix4x.MultiplyPoint(point), matrix4x.MultiplyPoint(point2));
|
|
}
|
|
}
|
|
Vector3 point3 = pd.path.InterpCurve3D(curve, percent / 100f, pd.path.normalizedInterp) - p;
|
|
vector = pd.path.InterpCurve3D(curve, percent / 100f + tangent * 0.01f, pd.path.normalizedInterp) - p;
|
|
Gizmos.color = Color.blue;
|
|
Vector3 size = new Vector3(pd.path.KnotSize * 0.01f, pd.path.KnotSize * 0.01f, pd.path.KnotSize * 0.01f);
|
|
Gizmos.DrawCube(matrix4x.MultiplyPoint(point3), size);
|
|
Gizmos.DrawCube(matrix4x.MultiplyPoint(vector), size);
|
|
}
|
|
|
|
public override void DrawGizmo(MegaModContext context)
|
|
{
|
|
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);
|
|
}
|
|
}
|
|
}
|