11 point.element = element;
12 point.progress = progress;
13 points_.emplace_back(
point);
15 std::sort(points_.begin(), points_.end());
17 auto it = std::find(points_.begin(), points_.end(),
point);
20 return std::distance(points_.begin(), it);
26 if(index >=
int(points_.size()))
31 points_.erase(points_.begin() + index);
32 std::sort(points_.begin(), points_.end());
40 std::sort(points_.begin(), points_.end());
53 for(
auto& p : points_)
55 p.progress = 1.0f - p.progress;
57 std::sort(points_.begin(), points_.end());
64 if(index >=
int(points_.size()))
69 points_[index].progress = progress;
70 std::sort(points_.begin(), points_.end());
77 if(index >=
int(points_.size()))
82 return points_[index].progress;
88 if(index >=
int(points_.size()))
93 points_[index].element = element;
100 if(index >=
int(points_.size()))
105 return points_[index].element;
111 return (
false == points_.empty());
120 regenerate_lut_if_needed();
121 return sample_from_lut(progress);
125 return sample_original(progress);
132 if(
false == is_valid())
138 int high = points_.size() - 1;
145 if(
point.progress > progress)
149 else if(
point.progress < progress)
155 return point.element;
159 if(points_[middle].progress > progress)
167 if(second >= 0 &&
size_t(second) >= points_.size())
169 return points_.back().element;
174 return points_.front().element;
177 const auto& point_first = points_[first];
178 const auto& point_second = points_[second];
180 switch(interpolation_mode_)
184 return point_first.element;
188 const auto abs_progress = (progress - point_first.progress) / (point_second.progress - point_first.progress);
189 return gradient_lerp(point_first.element, point_second.element, abs_progress);
193 return point_first.element;
199 interpolation_mode_ = mode;
206 return interpolation_mode_;
212 if(interpolation_mode_ != other.interpolation_mode_)
217 return points_ == other.points_;
224 lut_size_ = lut_size;
225 lut_.resize(lut_size_);
228 for(
size_t i = 0; i < lut_size_; ++i)
230 const float progress = float(i) / float(lut_size_ - 1);
231 lut_[i] = sample_original(progress);
248 if(lut_dirty_ && !lut_.empty())
251 const_cast<gradient<T>*
>(
this)->generate_lut(lut_size_);
256auto gradient<T>::sample_from_lut(
float progress)
const -> T
264 progress = std::max(0.0f, std::min(1.0f, progress));
267 const float index_f = progress * float(lut_size_ - 1);
268 const size_t index = size_t(index_f);
269 const float frac = index_f - float(index);
272 if(index >= lut_size_ - 1)
void set_progress(int index, float progress)
auto get_points() const noexcept -> const points_t &
auto get_progress(int index) -> float
auto is_valid() const noexcept -> bool
auto operator==(const gradient< T > &other) const -> bool
void set_element(int index, const T &element)
auto add_point(const T &element, float progress) -> size_t
std::vector< point_t > points_t
auto get_interpolation_mode() const noexcept -> gradient_interpolation_mode_t
void generate_lut(size_t lut_size=256)
void set_interpolation_mode(gradient_interpolation_mode_t mode)
auto get_element(int index) -> T
void set_points(const points_t &points)
void remove_point(int index)
auto sample(float progress) const -> T
auto gradient_lerp(const vec4 &start, const vec4 &end, float progress) -> vec4
gradient_interpolation_mode_t