24 return cyclic ? points_num : points_num - 1;
35 (cyclic && values.size() <= 1 ? 0 :
segments_num(values.size(), cyclic)));
37 for (
const int i :
IndexRange(values.size() - 1)) {
41 if (cyclic && values.size() > 1) {
42 lengths.last() = length +
math::distance(values.last(), values.first());
55 const int last_src_index = src.
size() - 1;
58 for (
const int i : dst_segment.index_range()) {
59 const int prev_index = indices[dst_segment_pos + i];
60 const float factor = factors[dst_segment_pos + i];
61 const bool is_cyclic_case = prev_index == last_src_index;
66 dst[dst_segment[i]] =
math::interpolate(src[prev_index], src[prev_index + 1], factor);
98 const float sample_length,
104 const Span<float> lengths = accumulated_segment_lengths;
109 if (hint !=
nullptr && hint->segment_index >= 0) {
110 const float length_in_segment = sample_length - hint->segment_start;
111 const float factor = length_in_segment * hint->segment_length_inv;
112 if (factor >= 0.0f && factor < 1.0f) {
113 r_segment_index = hint->segment_index;
119 const float total_length = lengths.last();
120 if (sample_length >= total_length) {
122 r_segment_index = lengths.size() - 1;
127 const int prev_point_index = std::upper_bound(lengths.begin(), lengths.end(), sample_length) -
129 const float segment_start = prev_point_index == 0 ? 0.0f : lengths[prev_point_index - 1];
130 const float segment_end = lengths[prev_point_index];
131 const float segment_length = segment_end - segment_start;
133 const float length_in_segment = sample_length - segment_start;
134 const float factor = length_in_segment * segment_length_inv;
136 r_segment_index = prev_point_index;
139 if (hint !=
nullptr) {
140 hint->segment_index = r_segment_index;
141 hint->segment_start = segment_start;
142 hint->segment_length_inv = segment_length_inv;
156 bool include_last_point,
170 bool include_first_point,
SIMD_FORCE_INLINE btScalar length() const
Return the length of the vector.
constexpr IndexRange index_range() const
constexpr const T & first() const
constexpr int64_t size() const
constexpr const T & last(const int64_t n=0) const
void foreach_segment_optimized(Fn &&fn) const
int segments_num(const int points_num, const bool cyclic)
void accumulate_lengths(const Span< T > values, const bool cyclic, MutableSpan< float > lengths)
void sample_at_lengths(Span< float > accumulated_segment_lengths, Span< float > sample_lengths, MutableSpan< int > r_segment_indices, MutableSpan< float > r_factors)
void sample_uniform_reverse(Span< float > accumulated_segment_lengths, bool include_first_point, MutableSpan< int > r_segment_indices, MutableSpan< float > r_factors)
void sample_at_length(const Span< float > accumulated_segment_lengths, const float sample_length, int &r_segment_index, float &r_factor, SampleSegmentHint *hint=nullptr)
void interpolate(const Span< T > src, const Span< int > indices, const Span< float > factors, MutableSpan< T > dst)
void sample_uniform(Span< float > accumulated_segment_lengths, bool include_last_point, MutableSpan< int > r_segment_indices, MutableSpan< float > r_factors)
void interpolate_to_masked(const Span< T > src, const Span< int > indices, const Span< float > factors, const IndexMask &dst_mask, MutableSpan< T > dst)
T safe_divide(const T &a, const T &b)
T distance(const T &a, const T &b)
T interpolate(const T &a, const T &b, const FactorT &t)