using System; using System.Collections.Generic; using UnityEngine; [ExecuteInEditMode] public class MegaShape : MonoBehaviour { public enum CrossSectionType { Circle = 0, Box = 1 } public MegaAxis axis = MegaAxis.Y; public Color col1 = new Color(1f, 1f, 1f, 1f); public Color col2 = new Color(0.1f, 0.1f, 0.1f, 1f); public Color KnotCol = new Color(0f, 1f, 0f, 1f); public Color HandleCol = new Color(1f, 0f, 0f, 1f); public Color VecCol = new Color(0.1f, 0.1f, 0.2f, 0.5f); public float KnotSize = 10f; public float stepdist = 1f; public bool normalizedInterp = true; public bool drawHandles; public bool drawKnots = true; public bool drawspline = true; public bool drawTwist; public bool lockhandles = true; public bool showorigin = true; public bool usesnap; public bool usesnaphandles; public Vector3 snap = Vector3.one; public MegaHandleType handleType; public float CursorPos; public List splines = new List(); public bool showanimations; public float keytime; public bool updateondrag = true; public float angleError = 0.08f; public float areaError = 0.15f; public float hardAngle = 88f; public float packMargin = 0.0039f; public float defRadius = 1f; public bool smoothonaddknot = true; private const float CIRCLE_VECTOR_LENGTH = 0.5517862f; public float testtime; public float time; public bool animate; public float speed = 1f; public int selcurve; public bool imported; public float CursorPercent; private float t; public float MaxTime = 1f; public MegaRepeatMode LoopMode; public bool dolateupdate; public bool makeMesh; public MeshShapeType meshType; public bool DoubleSided = true; public bool CalcTangents; public bool GenUV = true; public bool PhysUV; public float Height; public int HeightSegs = 1; public int Sides = 4; public float TubeStep = 0.1f; public float Start; public float End = 100f; public float Rotate; public Vector3 Pivot = Vector3.zero; public Vector2 UVOffset = Vector2.zero; public Vector2 UVRotate = Vector2.zero; public Vector2 UVScale = Vector2.one; public Vector2 UVOffset1 = Vector2.zero; public Vector2 UVRotate1 = Vector2.zero; public Vector2 UVScale1 = Vector2.one; public Vector2 UVOffset2 = Vector2.zero; public Vector2 UVRotate3 = Vector2.zero; public Vector2 UVScale3 = Vector2.one; public bool autosmooth; public float smoothness = 0.75f; public bool flipNormals; public MegaShapeBezComputeMode smoothMode; public bool smoothOnDrag; public bool freezeX; public bool freezeY; public bool freezeZ; public Material mat1; public Material mat2; public Material mat3; public bool UseHeightCurve; public AnimationCurve heightCrv = new AnimationCurve(new Keyframe(0f, 1f), new Keyframe(1f, 1f)); public float heightOff; public Mesh shapemesh; private static float lastout; private static float lastin = -9999f; private List verts = new List(); private List uvs = new List(); private List tris = new List(); private List tris1 = new List(); private List tris2 = new List(); private Vector3[] cross; public int tsides = 8; public CrossSectionType crossType; public float Twist; public int strands = 1; public float tradius = 0.1f; public float offset; public float uvtilex = 1f; public float uvtiley = 1f; public float uvtwist; public float TubeLength = 1f; public float TubeStart; public float SegsPerUnit = 20f; public float TwistPerUnit; public float strandRadius; public float startAng; public float rotate; private int segments; public bool cap; private Vector3[] tverts; private Vector2[] tuvs; private int[] ttris; private Matrix4x4 tm; private Matrix4x4 mat; private Matrix4x4 wtm; public MegaAxis RopeUp = MegaAxis.Y; private Vector3 ropeup = Vector3.up; public AnimationCurve scaleX = new AnimationCurve(new Keyframe(0f, 1f), new Keyframe(1f, 1f)); public AnimationCurve scaleY = new AnimationCurve(new Keyframe(0f, 1f), new Keyframe(1f, 1f)); public bool unlinkScale; public float boxwidth = 0.2f; public float boxheight = 0.2f; private float[] boxuv = new float[8]; public MegaAxis raxis; public int ribsegs = 1; private int[] empty = new int[3]; private static int CURVELENGTHSTEPS = 5; public bool conform; public GameObject target; public Collider conformCollider; public float[] offsets; public float[] last; public float conformAmount = 1f; public float raystartoff; public float raydist = 10f; public float conformOffset; private float minz; public float conformWeight = 1f; public virtual void MakeShape() { Matrix4x4 matrix = GetMatrix(); float num = 0.5517862f * defRadius; MegaSpline megaSpline = NewSpline(); for (int i = 0; i < 4; i++) { float f = (float)Math.PI * 2f * (float)i / 4f; float num2 = Mathf.Sin(f); float num3 = Mathf.Cos(f); Vector3 vector = new Vector3(num3 * defRadius, num2 * defRadius, 0f); Vector3 vector2 = new Vector3(num2 * num, (0f - num3) * num, 0f); megaSpline.AddKnot(vector, vector + vector2, vector - vector2, matrix); } megaSpline.closed = true; CalcLength(); } public virtual string GetHelpURL() { return "?page_id=390"; } [ContextMenu("Help")] public void Help() { Application.OpenURL("http://www.west-racing.com/mf/" + GetHelpURL()); } [ContextMenu("Reset Mesh Info")] public void ResetMesh() { shapemesh = null; BuildMesh(); } public Matrix4x4 GetMatrix() { Matrix4x4 identity = Matrix4x4.identity; switch (axis) { case MegaAxis.X: MegaMatrix.RotateY(ref identity, -(float)Math.PI / 2f); MegaMatrix.Scale(ref identity, -Vector3.one, false); break; case MegaAxis.Y: MegaMatrix.RotateX(ref identity, (float)Math.PI / 2f); break; } return identity; } public void CopyIDS(int curve) { if (curve > 0 && curve < splines.Count) { MegaSpline megaSpline = splines[curve]; MegaSpline megaSpline2 = splines[curve - 1]; for (int i = 0; i < megaSpline2.knots.Count && i < megaSpline.knots.Count; i++) { megaSpline.knots[i].id = megaSpline2.knots[i].id; } } } public void Reverse(int c) { if (c >= 0 && c < splines.Count) { splines[c].Reverse(); } } public void SetHeight(int c, float y) { if (c >= 0 && c < splines.Count) { splines[c].SetHeight(y); } } public void SetTwist(int c, float twist) { if (c >= 0 && c < splines.Count) { splines[c].SetTwist(twist); } } public MegaSpline NewSpline() { if (splines.Count == 0) { MegaSpline item = new MegaSpline(); splines.Add(item); } MegaSpline megaSpline = splines[0]; megaSpline.knots.Clear(); megaSpline.closed = false; return megaSpline; } private void Reset() { MakeShape(); } private void Awake() { if (splines.Count == 0) { MakeShape(); } } private void Update() { if (!dolateupdate) { DoUpdate(); } } private void LateUpdate() { if (dolateupdate) { DoUpdate(); } } private void DoUpdate() { if (!animate) { return; } BuildMesh(); time += Time.deltaTime * speed; switch (LoopMode) { case MegaRepeatMode.Loop: t = Mathf.Repeat(time, MaxTime); break; case MegaRepeatMode.PingPong: t = Mathf.PingPong(time, MaxTime); break; case MegaRepeatMode.Clamp: t = Mathf.Clamp(time, 0f, MaxTime); break; } for (int i = 0; i < splines.Count; i++) { if (splines[i].splineanim != null && splines[i].splineanim.Enabled && splines[i].splineanim.NumKeys() > 1) { splines[i].splineanim.GetState1(splines[i], t); splines[i].CalcLength(); } else { if (splines[i].animations == null || splines[i].animations.Count <= 0) { continue; } for (int j = 0; j < splines[i].animations.Count; j++) { Vector3 vector = splines[i].animations[j].con.GetVector3(t); switch (splines[i].animations[j].t) { case 0: splines[splines[i].animations[j].s].knots[splines[i].animations[j].p].invec = vector; break; case 1: splines[splines[i].animations[j].s].knots[splines[i].animations[j].p].p = vector; break; case 2: splines[splines[i].animations[j].s].knots[splines[i].animations[j].p].outvec = vector; break; } } splines[i].CalcLength(); } } } public void Centre(float scale, Vector3 axis) { Vector3 zero = Vector3.zero; int num = 0; for (int i = 0; i < splines.Count; i++) { num += splines[i].knots.Count; for (int j = 0; j < splines[i].knots.Count; j++) { zero += splines[i].knots[j].p; } } zero /= (float)num; for (int k = 0; k < splines.Count; k++) { for (int l = 0; l < splines[k].knots.Count; l++) { splines[k].knots[l].p -= zero; splines[k].knots[l].invec -= zero; splines[k].knots[l].outvec -= zero; splines[k].knots[l].p *= scale; splines[k].knots[l].invec *= scale; splines[k].knots[l].outvec *= scale; splines[k].knots[l].p = Vector3.Scale(splines[k].knots[l].p, axis); splines[k].knots[l].invec = Vector3.Scale(splines[k].knots[l].invec, axis); splines[k].knots[l].outvec = Vector3.Scale(splines[k].knots[l].outvec, axis); } } } public void Centre(float scale, Vector3 axis, int start) { Vector3 zero = Vector3.zero; int num = 0; for (int i = start; i < splines.Count; i++) { num += splines[i].knots.Count; for (int j = 0; j < splines[i].knots.Count; j++) { zero += splines[i].knots[j].p; } } zero /= (float)num; for (int k = start; k < splines.Count; k++) { for (int l = 0; l < splines[k].knots.Count; l++) { splines[k].knots[l].p -= zero; splines[k].knots[l].invec -= zero; splines[k].knots[l].outvec -= zero; splines[k].knots[l].p *= scale; splines[k].knots[l].invec *= scale; splines[k].knots[l].outvec *= scale; splines[k].knots[l].p = Vector3.Scale(splines[k].knots[l].p, axis); splines[k].knots[l].invec = Vector3.Scale(splines[k].knots[l].invec, axis); splines[k].knots[l].outvec = Vector3.Scale(splines[k].knots[l].outvec, axis); } } } public void CoordAdjust(float scale, Vector3 axis, int start) { for (int i = start; i < splines.Count; i++) { for (int j = 0; j < splines[i].knots.Count; j++) { splines[i].knots[j].p *= scale; splines[i].knots[j].invec *= scale; splines[i].knots[j].outvec *= scale; splines[i].knots[j].p = Vector3.Scale(splines[i].knots[j].p, axis); splines[i].knots[j].invec = Vector3.Scale(splines[i].knots[j].invec, axis); splines[i].knots[j].outvec = Vector3.Scale(splines[i].knots[j].outvec, axis); } } } public void Scale(float scale) { for (int i = 0; i < splines.Count; i++) { for (int j = 0; j < splines[i].knots.Count; j++) { splines[i].knots[j].invec *= scale; splines[i].knots[j].p *= scale; splines[i].knots[j].outvec *= scale; } if (splines[i].animations == null) { continue; } for (int k = 0; k < splines[i].animations.Count; k++) { if (splines[i].animations[k].con != null) { splines[i].animations[k].con.Scale(scale); } } } CalcLength(); } public void Scale(float scale, int start) { for (int i = start; i < splines.Count; i++) { for (int j = 0; j < splines[i].knots.Count; j++) { splines[i].knots[j].invec *= scale; splines[i].knots[j].p *= scale; splines[i].knots[j].outvec *= scale; } if (splines[i].animations == null) { continue; } for (int k = 0; k < splines[i].animations.Count; k++) { if (splines[i].animations[k].con != null) { splines[i].animations[k].con.Scale(scale); } } } CalcLength(); } public void Scale(Vector3 scale) { for (int i = 0; i < splines.Count; i++) { for (int j = 0; j < splines[i].knots.Count; j++) { splines[i].knots[j].invec.x *= scale.x; splines[i].knots[j].invec.y *= scale.y; splines[i].knots[j].invec.z *= scale.z; splines[i].knots[j].p.x *= scale.x; splines[i].knots[j].p.y *= scale.y; splines[i].knots[j].p.z *= scale.z; splines[i].knots[j].outvec.x *= scale.x; splines[i].knots[j].outvec.y *= scale.y; splines[i].knots[j].outvec.z *= scale.z; } if (splines[i].animations == null) { continue; } for (int k = 0; k < splines[i].animations.Count; k++) { if (splines[i].animations[k].con != null) { splines[i].animations[k].con.Scale(scale); } } } CalcLength(); } public void MoveSpline(Vector3 delta) { for (int i = 0; i < splines.Count; i++) { MoveSpline(delta, i, false); } CalcLength(); } public void MoveSpline(Vector3 delta, int c, bool calc) { for (int i = 0; i < splines[c].knots.Count; i++) { splines[c].knots[i].invec += delta; splines[c].knots[i].p += delta; splines[c].knots[i].outvec += delta; } if (splines[c].animations != null) { for (int j = 0; j < splines[c].animations.Count; j++) { if (splines[c].animations[j].con != null) { splines[c].animations[j].con.Move(delta); } } } if (calc) { CalcLength(c); } } public void RotateSpline(Vector3 rot, int c, bool calc) { Matrix4x4 matrix4x = Matrix4x4.TRS(Vector3.zero, Quaternion.Euler(rot), Vector3.one); for (int i = 0; i < splines[c].knots.Count; i++) { splines[c].knots[i].invec = matrix4x.MultiplyPoint3x4(splines[c].knots[i].invec); splines[c].knots[i].outvec = matrix4x.MultiplyPoint3x4(splines[c].knots[i].outvec); splines[c].knots[i].p = matrix4x.MultiplyPoint3x4(splines[c].knots[i].p); } if (splines[c].animations != null) { for (int j = 0; j < splines[c].animations.Count; j++) { if (splines[c].animations[j].con != null) { splines[c].animations[j].con.Rotate(matrix4x); } } } if (calc) { CalcLength(c); } } public int GetSpline(int p, ref MegaKnotAnim ma) { int num = 0; int num2 = p / 3; for (int i = 0; i < splines.Count; i++) { int num3 = num + splines[i].knots.Count; if (num2 < num3) { ma.s = i; ma.p = num2 - num; ma.t = p % 3; return i; } num = num3; } Debug.Log("Cant find point in spline"); return 0; } public float GetCurveLength(int curve) { if (curve < splines.Count) { return splines[curve].length; } return splines[0].length; } public float CalcLength(int curve, int step) { if (curve < splines.Count) { return splines[curve].CalcLength(step); } return 0f; } [ContextMenu("Recalc Length")] public void ReCalcLength() { CalcLength(); } public float CalcLength() { float num = 0f; for (int i = 0; i < splines.Count; i++) { num += splines[i].CalcLength(); } return num; } public float CalcLength(int curve) { return splines[curve].CalcLength(); } public Vector3 GetKnotPos(int curve, int knot) { return splines[curve].knots[knot].p; } public Vector3 GetKnotInVec(int curve, int knot) { return splines[curve].knots[knot].invec; } public Vector3 GetKnotOutVec(int curve, int knot) { return splines[curve].knots[knot].outvec; } public void SetKnotPos(int curve, int knot, Vector3 p) { splines[curve].knots[knot].p = p; CalcLength(); } public void SetKnot(int curve, int knot, Vector3 p, Vector3 intan, Vector3 outtan) { splines[curve].knots[knot].p = p; splines[curve].knots[knot].invec = intan; splines[curve].knots[knot].outvec = outtan; CalcLength(); } public void SetHandles(int curve, int knot, Vector3 intan, Vector3 outtan) { splines[curve].knots[knot].invec = splines[curve].knots[knot].p + intan; splines[curve].knots[knot].outvec = splines[curve].knots[knot].p + outtan; CalcLength(); } public void MoveKnot(int curve, int knot, Vector3 p) { Vector3 vector = p - splines[curve].knots[knot].p; splines[curve].knots[knot].p = p; splines[curve].knots[knot].invec += vector; splines[curve].knots[knot].outvec += vector; CalcLength(); } public Quaternion GetRotate(int curve, float alpha) { Vector3 vector = InterpCurve3D(curve, alpha, normalizedInterp); Vector3 vector2 = InterpCurve3D(curve, alpha + 0.001f, normalizedInterp); return Quaternion.LookRotation(vector - vector2); } public Vector3 InterpCurve3D(int curve, float alpha, bool type) { int k = 0; if (curve < splines.Count) { if (alpha < 0f) { if (!splines[curve].closed) { Vector3 vector = splines[curve].Interpolate(0f, type, ref k); Vector3 vector2 = splines[curve].Interpolate(0.01f, type, ref k); Vector3 vector3 = vector2 - vector; vector3.Normalize(); return vector + splines[curve].length * alpha * vector3; } alpha = Mathf.Repeat(alpha, 1f); } else if (alpha > 1f) { if (!splines[curve].closed) { Vector3 vector4 = splines[curve].Interpolate(1f, type, ref k); Vector3 vector5 = splines[curve].Interpolate(0.99f, type, ref k); Vector3 vector6 = vector5 - vector4; vector6.Normalize(); return vector4 + splines[curve].length * (1f - alpha) * vector6; } alpha %= 1f; } return splines[curve].Interpolate(alpha, type, ref k); } if (splines == null || splines.Count == 0) { return Vector3.zero; } return splines[0].Interpolate(1f, type, ref k); } public Vector3 InterpCurve3D(int curve, float alpha, bool type, ref float twist) { int k = 0; if (curve < splines.Count) { if (alpha < 0f) { if (!splines[curve].closed) { Vector3 vector = splines[curve].Interpolate(0f, type, ref k, ref twist); Vector3 vector2 = splines[curve].Interpolate(0.01f, type, ref k, ref twist); Vector3 vector3 = vector2 - vector; vector3.Normalize(); return vector + splines[curve].length * alpha * vector3; } alpha = Mathf.Repeat(alpha, 1f); } else if (alpha > 1f) { if (!splines[curve].closed) { Vector3 vector4 = splines[curve].Interpolate(1f, type, ref k, ref twist); Vector3 vector5 = splines[curve].Interpolate(0.99f, type, ref k, ref twist); Vector3 vector6 = vector5 - vector4; vector6.Normalize(); return vector4 + splines[curve].length * (1f - alpha) * vector6; } alpha %= 1f; } return splines[curve].Interpolate(alpha, type, ref k, ref twist); } if (splines == null || splines.Count == 0) { return Vector3.zero; } return splines[0].Interpolate(1f, type, ref k, ref twist); } public Vector3 InterpCurve3D(int curve, float alpha, float tanalpha, bool type, ref float twist, ref Quaternion rot) { int k = 0; Vector3 result; if (curve < splines.Count) { if (alpha < 0f) { if (!splines[curve].closed) { Vector3 vector = splines[curve].Interpolate(0f, type, ref k, ref twist); Vector3 vector2 = splines[curve].Interpolate(0.01f, type, ref k, ref twist); Vector3 vector3 = vector2 - vector; vector3.Normalize(); result = vector + splines[curve].length * alpha * vector3; rot = Quaternion.LookRotation(vector3) * Quaternion.Euler(0f, 0f, twist); return result; } alpha = Mathf.Repeat(alpha, 1f); } else if (alpha > 1f) { if (!splines[curve].closed) { Vector3 vector4 = splines[curve].Interpolate(1f, type, ref k, ref twist); Vector3 vector5 = splines[curve].Interpolate(0.99f, type, ref k, ref twist); Vector3 vector6 = vector5 - vector4; vector6.Normalize(); result = vector4 + splines[curve].length * (1f - alpha) * vector6; rot = Quaternion.LookRotation(vector6) * Quaternion.Euler(0f, 0f, twist); return result; } alpha %= 1f; } result = splines[curve].Interpolate(alpha, type, ref k, ref twist); Vector3 vector7 = splines[curve].Interpolate(tanalpha, type, ref k, ref twist); Vector3 forward = vector7 - result; rot = Quaternion.LookRotation(forward) * Quaternion.Euler(0f, 0f, twist); } else { rot = Quaternion.identity; if (splines == null || splines.Count == 0) { return Vector3.zero; } result = splines[0].Interpolate(1f, type, ref k, ref twist); } return result; } public static float veccalc(float angstep) { if (lastin == angstep) { return lastout; } float num = Mathf.Sin(angstep); float num2 = Mathf.Cos(angstep); MegaSpline megaSpline = new MegaSpline(); Vector3 vector = new Vector3(Mathf.Cos(0f), Mathf.Sin(0f), 0f); Vector3 vector2 = new Vector3(num2, num, 0f); float num3 = 1.5f; float num4 = 0f; int num5 = 200; float num6; while (true) { megaSpline.knots.Clear(); num6 = (num3 + num4) / 2f; Vector3 outvec = vector + new Vector3(0f, num6, 0f); Vector3 invec = vector2 + new Vector3(num * num6, (0f - num2) * num6, 0f); megaSpline.AddKnot(vector, vector, outvec); megaSpline.AddKnot(vector2, invec, vector2); float num7 = 0f; int k = 0; for (int i = 0; i < 10; i++) { Vector3 vector3 = megaSpline.Interpolate((float)i / 10f, false, ref k); num7 += Mathf.Sqrt(vector3.x * vector3.x + vector3.y * vector3.y); } num7 /= 10f; num5--; if (num7 == 1f || num5 <= 0) { break; } if (num7 > 1f) { num3 = num6; } else { num4 = num6; } } lastin = angstep; lastout = num6; return num6; } public Vector3 FindNearestPointWorld(Vector3 p, int iterations, ref int kn, ref Vector3 tangent, ref float alpha) { Vector3 result = base.transform.TransformPoint(FindNearestPoint(base.transform.worldToLocalMatrix.MultiplyPoint(p), iterations, ref kn, ref tangent, ref alpha)); tangent = base.transform.TransformPoint(tangent); return result; } public Vector3 FindNearestPointWorldXZ(Vector3 p, int iterations, ref int kn, ref Vector3 tangent, ref float alpha) { Vector3 result = base.transform.TransformPoint(FindNearestPointXZ(base.transform.worldToLocalMatrix.MultiplyPoint(p), iterations, ref kn, ref tangent, ref alpha)); tangent = base.transform.TransformPoint(tangent); return result; } public Vector3 FindNearestPoint(Vector3 p, int iterations, ref int kn, ref Vector3 tangent, ref float alpha) { float num = float.PositiveInfinity; float num2 = 0f; iterations = Mathf.Clamp(iterations, 0, 5); int k = 0; int num3 = selcurve; if (num3 >= splines.Count) { num3 = splines.Count - 1; } for (float num4 = 0f; num4 <= 1f; num4 += 0.01f) { float sqrMagnitude = (splines[num3].Interpolate(num4, true, ref k) - p).sqrMagnitude; if (num > sqrMagnitude) { num = sqrMagnitude; num2 = num4; } } for (int i = 0; i < iterations; i++) { float num5 = 0.01f * Mathf.Pow(10f, 0f - (float)i); float num6 = num5 * 0.1f; for (float num7 = Mathf.Clamp01(num2 - num5); num7 <= Mathf.Clamp01(num2 + num5); num7 += num6) { float sqrMagnitude2 = (splines[num3].Interpolate(num7, true, ref k) - p).sqrMagnitude; if (num > sqrMagnitude2) { num = sqrMagnitude2; num2 = num7; } } } kn = k; tangent = InterpCurve3D(num3, num2 + 0.01f, true); alpha = num2; return InterpCurve3D(num3, num2, true); } public Vector3 FindNearestPointXZ(Vector3 p, int iterations, ref int kn, ref Vector3 tangent, ref float alpha) { float num = float.PositiveInfinity; float num2 = 0f; iterations = Mathf.Clamp(iterations, 0, 5); int k = 0; int num3 = selcurve; if (num3 >= splines.Count) { num3 = splines.Count - 1; } for (float num4 = 0f; num4 <= 1f; num4 += 0.01f) { Vector3 vector = splines[num3].Interpolate(num4, true, ref k) - p; vector.y = 0f; float sqrMagnitude = vector.sqrMagnitude; if (num > sqrMagnitude) { num = sqrMagnitude; num2 = num4; } } for (int i = 0; i < iterations; i++) { float num5 = 0.01f * Mathf.Pow(10f, 0f - (float)i); float num6 = num5 * 0.1f; for (float num7 = Mathf.Clamp01(num2 - num5); num7 <= Mathf.Clamp01(num2 + num5); num7 += num6) { Vector3 vector2 = splines[num3].Interpolate(num7, true, ref k) - p; vector2.y = 0f; float sqrMagnitude2 = vector2.sqrMagnitude; if (num > sqrMagnitude2) { num = sqrMagnitude2; num2 = num7; } } } kn = k; tangent = InterpCurve3D(num3, num2 + 0.01f, true); alpha = num2; Vector3 result = InterpCurve3D(num3, num2, true); result.y = 0f; return result; } public Vector3 FindNearestPoint(int crv, Vector3 p, int iterations, ref int kn, ref Vector3 tangent, ref float alpha) { float num = float.PositiveInfinity; float num2 = 0f; iterations = Mathf.Clamp(iterations, 0, 5); int k = 0; if (crv >= splines.Count) { crv = splines.Count - 1; } for (float num3 = 0f; num3 <= 1f; num3 += 0.01f) { float sqrMagnitude = (splines[crv].Interpolate(num3, true, ref k) - p).sqrMagnitude; if (num > sqrMagnitude) { num = sqrMagnitude; num2 = num3; } } for (int i = 0; i < iterations; i++) { float num4 = 0.01f * Mathf.Pow(10f, 0f - (float)i); float num5 = num4 * 0.1f; for (float num6 = Mathf.Clamp01(num2 - num4); num6 <= Mathf.Clamp01(num2 + num4); num6 += num5) { float sqrMagnitude2 = (splines[crv].Interpolate(num6, true, ref k) - p).sqrMagnitude; if (num > sqrMagnitude2) { num = sqrMagnitude2; num2 = num6; } } } kn = k; tangent = InterpCurve3D(crv, num2 + 0.01f, true); alpha = num2; return InterpCurve3D(crv, num2, true); } public void BuildSplineWorld(int curve, Vector3[] points, bool closed) { if (curve >= 0 && curve < splines.Count) { MegaSpline megaSpline = splines[curve]; megaSpline.knots = new List(points.Length); for (int i = 0; i < points.Length; i++) { MegaKnot megaKnot = new MegaKnot(); megaKnot.p = base.transform.worldToLocalMatrix.MultiplyPoint(points[i]); megaSpline.knots.Add(megaKnot); } megaSpline.closed = closed; AutoCurve(megaSpline); } } public void BuildSpline(int curve, Vector3[] points, bool closed) { if (curve >= 0 && curve < splines.Count) { MegaSpline megaSpline = splines[curve]; megaSpline.knots = new List(points.Length); for (int i = 0; i < points.Length; i++) { MegaKnot megaKnot = new MegaKnot(); megaKnot.p = points[i]; megaSpline.knots.Add(megaKnot); } megaSpline.closed = closed; AutoCurve(megaSpline); } } public void BuildSpline(Vector3[] points, bool closed) { MegaSpline megaSpline = new MegaSpline(); megaSpline.knots = new List(points.Length); for (int i = 0; i < points.Length; i++) { MegaKnot megaKnot = new MegaKnot(); megaKnot.p = points[i]; megaSpline.knots.Add(megaKnot); } megaSpline.closed = closed; splines.Add(megaSpline); AutoCurve(megaSpline); } public void AddToSpline(int curve, Vector3[] points) { if (curve >= 0 && curve < splines.Count) { MegaSpline megaSpline = splines[curve]; int count = megaSpline.knots.Count; for (int i = 0; i < points.Length; i++) { MegaKnot megaKnot = new MegaKnot(); megaKnot.p = points[i]; megaSpline.knots.Add(megaKnot); } AutoCurve(megaSpline, count, count + points.Length); } } public void AddToSpline(int curve, Vector3 point) { if (curve >= 0 && curve < splines.Count) { MegaSpline megaSpline = splines[curve]; MegaKnot megaKnot = new MegaKnot(); megaKnot.p = point; megaSpline.knots.Add(megaKnot); AutoCurve(megaSpline, megaSpline.knots.Count - 2, megaSpline.knots.Count - 1); } } public void AutoCurve(int s) { AutoCurve(splines[s]); } public void AutoCurve(MegaSpline spline) { if (smoothMode == MegaShapeBezComputeMode.Old) { ComputeControlPointsOld(spline); } else { ComputeControlPointsNew(spline); } } public void ComputeControlPointsOld(MegaSpline spline) { if (spline.closed) { Vector3 vector = (spline.knots[spline.knots.Count - 1].p + spline.knots[0].p) * 0.5f; for (int i = 0; i < spline.knots.Count; i++) { int index = (i + 1) % spline.knots.Count; Vector3 vector2 = (spline.knots[index].p + spline.knots[i].p) * 0.5f; Vector3 vector3 = (vector2 + vector) * 0.5f; spline.knots[i].invec = spline.knots[i].p + (vector - vector3) * smoothness; spline.knots[i].outvec = spline.knots[i].p + (vector2 - vector3) * smoothness; vector = vector2; } for (int j = 0; j < spline.knots.Count; j++) { } } else { int num = spline.knots.Count - 1; Vector3 vector4 = spline.knots[0].p - (spline.knots[1].p - spline.knots[0].p) * 0.5f; Vector3 vector5 = spline.knots[num - 1].p + (spline.knots[num].p - spline.knots[num - 1].p) * 0.5f; for (int k = 0; k < spline.knots.Count - 1; k++) { Vector3 vector6 = (spline.knots[k + 1].p + spline.knots[k].p) * 0.5f; Vector3 vector7 = (vector6 + vector4) * 0.5f; spline.knots[k].invec = spline.knots[k].p + (vector4 - vector7) * smoothness; spline.knots[k].outvec = spline.knots[k].p + (vector6 - vector7) * smoothness; vector4 = vector6; } spline.knots[num].invec = spline.knots[num].p - (spline.knots[num].p - vector5) * smoothness; spline.knots[num].outvec = spline.knots[num].p + (spline.knots[num].p - vector5) * smoothness; for (int l = 1; l < spline.knots.Count; l++) { } } spline.CalcLength(); } public void ComputeControlPointsNew(MegaSpline spline) { if (spline.closed) { ComputeControlPointsNewClosed(spline); return; } int num = spline.knots.Count - 1; Vector3[] array = new Vector3[num + 1]; Vector3[] array2 = new Vector3[num + 1]; float[] array3 = new float[num + 1]; float[] array4 = new float[num + 1]; float[] array5 = new float[num + 1]; Vector3[] array6 = new Vector3[num + 1]; array3[0] = 0f; array4[0] = 2f; array5[0] = 1f; array6[0] = spline.knots[0].p + 2f * spline.knots[1].p; for (int i = 1; i < num - 1; i++) { array3[i] = 1f; array4[i] = 4f; array5[i] = 1f; array6[i] = 4f * spline.knots[i].p + 2f * spline.knots[i + 1].p; } array3[num - 1] = 2f; array4[num - 1] = 7f; array5[num - 1] = 0f; array6[num - 1] = 8f * spline.knots[num - 1].p + spline.knots[num].p; for (int j = 1; j < num; j++) { float num2 = array3[j] / array4[j - 1]; array4[j] -= num2 * array5[j - 1]; array6[j] -= num2 * array6[j - 1]; } array[num - 1] = array6[num - 1] / array4[num - 1]; for (int num3 = num - 2; num3 >= 0; num3--) { array[num3] = (array6[num3] - array5[num3] * array[num3 + 1]) / array4[num3]; } for (int k = 0; k < num - 1; k++) { array2[k] = 2f * spline.knots[k + 1].p - array[k + 1]; } array2[num - 1] = 0.5f * (spline.knots[num].p + array[num - 1]); for (int l = 0; l < num; l++) { spline.knots[l].outvec = array[l]; spline.knots[l + 1].invec = array2[l]; } spline.CalcLength(); } public void ComputeControlPointsNewClosed(MegaSpline spline) { int count = spline.knots.Count; Vector3[] array = new Vector3[count + 3]; array[0] = spline.knots[count - 1].p; for (int i = 0; i < count; i++) { array[i + 1] = spline.knots[i].p; } array[count + 1] = spline.knots[0].p; array[count + 2] = spline.knots[1].p; int num = array.Length - 1; Vector3[] array2 = new Vector3[num + 1]; Vector3[] array3 = new Vector3[num + 1]; float[] array4 = new float[num + 1]; float[] array5 = new float[num + 1]; float[] array6 = new float[num + 1]; Vector3[] array7 = new Vector3[num + 1]; array4[0] = 0f; array5[0] = 2f; array6[0] = 1f; array7[0] = array[0] + 2f * array[1]; for (int j = 1; j < num - 1; j++) { array4[j] = 1f; array5[j] = 4f; array6[j] = 1f; array7[j] = 4f * array[j] + 2f * array[j + 1]; } array4[num - 1] = 2f; array5[num - 1] = 7f; array6[num - 1] = 0f; array7[num - 1] = 8f * array[num - 1] + array[num]; for (int k = 1; k < num; k++) { float num2 = array4[k] / array5[k - 1]; array5[k] -= num2 * array6[k - 1]; array7[k] -= num2 * array7[k - 1]; } array2[num - 1] = array7[num - 1] / array5[num - 1]; for (int num3 = num - 2; num3 >= 0; num3--) { array2[num3] = (array7[num3] - array6[num3] * array2[num3 + 1]) / array5[num3]; } for (int l = 0; l < num - 1; l++) { array3[l] = 2f * array[l + 1] - array2[l + 1]; } array3[num - 1] = 0.5f * (array[num] + array2[num - 1]); for (int m = 0; m < array.Length; m++) { } for (int n = 0; n < array2.Length; n++) { } spline.knots[0].invec = array3[0]; for (int num4 = 0; num4 < count - 1; num4++) { spline.knots[num4].outvec = array2[num4 + 1]; spline.knots[num4 + 1].invec = array3[num4 + 1]; } spline.knots[count - 1].outvec = array2[count]; spline.CalcLength(); } public void AutoCurve(MegaSpline spline, int start, int end) { if (spline.closed) { int index = (start - 1) % spline.knots.Count; Vector3 vector = (spline.knots[index].p + spline.knots[start].p) * 0.5f; for (int i = start; i < end; i++) { int index2 = (i + 1) % spline.knots.Count; Vector3 vector2 = (spline.knots[index2].p + spline.knots[i].p) * 0.5f; Vector3 vector3 = (vector2 + vector) * 0.5f; spline.knots[i].invec = spline.knots[i].p + (vector - vector3) * smoothness; spline.knots[i].outvec = spline.knots[i].p + (vector2 - vector3) * smoothness; vector = vector2; } for (int j = start; j < end; j++) { } } else { int index3 = (start - 1) % spline.knots.Count; Vector3 vector4 = (spline.knots[index3].p + spline.knots[start].p) * 0.5f; for (int k = start; k < end - 1; k++) { Vector3 vector5 = (spline.knots[k + 1].p + spline.knots[k].p) * 0.5f; Vector3 vector6 = (vector5 + vector4) * 0.5f; spline.knots[k].invec = spline.knots[k].p + (vector4 - vector6) * smoothness; spline.knots[k].outvec = spline.knots[k].p + (vector5 - vector6) * smoothness; vector4 = vector5; } for (int l = start; l < end; l++) { } } spline.CalcLength(); } public void AutoCurve() { for (int i = 0; i < splines.Count; i++) { MegaSpline spline = splines[i]; AutoCurve(spline); } } private Vector3 SetVectorLength(Vector3 dir, float mag) { return dir * mag; } public void SmoothHandles(MegaSpline spline, int i, float lengthFactor) { if (i >= spline.knots.Count - 1) { return; } int num = i + 1; if (num >= spline.knots.Count) { if (!spline.closed) { return; } num = 0; } Vector3 vector = spline.knots[i].outvec - spline.knots[i].p; Vector3 vector2 = spline.knots[num].invec - spline.knots[num].p; float num2 = Vector3.Magnitude(spline.knots[num].p - spline.knots[i].p); if (vector.magnitude + vector2.magnitude > num2) { if (vector.magnitude > vector2.magnitude) { Vector3 dir = spline.knots[num].invec - spline.knots[i].p; dir = SetVectorLength(dir, vector2.magnitude * lengthFactor); spline.knots[i].outvec = spline.knots[i].p + dir; dir = SetVectorLength(dir, vector.magnitude); spline.knots[i].invec = spline.knots[i].p - dir; dir = spline.knots[num].invec - spline.knots[num].p; dir = SetVectorLength(dir, dir.magnitude * lengthFactor); spline.knots[num].invec = spline.knots[num].p + dir; } if (vector.magnitude < vector2.magnitude) { Vector3 dir2 = spline.knots[i].outvec - spline.knots[num].p; dir2 = SetVectorLength(dir2, vector.magnitude * lengthFactor); spline.knots[num].invec = spline.knots[num].p + dir2; dir2 = SetVectorLength(dir2, vector2.magnitude); spline.knots[num].outvec = spline.knots[i].p - dir2; dir2 = spline.knots[i].outvec - spline.knots[i].p; dir2 = SetVectorLength(dir2, dir2.magnitude * lengthFactor); spline.knots[i].outvec = spline.knots[i].p + dir2; } } } private void BuildCrossSection(float rad) { if (cross == null || cross.Length != tsides) { cross = new Vector3[tsides]; } float num = rotate * ((float)Math.PI / 180f); for (int i = 0; i < tsides; i++) { float f = num + (float)i / (float)tsides * (float)Math.PI * 2f; cross[i] = new Vector3(Mathf.Sin(f) * rad, 0f, Mathf.Cos(f) * rad); } } public void BuildTubeMesh() { BuildMultiStrandMesh(); } private Matrix4x4 GetDeformMat(float percent) { float twist = 0f; Vector3 vector = InterpCurve3D(selcurve, percent, normalizedInterp, ref twist); Vector3 vector2 = InterpCurve3D(selcurve, percent + 0.001f, normalizedInterp, ref twist); Vector3 vector3 = vector2 - vector; Quaternion quaternion = Quaternion.identity; if (vector3 != Vector3.zero) { quaternion = Quaternion.LookRotation(vector3, ropeup); } Quaternion quaternion2 = Quaternion.Euler(0f, 0f, twist); MegaMatrix.SetTR(ref wtm, vector, quaternion * quaternion2); wtm = mat * wtm; return wtm; } public void BuildBoxCrossSection(float width, float height) { if (cross == null || cross.Length != 8) { cross = new Vector3[8]; } float ang = rotate * ((float)Math.PI / 180f); Matrix4x4 identity = Matrix4x4.identity; MegaMatrix.RotateY(ref identity, ang); cross[0] = new Vector3(width * 0.5f, 0f, height * 0.5f); cross[1] = new Vector3(width * 0.5f, 0f, (0f - height) * 0.5f); cross[2] = new Vector3(width * 0.5f, 0f, (0f - height) * 0.5f); cross[3] = new Vector3((0f - width) * 0.5f, 0f, (0f - height) * 0.5f); cross[4] = new Vector3((0f - width) * 0.5f, 0f, (0f - height) * 0.5f); cross[5] = new Vector3((0f - width) * 0.5f, 0f, height * 0.5f); cross[6] = new Vector3((0f - width) * 0.5f, 0f, height * 0.5f); cross[7] = new Vector3(width * 0.5f, 0f, height * 0.5f); for (int i = 0; i < 8; i++) { cross[i] = identity.MultiplyPoint(cross[i]); } float num = 2f * boxwidth + 2f * boxheight; float num2 = 0f; boxuv[0] = 0f; num2 += boxheight; boxuv[1] = num2 / num; boxuv[2] = boxuv[1]; num2 += boxwidth; boxuv[3] = num2 / num; boxuv[4] = boxuv[3]; num2 += boxheight; boxuv[5] = num2 / num; boxuv[6] = boxuv[5]; num2 += boxwidth; boxuv[7] = num2 / num; } public void BuildRibbonCrossSection(float width) { if (cross == null || cross.Length != ribsegs + 1) { cross = new Vector3[ribsegs + 1]; } float ang = rotate * ((float)Math.PI / 180f); for (int i = 0; i <= ribsegs; i++) { float num = (float)i / (float)ribsegs * width - width * 0.5f; switch (raxis) { case MegaAxis.X: cross[i] = new Vector3(num, 0f, 0f); break; case MegaAxis.Y: cross[i] = new Vector3(0f, num, 0f); break; case MegaAxis.Z: cross[i] = new Vector3(0f, 0f, num); break; } } Matrix4x4 identity = Matrix4x4.identity; MegaMatrix.RotateY(ref identity, ang); for (int j = 0; j < cross.Length; j++) { cross[j] = identity.MultiplyPoint(cross[j]); } } private void BuildRibbonMesh() { TubeLength = Mathf.Clamp01(TubeLength); if (TubeLength == 0f || strands < 1) { shapemesh.Clear(); return; } BuildRibbonCrossSection(boxwidth); segments = (int)(splines[0].length * TubeLength / (stepdist * 0.1f)); Twist = TwistPerUnit; float num = startAng * ((float)Math.PI / 180f); int num2 = (segments + 1) * (ribsegs + 1) * strands; int num3 = ribsegs * 2 * segments * strands; float num4 = tradius * 0.5f + offset; if (strands == 1) { num4 = offset; } if (tverts == null || tverts.Length != num2) { tverts = new Vector3[num2]; } if (GenUV && (tuvs == null || tuvs.Length != num2)) { tuvs = new Vector2[num2]; } if (ttris == null || ttris.Length != num3 * 3) { ttris = new int[num3 * 3]; } mat = Matrix4x4.identity; tm = Matrix4x4.identity; switch (axis) { case MegaAxis.X: MegaMatrix.RotateY(ref tm, -(float)Math.PI / 2f); break; case MegaAxis.Y: MegaMatrix.RotateX(ref tm, -(float)Math.PI / 2f); break; } MegaMatrix.SetTrans(ref tm, Pivot); switch (RopeUp) { case MegaAxis.X: ropeup = Vector3.right; break; case MegaAxis.Y: ropeup = Vector3.up; break; case MegaAxis.Z: ropeup = Vector3.forward; break; } int num5 = 0; int num6 = 0; Vector2 zero = Vector2.zero; Vector3 zero2 = Vector3.zero; Vector3 one = Vector3.one; for (int i = 0; i < strands; i++) { float num7 = (float)i / (float)strands * (float)Math.PI * 2f; zero2.x = Mathf.Sin(num7) * num4; zero2.z = Mathf.Cos(num7) * num4; int num8 = num5; num8 = num5; for (int j = 0; j <= segments; j++) { float num9 = TubeStart + (float)j / (float)segments * TubeLength; wtm = GetDeformMat(num9); float num10 = num9 * uvtwist; float num11 = num + (num9 - TubeStart) * Twist * (float)Math.PI * 2f; zero2.x = Mathf.Sin(num7 + num11) * num4; zero2.z = Mathf.Cos(num7 + num11) * num4; one.x = scaleX.Evaluate(num9); float num12 = cross.Length - 1; for (int k = 0; k < cross.Length; k++) { Vector3 vector = cross[k]; vector.x *= one.x; Vector3 point = tm.MultiplyPoint3x4(vector + zero2); tverts[num5] = wtm.MultiplyPoint3x4(point); if (GenUV) { zero.y = (num9 - TubeStart) * splines[0].length * uvtiley + UVOffset.y; zero.x = (float)k / num12 * uvtilex + num10 + UVOffset.x; tuvs[num5++] = zero; } else { num5++; } } } if (!GenUV) { continue; } int num13 = ribsegs + 1; if (flipNormals) { for (int l = 0; l < segments; l++) { for (int m = 0; m < cross.Length - 1; m++) { ttris[num6++] = (l + 1) * num13 + m + num8; ttris[num6++] = l * num13 + m + num8; ttris[num6++] = (l + 1) * num13 + (m + 1) % num13 + num8; ttris[num6++] = (l + 1) * num13 + (m + 1) % num13 + num8; ttris[num6++] = l * num13 + m + num8; ttris[num6++] = l * num13 + (m + 1) % num13 + num8; } } continue; } for (int n = 0; n < segments; n++) { for (int num14 = 0; num14 < cross.Length - 1; num14++) { ttris[num6++] = (n + 1) * num13 + num14 + num8; ttris[num6++] = (n + 1) * num13 + (num14 + 1) % num13 + num8; ttris[num6++] = n * num13 + num14 + num8; ttris[num6++] = (n + 1) * num13 + (num14 + 1) % num13 + num8; ttris[num6++] = n * num13 + (num14 + 1) % num13 + num8; ttris[num6++] = n * num13 + num14 + num8; } } } if (conform) { CalcBounds(tverts); DoConform(tverts); } shapemesh.Clear(); shapemesh.subMeshCount = 1; shapemesh.vertices = tverts; shapemesh.triangles = ttris; if (GenUV) { shapemesh.uv = tuvs; } shapemesh.RecalculateBounds(); shapemesh.RecalculateNormals(); if (CalcTangents) { MegaUtils.BuildTangents(shapemesh); } } private void BuildBoxMesh() { TubeLength = Mathf.Clamp01(TubeLength); if (TubeLength == 0f || strands < 1) { shapemesh.Clear(); return; } BuildBoxCrossSection(boxwidth, boxheight); segments = (int)(splines[0].length * TubeLength / (stepdist * 0.1f)); Twist = TwistPerUnit; float num = startAng * ((float)Math.PI / 180f); int num2 = 9 * (segments + 1) * strands; int num3 = 8 * segments * strands; float num4 = tradius * 0.5f + offset; if (strands == 1) { num4 = offset; } if (cap) { num2 += 8 * strands; num3 += 4 * strands; } if (tverts == null || tverts.Length != num2) { tverts = new Vector3[num2]; } bool flag = false; if (GenUV && (tuvs == null || tuvs.Length != num2)) { tuvs = new Vector2[num2]; flag = true; } if (ttris == null || ttris.Length != num3 * 3) { ttris = new int[num3 * 3]; } mat = Matrix4x4.identity; tm = Matrix4x4.identity; switch (axis) { case MegaAxis.X: MegaMatrix.RotateY(ref tm, -(float)Math.PI / 2f); break; case MegaAxis.Y: MegaMatrix.RotateX(ref tm, -(float)Math.PI / 2f); break; } switch (RopeUp) { case MegaAxis.X: ropeup = Vector3.right; break; case MegaAxis.Y: ropeup = Vector3.up; break; case MegaAxis.Z: ropeup = Vector3.forward; break; } MegaMatrix.SetTrans(ref tm, Pivot); int num5 = 0; int num6 = 0; Vector2 zero = Vector2.zero; Vector3 zero2 = Vector3.zero; Vector3 one = Vector3.one; for (int i = 0; i < strands; i++) { float num7 = (float)i / (float)strands * (float)Math.PI * 2f; zero2.x = Mathf.Sin(num7) * num4; zero2.z = Mathf.Cos(num7) * num4; int num8 = num5; if (cap) { float tubeStart = TubeStart; wtm = GetDeformMat(tubeStart); float num9 = num + 0f * Twist * (float)Math.PI * 2f; zero2.x = Mathf.Sin(num7 + num9) * num4; zero2.z = Mathf.Cos(num7 + num9) * num4; one.x = scaleX.Evaluate(tubeStart); if (unlinkScale) { one.z = scaleY.Evaluate(tubeStart); } else { one.z = one.x; } for (int j = 0; j < 4; j++) { Vector3 vector = cross[j * 2]; vector.x *= one.x; vector.z *= one.z; Vector3 point = tm.MultiplyPoint3x4(vector + zero2); tverts[num5] = wtm.MultiplyPoint3x4(point); if (flag) { zero.y = 0f; zero.x = 0f; tuvs[num5++] = zero; } else { num5++; } } if (flipNormals) { ttris[num6++] = num8; ttris[num6++] = num8 + 1; ttris[num6++] = num8 + 2; ttris[num6++] = num8; ttris[num6++] = num8 + 2; ttris[num6++] = num8 + 3; } else { ttris[num6++] = num8; ttris[num6++] = num8 + 2; ttris[num6++] = num8 + 1; ttris[num6++] = num8; ttris[num6++] = num8 + 3; ttris[num6++] = num8 + 2; } num8 = num5; tubeStart = TubeStart + TubeLength; wtm = GetDeformMat(tubeStart); num9 = num + TubeLength * Twist * (float)Math.PI * 2f; zero2.x = Mathf.Sin(num7 + num9) * num4; zero2.z = Mathf.Cos(num7 + num9) * num4; one.x = scaleX.Evaluate(tubeStart); if (unlinkScale) { one.z = scaleY.Evaluate(tubeStart); } else { one.z = one.x; } for (int k = 0; k < 4; k++) { Vector3 vector2 = cross[k * 2]; vector2.x *= one.x; vector2.z *= one.z; Vector3 point2 = tm.MultiplyPoint3x4(vector2 + zero2); tverts[num5] = wtm.MultiplyPoint3x4(point2); if (GenUV) { zero.y = 0f; zero.x = 0f; tuvs[num5++] = zero; } else { num5++; } } if (flipNormals) { ttris[num6++] = num8; ttris[num6++] = num8 + 2; ttris[num6++] = num8 + 1; ttris[num6++] = num8; ttris[num6++] = num8 + 3; ttris[num6++] = num8 + 2; } else { ttris[num6++] = num8; ttris[num6++] = num8 + 1; ttris[num6++] = num8 + 2; ttris[num6++] = num8; ttris[num6++] = num8 + 2; ttris[num6++] = num8 + 3; } } num8 = num5; for (int l = 0; l <= segments; l++) { float num10 = TubeStart + (float)l / (float)segments * TubeLength; wtm = GetDeformMat(num10); float num11 = num10 * uvtwist; float num12 = num + (num10 - TubeStart) * Twist * (float)Math.PI * 2f; zero2.x = Mathf.Sin(num7 + num12) * num4; zero2.z = Mathf.Cos(num7 + num12) * num4; one.x = scaleX.Evaluate(num10); if (unlinkScale) { one.z = scaleY.Evaluate(num10); } else { one.z = one.x; } for (int m = 0; m < cross.Length; m++) { Vector3 vector3 = cross[m]; vector3.x *= one.x; vector3.z *= one.z; Vector3 point3 = tm.MultiplyPoint3x4(vector3 + zero2); tverts[num5] = wtm.MultiplyPoint3x4(point3); if (GenUV) { zero.y = (num10 - TubeStart) * splines[0].length * uvtiley + UVOffset.y; zero.x = boxuv[m] * uvtilex + num11 + UVOffset.x; tuvs[num5++] = zero; } else { num5++; } } } if (!GenUV) { continue; } int num13 = 8; if (flipNormals) { for (int n = 0; n < segments; n++) { for (int num14 = 0; num14 < 4; num14++) { int num15 = num14 * 2; ttris[num6++] = n * num13 + num15 + num8; ttris[num6++] = (n + 1) * num13 + num15 + num8; ttris[num6++] = (n + 1) * num13 + (num15 + 1) + num8; ttris[num6++] = n * num13 + num15 + num8; ttris[num6++] = (n + 1) * num13 + (num15 + 1) + num8; ttris[num6++] = n * num13 + (num15 + 1) + num8; } } continue; } for (int num16 = 0; num16 < segments; num16++) { for (int num17 = 0; num17 < 4; num17++) { int num18 = num17 * 2; ttris[num6++] = num16 * num13 + num18 + num8; ttris[num6++] = (num16 + 1) * num13 + (num18 + 1) + num8; ttris[num6++] = (num16 + 1) * num13 + num18 + num8; ttris[num6++] = num16 * num13 + num18 + num8; ttris[num6++] = num16 * num13 + (num18 + 1) + num8; ttris[num6++] = (num16 + 1) * num13 + (num18 + 1) + num8; } } } if (conform) { CalcBounds(tverts); DoConform(tverts); } shapemesh.Clear(); shapemesh.subMeshCount = 1; shapemesh.vertices = tverts; shapemesh.triangles = ttris; if (GenUV) { shapemesh.uv = tuvs; } shapemesh.RecalculateBounds(); shapemesh.RecalculateNormals(); if (CalcTangents) { MegaUtils.BuildTangents(shapemesh); } } private void BuildMultiStrandMesh() { TubeLength = Mathf.Clamp01(TubeLength); if (TubeLength == 0f || strands < 1) { shapemesh.Clear(); return; } Twist = TwistPerUnit; segments = (int)(splines[selcurve].length * TubeLength / (stepdist * 0.1f)); float num = startAng * ((float)Math.PI / 180f); float num2 = tradius * 0.5f + offset; if (strands == 1) { num2 = offset; } float rad = tradius * 0.5f + strandRadius; BuildCrossSection(rad); int num3 = (segments + 1) * (tsides + 1) * strands; int num4 = tsides * 2 * segments * strands; if (cap) { num3 += (tsides + 1) * 2 * strands; num4 += tsides * 2 * strands; } if (tverts == null || tverts.Length != num3) { tverts = new Vector3[num3]; } bool flag = false; if (GenUV && (tuvs == null || tuvs.Length != num3)) { tuvs = new Vector2[num3]; flag = true; } if (ttris == null || ttris.Length != num4 * 3) { ttris = new int[num4 * 3]; } mat = Matrix4x4.identity; tm = Matrix4x4.identity; switch (axis) { case MegaAxis.X: MegaMatrix.RotateY(ref tm, -(float)Math.PI / 2f); break; case MegaAxis.Y: MegaMatrix.RotateX(ref tm, -(float)Math.PI / 2f); break; } MegaMatrix.SetTrans(ref tm, Pivot); switch (RopeUp) { case MegaAxis.X: ropeup = Vector3.right; break; case MegaAxis.Y: ropeup = Vector3.up; break; case MegaAxis.Z: ropeup = Vector3.forward; break; } int num5 = 0; int num6 = 0; Vector2 zero = Vector2.zero; Vector3 zero2 = Vector3.zero; Vector3 one = Vector3.one; for (int i = 0; i < strands; i++) { float num7 = (float)i / (float)strands * (float)Math.PI * 2f; zero2.x = Mathf.Sin(num7) * num2; zero2.z = Mathf.Cos(num7) * num2; int num8 = num5; if (cap) { float tubeStart = TubeStart; wtm = GetDeformMat(tubeStart); float num9 = num + (tubeStart - TubeStart) * Twist * (float)Math.PI * 2f; zero2.x = Mathf.Sin(num7 + num9) * num2; zero2.z = Mathf.Cos(num7 + num9) * num2; one.x = scaleX.Evaluate(tubeStart); if (unlinkScale) { one.z = scaleY.Evaluate(tubeStart); } else { one.z = one.x; } for (int j = 0; j <= cross.Length; j++) { Vector3 vector = cross[j % cross.Length]; vector.x *= one.x; vector.z *= one.z; Vector3 point = tm.MultiplyPoint3x4(vector + zero2); tverts[num5] = wtm.MultiplyPoint3x4(point); if (flag) { zero.y = 0f; zero.x = 0f; tuvs[num5++] = zero; } else { num5++; } } if (GenUV) { if (flipNormals) { for (int k = 1; k < tsides; k++) { ttris[num6++] = num8; ttris[num6++] = num8 + k; ttris[num6++] = num8 + k + 1; } } else { for (int l = 1; l < tsides; l++) { ttris[num6++] = num8; ttris[num6++] = num8 + l + 1; ttris[num6++] = num8 + l; } } } num8 = num5; tubeStart = TubeStart + TubeLength; wtm = GetDeformMat(tubeStart); num9 = num + (tubeStart - TubeStart) * Twist * (float)Math.PI * 2f; zero2.x = Mathf.Sin(num7 + num9) * num2; zero2.z = Mathf.Cos(num7 + num9) * num2; one.x = scaleX.Evaluate(tubeStart); if (unlinkScale) { one.z = scaleY.Evaluate(tubeStart); } else { one.z = one.x; } for (int m = 0; m <= cross.Length; m++) { Vector3 vector2 = cross[m % cross.Length]; vector2.x *= one.x; vector2.z *= one.z; Vector3 point2 = tm.MultiplyPoint3x4(vector2 + zero2); tverts[num5] = wtm.MultiplyPoint3x4(point2); if (GenUV) { zero.y = 0f; zero.x = 0f; tuvs[num5++] = zero; } else { num5++; } } if (GenUV) { if (flipNormals) { for (int n = 1; n < tsides; n++) { ttris[num6++] = num8; ttris[num6++] = num8 + n + 1; ttris[num6++] = num8 + n; } } else { for (int num10 = 1; num10 < tsides; num10++) { ttris[num6++] = num8; ttris[num6++] = num8 + num10; ttris[num6++] = num8 + num10 + 1; } } } } num8 = num5; for (int num11 = 0; num11 <= segments; num11++) { float num12 = TubeStart + (float)num11 / (float)segments * TubeLength; one.x = scaleX.Evaluate(num12); if (unlinkScale) { one.z = scaleY.Evaluate(num12); } else { one.z = one.x; } wtm = GetDeformMat(num12); float num13 = num12 * uvtwist; float num14 = num + (num12 - TubeStart) * Twist * (float)Math.PI * 2f; zero2.x = Mathf.Sin(num7 + num14) * num2; zero2.z = Mathf.Cos(num7 + num14) * num2; for (int num15 = 0; num15 <= cross.Length; num15++) { Vector3 vector3 = cross[num15 % cross.Length]; vector3.x *= one.x; vector3.z *= one.z; Vector3 point3 = tm.MultiplyPoint3x4(vector3 + zero2); tverts[num5] = wtm.MultiplyPoint3x4(point3); if (GenUV) { zero.y = (num12 - TubeStart) * splines[0].length * uvtiley + UVOffset.y; zero.x = (float)num15 / (float)cross.Length * uvtilex + num13 + UVOffset.x; tuvs[num5++] = zero; } else { num5++; } } } if (!GenUV) { continue; } int num16 = tsides + 1; if (flipNormals) { for (int num17 = 0; num17 < segments; num17++) { for (int num18 = 0; num18 < cross.Length; num18++) { ttris[num6++] = num17 * num16 + num18 + num8; ttris[num6++] = (num17 + 1) * num16 + num18 + num8; ttris[num6++] = (num17 + 1) * num16 + (num18 + 1) % num16 + num8; ttris[num6++] = num17 * num16 + num18 + num8; ttris[num6++] = (num17 + 1) * num16 + (num18 + 1) % num16 + num8; ttris[num6++] = num17 * num16 + (num18 + 1) % num16 + num8; } } continue; } for (int num19 = 0; num19 < segments; num19++) { for (int num20 = 0; num20 < cross.Length; num20++) { ttris[num6++] = num19 * num16 + num20 + num8; ttris[num6++] = (num19 + 1) * num16 + (num20 + 1) % num16 + num8; ttris[num6++] = (num19 + 1) * num16 + num20 + num8; ttris[num6++] = num19 * num16 + num20 + num8; ttris[num6++] = num19 * num16 + (num20 + 1) % num16 + num8; ttris[num6++] = (num19 + 1) * num16 + (num20 + 1) % num16 + num8; } } } if (conform) { CalcBounds(tverts); DoConform(tverts); } shapemesh.Clear(); shapemesh.subMeshCount = 1; shapemesh.vertices = tverts; shapemesh.triangles = ttris; if (GenUV) { shapemesh.uv = tuvs; } shapemesh.RecalculateBounds(); shapemesh.RecalculateNormals(); if (CalcTangents) { MegaUtils.BuildTangents(shapemesh); } } public void ClearMesh() { MeshFilter component = base.gameObject.GetComponent(); if (component != null) { component.sharedMesh = null; shapemesh = null; } } public void SetMats() { MeshRenderer meshRenderer = base.gameObject.GetComponent(); if (meshRenderer == null) { meshRenderer = base.gameObject.AddComponent(); } if (meshType == MeshShapeType.Fill) { meshRenderer.sharedMaterials = new Material[3] { mat1, mat2, mat3 }; } else { meshRenderer.sharedMaterials = new Material[1] { mat1 }; } } public void BuildMesh() { if (!makeMesh || splines == null || splines.Count == 0) { return; } if (shapemesh == null) { MeshFilter meshFilter = base.gameObject.GetComponent(); if (meshFilter == null) { meshFilter = base.gameObject.AddComponent(); } meshFilter.sharedMesh = new Mesh(); MeshRenderer component = base.gameObject.GetComponent(); if (component == null) { component = base.gameObject.AddComponent(); } SetMats(); shapemesh = meshFilter.sharedMesh; } if (meshType == MeshShapeType.Tube) { BuildTubeMesh(); return; } if (meshType == MeshShapeType.Box) { BuildBoxMesh(); return; } if (meshType == MeshShapeType.Ribbon) { BuildRibbonMesh(); return; } float num = stepdist * 0.1f; if (splines[selcurve].length / num > 1500f) { num = splines[selcurve].length / 1500f; } Vector3 size = Vector3.zero; verts.Clear(); uvs.Clear(); tris.Clear(); tris1.Clear(); tris2.Clear(); tris = MegaTriangulator.Triangulate(this, splines[selcurve], num, ref verts, ref uvs, ref tris, Pivot, ref size); if (axis != MegaAxis.Y) { for (int i = 0; i < tris.Count; i += 3) { int value = tris[i]; tris[i] = tris[i + 2]; tris[i + 2] = value; } } int count = verts.Count; int count2 = tris.Count; if (Height < 0f) { Height = 0f; } float height = Height; Matrix4x4 matrix4x = Matrix4x4.TRS(Vector3.zero, Quaternion.Euler(UVRotate.x, UVRotate.y, 0f), new Vector3(UVScale.x, 1f, UVScale.y)); if (GenUV) { uvs.Clear(); Vector2 zero = Vector2.zero; Vector3 point = Vector3.zero; int index = 0; int index2 = 2; switch (axis) { case MegaAxis.X: index = 1; break; case MegaAxis.Z: index2 = 1; break; } for (int j = 0; j < verts.Count; j++) { point.x = verts[j][index]; point.z = verts[j][index2]; if (!PhysUV) { point.x /= size[index]; point.z /= size[index2]; } point = matrix4x.MultiplyPoint3x4(point); zero.x = point.x + UVOffset.x; zero.y = point.z + UVOffset.y; uvs.Add(zero); } } if (DoubleSided && height != 0f) { for (int k = 0; k < count; k++) { Vector3 item = verts[k]; if (UseHeightCurve) { float num2 = MegaTriangulator.m_points[k].z / splines[selcurve].length; item[(int)axis] -= height * heightCrv.Evaluate(num2 + heightOff); } else { item[(int)axis] -= height; } verts.Add(item); uvs.Add(uvs[k]); } for (int num3 = count2 - 1; num3 >= 0; num3--) { tris1.Add(tris[num3] + count); } } if (height != 0f) { int count3 = verts.Count; Vector3 vector = Vector3.zero; Vector2 zero2 = Vector2.zero; matrix4x = Matrix4x4.TRS(Vector3.zero, Quaternion.Euler(UVRotate1.x, UVRotate1.y, 0f), new Vector3(UVScale1.x, 1f, UVScale1.y)); for (int l = 0; l < MegaTriangulator.m_points.Count; l++) { vector = verts[l]; verts.Add(vector); vector.x = MegaTriangulator.m_points[l].z; if (!PhysUV) { vector.x /= size.x; } vector.y = 0f; vector.z = 0f; vector = matrix4x.MultiplyPoint3x4(vector); zero2.x = vector.x + UVOffset1.x; zero2.y = vector.z + UVOffset1.y; uvs.Add(zero2); } vector = verts[0]; verts.Add(vector); zero2.x = splines[selcurve].length * UVScale1.x + UVOffset1.x; if (!PhysUV) { zero2.x /= size.x; } zero2.y = UVOffset1.y; uvs.Add(zero2); float num4 = 1f; for (int m = 0; m < MegaTriangulator.m_points.Count; m++) { float num5 = MegaTriangulator.m_points[m].z / splines[selcurve].length; vector = verts[m]; if (UseHeightCurve) { num4 = heightCrv.Evaluate(num5 + heightOff); } vector[(int)axis] -= height * num4; verts.Add(vector); vector.x = MegaTriangulator.m_points[m].z; vector.z = vector.y; vector.y = 0f; if (!PhysUV) { vector.x /= size.x; vector.z /= height * num4; } vector = matrix4x.MultiplyPoint3x4(vector); zero2.x = vector.x + UVOffset1.x; zero2.y = vector.z + UVOffset1.y; uvs.Add(zero2); } vector = verts[0]; if (UseHeightCurve) { num4 = heightCrv.Evaluate(heightOff); } vector[(int)axis] -= height * num4; verts.Add(vector); vector.x = MegaTriangulator.m_points[0].z; vector.z = vector.y; vector.y = 0f; if (!PhysUV) { vector.x /= size.x; vector.z /= height * num4; } vector = matrix4x.MultiplyPoint3x4(vector); zero2.x = vector.x + UVOffset1.x; zero2.y = vector.z + UVOffset1.y; uvs.Add(zero2); int num6 = MegaTriangulator.m_points.Count + 1; int num7 = 0; if (splines[selcurve].reverse) { for (num7 = 0; num7 < MegaTriangulator.m_points.Count; num7++) { tris2.Add(num7 + count3 + 1); tris2.Add(num7 + count3 + num6); tris2.Add(num7 + count3); tris2.Add(num7 + count3 + num6 + 1); tris2.Add(num7 + count3 + num6); tris2.Add(num7 + count3 + 1); } } else { for (num7 = 0; num7 < MegaTriangulator.m_points.Count; num7++) { tris2.Add(num7 + count3); tris2.Add(num7 + count3 + num6); tris2.Add(num7 + count3 + 1); tris2.Add(num7 + count3 + 1); tris2.Add(num7 + count3 + num6); tris2.Add(num7 + count3 + num6 + 1); } } } Vector3[] vertices = verts.ToArray(); if (conform) { CalcBounds(vertices); DoConform(vertices); } shapemesh.Clear(); shapemesh.vertices = vertices; shapemesh.uv = uvs.ToArray(); shapemesh.subMeshCount = 3; shapemesh.SetTriangles(tris.ToArray(), 0); if (tris1.Count == 0) { shapemesh.SetTriangles(empty, 1); } else { shapemesh.SetTriangles(tris1.ToArray(), 1); } if (tris2.Count == 0) { shapemesh.SetTriangles(empty, 2); } else { shapemesh.SetTriangles(tris2.ToArray(), 2); } shapemesh.RecalculateNormals(); shapemesh.RecalculateBounds(); if (CalcTangents) { MegaUtils.BuildTangents(shapemesh); } } public static float CurveLength(MegaSpline spline, int knot, float v1, float v2, float size) { float num = 0f; if (size == 0f) { Vector3 vector = spline.InterpBezier3D(knot, v1); float num2 = (v2 - v1) / (float)CURVELENGTHSTEPS; int num3 = 1; float num4 = num2; while (num3 < CURVELENGTHSTEPS) { Vector3 vector2 = spline.InterpBezier3D(knot, v1 + num4); num += Vector3.Magnitude(vector2 - vector); vector = vector2; num3++; num4 += num2; } return num + Vector3.Magnitude(spline.InterpBezier3D(knot, v2) - vector); } int count = spline.knots.Count; int num5 = (knot + count - 1) % count; int num6 = (knot + 1) % count; float num7 = v1 - 0.01f; int knot2 = knot; if (num7 < 0f) { if (spline.closed) { num7 += 1f; knot2 = num5; } else { num7 = 0f; } } float a = v1 + 0.01f; Vector3 vector3 = Vector3.Normalize(spline.InterpBezier3D(knot, a) - spline.InterpBezier3D(knot2, num7)); vector3.y = 0f; Vector3 vector4 = new Vector3(vector3.z * size, 0f, (0f - vector3.x) * size); Vector3 vector5 = spline.InterpBezier3D(knot, v1) + vector4; float num8 = (v2 - v1) / (float)CURVELENGTHSTEPS; int num9 = 1; float num10 = num8; while (num9 < CURVELENGTHSTEPS) { num7 = v1 + num10 - 0.01f; a = v1 + num10 + 0.01f; vector3 = Vector3.Normalize(spline.InterpBezier3D(knot, a) - spline.InterpBezier3D(knot, num7)); vector3.y = 0f; vector4 = new Vector3(vector3.z * size, 0f, (0f - vector3.x) * size); Vector3 vector6 = spline.InterpBezier3D(knot, v1 + num10) + vector4; num += Vector3.Magnitude(vector6 - vector5); vector5 = vector6; num9++; num10 += num8; } num7 = v2 - 0.01f; int knot3 = knot; a = v2 + 0.01f; if (a > 1f) { if (spline.closed) { a -= 1f; knot3 = num6; } else { a = 1f; } } vector3 = Vector3.Normalize(spline.InterpBezier3D(knot3, a) - spline.InterpBezier3D(knot, num7)); vector3.y = 0f; vector4 = new Vector3(vector3.z * size, 0f, (0f - vector3.x) * size); return num + Vector3.Magnitude(spline.InterpBezier3D(knot, v2) + vector4 - vector5); } public void OutlineSpline(MegaShape shape, int poly, float size, bool centered) { MegaSpline inSpline = shape.splines[poly]; MegaSpline megaSpline = new MegaSpline(); OutlineSpline(inSpline, megaSpline, size, centered); shape.splines.Add(megaSpline); megaSpline.CalcLength(); } public void OutlineSpline(MegaSpline inSpline, MegaSpline outSpline, float size, bool centered) { float num = ((!centered) ? 0f : (size / 2f)); int count = inSpline.knots.Count; outSpline.knots.Clear(); if (inSpline.closed) { for (int i = 0; i < count; i++) { int knot = (i + count - 1) % count; float num2 = CurveLength(inSpline, knot, 0.5f, 1f, 0f); float num3 = CurveLength(inSpline, i, 0f, 0.5f, 0f); Vector3 p = inSpline.knots[i].p; Vector3 vector = Vector3.Normalize(inSpline.InterpBezier3D(knot, 0.99f) - p); Vector3 vector2 = Vector3.Normalize(inSpline.InterpBezier3D(i, 0.01f) - p); Vector3 vector3 = Vector3.Normalize(vector2 - vector); vector3.y = 0f; float num4 = Vector3.Dot(vector, vector2); float f = ((!(num4 >= -0.9999939f)) ? ((float)Math.PI / 2f) : ((0f - Mathf.Acos(num4)) / 2f)); float num5 = num / Mathf.Tan(f); float num6 = ((!(num < 0f)) ? 1f : (-1f)); float num7 = Mathf.Sqrt(num5 * num5 + num * num) * num6; Vector3 vector4 = new Vector3(vector3.z * num7, 0f, (0f - vector3.x) * num7); float num8 = CurveLength(inSpline, knot, 0.5f, 1f, num); float num9 = CurveLength(inSpline, i, 0f, 0.5f, num); Vector3 vector5 = p + vector4; float num10 = num8 / num2; float num11 = num9 / num3; outSpline.AddKnot(vector5, vector5 + (inSpline.knots[i].invec - p) * num10, vector5 + (inSpline.knots[i].outvec - p) * num11); } outSpline.closed = true; return; } for (int i = 0; i < count; i++) { Vector3 p2 = inSpline.knots[i].p; float num12 = ((i != 0) ? CurveLength(inSpline, i - 1, 0.5f, 1f, 0f) : 1f); float num13 = ((i != count - 1) ? CurveLength(inSpline, i, 0f, 0.5f, 0f) : 1f); float num14 = 0f; Vector3 vector6; if (i == 0) { vector6 = Vector3.Normalize(inSpline.InterpBezier3D(i, 0.01f) - p2); num14 = num; } else if (i == count - 1) { vector6 = Vector3.Normalize(p2 - inSpline.InterpBezier3D(i - 1, 0.99f)); num14 = num; } else { Vector3 vector7 = Vector3.Normalize(inSpline.InterpBezier3D(i - 1, 0.99f) - p2); Vector3 vector8 = Vector3.Normalize(inSpline.InterpBezier3D(i, 0.01f) - p2); vector6 = Vector3.Normalize(vector8 - vector7); float num15 = Vector3.Dot(vector7, vector8); if (num15 >= -0.9999939f) { float f2 = (0f - Mathf.Acos(num15)) / 2f; float num16 = num / Mathf.Tan(f2); float num17 = ((!(num < 0f)) ? 1f : (-1f)); num14 = Mathf.Sqrt(num16 * num16 + num * num) * num17; } else { num14 = num; } } vector6.y = 0f; Vector3 vector9 = new Vector3(vector6.z * num14, 0f, (0f - vector6.x) * num14); float num18 = ((i != 0) ? CurveLength(inSpline, i - 1, 0.5f, 1f, num) : 1f); float num19 = ((i != count - 1) ? CurveLength(inSpline, i, 0f, 0.5f, num) : 1f); float num20 = num18 / num12; float num21 = num19 / num13; Vector3 vector10 = p2 + vector9; outSpline.AddKnot(vector10, vector10 + (inSpline.knots[i].invec - p2) * num20, vector10 + (inSpline.knots[i].outvec - p2) * num21); } outSpline.closed = false; } public void SetTarget(GameObject targ) { target = targ; if ((bool)target) { conformCollider = target.GetComponent(); } } private void CalcBounds(Vector3[] verts) { minz = verts[0].y; for (int i = 1; i < verts.Length; i++) { if (verts[i].y < minz) { minz = verts[i].y; } } } public void InitConform(Vector3[] verts) { if (offsets == null || offsets.Length != verts.Length) { offsets = new float[verts.Length]; last = new float[verts.Length]; for (int i = 0; i < verts.Length; i++) { offsets[i] = verts[i].y - minz; } } if ((bool)target) { conformCollider = target.GetComponent(); } } private void DoConform(Vector3[] verts) { InitConform(verts); if (!target || !conformCollider) { return; } Matrix4x4 localToWorldMatrix = base.transform.localToWorldMatrix; Matrix4x4 matrix4x = localToWorldMatrix; Matrix4x4 inverse = matrix4x.inverse; Ray ray = default(Ray); float num = conformAmount; for (int i = 0; i < verts.Length; i++) { Vector3 origin = matrix4x.MultiplyPoint(verts[i]); origin.y += raystartoff; ray.origin = origin; ray.direction = Vector3.down; RaycastHit hitInfo; if (conformCollider.Raycast(ray, out hitInfo, raydist)) { Vector3 vector = inverse.MultiplyPoint(hitInfo.point); verts[i].y = Mathf.Lerp(verts[i].y, vector.y + offsets[i] + conformOffset, num); last[i] = verts[i].y; } else { Vector3 origin2 = ray.origin; origin2.y -= raydist; verts[i].y = last[i]; } } } private void ConformTarget() { } }