HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
CL_Spring.h
Go to the documentation of this file.
1 /*
2  * PROPRIETARY INFORMATION. This software is proprietary to
3  * Side Effects Software Inc., and is not to be reproduced,
4  * transmitted, or disclosed in any way without written permission.
5  *
6  * NAME: CL_Spring.h ( Clip Library, C++)
7  *
8  * COMMENTS:
9  * Applies a spring filter to input data
10  */
11 
12 
13 #ifndef __CL_Spring__
14 #define __CL_Spring__
15 
16 #include "CL_API.h"
17 #include <SYS/SYS_Math.h>
18 #include <SYS/SYS_Types.h>
19 
20 #include <algorithm>
21 
22 class UT_Interrupt;
23 
24 class CL_Spring
25 {
26 public:
27 
28  /// Method used to compute the spring filter. Either position or force
29  enum class Method
30  {
31  POSITION,
32  FORCE
33  };
34 
35 
36  /// Solve for a spring filter given input data
37  /// data and result must both be of length size
38  /// computes initial displacement and initial velocity
39  /// automatically based on the input data
40  template <class F>
41  static void solve(const fpreal *data, fpreal *result, int size,
42  fpreal spring_constant, fpreal mass,
43  fpreal damping_constant, fpreal inc,
44  Method method, const F& interrupt);
45 
46  /// Solve for a spring filter given input data
47  /// data and result must both be of length size
48  /// computes initial displacement and initial velocity
49  /// automatically based on the input data
50  /// Note: This method is an overload for the above, allowing the user to
51  /// avoid passing in a lambda for the interrupt method.
52  /// With c++17 support, this could be more gracefully handled using
53  /// inline variables:
54  ///
55  /// static inline auto defaultInterruptor = []() { return false; };
56 
57  /// template <typename F = decltype(defaultInterruptor)>
58  /// static void foo(const F &interrupt = defaultInterruptor) {}
59  static void solve(const fpreal *data, fpreal *result, int size,
60  fpreal spring_constant, fpreal mass,
61  fpreal damping_constant, fpreal inc,
62  Method method)
63  {
64  solve(data, result, size, spring_constant, mass, damping_constant, inc,
65  method, []() { return false; });
66  }
67 
68  /// Solve for a spring filter given input data
69  /// data and result must both be of length size
70  /// initial displacement and initial velocity are passed in manually
71  template <class F>
72  static void solve(const fpreal *data, fpreal *result, int size,
73  fpreal spring_constant, fpreal mass,
74  fpreal damping_constant, fpreal inc,
75  fpreal initial_displacement, fpreal initial_velocity,
76  Method method, const F& interrupt);
77 
78  static void solve(const fpreal *data, fpreal *result, int size,
79  fpreal spring_constant, fpreal mass,
80  fpreal damping_constant, fpreal inc,
81  fpreal initial_displacement, fpreal initial_velocity,
82  Method method)
83  {
84  solve(data, result, size, spring_constant, mass, damping_constant, inc,
85  initial_displacement, initial_velocity, method, []() { return false; });
86  }
87 
88  /// Spring solver for realtime data
89  /// Must provide a lambda (get_data) which returns the data value
90  /// given the result index
91  /// \return bool - whether or not the solution is steady
92  /// \return d1, d2 - output parameters d1 and d2 are updated in place
93  template <class F>
94  static bool solveRealtime(const F& get_data, fpreal *result, int size,
95  fpreal spring_constant, fpreal mass,
96  fpreal damping_constant, fpreal inc,
97  fpreal &d1, fpreal &d2,
98  Method method);
99 
100 private:
101  static fpreal doSolve(fpreal f, fpreal spring_constant, fpreal mass,
102  fpreal damping_constant, fpreal inc, Method method,
103  fpreal &d1, fpreal &d2)
104  {
105  if (method != Method::FORCE)
106  f *= spring_constant;
107 
108  fpreal vel = (d1 - d2) / inc;
109 
110  fpreal acc = (f - vel * damping_constant - d1 * spring_constant) / mass;
111  vel += acc * inc;
112  fpreal d = d1 + vel * inc;
113 
114  d2 = d1;
115  d1 = d;
116 
117  return d;
118  }
119 };
120 
121 template <class F>
122 inline void
124  fpreal spring_constant, fpreal mass,
125  fpreal damping_constant, fpreal inc,
126  fpreal initial_displacement, fpreal initial_velocity,
127  Method method, const F& interrupt)
128 {
129  fpreal d1 = initial_displacement;
130  fpreal d2 = d1 - initial_velocity * inc;
131 
132  for (exint j = 0; j < size; j++)
133  {
134  if (interrupt())
135  return;
136 
137  result[j] = doSolve(data[j], spring_constant, mass, damping_constant, inc, method, d1, d2);
138  }
139 }
140 
141 
142 template <class F>
143 inline void
145  fpreal spring_constant, fpreal mass,
146  fpreal damping_constant, fpreal inc,
147  Method method, const F& interrupt)
148 {
149  if (size < 2)
150  {
151  if (result != data)
152  std::copy(data, data + size, result);
153  return;
154  }
155 
156  fpreal initial_displacement = data[0];
157  fpreal initial_velocity = data[1] - initial_displacement;
158 
159  solve(data, result, size, spring_constant, mass,
160  damping_constant, inc, initial_displacement, initial_velocity,
161  method, interrupt);
162 }
163 
164 template <class F>
165 inline bool
167  fpreal spring_constant, fpreal mass,
168  fpreal damping_constant, fpreal inc,
169  fpreal &d1, fpreal &d2,
170  Method method)
171 {
172  fpreal delta = 0.0;
173  bool steady = true;
174  for (exint j = 0; j < size; j++)
175  {
176  fpreal f = get_data(j);
177  fpreal d = doSolve(f, spring_constant, mass, damping_constant, inc, method, d1, d2);
178 
179  if (method == Method::FORCE)
180  f /= spring_constant;
181 
182  delta = SYSabs(f - d);
183 
184  if (delta > 0.001)
185  steady = false;
186 
187  result[j] = d;
188  }
189 
190  return steady;
191 }
192 
193 #endif
Method
Method used to compute the spring filter. Either position or force.
Definition: CL_Spring.h:29
OIIO_UTIL_API bool copy(string_view from, string_view to, std::string &err)
int64 exint
Definition: SYS_Types.h:125
#define SYSabs(a)
Definition: SYS_Math.h:1540
**But if you need a result
Definition: thread.h:613
static void solve(const fpreal *data, fpreal *result, int size, fpreal spring_constant, fpreal mass, fpreal damping_constant, fpreal inc, fpreal initial_displacement, fpreal initial_velocity, Method method)
Definition: CL_Spring.h:78
auto get_data(std::basic_string< Char > &s) -> Char *
Definition: format.h:331
GLfloat f
Definition: glcorearb.h:1926
static void solve(const fpreal *data, fpreal *result, int size, fpreal spring_constant, fpreal mass, fpreal damping_constant, fpreal inc, Method method, const F &interrupt)
Definition: CL_Spring.h:144
GLint j
Definition: glad.h:2733
GA_API const UT_StringHolder mass
GLsizeiptr size
Definition: glcorearb.h:664
static void solve(const fpreal *data, fpreal *result, int size, fpreal spring_constant, fpreal mass, fpreal damping_constant, fpreal inc, Method method)
Definition: CL_Spring.h:59
fpreal64 fpreal
Definition: SYS_Types.h:277
static bool solveRealtime(const F &get_data, fpreal *result, int size, fpreal spring_constant, fpreal mass, fpreal damping_constant, fpreal inc, fpreal &d1, fpreal &d2, Method method)
Definition: CL_Spring.h:166
Definition: format.h:895