209 lines
3.9 KiB
C#
209 lines
3.9 KiB
C#
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];
|
|
}
|
|
}
|