-
Notifications
You must be signed in to change notification settings - Fork 0
/
movement_spline.h
174 lines (141 loc) · 3.98 KB
/
movement_spline.h
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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
#pragma once
#include "basic_data_structures.h"
#include "linear_math/vector.h"
#include "misc.h"
#define WAYPOINT_CAPACITY_PER_TRAJECTORY 20
#define TRAJECTORY_CAPACITY 20
struct waypoint
{
vec3 Position;
vec2 Facing;
float Velocity;
};
struct spline_follow_state
{
int32_t SplineIndex;
int32_t NextWaypointIndex;
bool Loop;
bool MovingInPositive;
};
struct movement_line
{
vec3 A;
vec3 B;
};
inline float
GetCatmullRomPoint(float A, float B, float C, float D, float t)
{
assert(0 <= t && t <= 1);
float ttt = t * t * t;
float tt = t * t;
float wA = -ttt + 2 * tt - t;
float wB = 3 * ttt - 5 * tt + 2;
float wC = -3 * ttt + 4 * tt + t;
float wD = ttt - tt;
return 0.5f * (A * wA + B * wB + C * wC + D * wD);
}
inline float
GetCatmullRomGradient(float A, float B, float C, float D, float t)
{
assert(0 <= t && t <= 1);
float tt = t * t;
float wA = -3*tt + 4 * t - 1;
float wB = 9 * tt - 10 * t;
float wC = -9 * tt + 8 * t + 1;
float wD = 3 * tt - 2 * t;
return 0.5f * (A * wA + B * wB + C * wC + D * wD);
}
inline vec3
GetCatmullRomPoint(vec3 A, vec3 B, vec3 C, vec3 D, float t)
{
vec3 Result = { GetCatmullRomPoint(A.X, B.X, C.X, D.X, t),
GetCatmullRomPoint(A.Y, B.Y, C.Y, D.Y, t),
GetCatmullRomPoint(A.Z, B.Z, C.Z, D.Z, t) };
return Result;
}
inline vec3
GetCatmullRomGradient(vec3 A, vec3 B, vec3 C, vec3 D, float t)
{
vec3 Result = { GetCatmullRomGradient(A.X, B.X, C.X, D.X, t),
GetCatmullRomGradient(A.Y, B.Y, C.Y, D.Y, t),
GetCatmullRomGradient(A.Z, B.Z, C.Z, D.Z, t) };
return Result;
}
struct movement_spline
{
fixed_stack<waypoint, WAYPOINT_CAPACITY_PER_TRAJECTORY> Waypoints;
inline void
GetSplineControlPointIndices(int* IndA, int* IndB, int* IndC, int* IndD, int NextIndex,
bool Loop = false) const
{
int Count = Waypoints.Count;
assert(0 < Count);
*IndA = NextIndex - 2;
*IndB = NextIndex - 1;
*IndC = NextIndex - 0;
*IndD = NextIndex + 1;
if(Loop)
{
*IndA = (*IndA + Count) % Count;
*IndB = (*IndB + Count) % Count;
*IndC = (*IndC + Count) % Count;
*IndD = (*IndD + Count) % Count;
}
*IndA = ClampInt32InIn(0, *IndA, Waypoints.Count - 1);
*IndB = ClampInt32InIn(0, *IndB, Waypoints.Count - 1);
*IndC = ClampInt32InIn(0, *IndC, Waypoints.Count - 1);
*IndD = ClampInt32InIn(0, *IndD, Waypoints.Count - 1);
}
inline vec3
CatmullRomPoint(int NextIndex, float t, bool Loop = false) const
{
int IndA;
int IndB;
int IndC;
int IndD;
GetSplineControlPointIndices(&IndA, &IndB, &IndC, &IndD, NextIndex, Loop);
vec3 A = Waypoints[IndA].Position;
vec3 B = Waypoints[IndB].Position;
vec3 C = Waypoints[IndC].Position;
vec3 D = Waypoints[IndD].Position;
return GetCatmullRomPoint(A, B, C, D, t);
}
inline vec3
CatmullRomGradient(int NextIndex, float t, bool Loop = false) const
{
int IndA;
int IndB;
int IndC;
int IndD;
GetSplineControlPointIndices(&IndA, &IndB, &IndC, &IndD, NextIndex, Loop);
vec3 A = Waypoints[IndA].Position;
vec3 B = Waypoints[IndB].Position;
vec3 C = Waypoints[IndC].Position;
vec3 D = Waypoints[IndD].Position;
return GetCatmullRomGradient(A, B, C, D, t);
}
inline movement_line
GetCurrentLine(int32_t NextIndex, bool Looped = false) const
{
int IndA = NextIndex - 1;
int IndB = NextIndex;
int Count = Waypoints.Count;
assert(Count > 0);
if(Looped)
{
IndA = (IndA + Count) % Count;
IndB = (IndB + Count) % Count;
}
IndA = ClampInt32InIn(0, IndA, Waypoints.Count - 1);
IndB = ClampInt32InIn(0, IndB, Waypoints.Count - 1);
movement_line Result = { Waypoints[IndA].Position, Waypoints[IndB].Position };
return Result;
}
};
struct spline_system
{
fixed_stack<movement_spline, TRAJECTORY_CAPACITY> Splines;
bool IsWaypointPlacementMode;
int32_t SelectedSplineIndex;
int32_t SelectedWaypointIndex;
};