HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
evalCache.h
Go to the documentation of this file.
1 //
2 // Copyright 2023 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 
25 #ifndef PXR_BASE_TS_EVAL_CACHE_H
26 #define PXR_BASE_TS_EVAL_CACHE_H
27 
28 #include "pxr/pxr.h"
29 #include "pxr/base/gf/math.h"
31 #include "pxr/base/ts/mathUtils.h"
32 #include "pxr/base/ts/types.h"
33 #include "pxr/base/vt/value.h"
34 
35 #include "pxr/base/tf/tf.h"
36 
37 #include <type_traits>
38 
40 
41 class TsKeyFrame;
42 template <typename T> class Ts_TypedData;
43 
44 // Bezier data. This holds two beziers (time and value) as both points
45 // and the coefficients of a cubic polynomial.
46 template <typename T>
47 class Ts_Bezier {
48 public:
49  Ts_Bezier() { }
50  Ts_Bezier(const TsTime timePoints[4], const T valuePoints[4]);
51  void DerivePolynomial();
52 
53 public:
58 };
59 
60 template <typename T>
62 {
63  timePoints[0] = time[0];
64  timePoints[1] = time[1];
65  timePoints[2] = time[2];
66  timePoints[3] = time[3];
67  valuePoints[0] = value[0];
68  valuePoints[1] = value[1];
69  valuePoints[2] = value[2];
70  valuePoints[3] = value[3];
71  DerivePolynomial();
72 }
73 
74 template <typename T>
75 void
77 {
78  timeCoeff[0] = timePoints[0];
79  timeCoeff[1] = -3.0 * timePoints[0] +
80  3.0 * timePoints[1];
81  timeCoeff[2] = 3.0 * timePoints[0] +
82  -6.0 * timePoints[1] +
83  3.0 * timePoints[2];
84  timeCoeff[3] = -1.0 * timePoints[0] +
85  3.0 * timePoints[1] +
86  -3.0 * timePoints[2] +
87  timePoints[3];
88  valueCoeff[0] = valuePoints[0];
89  valueCoeff[1] = -3.0 * valuePoints[0] +
90  3.0 * valuePoints[1];
91  valueCoeff[2] = 3.0 * valuePoints[0] +
92  -6.0 * valuePoints[1] +
93  3.0 * valuePoints[2];
94  valueCoeff[3] = -1.0 * valuePoints[0] +
95  3.0 * valuePoints[1] +
96  -3.0 * valuePoints[2] +
97  valuePoints[3];
98 }
99 
101 public:
102  typedef std::shared_ptr<Ts_UntypedEvalCache> SharedPtr;
103 
104  /// Construct and return a new eval cache for the given keyframes.
105  static SharedPtr New(const TsKeyFrame &kf1, const TsKeyFrame &kf2);
106 
107  virtual VtValue Eval(TsTime) const = 0;
108  virtual VtValue EvalDerivative(TsTime) const = 0;
109 
110  // Equivalent to invoking New() and Eval(time) on the newly created cache,
111  // but without the heap allocation.
112  static VtValue EvalUncached(const TsKeyFrame &kf1,
113  const TsKeyFrame &kf2,
114  TsTime time);
115 
116  // Equivalent to invoking New() and EvalDerivative(time) on the newly
117  // created cache, but without the heap allocation.
118  static VtValue EvalDerivativeUncached(const TsKeyFrame &kf1,
119  const TsKeyFrame &kf2,
120  TsTime time);
121 
122 protected:
123  ~Ts_UntypedEvalCache() = default;
124 
125  // Compute the Bezier control points.
126  template <typename T>
127  static void _SetupBezierGeometry(TsTime* timePoints, T* valuePoints,
128  const Ts_TypedData<T>* kf1,
129  const Ts_TypedData<T>* kf2);
130 
131  // Compute the time coordinate of the 2nd Bezier control point. This
132  // synthesizes tangents for held and linear knots.
133  template <typename T>
134  static TsTime _GetBezierPoint2Time(const Ts_TypedData<T>* kf1,
135  const Ts_TypedData<T>* kf2);
136 
137  // Compute the time coordinate of the 3rd Bezier control point. This
138  // synthesizes tangents for held and linear knots.
139  template <typename T>
140  static TsTime _GetBezierPoint3Time(const Ts_TypedData<T>* kf1,
141  const Ts_TypedData<T>* kf2);
142 
143  // Compute the value coordinate of the 2nd Bezier control point. This
144  // synthesizes tangents for held and linear knots.
145  template <typename T>
146  static T _GetBezierPoint2Value(const Ts_TypedData<T>* kf1,
147  const Ts_TypedData<T>* kf2);
148 
149  // Compute the value coordinate of the 3rd Bezier control point. This
150  // synthesizes tangents for held and linear knots.
151  template <typename T>
152  static T _GetBezierPoint3Value(const Ts_TypedData<T>* kf1,
153  const Ts_TypedData<T>* kf2);
154 
155  // Compute the value coordinate of the 4th Bezier control point. This
156  // synthesizes tangents for held and linear knots.
157  template <typename T>
158  static T _GetBezierPoint4Value(const Ts_TypedData<T>* kf1,
159  const Ts_TypedData<T>* kf2);
160 };
161 
162 template <typename T, bool INTERPOLATABLE = TsTraits<T>::interpolatable >
164 
165 template <typename T>
167 protected:
168  static_assert(std::is_same<T, GfQuatf>::value
170  , "T must be Quatd or Quatf");
173  const Ts_TypedData<T>* kf2);
175  const TsKeyFrame & kf2);
176 
177 public:
178  T TypedEval(TsTime) const;
180 
181  VtValue Eval(TsTime t) const override;
182  VtValue EvalDerivative(TsTime t) const override;
183 private:
184  void _Init(const Ts_TypedData<T>* kf1, const Ts_TypedData<T>* kf2);
185  double _kf1_time, _kf2_time;
186  T _kf1_value, _kf2_value;
187  TsKnotType _kf1_knot_type;
188 };
189 
190 template<>
191 class Ts_EvalCache<GfQuatf, true> final
192  : public Ts_EvalQuaternionCache<GfQuatf> {
193 public:
197  const Ts_TypedData<GfQuatf>* kf2) :
198  Ts_EvalQuaternionCache<GfQuatf>(kf1, kf2) {}
199  Ts_EvalCache(const TsKeyFrame & kf1, const TsKeyFrame & kf2) :
200  Ts_EvalQuaternionCache<GfQuatf>(kf1, kf2) {}
201 
202  typedef std::shared_ptr<Ts_EvalCache<GfQuatf, true> > TypedSharedPtr;
203 
204  /// Construct and return a new eval cache for the given keyframes.
205  static TypedSharedPtr New(const TsKeyFrame &kf1, const TsKeyFrame &kf2);
206 };
207 
208 template<>
209 class Ts_EvalCache<GfQuatd, true> final
210  : public Ts_EvalQuaternionCache<GfQuatd> {
211 public:
215  const Ts_TypedData<GfQuatd>* kf2) :
216  Ts_EvalQuaternionCache<GfQuatd>(kf1, kf2) {}
217  Ts_EvalCache(const TsKeyFrame & kf1, const TsKeyFrame & kf2) :
218  Ts_EvalQuaternionCache<GfQuatd>(kf1, kf2) {}
219 
220  typedef std::shared_ptr<Ts_EvalCache<GfQuatd, true> > TypedSharedPtr;
221 
222  /// Construct and return a new eval cache for the given keyframes.
223  static TypedSharedPtr New(const TsKeyFrame &kf1, const TsKeyFrame &kf2);
224 
225 };
226 
227 // Partial specialization for types that cannot be interpolated.
228 template <typename T>
229 class Ts_EvalCache<T, false> final : public Ts_UntypedEvalCache {
230 public:
232  Ts_EvalCache(const Ts_TypedData<T>* kf1, const Ts_TypedData<T>* kf2);
233  Ts_EvalCache(const TsKeyFrame & kf1, const TsKeyFrame & kf2);
234  T TypedEval(TsTime) const;
235  T TypedEvalDerivative(TsTime) const;
236 
237  VtValue Eval(TsTime t) const override;
238  VtValue EvalDerivative(TsTime t) const override;
239 
240  typedef std::shared_ptr<Ts_EvalCache<T, false> > TypedSharedPtr;
241 
242  /// Construct and return a new eval cache for the given keyframes.
243  static TypedSharedPtr New(const TsKeyFrame &kf1, const TsKeyFrame &kf2);
244 
245 private:
246  T _value;
247 };
248 
249 // Partial specialization for types that can be interpolated.
250 template <typename T>
251 class Ts_EvalCache<T, true> final : public Ts_UntypedEvalCache {
252 public:
253  Ts_EvalCache(const Ts_EvalCache<T, true> * rhs);
254  Ts_EvalCache(const Ts_TypedData<T>* kf1, const Ts_TypedData<T>* kf2);
255  Ts_EvalCache(const TsKeyFrame & kf1, const TsKeyFrame & kf2);
256  T TypedEval(TsTime) const;
257  T TypedEvalDerivative(TsTime) const;
258 
259  VtValue Eval(TsTime t) const override;
260  VtValue EvalDerivative(TsTime t) const override;
261 
262  const Ts_Bezier<T>* GetBezier() const;
263 
264  typedef std::shared_ptr<Ts_EvalCache<T, true> > TypedSharedPtr;
265 
266  /// Construct and return a new eval cache for the given keyframes.
267  static TypedSharedPtr New(const TsKeyFrame &kf1, const TsKeyFrame &kf2);
268 
269 private:
270  void _Init(const Ts_TypedData<T>* kf1, const Ts_TypedData<T>* kf2);
271 
272 private:
273  bool _interpolate;
274 
275  // Value to use when _interpolate is false.
276  T _value;
277 
278  Ts_Bezier<T> _cache;
279 };
280 
281 ////////////////////////////////////////////////////////////////////////
282 // Ts_UntypedEvalCache
283 
284 template <typename T>
285 TsTime
287  const Ts_TypedData<T>* kf2)
288 {
289  switch (kf1->_knotType) {
290  default:
291  case TsKnotHeld:
292  case TsKnotLinear:
293  return (2.0 * kf1->GetTime() + kf2->GetTime()) / 3.0;
294 
295  case TsKnotBezier:
296  return kf1->GetTime() + kf1->_rightTangentLength;
297  }
298 }
299 
300 template <typename T>
301 TsTime
303  const Ts_TypedData<T>* kf2)
304 {
305  // If the the first keyframe is held then the we treat the third bezier
306  // point as held too.
307  TsKnotType knotType = (kf1->_knotType == TsKnotHeld) ?
308  TsKnotHeld : kf2->_knotType;
309 
310  switch (knotType) {
311  default:
312  case TsKnotHeld:
313  case TsKnotLinear:
314  return (kf1->GetTime() + 2.0 * kf2->GetTime()) / 3.0;
315 
316  case TsKnotBezier:
317  return kf2->GetTime() - kf2->_leftTangentLength;
318  }
319 }
320 
321 template <typename T>
322 T
324  const Ts_TypedData<T>* kf2)
325 {
326  switch (kf1->_knotType) {
327  default:
328  case TsKnotHeld:
329  return kf1->_GetRightValue();
330 
331  case TsKnotLinear:
332  return (1.0 / 3.0) *
333  (2.0 * kf1->_GetRightValue() +
334  (kf2->_isDual ? kf2->_GetLeftValue() : kf2->_GetRightValue()));
335 
336  case TsKnotBezier:
337  return kf1->_GetRightValue() +
338  kf1->_rightTangentLength * kf1->_GetRightTangentSlope();
339  }
340 }
341 
342 template <typename T>
343 T
345  const Ts_TypedData<T>* kf2)
346 {
347  // If the first key frame is held then the we just use the first key frame's
348  // value
349  if (kf1->_knotType == TsKnotHeld) {
350  return kf1->_GetRightValue();
351  }
352 
353  switch (kf2->_knotType) {
354  default:
355  case TsKnotHeld:
356  if (kf1->_knotType != TsKnotLinear) {
357  return kf2->_isDual ? kf2->_GetLeftValue() : kf2->_GetRightValue();
358  }
359  // Fall through to linear case if the first knot is linear
360  [[fallthrough]];
361 
362  case TsKnotLinear:
363  return (1.0 / 3.0) *
364  (kf1->_GetRightValue() + 2.0 *
365  (kf2->_isDual ? kf2->_GetLeftValue() : kf2->_GetRightValue()));
366 
367  case TsKnotBezier:
368  return (kf2->_isDual ? kf2->_GetLeftValue() : kf2->_GetRightValue()) -
369  kf2->_leftTangentLength * kf2->_GetLeftTangentSlope();
370  }
371 }
372 
373 template <typename T>
374 T
376  const Ts_TypedData<T>* kf2)
377 {
378  // If the first knot is held then the last value is still the value of
379  // the first knot, otherwise it's the left side of the second knot
380  if (kf1->_knotType == TsKnotHeld) {
381  return kf1->_GetRightValue();
382  } else {
383  return (kf2->_isDual ? kf2->_GetLeftValue() : kf2->_GetRightValue());
384  }
385 }
386 
387 template <typename T>
388 void
390  TsTime* timePoints, T* valuePoints,
391  const Ts_TypedData<T>* kf1, const Ts_TypedData<T>* kf2)
392 {
393  timePoints[0] = kf1->GetTime();
394  timePoints[1] = _GetBezierPoint2Time(kf1, kf2);
395  timePoints[2] = _GetBezierPoint3Time(kf1, kf2);
396  timePoints[3] = kf2->GetTime();
397  valuePoints[0] = kf1->_GetRightValue();
398  valuePoints[1] = _GetBezierPoint2Value(kf1, kf2);
399  valuePoints[2] = _GetBezierPoint3Value(kf1, kf2);
400  valuePoints[3] = _GetBezierPoint4Value(kf1, kf2);
401 }
402 
403 ////////////////////////////////////////////////////////////////////////
404 // Ts_EvalCache non-interpolatable
405 
406 template <typename T>
408 {
409  _value = rhs->_value;
410 }
411 
412 template <typename T>
414  const Ts_TypedData<T>* kf2)
415 {
416  if (!kf1 || !kf2) {
417  TF_CODING_ERROR("Constructing an Ts_EvalCache from invalid keyframes");
418  return;
419  }
420 
421  _value = kf1->_GetRightValue();
422 }
423 
424 template <typename T>
426  const TsKeyFrame &kf2)
427 {
428  // Cast to the correct typed data. This is a private class, and we assume
429  // callers are passing only keyframes from the same spline, and correctly
430  // arranging our T to match.
432  static_cast<Ts_TypedData<T> const*>(Ts_GetKeyFrameData(kf1));
433 
434  _value = data->_GetRightValue();
435 }
436 
437 template <typename T>
438 VtValue
440  return VtValue(TypedEval(t));
441 }
442 
443 template <typename T>
444 VtValue
446  return VtValue(TypedEvalDerivative(t));
447 }
448 
449 template <typename T>
450 T
452 {
453  return _value;
454 }
455 
456 template <typename T>
457 T
459 {
460  return TsTraits<T>::zero;
461 }
462 
463 ////////////////////////////////////////////////////////////////////////
464 // Ts_EvalCache interpolatable
465 
466 template <typename T>
468 {
469  _interpolate = rhs->_interpolate;
470  _value = rhs->_value;
471  _cache = rhs->_cache;
472 }
473 
474 template <typename T>
476  const Ts_TypedData<T>* kf2)
477 {
478  _Init(kf1,kf2);
479 }
480 
481 template <typename T>
483  const TsKeyFrame &kf2)
484 {
485  // Cast to the correct typed data. This is a private class, and we assume
486  // callers are passing only keyframes from the same spline, and correctly
487  // arranging our T to match.
488  _Init(static_cast<Ts_TypedData<T> const*>(Ts_GetKeyFrameData(kf1)),
489  static_cast<Ts_TypedData<T> const*>(Ts_GetKeyFrameData(kf2)));
490 }
491 
492 template <typename T>
493 void
495  const Ts_TypedData<T>* kf1,
496  const Ts_TypedData<T>* kf2)
497 {
498  if (!kf1 || !kf2) {
499  TF_CODING_ERROR("Constructing an Ts_EvalCache from invalid keyframes");
500  return;
501  }
502 
503  // Curve for same knot types or left half of blend for different knot types
504  _SetupBezierGeometry(_cache.timePoints, _cache.valuePoints, kf1, kf2);
505  _cache.DerivePolynomial();
506 
507  if (kf1->ValueCanBeInterpolated() && kf2->ValueCanBeInterpolated()) {
508  _interpolate = true;
509  } else {
510  _interpolate = false;
511  _value = kf1->_GetRightValue();
512  }
513 }
514 
515 template <typename T>
516 VtValue
518  return VtValue(TypedEval(t));
519 }
520 
521 template <typename T>
522 VtValue
524  return VtValue(TypedEvalDerivative(t));
525 }
526 
527 template <typename T>
528 T
530 {
531  if (!_interpolate)
532  return _value;
533 
534  double u = GfClamp(Ts_SolveCubic(_cache.timeCoeff, time), 0.0, 1.0);
535  return Ts_EvalCubic(_cache.valueCoeff, u);
536 }
537 
538 template <typename T>
539 T
541 {
542  if (!TsTraits<T>::supportsTangents || !_interpolate) {
543  return TsTraits<T>::zero;
544  }
545 
546  // calculate the derivative as
547  // u = t^-1(time)
548  // dx(u)
549  // ----
550  // du dx(u)
551  // -------- = -----
552  // dt(u) dt(u)
553  // ----
554  // du
555  double u;
556  u = GfClamp(Ts_SolveCubic(_cache.timeCoeff, time), 0.0, 1.0);
557  T x = Ts_EvalCubicDerivative(_cache.valueCoeff, u);
558  TsTime t = Ts_EvalCubicDerivative(_cache.timeCoeff, u);
559  T derivative = x * (1.0 / t);
560  return derivative;
561 }
562 
563 template <typename T>
564 const Ts_Bezier<T>*
566 {
567  return &_cache;
568 }
569 
570 template <typename T>
571 std::shared_ptr<Ts_EvalCache<T, true> >
573 {
574  // Cast to the correct typed data. This is a private class, and we assume
575  // callers are passing only keyframes from the same spline, and correctly
576  // arranging our T to match.
577  return static_cast<const Ts_TypedData<T>*>(
578  Ts_GetKeyFrameData(kf1))->
579  CreateTypedEvalCache(Ts_GetKeyFrameData(kf2));
580 }
581 
582 template <typename T>
583 std::shared_ptr<Ts_EvalCache<T, false> >
585 {
586  // Cast to the correct typed data. This is a private class, and we assume
587  // callers are passing only keyframes from the same spline, and correctly
588  // arranging our T to match.
589  return static_cast<const Ts_TypedData<T>*>(
590  Ts_GetKeyFrameData(kf1))->
591  CreateTypedEvalCache(Ts_GetKeyFrameData(kf2));
592 }
593 
594 ////////////////////////////////////////////////////////////////////////
595 // Ts_EvalQuaternionCache
596 
597 template <typename T>
599  const Ts_EvalQuaternionCache<T> * rhs)
600 {
601  _kf1_knot_type = rhs->_kf1_knot_type;
602 
603  _kf1_time = rhs->_kf1_time;
604  _kf2_time = rhs->_kf2_time;
605 
606  _kf1_value = rhs->_kf1_value;
607  _kf2_value = rhs->_kf2_value;
608 }
609 
610 template <typename T>
612  const Ts_TypedData<T>* kf1, const Ts_TypedData<T>* kf2)
613 {
614  _Init(kf1,kf2);
615 }
616 
617 template <typename T>
619  const TsKeyFrame &kf2)
620 {
621  // Cast to the correct typed data. This is a private class, and we assume
622  // callers are passing only keyframes from the same spline, and correctly
623  // arranging our T to match.
624  _Init(static_cast<Ts_TypedData<T> const*>(Ts_GetKeyFrameData(kf1)),
625  static_cast<Ts_TypedData<T> const*>(Ts_GetKeyFrameData(kf2)));
626 }
627 
628 template <typename T>
629 void
631  const Ts_TypedData<T>* kf1,
632  const Ts_TypedData<T>* kf2)
633 {
634  if (!kf1 || !kf2) {
635  TF_CODING_ERROR("Constructing an Ts_EvalQuaternionCache"
636  " from invalid keyframes");
637  return;
638  }
639 
640  _kf1_knot_type = kf1->_knotType;
641 
642  _kf1_time = kf1->GetTime();
643  _kf2_time = kf2->GetTime();
644 
645  _kf1_value = kf1->_GetRightValue();
646  _kf2_value = kf2->_isDual ? kf2->_GetLeftValue() : kf2->_GetRightValue();
647 }
648 
649 template <typename T>
650 VtValue
652  return VtValue(TypedEval(t));
653 }
654 
655 template <typename T>
657 {
658  if (_kf1_knot_type == TsKnotHeld) {
659  return _kf1_value;
660  }
661 
662  // XXX: do we want any snapping here? divide-by-zero avoidance?
663  // The following code was in Presto; not sure it belongs in Ts.
664  //
665  //if (fabs(_kf2_time - _kf1_time) < ARCH_MIN_FLOAT_EPS_SQR) {
666  // return _kf1_value;
667  //}
668 
669  double u = (time - _kf1_time) / (_kf2_time - _kf1_time);
670  return GfSlerp(_kf1_value, _kf2_value, u);
671 }
672 
673 template<typename T>
675  return VtValue(TypedEvalDerivative(t));
676 }
677 
678 template<typename T>
680  return TsTraits<T>::zero;
681 }
682 
684 
685 #endif
VtValue Eval(TsTime t) const override
Definition: evalCache.h:651
T TypedEval(TsTime) const
Definition: evalCache.h:656
TsTime timeCoeff[4]
Definition: evalCache.h:55
double GfClamp(double value, double min, double max)
Definition: math.h:156
A Linear knot; tangents will be ignored.
Definition: types.h:66
Ts_EvalQuaternionCache(const Ts_EvalQuaternionCache< T > *rhs)
Definition: evalCache.h:598
GT_API const UT_StringHolder time
static VtValue EvalDerivativeUncached(const TsKeyFrame &kf1, const TsKeyFrame &kf2, TsTime time)
GLsizei const GLfloat * value
Definition: glcorearb.h:824
A held-value knot; tangents will be ignored.
Definition: types.h:65
#define TF_CODING_ERROR
A Bezier knot.
Definition: types.h:67
bool ValueCanBeInterpolated() const override
Definition: data.h:750
static TsTime _GetBezierPoint2Time(const Ts_TypedData< T > *kf1, const Ts_TypedData< T > *kf2)
Definition: evalCache.h:286
~Ts_UntypedEvalCache()=default
T Ts_EvalCubic(const T c[4], double u)
Definition: mathUtils.h:74
std::shared_ptr< Ts_EvalCache< T, true > > TypedSharedPtr
Definition: evalCache.h:264
Definition: quatf.h:59
virtual VtValue Eval(TsTime) const =0
static TsTime _GetBezierPoint3Time(const Ts_TypedData< T > *kf1, const Ts_TypedData< T > *kf2)
Definition: evalCache.h:302
T Ts_EvalCubicDerivative(const T c[4], double u)
Definition: mathUtils.h:81
GF_API GfQuatd GfSlerp(double alpha, const GfQuatd &q0, const GfQuatd &q1)
TS_API Ts_Data * Ts_GetKeyFrameData(TsKeyFrame &kf)
T valueCoeff[4]
Definition: evalCache.h:57
std::shared_ptr< Ts_UntypedEvalCache > SharedPtr
Definition: evalCache.h:102
TsKnotType
Keyframe knot types.
Definition: types.h:64
TS_API double Ts_SolveCubic(const TsTime c[4], TsTime time)
static VtValue EvalUncached(const TsKeyFrame &kf1, const TsKeyFrame &kf2, TsTime time)
Ts_EvalCache(const Ts_TypedData< GfQuatf > *kf1, const Ts_TypedData< GfQuatf > *kf2)
Definition: evalCache.h:196
Specifies the value of an TsSpline object at a particular point in time.
Definition: keyFrame.h:66
GLint GLenum GLint x
Definition: glcorearb.h:409
Ts_EvalCache(const Ts_TypedData< GfQuatd > *kf1, const Ts_TypedData< GfQuatd > *kf2)
Definition: evalCache.h:214
Ts_EvalCache(const Ts_EvalCache< GfQuatd, true > *rhs)
Definition: evalCache.h:212
static T _GetBezierPoint2Value(const Ts_TypedData< T > *kf1, const Ts_TypedData< T > *kf2)
Definition: evalCache.h:323
GLdouble t
Definition: glad.h:2397
PXR_NAMESPACE_OPEN_SCOPE typedef double TsTime
The time type used by Ts.
Definition: types.h:57
TsTime timePoints[4]
Definition: evalCache.h:54
Ts_EvalCache(const TsKeyFrame &kf1, const TsKeyFrame &kf2)
Definition: evalCache.h:217
static SharedPtr New(const TsKeyFrame &kf1, const TsKeyFrame &kf2)
Construct and return a new eval cache for the given keyframes.
T TypedEvalDerivative(TsTime) const
Definition: evalCache.h:679
PXR_NAMESPACE_CLOSE_SCOPE PXR_NAMESPACE_OPEN_SCOPE
Definition: path.h:1432
TsTime GetTime() const
Definition: data.h:75
static T _GetBezierPoint4Value(const Ts_TypedData< T > *kf1, const Ts_TypedData< T > *kf2)
Definition: evalCache.h:375
static void _SetupBezierGeometry(TsTime *timePoints, T *valuePoints, const Ts_TypedData< T > *kf1, const Ts_TypedData< T > *kf2)
Definition: evalCache.h:389
static T _GetBezierPoint3Value(const Ts_TypedData< T > *kf1, const Ts_TypedData< T > *kf2)
Definition: evalCache.h:344
std::shared_ptr< Ts_EvalCache< GfQuatf, true > > TypedSharedPtr
Definition: evalCache.h:202
#define PXR_NAMESPACE_CLOSE_SCOPE
Definition: pxr.h:91
void DerivePolynomial()
Definition: evalCache.h:76
T valuePoints[4]
Definition: evalCache.h:56
Definition: core.h:1131
Ts_EvalCache(const TsKeyFrame &kf1, const TsKeyFrame &kf2)
Definition: evalCache.h:199
std::shared_ptr< Ts_EvalCache< GfQuatd, true > > TypedSharedPtr
Definition: evalCache.h:220
Definition: quatd.h:59
VtValue EvalDerivative(TsTime t) const override
Definition: evalCache.h:674
Ts_EvalCache(const Ts_EvalCache< GfQuatf, true > *rhs)
Definition: evalCache.h:194
Ts_Bezier()
Definition: evalCache.h:49
Definition: value.h:164
Definition: format.h:895
std::shared_ptr< Ts_EvalCache< T, false > > TypedSharedPtr
Definition: evalCache.h:240
virtual VtValue EvalDerivative(TsTime) const =0