-
Notifications
You must be signed in to change notification settings - Fork 25
Expand file tree
/
Copy pathCurve3D.cs
More file actions
128 lines (108 loc) · 2.67 KB
/
Curve3D.cs
File metadata and controls
128 lines (108 loc) · 2.67 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
using System;
using System.Collections;
using UnityEngine;
namespace CameraTools
{
public class Curve3D
{
private Vector3[] points;
private float[] times;
private AnimationCurve[] curves;
bool curveReady = false;
// Use this for initialization
public Curve3D()
{
curves = new AnimationCurve[]{new AnimationCurve(), new AnimationCurve(), new AnimationCurve()};
}
public Curve3D(Vector3[] newPoints, float[] newTimes)
{
curves = new AnimationCurve[]{new AnimationCurve(), new AnimationCurve(), new AnimationCurve()};
SetPoints(newPoints, newTimes);
}
public void SetPoints(Vector3[] newPoints, float[] newTimes)
{
if(newPoints.Length != newTimes.Length)
{
Debug.LogError("Curve3D: points array must be same length as times array");
return;
}
points = new Vector3[newPoints.Length];
times = new float[newPoints.Length];
for(int i = 0; i < points.Length; i++)
{
points[i] = newPoints[i];
times[i] = newTimes[i];
}
UpdateCurve();
}
public void SetPoint(int index, Vector3 newPoint, float newTime)
{
if(index < points.Length)
{
SetAnimKey(index, newPoint, newTime);
}
else
{
Debug.LogError("Tried to set new point in a Curve3D beyond the existing array. Not yet implemented.");
}
}
private void UpdateCurve()
{
curveReady = false;
//clear existing keys
for(int i = 0; i < 3; i++)
{
curves[i] = new AnimationCurve();
}
if(points.Length == 0) return;
for(int i = 0; i < points.Length; i++)
{
SetAnimKey(i, points[i], times[i]);
}
curveReady = true;
}
void SetAnimKey(int index, Vector3 point, float time)
{
if(index >= curves[0].keys.Length)
{
curves[0].AddKey(time, point.x);
curves[1].AddKey(time, point.y);
curves[2].AddKey(time, point.z);
}
else
{
curves[0].MoveKey(index, new Keyframe(time, point.x));
curves[1].MoveKey(index, new Keyframe(time, point.y));
curves[2].MoveKey(index, new Keyframe(time, point.z));
}
}
public Vector3 GetPoint(float time)
{
if(!curveReady)
{
Debug.LogWarning("Curve was accessed but it was not properly initialized.");
return Vector3.zero;
}
float x = curves[0].Evaluate(time);
float y = curves[1].Evaluate(time);
float z = curves[2].Evaluate(time);
return new Vector3(x,y,z);
}
public Vector3 GetTangent(float time)
{
if(!curveReady)
{
Debug.LogWarning("Curve was accessed but it was not properly initialized.");
return Vector3.one;
}
if(time < 1)
{
return (GetPoint(Mathf.Min(time+0.01f, 1))-GetPoint(time)).normalized;
}
else
{
return (GetPoint(1)-GetPoint(0.99f)).normalized;
}
}
}
}