using System; using UnityEngine; [RequireComponent(typeof(MtreeComponent))] public class MtreeBezier : MonoBehaviour { [SerializeField] public Vector3[] points; [SerializeField] public Vector3[] s_positions = new Vector3[0]; [SerializeField] public Vector3[] s_directions = new Vector3[0]; [SerializeField] public bool MTreeDoBezier; [SerializeField] public bool MTreeLeafDirection; [SerializeField] private BezierControlPointMode[] modes; [SerializeField] public Vector3 s_branchdirection; public int ControlPointCount { get { return points.Length; } } public int CurveCount { get { return (points.Length - 1) / 3; } } public Vector3 GetControlPoint(int index) { return points[index]; } public void SetControlPoint(int index, Vector3 point) { if (index % 3 == 0) { Vector3 vector = point - points[index]; if (index > 0) { points[index - 1] += vector; } if (index + 1 < points.Length) { points[index + 1] += vector; } } points[index] = point; EnforceMode(index); if (points.Length > 3 && MTreeDoBezier) { s_positions = new Vector3[0]; s_directions = new Vector3[0]; } } public BezierControlPointMode GetControlPointMode(int index) { return modes[(index + 1) / 3]; } public void SetControlPointMode(int index, BezierControlPointMode mode) { int num = (index + 1) / 3; modes[num] = mode; if (num == modes.Length - 1) { modes[0] = mode; } EnforceMode(index); } private void EnforceMode(int index) { int num = (index + 1) / 3; BezierControlPointMode bezierControlPointMode = modes[num]; if (bezierControlPointMode == BezierControlPointMode.Free || num == 0 || num == modes.Length - 1) { return; } int num2 = num * 3; int num3; int num4; if (index <= num2) { num3 = num2 - 1; if (num3 < 0) { num3 = points.Length - 2; } num4 = num2 + 1; if (num4 >= points.Length) { num4 = 1; } } else { num3 = num2 + 1; if (num3 >= points.Length) { num3 = 1; } num4 = num2 - 1; if (num4 < 0) { num4 = points.Length - 2; } } Vector3 vector = points[num2]; Vector3 vector2 = vector - points[num3]; if (bezierControlPointMode == BezierControlPointMode.Aligned) { vector2 = vector2.normalized * Vector3.Distance(vector, points[num4]); } points[num4] = vector + vector2; } public Vector3 GetPoint(float t) { int num; if (t >= 1f) { t = 1f; num = points.Length - 4; } else { t = Mathf.Clamp01(t) * (float)CurveCount; num = (int)t; t -= (float)num; num *= 3; } return base.transform.TransformPoint(Bezier.GetPoint(points[num], points[num + 1], points[num + 2], points[num + 3], t)); } public Vector3 GetVelocity(float t) { int num; if (t >= 1f) { t = 1f; num = points.Length - 4; } else { t = Mathf.Clamp01(t) * (float)CurveCount; num = (int)t; t -= (float)num; num *= 3; } return base.transform.TransformPoint(Bezier.GetFirstDerivative(points[num], points[num + 1], points[num + 2], points[num + 3], t)) - base.transform.position; } public Vector3 GetDirection(float t) { return GetVelocity(t).normalized; } public void AddCurve() { Vector3 vector = points[points.Length - 1]; Array.Resize(ref points, points.Length + 3); vector.y += 1f; points[points.Length - 3] = vector; vector.y += 1f; points[points.Length - 2] = vector; vector.y += 1f; points[points.Length - 1] = vector; Array.Resize(ref modes, modes.Length + 1); modes[modes.Length - 1] = modes[modes.Length - 2]; EnforceMode(points.Length - 4); } public float GetLength() { return Bezier.GetTotalLenght(points); } public void Reset() { points = new Vector3[4] { new Vector3(0f, 0f, 0f), new Vector3(0f, 2f, 0f), new Vector3(0f, 6f, 0f), new Vector3(0f, 8f, 0f) }; modes = new BezierControlPointMode[2]; s_positions = new Vector3[0]; s_directions = new Vector3[0]; } }