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>
12 namespace ossia::nodes
14 class 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 void set_gradient(grad_type t) { m_data = std::move(t); }
39 auto outlet = m_outlets.back();
40 if(
auto unit = outlet->target<ossia::value_port>()->type.target<
ossia::unit_t>())
54 return ossia::convert(res, ossia::argb_u{}, get_unit());
57 void handle_before_first(
const ossia::token_request& tk, int64_t tick_start,
double position)
59 auto& out = *m_outlets[0]->target<ossia::value_port>();
60 auto beg = m_data.begin();
62 if(beg->first >= position)
64 out.write_value(get_color(ossia::argb{beg->second}), tick_start);
68 out.write_value(get_color(ossia::argb{beg->second}), tick_start);
79 tween = ossia::argb{ossia::convert<ossia::vec4f>((*addr)->value())};
83 tween = ossia::argb{beg->second};
87 ease_color(0., *tween, beg->first, beg->second, position), tick_start);
92 void run(
const ossia::token_request& t, ossia::exec_state_facade e) noexcept
override
94 if(this->process_dur.impl <= 0)
97 auto& out = *m_outlets[0]->target<ossia::value_port>();
99 const auto [tick_start, d] = e.timings(t);
100 const double pos = t.position() * double(t.parent_duration.impl) / double(this->process_dur.impl);
102 switch(m_data.size())
105 out.write_value(get_color(ossia::argb{0., 0., 0., 0.}), tick_start);
108 handle_before_first(t, tick_start, pos);
111 auto it_next = m_data.lower_bound(pos);
113 if(it_next == m_data.begin())
115 handle_before_first(t, tick_start, pos);
118 else if(it_next == m_data.end())
120 out.write_value(get_color(ossia::argb{m_data.rbegin()->second}), tick_start);
124 auto it_prev = it_next;
129 it_prev->first, it_prev->second, it_next->first, it_next->second,
138 double prev_pos, ossia::hunter_lab prev,
double next_pos, ossia::hunter_lab next,
142 const auto coeff = (pos - prev_pos) / (next_pos - prev_pos);
144 ossia::hunter_lab res;
145 ossia::easing::ease e{};
146 res.dataspace_value = ossia::make_vec(
147 e(prev.dataspace_value[0], next.dataspace_value[0], coeff),
148 e(prev.dataspace_value[1], next.dataspace_value[1], coeff),
149 e(prev.dataspace_value[2], next.dataspace_value[2], coeff));
151 return get_color(ossia::argb{res});
155 std::optional<ossia::argb> tween;
164 class gradient_process final :
public ossia::node_process
167 using ossia::node_process::node_process;
168 void start()
override {
169 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:28
Definition: dataspace.hpp:24