15 #ifndef MOTIVE_MATH_SPLINE_UTIL_H_
16 #define MOTIVE_MATH_SPLINE_UTIL_H_
18 #include "mathfu/glsl_mappings.h"
22 inline int NormalizeIdx(
const int idx,
const int max,
const bool wraps) {
23 return wraps ? (idx < 0 ? idx + max : idx >= max ? idx - max : idx)
24 : (idx < 0 ? 0 : idx >= max ? max - 1 : idx);
27 template <
int kDimensions>
29 const mathfu::VectorPacked<float, kDimensions>*
const positions,
30 const int num_positions,
const bool wraps,
const int start_idx,
31 const int delta_idx,
const float min_dist) {
32 typedef typename mathfu::Vector<float, kDimensions> Vec;
34 const Vec start_position(positions[start_idx]);
35 const int end_idx = NormalizeIdx(
36 start_idx + delta_idx * (num_positions / 2 - 1), num_positions, wraps);
37 for (
int i = NormalizeIdx(start_idx + delta_idx, num_positions, wraps);
38 i != end_idx; i = NormalizeIdx(i + delta_idx, num_positions, wraps)) {
39 const Vec delta = Vec(positions[i]) - start_position;
40 const float dist = delta.Length();
41 if (dist >= min_dist)
return i;
69 template <
int kDimensions>
70 void CalculateConstSpeedCurveFromPositions(
71 const mathfu::VectorPacked<float, kDimensions>*
const positions,
72 const int num_positions,
const float total_time,
73 const float min_reliable_dist,
float*
const times,
74 mathfu::VectorPacked<float, kDimensions>*
const derivatives) {
75 typedef typename mathfu::Vector<float, kDimensions> Vec;
79 if (num_positions <= 0)
return;
80 if (num_positions == 1) {
81 derivatives[0] = Vec(0.0f);
88 std::vector<float> dist(num_positions);
90 for (
int i = 1; i < num_positions; ++i) {
91 const Vec delta = Vec(positions[i]) - Vec(positions[i - 1]);
92 dist[i] = dist[i - 1] + delta.Length();
96 const float total_dist = dist[num_positions - 1];
97 const float const_speed_inv = total_time / total_dist;
98 const float const_speed = total_dist / total_time;
99 for (
int i = 0; i < num_positions; ++i) {
100 times[i] = const_speed_inv * dist[i];
105 const Vec start_to_end =
106 Vec(positions[0]) - Vec(positions[num_positions - 1]);
107 const bool wraps = start_to_end.Length() < min_reliable_dist;
111 for (
int i = 0; i < num_positions; ++i) {
112 const int prev_idx = FindFartherIdx(positions, num_positions, wraps, i, -1,
114 const int next_idx = FindFartherIdx(positions, num_positions, wraps, i, 1,
116 const Vec delta = Vec(positions[next_idx]) - Vec(positions[prev_idx]);
117 derivatives[i] = const_speed * delta.Normalized();
126 #endif // MOTIVE_MATH_SPLINE_UTIL_H_