using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
using System.Linq;
public enum BezierControlPointMode {
Aligned, //Handles are allowed to have different magnitudes
Mirrored //Handles both have the same magnitude
}
[Serializable]
public class ControlPoint {
[SerializeField]
private Vector3 anchor;
[SerializeField]
private Vector3[] handles; //handles[0] is the handle before the anchor, handles[1] is the handle after the anchor
[SerializeField]
private Vector3 up; //Used to store rotations along the splines axis
[SerializeField]
private BezierControlPointMode mode;
public int connectedIndex; //Used when ControlPoint is part of a junction. Default value = -1
//Constructor
public ControlPoint() {
anchor = Vector3.zero;
handles = new Vector3[2] {
-.5f * Vector3.forward,
.5f * Vector3.forward
};
up = Vector3.up;
mode = BezierControlPointMode.Mirrored;
connectedIndex = -1;
}
//Constructor with position and direction
public ControlPoint(Vector3 position, Vector3 forward) {
anchor = position;
handles = new Vector3[2] {
-.5f * forward,
.5f * forward
};
up = Vector3.up;
mode = BezierControlPointMode.Mirrored;
connectedIndex = -1;
}
public Vector3 GetAnchorPosition () {
return anchor;
}
public Vector3 GetHandlePosition(int index) {
return anchor + GetRelativeHandlePosition(index);
}
public Vector3 GetRelativeHandlePosition(int index) {
return handles[index];
}
public float GetHandleMagnitude (int index) {
return handles[index].magnitude;
}
public Quaternion GetRotation() {
return Quaternion.LookRotation(handles[1], up);
}
//Euler angles are calculated using the Spline.GetEulerAngles method.
public Vector3 GetEulerAngles() {
return Spline.GetEulerAngles(up, handles[1]);
}
public BezierControlPointMode GetMode() {
return mode;
}
public void SetAnchorPosition(Vector3 position) {
anchor = position;
}
public void SetHandlePosition(int index, Vector3 position) {
SetRelativeHandlePosition(index, position - anchor);
}
//Updates both handle positions based on the new position of a single handle
public void SetRelativeHandlePosition (int index, Vector3 position) {
handles[index] = position;
switch (mode) {
case BezierControlPointMode.Aligned:
Vector3 direction = -position;
handles[1 - index] = direction.normalized * handles[1 - index].magnitude;
break;
case BezierControlPointMode.Mirrored:
handles[1 - index] = -position;
break;
}
}
//Set the magnitude of a handle (or both handles when type is mirrored)
public void SetHandleMagnitude (int index, float magnitude) {
if (magnitude < .01f)
magnitude = .01f;
handles[index] = handles[index].normalized * magnitude;
if (mode == BezierControlPointMode.Mirrored)
handles[1 - index] = -handles[index];
}
public void Scale (Vector3 scale) {
handles[0].Scale(scale);
handles[1].Scale(scale);
}
public void SetMode (BezierControlPointMode newMode) {
mode = newMode;
SetRelativeHandlePosition(1, GetRelativeHandlePosition(1));
}
public void SetRotation (Quaternion rotation) {
handles[0] = rotation * Vector3.back * handles[0].magnitude;
handles[1] = rotation* Vector3.forward * handles[1].magnitude;
up = rotation * Vector3.up;
}
}