OSSIA
Open Scenario System for Interactive Application
spline.hpp
1 #pragma once
2 #include <ossia/dataflow/graph_node.hpp>
3 #include <ossia/dataflow/nodes/spline/spline2d.hpp>
4 #include <ossia/dataflow/nodes/spline/spline3d.hpp>
5 #include <ossia/dataflow/port.hpp>
6 
7 // Courtesy of tinyspline library, MIT license.
8 #include <ossia/editor/automation/tinyspline_util.hpp>
10 
11 namespace ossia::nodes
12 {
13 
14 class spline final : public ossia::nonowning_graph_node
15 {
16 public:
17  spline() { m_outlets.push_back(&value_out); }
18 
19  ~spline() override = default;
20 
21  std::string label() const noexcept override { return "spline"; }
22 
23  void set_spline(const spline_data& t)
24  {
25  m_spline.set_points(
26  reinterpret_cast<const tsReal*>(t.points.data()), t.points.size());
27  }
28 
29 private:
30  void run(const ossia::token_request& t, ossia::exec_state_facade e) noexcept override
31  {
32  if(!m_spline)
33  return;
34 
35  ossia::value_port& vp = *value_out;
36  const double pos = ossia::clamp(t.position(), 0., 1.);
37 
38  const auto [res_x, res_y] = m_spline.evaluate(pos);
39 
40  const auto [tick_start, d] = e.timings(t);
41 
42  vp.write_value(
43  ossia::make_vec(m_x + m_scaleX * res_x, m_y + m_scaleY * res_y), tick_start);
44  }
45 
46  ossia::value_outlet value_out;
47  ts::spline<2> m_spline;
48  double m_x{}, m_y{};
49  static constexpr double m_scaleX{1.}, m_scaleY{1.};
50 };
51 
52 class spline3d final : public ossia::nonowning_graph_node
53 {
54 public:
55  spline3d() { m_outlets.push_back(&value_out); }
56 
57  ~spline3d() override = default;
58 
59  std::string label() const noexcept override { return "spline"; }
60 
61  void set_spline(const spline3d_data& t)
62  {
63  m_spline.set_points(
64  reinterpret_cast<const tsReal*>(t.points.data()), t.points.size());
65  }
66 
67 private:
68  void run(const ossia::token_request& t, ossia::exec_state_facade e) noexcept override
69  {
70  if(!m_spline)
71  return;
72 
73  ossia::value_port& vp = *value_out;
74  const double pos = ossia::clamp(t.position(), 0., 1.);
75 
76  const auto [res_x, res_y, res_z] = m_spline.evaluate(pos);
77 
78  const auto [tick_start, d] = e.timings(t);
79 
80  vp.write_value(
81  ossia::make_vec(
82  m_x + m_scaleX * res_x, m_y + m_scaleY * res_y, m_z + m_scaleZ * res_z),
83  tick_start);
84  }
85 
86  ossia::value_outlet value_out;
87  ts::spline<3> m_spline;
88  double m_x{}, m_y{}, m_z{};
89  static constexpr double m_scaleX{1.}, m_scaleY{1.}, m_scaleZ{1.};
90 };
91 }
constexpr OSSIA_INLINE T clamp(T d, const T min, const T max) noexcept
clamp Returns the value bounded by a min and a max
Definition: math.hpp:154
double tsReal
Definition: tinyspline.h:213