25 #ifndef PXR_BASE_TS_EVAL_CACHE_H
26 #define PXR_BASE_TS_EVAL_CACHE_H
37 #include <type_traits>
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];
78 timeCoeff[0] = timePoints[0];
79 timeCoeff[1] = -3.0 * timePoints[0] +
81 timeCoeff[2] = 3.0 * timePoints[0] +
82 -6.0 * timePoints[1] +
84 timeCoeff[3] = -1.0 * timePoints[0] +
86 -3.0 * timePoints[2] +
88 valueCoeff[0] = valuePoints[0];
89 valueCoeff[1] = -3.0 * valuePoints[0] +
91 valueCoeff[2] = 3.0 * valuePoints[0] +
92 -6.0 * valuePoints[1] +
94 valueCoeff[3] = -1.0 * valuePoints[0] +
95 3.0 * valuePoints[1] +
96 -3.0 * valuePoints[2] +
126 template <
typename T>
133 template <
typename T>
139 template <
typename T>
145 template <
typename T>
151 template <
typename T>
157 template <
typename T>
162 template <typename T, bool INTERPOLATABLE = TsTraits<T>::interpolatable >
165 template <
typename T>
170 ,
"T must be Quatd or Quatf");
185 double _kf1_time, _kf2_time;
186 T _kf1_value, _kf2_value;
228 template <
typename T>
235 T TypedEvalDerivative(
TsTime)
const;
250 template <
typename T>
257 T TypedEvalDerivative(
TsTime)
const;
284 template <
typename T>
289 switch (kf1->_knotType) {
296 return kf1->
GetTime() + kf1->_rightTangentLength;
300 template <
typename T>
317 return kf2->
GetTime() - kf2->_leftTangentLength;
321 template <
typename T>
326 switch (kf1->_knotType) {
329 return kf1->_GetRightValue();
333 (2.0 * kf1->_GetRightValue() +
334 (kf2->_isDual ? kf2->_GetLeftValue() : kf2->_GetRightValue()));
337 return kf1->_GetRightValue() +
338 kf1->_rightTangentLength * kf1->_GetRightTangentSlope();
342 template <
typename T>
350 return kf1->_GetRightValue();
353 switch (kf2->_knotType) {
357 return kf2->_isDual ? kf2->_GetLeftValue() : kf2->_GetRightValue();
364 (kf1->_GetRightValue() + 2.0 *
365 (kf2->_isDual ? kf2->_GetLeftValue() : kf2->_GetRightValue()));
368 return (kf2->_isDual ? kf2->_GetLeftValue() : kf2->_GetRightValue()) -
369 kf2->_leftTangentLength * kf2->_GetLeftTangentSlope();
373 template <
typename T>
381 return kf1->_GetRightValue();
383 return (kf2->_isDual ? kf2->_GetLeftValue() : kf2->_GetRightValue());
387 template <
typename T>
390 TsTime* timePoints, T* valuePoints,
393 timePoints[0] = kf1->
GetTime();
396 timePoints[3] = kf2->
GetTime();
397 valuePoints[0] = kf1->_GetRightValue();
406 template <
typename T>
409 _value = rhs->_value;
412 template <
typename T>
417 TF_CODING_ERROR(
"Constructing an Ts_EvalCache from invalid keyframes");
421 _value = kf1->_GetRightValue();
424 template <
typename T>
434 _value = data->_GetRightValue();
437 template <
typename T>
443 template <
typename T>
446 return VtValue(TypedEvalDerivative(t));
449 template <
typename T>
456 template <
typename T>
466 template <
typename T>
469 _interpolate = rhs->_interpolate;
470 _value = rhs->_value;
471 _cache = rhs->_cache;
474 template <
typename T>
481 template <
typename T>
492 template <
typename T>
499 TF_CODING_ERROR(
"Constructing an Ts_EvalCache from invalid keyframes");
504 _SetupBezierGeometry(_cache.timePoints, _cache.valuePoints, kf1, kf2);
505 _cache.DerivePolynomial();
510 _interpolate =
false;
511 _value = kf1->_GetRightValue();
515 template <
typename T>
521 template <
typename T>
524 return VtValue(TypedEvalDerivative(t));
527 template <
typename T>
538 template <
typename T>
559 T derivative = x * (1.0 /
t);
563 template <
typename T>
570 template <
typename T>
571 std::shared_ptr<Ts_EvalCache<T, true> >
582 template <
typename T>
583 std::shared_ptr<Ts_EvalCache<T, false> >
597 template <
typename T>
601 _kf1_knot_type = rhs->_kf1_knot_type;
603 _kf1_time = rhs->_kf1_time;
604 _kf2_time = rhs->_kf2_time;
606 _kf1_value = rhs->_kf1_value;
607 _kf2_value = rhs->_kf2_value;
610 template <
typename T>
617 template <
typename T>
628 template <
typename T>
636 " from invalid keyframes");
640 _kf1_knot_type = kf1->_knotType;
645 _kf1_value = kf1->_GetRightValue();
646 _kf2_value = kf2->_isDual ? kf2->_GetLeftValue() : kf2->_GetRightValue();
649 template <
typename T>
655 template <
typename T>
669 double u = (time - _kf1_time) / (_kf2_time - _kf1_time);
670 return GfSlerp(_kf1_value, _kf2_value, u);
675 return VtValue(TypedEvalDerivative(t));
VtValue Eval(TsTime t) const override
T TypedEval(TsTime) const
double GfClamp(double value, double min, double max)
A Linear knot; tangents will be ignored.
Ts_EvalQuaternionCache(const Ts_EvalQuaternionCache< T > *rhs)
GT_API const UT_StringHolder time
static VtValue EvalDerivativeUncached(const TsKeyFrame &kf1, const TsKeyFrame &kf2, TsTime time)
GLsizei const GLfloat * value
A held-value knot; tangents will be ignored.
bool ValueCanBeInterpolated() const override
static TsTime _GetBezierPoint2Time(const Ts_TypedData< T > *kf1, const Ts_TypedData< T > *kf2)
~Ts_UntypedEvalCache()=default
T Ts_EvalCubic(const T c[4], double u)
std::shared_ptr< Ts_EvalCache< T, true > > TypedSharedPtr
virtual VtValue Eval(TsTime) const =0
static TsTime _GetBezierPoint3Time(const Ts_TypedData< T > *kf1, const Ts_TypedData< T > *kf2)
T Ts_EvalCubicDerivative(const T c[4], double u)
GF_API GfQuatd GfSlerp(double alpha, const GfQuatd &q0, const GfQuatd &q1)
TS_API Ts_Data * Ts_GetKeyFrameData(TsKeyFrame &kf)
std::shared_ptr< Ts_UntypedEvalCache > SharedPtr
TsKnotType
Keyframe knot types.
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)
Specifies the value of an TsSpline object at a particular point in time.
Ts_EvalCache(const Ts_TypedData< GfQuatd > *kf1, const Ts_TypedData< GfQuatd > *kf2)
Ts_EvalCache(const Ts_EvalCache< GfQuatd, true > *rhs)
static T _GetBezierPoint2Value(const Ts_TypedData< T > *kf1, const Ts_TypedData< T > *kf2)
PXR_NAMESPACE_OPEN_SCOPE typedef double TsTime
The time type used by Ts.
Ts_EvalCache(const TsKeyFrame &kf1, const TsKeyFrame &kf2)
static SharedPtr New(const TsKeyFrame &kf1, const TsKeyFrame &kf2)
Construct and return a new eval cache for the given keyframes.
T TypedEvalDerivative(TsTime) const
PXR_NAMESPACE_CLOSE_SCOPE PXR_NAMESPACE_OPEN_SCOPE
static T _GetBezierPoint4Value(const Ts_TypedData< T > *kf1, const Ts_TypedData< T > *kf2)
static void _SetupBezierGeometry(TsTime *timePoints, T *valuePoints, const Ts_TypedData< T > *kf1, const Ts_TypedData< T > *kf2)
static T _GetBezierPoint3Value(const Ts_TypedData< T > *kf1, const Ts_TypedData< T > *kf2)
std::shared_ptr< Ts_EvalCache< GfQuatf, true > > TypedSharedPtr
#define PXR_NAMESPACE_CLOSE_SCOPE
Ts_EvalCache(const TsKeyFrame &kf1, const TsKeyFrame &kf2)
std::shared_ptr< Ts_EvalCache< GfQuatd, true > > TypedSharedPtr
VtValue EvalDerivative(TsTime t) const override
Ts_EvalCache(const Ts_EvalCache< GfQuatf, true > *rhs)
std::shared_ptr< Ts_EvalCache< T, false > > TypedSharedPtr
virtual VtValue EvalDerivative(TsTime) const =0