/
Spline.cs
104 lines (83 loc) · 2.64 KB
/
Spline.cs
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
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
namespace Assets.Scripts
{
public class Spline
{
private readonly bool _cycle;
//public static event EventHandler SplineEnd;
//private static void OnSplineEnd()
//{
// EventHandler handler = SplineEnd;
// if (handler != null) handler(null, EventArgs.Empty);
//}
public bool End;
private struct KeyFrame
{
public float Time { get; private set; }
public Vector3 Position { get; private set; }
public KeyFrame(Vector3 position, float time)
: this()
{
Position = position;
Time = time;
}
}
readonly List<KeyFrame> _keyframes;
float _timer;
public Spline(bool cycle = false)
{
_cycle = cycle;
_keyframes = new List<KeyFrame>();
}
public void AddKeyframe(float t, Vector3 keyFramePosition)
{
_keyframes.Add(new KeyFrame(keyFramePosition, t));
}
public Vector3 GetPosition()
{
var reset = true;
var prevKey = 1;
var nextKey = 1;
//Find the two keyframes
for (var keyidx = 1; keyidx < _keyframes.Count - 2; keyidx++)
{
prevKey = keyidx;
nextKey = keyidx + 1;
if (!(_keyframes[nextKey].Time >= _timer)) continue;
reset = false;
break;
}
if (!_cycle && reset)
{
End = true;
return _keyframes[nextKey].Position;
}
if (reset)
{
prevKey = 1;
nextKey = 2;
_timer = 0;
}
var timeBetweenKeys = _keyframes[nextKey].Time - _keyframes[prevKey].Time;
var t = (_timer - _keyframes[prevKey].Time) / timeBetweenKeys;
return CubicLerp(_keyframes[prevKey - 1].Position, _keyframes[prevKey].Position, _keyframes[nextKey].Position, _keyframes[nextKey + 1].Position, t);
}
public void Update(float deltaTime)
{
_timer += deltaTime;
}
private static Vector3 CubicLerp(Vector3 v0, Vector3 v1, Vector3 v2, Vector3 v3, float t)
{
var t2 = t * t;
var a0 = v3 - v2 - v0 + v1;
var a1 = v0 - v1 - a0;
var a2 = v2 - v0;
var a3 = v1;
return (a0 * t * t2 + a1 * t2 + a2 * t + a3);
}
}
}