HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
timeSampleArray.h
Go to the documentation of this file.
1 //
2 // Copyright 2016 Pixar
3 //
4 // Licensed under the terms set forth in the LICENSE.txt file available at
5 // https://openusd.org/license.
6 //
7 #ifndef PXR_IMAGING_HD_TIME_SAMPLE_ARRAY_H
8 #define PXR_IMAGING_HD_TIME_SAMPLE_ARRAY_H
9 
10 #include "pxr/pxr.h"
11 #include "pxr/imaging/hd/api.h"
12 #include "pxr/imaging/hd/version.h"
13 #include "pxr/base/vt/array.h"
14 #include "pxr/base/vt/value.h"
15 #include "pxr/base/gf/math.h"
16 #include "pxr/base/gf/quatf.h"
17 #include "pxr/base/tf/diagnostic.h"
19 
21 
22 /// Resample two neighboring samples.
23 template <typename T>
24 inline T HdResampleNeighbors(float alpha, const T& v0, const T& v1)
25 {
26  return GfLerp(alpha, v0, v1);
27 }
28 
29 /// Specialization for HdQuatf: spherical linear interpolation.
30 HD_API
32  const GfQuatf &v0,
33  const GfQuatf &v1)
34 {
35  return GfSlerp(double(alpha), v0, v1);
36 }
37 
38 /// Specialization for VtArray: component-wise resampling.
39 template <typename T>
41  const VtArray<T>& v0,
42  const VtArray<T>& v1)
43 {
44  VtArray<T> r(v0.size());
45  for (size_t i=0; i < r.size(); ++i) {
46  r[i] = HdResampleNeighbors(alpha, v0[i], v1[i]);
47  }
48  return r;
49 }
50 
51 /// Specialization for VtValue: interpolate the held values.
52 HD_API
53 VtValue HdResampleNeighbors(float alpha, const VtValue& v0, const VtValue& v1);
54 
55 /// Resample a function described by an ordered array of samples,
56 /// using a linear reconstruction filter evaluated at the given
57 /// parametric position u. The function is considered constant
58 /// outside the supplied sample range.
59 template <typename T>
61  float u,
62  size_t numSamples,
63  const float *us,
64  const T *vs)
65 {
66  if (numSamples == 0) {
67  TF_CODING_ERROR("HdResampleRawTimeSamples: Zero samples provided");
68  return T();
69  }
70 
71  size_t i=0;
72  for (; i < numSamples; ++i) {
73  if (us[i] == u) {
74  // Fast path for exact parameter match.
75  return vs[i];
76  }
77  if (us[i] > u) {
78  break;
79  }
80  }
81  if (i == 0) {
82  // u is before the first sample.
83  return vs[0];
84  } else if (i == numSamples) {
85  // u is after the last sample.
86  return vs[numSamples-1];
87  } else if (us[i] == us[i-1]) {
88  // Neighboring samples have identical parameter.
89  // Arbitrarily choose a sample.
90  TF_WARN("HdResampleRawTimeSamples: overlapping samples at %f; "
91  "using first sample", us[i]);
92  return vs[i-1];
93  } else {
94  // Linear blend of neighboring samples.
95  float alpha = (u-us[i-1]) / (us[i]-us[i-1]);
96  return HdResampleNeighbors(alpha, vs[i-1], vs[i]);
97  }
98 }
99 
100 /// Resample a function described by an ordered array of samples and sample
101 /// indices, using a linear reconstruction filter evaluated at the given
102 /// parametric position u. The function is considered constant outside the
103 /// supplied sample range.
104 template <typename T>
105 std::pair<T, VtIntArray> HdResampleRawTimeSamples(
106  float u,
107  size_t numSamples,
108  const float *us,
109  const T *vs,
110  const VtIntArray *is)
111 {
112  if (numSamples == 0) {
113  TF_CODING_ERROR("HdResampleRawTimeSamples: Zero samples provided");
114  return std::pair<T, VtIntArray>(T(), VtIntArray(0));
115  }
116 
117  size_t i=0;
118  for (; i < numSamples; ++i) {
119  if (us[i] == u) {
120  // Fast path for exact parameter match.
121  return std::pair<T, VtIntArray>(vs[i], is[i]);
122  }
123  if (us[i] > u) {
124  break;
125  }
126  }
127  if (i == 0) {
128  // u is before the first sample.
129  return std::pair<T, VtIntArray>(vs[0], is[0]);
130  } else if (i == numSamples) {
131  // u is after the last sample.
132  return std::pair<T, VtIntArray>(vs[numSamples-1], is[numSamples-1]);
133  } else if (us[i] == us[i-1]) {
134  // Neighboring samples have identical parameter.
135  // Arbitrarily choose a sample.
136  TF_WARN("HdResampleRawTimeSamples: overlapping samples at %f; "
137  "using first sample", us[i]);
138  return std::pair<T, VtIntArray>(vs[i-1], is[i-1]);
139  } else {
140  // Linear blend of neighboring samples for values
141  // Hold earlier value for indices
142  float alpha = (us[i]-u) / (us[i]-us[i-1]);
143  return std::pair<T, VtIntArray>(
144  HdResampleNeighbors(alpha, vs[i-1], vs[i]),
145  is[i-1]);
146  }
147 }
148 
149 // Returns contributing sample times for the interval from startTime to endTime.
150 //
151 // If there is no sample at the startTime, this will include the sample times
152 // just before the start time if it exists. Similarly for the endTime.
153 //
154 // Return true if the value is changing on the interval from startTime to
155 // endTime - or equivalently if we return two times.
156 bool
158  size_t count,
159  const float * sampleTimes,
160  float startTime,
161  float endTime,
162  std::vector<float> * outSampleTimes);
163 
164 /// An array of a value sampled over time, in struct-of-arrays layout.
165 /// This is provided as a convenience for time-sampling attributes.
166 /// This type has static capacity but dynamic size, providing
167 /// a limited ability to handle variable sampling without requiring
168 /// heap allocation.
169 template<typename TYPE, unsigned int CAPACITY>
171 {
173  times.resize(CAPACITY);
174  values.resize(CAPACITY);
175  count = 0;
176  }
177 
179  times = rhs.times;
180  values = rhs.values;
181  count = rhs.count;
182  }
183 
185  times = rhs.times;
186  values = rhs.values;
187  count = rhs.count;
188  return *this;
189  }
190 
191  /// Resize the internal buffers.
192  virtual void Resize(unsigned int newSize) {
193  times.resize(newSize);
194  values.resize(newSize);
195  count = newSize;
196  }
197 
198  /// Convience method for invoking HdResampleRawTimeSamples
199  /// on this HdTimeSampleArray.
200  TYPE Resample(float u) const {
201  return HdResampleRawTimeSamples(u, count, times.data(), values.data());
202  }
203 
204  /// Unbox an HdTimeSampleArray holding boxed VtValue<VtArray<T>>
205  /// samples into an array holding VtArray<T> samples. If any of the values
206  /// contain the wrong type, their data is discarded. The function returns
207  /// true if all samples have the correct type.
209  bool ret = true;
210  Resize(box.count);
211  times = box.times;
212  for (size_t i=0; i < box.count; ++i) {
213  if (box.values[i].template IsHolding<TYPE>() &&
214  box.values[i].GetArraySize() > 0) {
215  values[i] = box.values[i].template Get<TYPE>();
216  } else {
217  values[i] = TYPE();
218  ret = false;
219  }
220  }
221  return ret;
222  }
223 
224  /// See HdGetContributingSampleTimesForInterval.
226  const float startTime, const float endTime,
227  std::vector<float> * const outSampleTimes) const
228  {
230  count, times.data(), startTime, endTime, outSampleTimes);
231  }
232 
233  size_t count;
236 };
237 
238 /// An array of a value and its indices sampled over time, in struct-of-arrays
239 /// layout.
240 template<typename TYPE, unsigned int CAPACITY>
241 struct HdIndexedTimeSampleArray : public HdTimeSampleArray<TYPE, CAPACITY>
242 {
244  indices.resize(CAPACITY);
245  }
246 
248  HdTimeSampleArray<TYPE, CAPACITY>(rhs) {
249  indices = rhs.indices;
250  }
251 
254  this->times = rhs.times;
255  this->values = rhs.values;
256  this->count = rhs.count;
257  indices = rhs.indices;
258  return *this;
259  }
260 
261  /// Resize the internal buffers.
262  void Resize(unsigned int newSize) override {
264  indices.resize(newSize);
265  }
266 
267  /// Convience method for invoking HdResampleRawTimeSamples
268  /// on this HdIndexedTimeSampleArray.
269  std::pair<TYPE, VtIntArray> ResampleIndexed(float u) const {
270  return HdResampleRawTimeSamples(u, this->count, this->times.data(),
271  this->values.data(), indices.data());
272  }
273 
274  /// Unbox an HdIndexedTimeSampleArray holding boxed VtValue<VtArray<T>>
275  /// samples into an array holding VtArray<T> samples. If any of the values
276  /// contain the wrong type, their data is discarded. The function returns
277  /// true if all samples have the correct type.
279  bool ret = true;
280  Resize(box.count);
281  this->times = box.times;
282  indices = box.indices;
283  for (size_t i=0; i < box.count; ++i) {
284  if (box.values[i].template IsHolding<TYPE>() &&
285  box.values[i].GetArraySize() > 0) {
286  this->values[i] = box.values[i].template Get<TYPE>();
287  } else {
288  this->values[i] = TYPE();
289  ret = false;
290  }
291  }
292  return ret;
293  }
294 
296 };
297 
299 
300 #endif // PXR_IMAGING_HD_TIME_SAMPLE_ARRAY_H
void resize(size_type newSize, const value_type &v=value_type())
Definition: smallVector.h:421
GLsizei GLenum const void * indices
Definition: glcorearb.h:406
HdTimeSampleArray(const HdTimeSampleArray &rhs)
TfSmallVector< float, CAPACITY > times
PXR_NAMESPACE_OPEN_SCOPE T HdResampleNeighbors(float alpha, const T &v0, const T &v1)
Resample two neighboring samples.
bool GetContributingSampleTimesForInterval(const float startTime, const float endTime, std::vector< float > *const outSampleTimes) const
See HdGetContributingSampleTimesForInterval.
#define TF_CODING_ERROR
#define HD_API
Definition: api.h:23
TYPE Resample(float u) const
T GfLerp(double alpha, const T &a, const T &b)
Definition: math.h:300
Definition: quatf.h:42
GF_API GfQuatd GfSlerp(double alpha, const GfQuatd &q0, const GfQuatd &q1)
bool HdGetContributingSampleTimesForInterval(size_t count, const float *sampleTimes, float startTime, float endTime, std::vector< float > *outSampleTimes)
#define TF_WARN
std::pair< TYPE, VtIntArray > ResampleIndexed(float u) const
bool UnboxFrom(HdTimeSampleArray< VtValue, CAPACITY > const &box)
GLfloat GLfloat GLfloat alpha
Definition: glcorearb.h:112
Definition: types.h:153
TfSmallVector< TYPE, CAPACITY > values
GLfloat v0
Definition: glcorearb.h:816
virtual void Resize(unsigned int newSize)
Resize the internal buffers.
void Resize(unsigned int newSize) override
Resize the internal buffers.
PXR_NAMESPACE_CLOSE_SCOPE PXR_NAMESPACE_OPEN_SCOPE
Definition: path.h:1425
GLenum GLsizei GLsizei GLint * values
Definition: glcorearb.h:1602
HdIndexedTimeSampleArray(const HdIndexedTimeSampleArray &rhs)
GLfloat GLfloat v1
Definition: glcorearb.h:817
#define PXR_NAMESPACE_CLOSE_SCOPE
Definition: pxr.h:74
HdIndexedTimeSampleArray & operator=(const HdIndexedTimeSampleArray &rhs)
T HdResampleRawTimeSamples(float u, size_t numSamples, const float *us, const T *vs)
GLboolean r
Definition: glcorearb.h:1222
IMF_EXPORT int numSamples(int s, int a, int b)
TfSmallVector< VtIntArray, CAPACITY > indices
Definition: value.h:146
GLint GLsizei count
Definition: glcorearb.h:405
HdTimeSampleArray & operator=(const HdTimeSampleArray &rhs)
bool UnboxFrom(HdIndexedTimeSampleArray< VtValue, CAPACITY > const &box)
value_type * data()
Definition: smallVector.h:735