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 mass_min = 0.001;
111  mass = SYSmax(mass, mass_min);
112 
113  fpreal acc = (f - vel * damping_constant - d1 * spring_constant) / mass;
114  vel += acc * inc;
115  fpreal d = d1 + vel * inc;
116 
117  d2 = d1;
118  d1 = d;
119 
120  return d;
121  }
122 };
123 
124 template <class F>
125 inline void
127  fpreal spring_constant, fpreal mass,
128  fpreal damping_constant, fpreal inc,
129  fpreal initial_displacement, fpreal initial_velocity,
130  Method method, const F& interrupt)
131 {
132  fpreal d1 = initial_displacement;
133  fpreal d2 = d1 - initial_velocity * inc;
134 
135  for (exint j = 0; j < size; j++)
136  {
137  if (interrupt())
138  return;
139 
140  result[j] = doSolve(data[j], spring_constant, mass, damping_constant, inc, method, d1, d2);
141  }
142 }
143 
144 
145 template <class F>
146 inline void
148  fpreal spring_constant, fpreal mass,
149  fpreal damping_constant, fpreal inc,
150  Method method, const F& interrupt)
151 {
152  if (size < 2)
153  {
154  if (result != data)
155  std::copy(data, data + size, result);
156  return;
157  }
158 
159  fpreal initial_displacement = data[0];
160  fpreal initial_velocity = data[1] - initial_displacement;
161 
162  solve(data, result, size, spring_constant, mass,
163  damping_constant, inc, initial_displacement, initial_velocity,
164  method, interrupt);
165 }
166 
167 template <class F>
168 inline bool
170  fpreal spring_constant, fpreal mass,
171  fpreal damping_constant, fpreal inc,
172  fpreal &d1, fpreal &d2,
173  Method method)
174 {
175  fpreal delta = 0.0;
176  bool steady = true;
177  for (exint j = 0; j < size; j++)
178  {
179  fpreal f = get_data(j);
180  fpreal d = doSolve(f, spring_constant, mass, damping_constant, inc, method, d1, d2);
181 
182  if (method == Method::FORCE)
183  f /= spring_constant;
184 
185  delta = SYSabs(f - d);
186 
187  if (delta > 0.001)
188  steady = false;
189 
190  result[j] = d;
191  }
192 
193  return steady;
194 }
195 
196 #endif
#define SYSmax(a, b)
Definition: SYS_Math.h:1952
Method
Method used to compute the spring filter. Either position or force.
Definition: CL_Spring.h:29
int64 exint
Definition: SYS_Types.h:125
#define SYSabs(a)
Definition: SYS_Math.h:1954
**But if you need a result
Definition: thread.h:622
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:549
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:147
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:283
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:169
Definition: format.h:1821