OSSIA
Open Scenario System for Interactive Application
tinyspline_util.hpp
1 #pragma once
2 // clang-format off
3 #include <ossia/detail/config.hpp>
4 #define TINYSPLINE_API OSSIA_EXPORT
5 
6 #include "tinyspline.h"
7 // clang-format on
8 
9 #include <array>
10 #include <cstdint>
11 
12 extern "C" {
13 TINYSPLINE_API
14 void ts_int_deboornet_init(tsDeBoorNet* _deBoorNet_);
15 
16 TINYSPLINE_API
17 tsError
18 ts_int_deboornet_new(const tsBSpline* spline, tsDeBoorNet* net, tsStatus* status);
19 
20 TINYSPLINE_API
21 void ts_int_bspline_init(tsBSpline* spline);
22 
23 TINYSPLINE_API
24 tsError ts_int_bspline_eval_woa(
25  const tsBSpline* spline, tsReal u, tsDeBoorNet* net, tsStatus* status);
26 
27 TINYSPLINE_API
28 tsReal* ts_int_deboornet_access_result(const tsDeBoorNet* net);
29 }
30 
31 namespace ts
32 {
33 template <std::size_t N>
34 struct spline
35 {
36  tsBSpline m_spline;
37  mutable tsDeBoorNet m_net;
38 
39  spline()
40  {
41  ts_int_bspline_init(&m_spline);
42  ts_int_deboornet_init(&m_net);
43  }
44 
45  ~spline()
46  {
47  if(m_net.pImpl)
48  ts_deboornet_free(&m_net);
49  if(m_spline.pImpl)
50  ts_bspline_free(&m_spline);
51  }
52 
53  operator bool() const noexcept { return m_net.pImpl; }
54 
55  void set_points(const tsReal* points, std::size_t numPoints) noexcept
56  {
57  tsStatus status;
58  if(m_net.pImpl)
59  ts_deboornet_free(&m_net);
60 
61  if(m_spline.pImpl)
62  ts_bspline_free(&m_spline);
63 
64  ts_int_bspline_init(&m_spline);
65  ts_bspline_new(numPoints, N, 3, TS_CLAMPED, &m_spline, &status);
66 
67  ts_bspline_set_control_points(&m_spline, points, &status);
68 
69  ts_int_deboornet_init(&m_net);
70  ts_int_deboornet_new(&m_spline, &m_net, &status);
71  }
72 
73  std::array<tsReal, N> evaluate(double pos) const noexcept
74  {
75  std::array<tsReal, N> res = {};
76 
77  tsStatus status;
78  if(ts_int_bspline_eval_woa(&m_spline, pos, &m_net, &status) != 0)
79  {
80  // error during evaluation
81  return res;
82  }
83 
84  {
85  const auto bytes = std::min(
86  (std::size_t)N * sizeof(tsReal), (std::size_t)ts_deboornet_sof_result(&m_net));
87  memcpy(res.data(), ts_int_deboornet_access_result(&m_net), bytes);
88  }
89 
90  return res;
91  }
92 };
93 }
constexpr OSSIA_INLINE auto min(const T a, const U b) noexcept -> typename std::conditional<(sizeof(T) > sizeof(U)), T, U >::type
min function tailored for values
Definition: math.hpp:125
Definition: tinyspline.h:718
Definition: tinyspline.h:1308
struct tsDeBoorNetImpl * pImpl
Definition: tinyspline.h:1309
Definition: tinyspline.h:477
tsError TINYSPLINE_API ts_bspline_new(size_t num_control_points, size_t dimension, size_t degree, tsBSplineType type, tsBSpline *spline, tsStatus *status)
Definition: tinyspline.c:464
tsError TINYSPLINE_API ts_bspline_set_control_points(tsBSpline *spline, const tsReal *ctrlp, tsStatus *status)
Definition: tinyspline.c:242
void TINYSPLINE_API ts_deboornet_free(tsDeBoorNet *net)
Definition: tinyspline.c:735
void TINYSPLINE_API ts_bspline_free(tsBSpline *spline)
Definition: tinyspline.c:573
tsError
Definition: tinyspline.h:426
double tsReal
Definition: tinyspline.h:213
@ TS_CLAMPED
Definition: tinyspline.h:647
size_t TINYSPLINE_API ts_deboornet_sof_result(const tsDeBoorNet *net)
Definition: tinyspline.c:667