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 Apache License, Version 2.0 (the "Apache License")
5 // with the following modification; you may not use this file except in
6 // compliance with the Apache License and the following modification to it:
7 // Section 6. Trademarks. is deleted and replaced with:
8 //
9 // 6. Trademarks. This License does not grant permission to use the trade
10 // names, trademarks, service marks, or product names of the Licensor
11 // and its affiliates, except as required to comply with Section 4(c) of
12 // the License and to reproduce the content of the NOTICE file.
13 //
14 // You may obtain a copy of the Apache License at
15 //
16 // http://www.apache.org/licenses/LICENSE-2.0
17 //
18 // Unless required by applicable law or agreed to in writing, software
19 // distributed under the Apache License with the above modification is
20 // distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
21 // KIND, either express or implied. See the Apache License for the specific
22 // language governing permissions and limitations under the Apache License.
23 //
24 #ifndef PXR_IMAGING_HD_TIME_SAMPLE_ARRAY_H
25 #define PXR_IMAGING_HD_TIME_SAMPLE_ARRAY_H
26 
27 #include "pxr/pxr.h"
28 #include "pxr/imaging/hd/api.h"
29 #include "pxr/imaging/hd/version.h"
30 #include "pxr/base/vt/array.h"
31 #include "pxr/base/vt/value.h"
32 #include "pxr/base/gf/math.h"
33 #include "pxr/base/gf/quatf.h"
34 #include "pxr/base/tf/diagnostic.h"
36 
38 
39 /// Resample two neighboring samples.
40 template <typename T>
41 inline T HdResampleNeighbors(float alpha, const T& v0, const T& v1)
42 {
43  return GfLerp(alpha, v0, v1);
44 }
45 
46 /// Specialization for HdQuatf: spherical linear interpolation.
47 HD_API
49  const GfQuatf &v0,
50  const GfQuatf &v1)
51 {
52  return GfSlerp(double(alpha), v0, v1);
53 }
54 
55 /// Specialization for VtArray: component-wise resampling.
56 template <typename T>
58  const VtArray<T>& v0,
59  const VtArray<T>& v1)
60 {
61  VtArray<T> r(v0.size());
62  for (size_t i=0; i < r.size(); ++i) {
63  r[i] = HdResampleNeighbors(alpha, v0[i], v1[i]);
64  }
65  return r;
66 }
67 
68 /// Specialization for VtValue: interpolate the held values.
69 HD_API
70 VtValue HdResampleNeighbors(float alpha, const VtValue& v0, const VtValue& v1);
71 
72 /// Resample a function described by an ordered array of samples,
73 /// using a linear reconstruction filter evaluated at the given
74 /// parametric position u. The function is considered constant
75 /// outside the supplied sample range.
76 template <typename T>
78  float u,
79  size_t numSamples,
80  const float *us,
81  const T *vs)
82 {
83  if (numSamples == 0) {
84  TF_CODING_ERROR("HdResampleRawTimeSamples: Zero samples provided");
85  return T();
86  }
87 
88  size_t i=0;
89  for (; i < numSamples; ++i) {
90  if (us[i] == u) {
91  // Fast path for exact parameter match.
92  return vs[i];
93  }
94  if (us[i] > u) {
95  break;
96  }
97  }
98  if (i == 0) {
99  // u is before the first sample.
100  return vs[0];
101  } else if (i == numSamples) {
102  // u is after the last sample.
103  return vs[numSamples-1];
104  } else if (us[i] == us[i-1]) {
105  // Neighboring samples have identical parameter.
106  // Arbitrarily choose a sample.
107  TF_WARN("HdResampleRawTimeSamples: overlapping samples at %f; "
108  "using first sample", us[i]);
109  return vs[i-1];
110  } else {
111  // Linear blend of neighboring samples.
112  float alpha = (u-us[i-1]) / (us[i]-us[i-1]);
113  return HdResampleNeighbors(alpha, vs[i-1], vs[i]);
114  }
115 }
116 
117 /// Resample a function described by an ordered array of samples and sample
118 /// indices, using a linear reconstruction filter evaluated at the given
119 /// parametric position u. The function is considered constant outside the
120 /// supplied sample range.
121 template <typename T>
122 std::pair<T, VtIntArray> HdResampleRawTimeSamples(
123  float u,
124  size_t numSamples,
125  const float *us,
126  const T *vs,
127  const VtIntArray *is)
128 {
129  if (numSamples == 0) {
130  TF_CODING_ERROR("HdResampleRawTimeSamples: Zero samples provided");
131  return std::pair<T, VtIntArray>(T(), VtIntArray(0));
132  }
133 
134  size_t i=0;
135  for (; i < numSamples; ++i) {
136  if (us[i] == u) {
137  // Fast path for exact parameter match.
138  return std::pair<T, VtIntArray>(vs[i], is[i]);
139  }
140  if (us[i] > u) {
141  break;
142  }
143  }
144  if (i == 0) {
145  // u is before the first sample.
146  return std::pair<T, VtIntArray>(vs[0], is[0]);
147  } else if (i == numSamples) {
148  // u is after the last sample.
149  return std::pair<T, VtIntArray>(vs[numSamples-1], is[numSamples-1]);
150  } else if (us[i] == us[i-1]) {
151  // Neighboring samples have identical parameter.
152  // Arbitrarily choose a sample.
153  TF_WARN("HdResampleRawTimeSamples: overlapping samples at %f; "
154  "using first sample", us[i]);
155  return std::pair<T, VtIntArray>(vs[i-1], is[i-1]);
156  } else {
157  // Linear blend of neighboring samples for values
158  // Hold earlier value for indices
159  float alpha = (us[i]-u) / (us[i]-us[i-1]);
160  return std::pair<T, VtIntArray>(
161  HdResampleNeighbors(alpha, vs[i-1], vs[i]),
162  is[i-1]);
163  }
164 }
165 
166 /// An array of a value sampled over time, in struct-of-arrays layout.
167 /// This is provided as a convenience for time-sampling attributes.
168 /// This type has static capacity but dynamic size, providing
169 /// a limited ability to handle variable sampling without requiring
170 /// heap allocation.
171 template<typename TYPE, unsigned int CAPACITY>
173 {
175  times.resize(CAPACITY);
176  values.resize(CAPACITY);
177  count = 0;
178  }
179 
181  times = rhs.times;
182  values = rhs.values;
183  count = rhs.count;
184  }
185 
187  times = rhs.times;
188  values = rhs.values;
189  count = rhs.count;
190  return *this;
191  }
192 
193  /// Resize the internal buffers.
194  virtual void Resize(unsigned int newSize) {
195  times.resize(newSize);
196  values.resize(newSize);
197  count = newSize;
198  }
199 
200  /// Convience method for invoking HdResampleRawTimeSamples
201  /// on this HdTimeSampleArray.
202  TYPE Resample(float u) const {
203  return HdResampleRawTimeSamples(u, count, times.data(), values.data());
204  }
205 
206  /// Unbox an HdTimeSampleArray holding boxed VtValue<VtArray<T>>
207  /// samples into an array holding VtArray<T> samples. If any of the values
208  /// contain the wrong type, their data is discarded. The function returns
209  /// true if all samples have the correct type.
211  bool ret = true;
212  Resize(box.count);
213  times = box.times;
214  for (size_t i=0; i < box.count; ++i) {
215  if (box.values[i].template IsHolding<TYPE>() &&
216  box.values[i].GetArraySize() > 0) {
217  values[i] = box.values[i].template Get<TYPE>();
218  } else {
219  values[i] = TYPE();
220  ret = false;
221  }
222  }
223  return ret;
224  }
225 
226  size_t count;
229 };
230 
231 /// An array of a value and its indices sampled over time, in struct-of-arrays
232 /// layout.
233 template<typename TYPE, unsigned int CAPACITY>
234 struct HdIndexedTimeSampleArray : public HdTimeSampleArray<TYPE, CAPACITY>
235 {
237  indices.resize(CAPACITY);
238  }
239 
241  HdTimeSampleArray<TYPE, CAPACITY>(rhs) {
242  indices = rhs.indices;
243  }
244 
247  this->times = rhs.times;
248  this->values = rhs.values;
249  this->count = rhs.count;
250  indices = rhs.indices;
251  return *this;
252  }
253 
254  /// Resize the internal buffers.
255  void Resize(unsigned int newSize) override {
257  indices.resize(newSize);
258  }
259 
260  /// Convience method for invoking HdResampleRawTimeSamples
261  /// on this HdIndexedTimeSampleArray.
262  std::pair<TYPE, VtIntArray> ResampleIndexed(float u) const {
263  return HdResampleRawTimeSamples(u, this->count, this->times.data(),
264  this->values.data(), indices.data());
265  }
266 
267  /// Unbox an HdIndexedTimeSampleArray holding boxed VtValue<VtArray<T>>
268  /// samples into an array holding VtArray<T> samples. If any of the values
269  /// contain the wrong type, their data is discarded. The function returns
270  /// true if all samples have the correct type.
272  bool ret = true;
273  Resize(box.count);
274  this->times = box.times;
275  indices = box.indices;
276  for (size_t i=0; i < box.count; ++i) {
277  if (box.values[i].template IsHolding<TYPE>() &&
278  box.values[i].GetArraySize() > 0) {
279  this->values[i] = box.values[i].template Get<TYPE>();
280  } else {
281  this->values[i] = TYPE();
282  ret = false;
283  }
284  }
285  return ret;
286  }
287 
289 };
290 
292 
293 #endif // PXR_IMAGING_HD_TIME_SAMPLE_ARRAY_H
void resize(size_type newSize, const value_type &v=value_type())
Definition: smallVector.h:454
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.
#define TF_CODING_ERROR
#define HD_API
Definition: api.h:40
TYPE Resample(float u) const
T GfLerp(double alpha, const T &a, const T &b)
Definition: math.h:193
Definition: quatf.h:59
GF_API GfQuatd GfSlerp(double alpha, const GfQuatd &q0, const GfQuatd &q1)
#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:173
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:1441
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:91
HdIndexedTimeSampleArray & operator=(const HdIndexedTimeSampleArray &rhs)
T HdResampleRawTimeSamples(float u, size_t numSamples, const float *us, const T *vs)
GLboolean r
Definition: glcorearb.h:1222
TfSmallVector< VtIntArray, CAPACITY > indices
Definition: value.h:167
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:768