Loading...
Searching...
No Matches
CurveConversion.hpp
1#pragma once
2#include <Curve/Segment/Linear/LinearSegment.hpp>
3#include <Curve/Segment/Power/PowerSegment.hpp>
4
5#include <ossia/editor/curve/curve.hpp>
6
7namespace Engine
8{
9namespace score_to_ossia
10{
11
12template <typename Y_T>
14
15template <>
16struct CurveTraits<int>
17{
18 static const constexpr auto fun = &Curve::SegmentModel::makeIntFunction;
19 static const constexpr auto scaled = &Curve::SegmentModel::makeScaledIntFunction;
20};
21
22template <>
23struct CurveTraits<float>
24{
25 static const constexpr auto fun = &Curve::SegmentModel::makeFloatFunction;
26 static const constexpr auto scaled = &Curve::SegmentModel::makeScaledFloatFunction;
27};
28
29template <>
30struct CurveTraits<double>
31{
32 static const constexpr auto fun = &Curve::SegmentModel::makeDoubleFunction;
33 static const constexpr auto scaled = &Curve::SegmentModel::makeScaledDoubleFunction;
34};
35
36template <
37 typename X_T, typename Y_T, typename XScaleFun, typename YScaleFun,
38 typename Segments>
39std::shared_ptr<ossia::curve<X_T, Y_T>> curve(
40 XScaleFun scale_x, YScaleFun scale_y, const Segments& segments,
41 const std::optional<ossia::destination>& tween)
42{
43 auto curve = std::make_shared<ossia::curve<X_T, Y_T>>();
44 curve->reserve(segments.size() + 1);
45
46 // Where the curve begins, wherever that is. The first segment is not
47 // required to start at 0: leaving x0/y0 at their defaults there made the
48 // ossia curve ramp from (0, 0) to the first segment's end, which throws that
49 // segment away and shifts everything after it.
50 auto start = segments[0]->start();
51 curve->set_x0(scale_x(start.x()));
52 curve->set_y0(scale_y(start.y()));
53
54 // scale_y is affine: sampled segments are given it as offset and factor.
55 const double offset = scale_y(0.);
56 const double factor = double(scale_y(1.)) - offset;
57 for(const auto& score_segment : segments)
58 {
59 auto end = score_segment->end();
60 curve->add_point(
61 (score_segment->*CurveTraits<Y_T>::scaled)(offset, factor), scale_x(end.x()),
62 scale_y(end.y()));
63 }
64
65 if(tween)
66 {
67 curve->set_y0_destination(*tween);
68 }
69
70 return curve;
71}
72
73// Simpler curve, between [0; 1]
74template <typename Segments>
75ossia::curve<double, float>
76floatCurve(const Segments& segments, const std::optional<ossia::destination>& tween)
77{
78 ossia::curve<double, float> curve;
79
80 // See above: the first segment need not start at 0.
81 auto start = segments[0]->start();
82 curve.set_x0(start.x());
83 curve.set_y0(start.y());
84
85 for(const auto& score_segment : segments)
86 {
87 auto end = score_segment->end();
88 curve.add_point(
89 (score_segment->*CurveTraits<float>::scaled)(0., 1.), end.x(), end.y());
90 }
91
92 if(tween)
93 {
94 curve.set_y0_destination(*tween);
95 }
96
97 return curve;
98}
99
100}
101}
virtual ossia::curve_segment< double > makeScaledDoubleFunction(double offset, double factor) const
Definition CurveSegmentModel.cpp:81
Link of score with the OSSIA API execution engine.
Definition CurveConversion.hpp:8
Definition CurveConversion.hpp:13