All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
timeSampleArray.h
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"
19
20PXR_NAMESPACE_OPEN_SCOPE
21
23template <typename T>
24inline T HdResampleNeighbors(float alpha, const T& v0, const T& v1)
25{
26 return GfLerp(alpha, v0, v1);
27}
28
30HD_API
31inline GfQuatf HdResampleNeighbors(float alpha,
32 const GfQuatf &v0,
33 const GfQuatf &v1)
34{
35 return GfSlerp(double(alpha), v0, v1);
36}
37
39template <typename T>
40inline VtArray<T> HdResampleNeighbors(float alpha,
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
52HD_API
53VtValue HdResampleNeighbors(float alpha, const VtValue& v0, const VtValue& v1);
54
59template <typename T>
60T HdResampleRawTimeSamples(
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
104template <typename T>
105std::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.
156bool
157HdGetContributingSampleTimesForInterval(
158 size_t count,
159 const float * sampleTimes,
160 float startTime,
161 float endTime,
162 std::vector<float> * outSampleTimes);
163
169template<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
184 HdTimeSampleArray& operator=(const HdTimeSampleArray& rhs) {
185 times = rhs.times;
186 values = rhs.values;
187 count = rhs.count;
188 return *this;
189 }
190
192 virtual void Resize(unsigned int newSize) {
193 times.resize(newSize);
194 values.resize(newSize);
195 count = newSize;
196 }
197
200 TYPE Resample(float u) const {
201 return HdResampleRawTimeSamples(u, count, times.data(), values.data());
202 }
203
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
226 const float startTime, const float endTime,
227 std::vector<float> * const outSampleTimes) const
228 {
229 return HdGetContributingSampleTimesForInterval(
230 count, times.data(), startTime, endTime, outSampleTimes);
231 }
232
233 size_t count;
236};
237
240template<typename TYPE, unsigned int CAPACITY>
241struct HdIndexedTimeSampleArray : public HdTimeSampleArray<TYPE, CAPACITY>
242{
244 indices.resize(CAPACITY);
245 }
246
249 indices = rhs.indices;
250 }
251
253 operator=(const HdIndexedTimeSampleArray& rhs) {
254 this->times = rhs.times;
255 this->values = rhs.values;
256 this->count = rhs.count;
257 indices = rhs.indices;
258 return *this;
259 }
260
262 void Resize(unsigned int newSize) override {
264 indices.resize(newSize);
265 }
266
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
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
298PXR_NAMESPACE_CLOSE_SCOPE
299
300#endif // PXR_IMAGING_HD_TIME_SAMPLE_ARRAY_H
Low-level utilities for informing users of various internal and external diagnostic conditions.
Basic type: a quaternion, a complex number with a real coefficient and three imaginary coefficients,...
Definition: quatf.h:43
This is a small-vector class with local storage optimization, the local storage can be specified via ...
Definition: smallVector.h:157
void resize(size_type newSize, const value_type &v=value_type())
Resize the vector to newSize and insert copies of \v.
Definition: smallVector.h:421
value_type * data()
Direct access to the underlying array.
Definition: smallVector.h:735
Represents an arbitrary dimensional rectangular container class.
Definition: array.h:211
Provides a container which may hold any type, and provides introspection and iteration over array typ...
Definition: value.h:147
Assorted mathematical utility functions.
size_t size() const
Return the total number of elements in this array.
Definition: array.h:472
T GfLerp(double alpha, const T &a, const T &b)
Linear interpolation function.
Definition: math.h:300
#define TF_CODING_ERROR(fmt, args)
Issue an internal programming error, but continue execution.
Definition: diagnostic.h:68
#define TF_WARN(...)
Issue a warning, but continue execution.
Definition: diagnostic.h:132
GF_API GfQuatd GfSlerp(double alpha, const GfQuatd &q0, const GfQuatd &q1)
Spherically linearly interpolate between q0 and q1.
An array of a value and its indices sampled over time, in struct-of-arrays layout.
void Resize(unsigned int newSize) override
Resize the internal buffers.
std::pair< TYPE, VtIntArray > ResampleIndexed(float u) const
Convience method for invoking HdResampleRawTimeSamples on this HdIndexedTimeSampleArray.
bool UnboxFrom(HdIndexedTimeSampleArray< VtValue, CAPACITY > const &box)
Unbox an HdIndexedTimeSampleArray holding boxed VtValue<VtArray<T>> samples into an array holding VtA...
An array of a value sampled over time, in struct-of-arrays layout.
bool GetContributingSampleTimesForInterval(const float startTime, const float endTime, std::vector< float > *const outSampleTimes) const
See HdGetContributingSampleTimesForInterval.
TYPE Resample(float u) const
Convience method for invoking HdResampleRawTimeSamples on this HdTimeSampleArray.
bool UnboxFrom(HdTimeSampleArray< VtValue, CAPACITY > const &box)
Unbox an HdTimeSampleArray holding boxed VtValue<VtArray<T>> samples into an array holding VtArray<T>...
virtual void Resize(unsigned int newSize)
Resize the internal buffers.