2#include <ossia/dataflow/graph_node.hpp>
3#include <ossia/dataflow/node_process.hpp>
4#include <ossia/dataflow/port.hpp>
5#include <ossia/detail/flat_map.hpp>
8#include <ossia/network/base/parameter.hpp>
9#include <ossia/network/dataspace/color.hpp>
14class gradient final :
public ossia::graph_node
17 using grad_type = ossia::flat_map<double, ossia::hunter_lab>;
19 static auto clamp_color(ossia::argb col)
22 for(
size_t i = 0; i < col.dataspace_value.size(); i++)
23 col.dataspace_value[i] = ossia::clamp<float>(col.dataspace_value[i], 0.f, 1.f);
30 ossia::outlet_ptr vp =
new ossia::value_outlet;
31 vp->target<ossia::value_port>()->type = ossia::argb_u{};
32 m_outlets.push_back(std::move(vp));
35 std::string label() const noexcept
override {
return "gradient"; }
37 void set_gradient(grad_type t) { m_data = std::move(t); }
41 auto outlet = m_outlets.back();
42 if(
auto unit = outlet->target<ossia::value_port>()->type.target<
ossia::unit_t>())
56 return ossia::convert(res, ossia::argb_u{}, get_unit());
59 void handle_before_first(
const ossia::token_request& tk, int64_t tick_start,
double position)
61 auto& out = *m_outlets[0]->target<ossia::value_port>();
62 auto beg = m_data.begin();
64 if(beg->first >= position)
66 out.write_value(get_color(ossia::argb{beg->second}), tick_start);
70 out.write_value(get_color(ossia::argb{beg->second}), tick_start);
81 tween = ossia::argb{ossia::convert<ossia::vec4f>((*addr)->value())};
85 tween = ossia::argb{beg->second};
89 ease_color(0., *tween, beg->first, beg->second, position), tick_start);
94 void run(
const ossia::token_request& t, ossia::exec_state_facade e)
noexcept override
96 if(this->process_dur.impl <= 0)
99 auto& out = *m_outlets[0]->target<ossia::value_port>();
101 const auto [tick_start, d] = e.timings(t);
102 const double pos = t.position() * double(t.parent_duration.impl) / double(this->process_dur.impl);
104 switch(m_data.size())
107 out.write_value(get_color(ossia::argb{0., 0., 0., 0.}), tick_start);
110 handle_before_first(t, tick_start, pos);
113 auto it_next = m_data.lower_bound(pos);
115 if(it_next == m_data.begin())
117 handle_before_first(t, tick_start, pos);
120 else if(it_next == m_data.end())
122 out.write_value(get_color(ossia::argb{m_data.rbegin()->second}), tick_start);
126 auto it_prev = it_next;
131 it_prev->first, it_prev->second, it_next->first, it_next->second,
140 double prev_pos, ossia::hunter_lab prev,
double next_pos, ossia::hunter_lab next,
144 const auto coeff = (pos - prev_pos) / (next_pos - prev_pos);
146 ossia::hunter_lab res;
147 ossia::easing::ease e{};
148 res.dataspace_value = ossia::make_vec(
149 e(prev.dataspace_value[0], next.dataspace_value[0], coeff),
150 e(prev.dataspace_value[1], next.dataspace_value[1], coeff),
151 e(prev.dataspace_value[2], next.dataspace_value[2], coeff));
153 return get_color(ossia::argb{res});
157 std::optional<ossia::argb> tween;
166class gradient_process final :
public ossia::node_process
169 using ossia::node_process::node_process;
170 void start()
override {
171 static_cast<gradient*
>(node.get())->tween = std::nullopt;
The parameter_base class.
Definition ossia/network/base/parameter.hpp:48
The value class.
Definition value.hpp:173
The time_value class.
Definition ossia/editor/scenario/time_value.hpp:30
Definition dataspace.hpp:24