HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
timeCode.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_USD_USD_TIME_CODE_H
8 #define PXR_USD_USD_TIME_CODE_H
9 
10 #include "pxr/pxr.h"
11 #include "pxr/usd/usd/api.h"
12 #include "pxr/usd/sdf/timeCode.h"
13 #include "pxr/base/arch/hints.h"
15 #include "pxr/base/tf/hash.h"
16 
17 #include <limits>
18 #include <iosfwd>
19 #include <cmath>
20 
21 
23 
24 
25 #define USD_TIME_CODE_TOKENS \
26  (DEFAULT) \
27  (EARLIEST) \
28  (PRE_TIME)
29 
31 
32 
33 /// \class UsdTimeCode
34 ///
35 /// Represent a time value, which may be either numeric, holding a double
36 /// value, or a sentinel value UsdTimeCode::Default().
37 ///
38 /// A UsdTimeCode does \em not represent an
39 /// <a href="https://en.wikipedia.org/wiki/SMPTE_timecode">SMPTE timecode</a>,
40 /// although we may, in future, support conversion functions between the two.
41 /// Instead, UsdTimeCode is an abstraction that acknowledges that in the
42 /// principal domains of use for USD, there are many different ways of encoding
43 /// time, and USD must be able to capture and translate between all of them for
44 /// interchange, retaining as much intent of the authoring application as
45 /// possible.
46 ///
47 /// A UsdTimeCode is therefore a unitless, generic time measurement that serves
48 /// as the ordinate for time-sampled data in USD files. A client of USD relies
49 /// on the UsdStage (which in turn consults metadata authored in its root layer)
50 /// to define the mapping of TimeCodes to units like seconds and frames.
51 ///
52 /// \sa UsdStage::GetStartTimeCode()
53 /// \sa UsdStage::GetEndTimeCode()
54 /// \sa UsdStage::GetTimeCodesPerSecond()
55 /// \sa UsdStage::GetFramesPerSecond()
56 ///
57 /// As described in \ref Usd_ValueResolution , USD optionally provides an
58 /// unvarying, 'default' value for every attribute. UsdTimeCode embodies a time
59 /// value that can either be a floating-point sample time, or the default.
60 ///
61 /// All UsdAttribute and derived API that requires a time parameter defaults
62 /// to UsdTimeCode::Default() if the parameter is left unspecified, and
63 /// auto-constructs from a floating-point argument.
64 ///
65 /// UsdTimeCode::EarliestTime() is provided to aid clients who wish
66 /// to retrieve the first authored timesample for any attribute.
67 ///
68 /// A UsdTimeCode can also represent a 'pre-time' value, which means the limit
69 /// as time approaches the value from the left. Refer UsdAttribute::Get() for
70 /// details on usage of UsdTimeCode::PreTime().
71 ///
72 class UsdTimeCode {
73 public:
74  /// Construct with optional time value. Impilicitly convert from double.
75  constexpr UsdTimeCode(double t = 0.0) noexcept : _value(t) {}
76 
77  /// Construct and implicitly cast from SdfTimeCode.
78  constexpr UsdTimeCode(const SdfTimeCode &sdfTimeCode) noexcept
79  : _value(sdfTimeCode.GetValue()) {}
80 
81  /// Produces a UsdTimeCode representing a pre-time at \p t.
82  ///
83  /// \sa UsdAttribute::Get()
84  static constexpr UsdTimeCode PreTime(double t) noexcept {
85  return UsdTimeCode(t, /*isPreTime=*/true);
86  }
87 
88  /// Produces a UsdTimeCode representing a pre-time using SdfTimeCode \p
89  /// timeCode.
90  static constexpr UsdTimeCode PreTime(const SdfTimeCode& timeCode) noexcept {
91  return UsdTimeCode(timeCode.GetValue(), /*isPreTime=*/true);
92  }
93 
94  /// Produce a UsdTimeCode representing the lowest/earliest possible
95  /// timeCode. Thus, for any given timeSample \em s, its time ordinate
96  /// \em t will obey: t >= UsdTimeCode::EarliestTime()
97  ///
98  /// This is useful for clients that wish to retrieve the first authored
99  /// timeSample for an attribute, as they can use UsdTimeCode::EarliestTime()
100  /// as the \em time argument to UsdAttribute::Get() and
101  /// UsdAttribute::GetBracketingTimeSamples()
102  static constexpr UsdTimeCode EarliestTime() {
103  return UsdTimeCode(std::numeric_limits<double>::lowest());
104  }
105 
106  /// Produce a UsdTimeCode representing the sentinel value for 'default'.
107  ///
108  /// \note In inequality comparisons, Default() is considered less than any
109  /// numeric TimeCode, including EarliestTime(), indicative of the fact that
110  /// in UsdAttribute value resolution, the sample at Default() (if any) is
111  /// always weaker than any numeric timeSample in the same layer. For
112  /// more information, see \ref Usd_ValueResolution
113  static constexpr UsdTimeCode Default() {
114  return UsdTimeCode(std::numeric_limits<double>::quiet_NaN());
115  }
116 
117  /// Produce a safe step value such that for any numeric UsdTimeCode t in
118  /// [-maxValue, maxValue], t +/- (step / maxCompression) != t with a safety
119  /// factor of 2. This is shorthand for
120  /// std::numeric_limits<double>::epsilon() * maxValue * maxCompression *
121  /// 2.0. Such a step value is recommended for simulating jump
122  /// discontinuities in time samples. For example, author value x at time t,
123  /// and value y at time t + SafeStep(). This ensures that as the sample
124  /// times are shifted and scaled, t and t + SafeStep() remain distinct so
125  /// long as they adhere to the \p maxValue and \p maxCompression limits.
126  static constexpr double
127  SafeStep(double maxValue=1e6, double maxCompression=10.0) {
128  return std::numeric_limits<double>::epsilon() *
129  maxValue * maxCompression * 2.0;
130  }
131 
132  /// Return true if this timeCode represents a pre-value, false otherwise.
133  bool IsPreTime() const {
134  return _isPreTime;
135  }
136 
137  /// Return true if this time represents the lowest/earliest possible
138  /// timeCode, false otherwise.
139  bool IsEarliestTime() const {
140  return IsNumeric() && (_value == std::numeric_limits<double>::lowest());
141  }
142 
143  /// Return true if this time represents the 'default' sentinel value, false
144  /// otherwise. This is equivalent to !IsNumeric().
145  bool IsDefault() const {
146  return std::isnan(_value);
147  }
148 
149  /// Return true if this time represents a numeric value, false otherwise.
150  /// This is equivalent to !IsDefault().
151  bool IsNumeric() const {
152  return !IsDefault();
153  }
154 
155  /// Return the numeric value for this time. If this time \a IsDefault(),
156  /// return a quiet NaN value.
157  double GetValue() const {
158  if (ARCH_UNLIKELY(IsDefault()))
159  _IssueGetValueOnDefaultError();
160  return _value;
161  }
162 
163  /// Equality comparison.
164  friend bool operator==(const UsdTimeCode &lhs, const UsdTimeCode& rhs) {
165  if (lhs.IsDefault() && rhs.IsDefault()) {
166  return true;
167  }
168  return lhs._value == rhs._value &&
169  lhs._isPreTime == rhs._isPreTime;
170  }
171 
172  /// Inequality comparison.
173  friend bool operator!=(const UsdTimeCode &lhs, const UsdTimeCode& rhs) {
174  return !(lhs == rhs);
175  }
176 
177  /// Less-than.
178  ///
179  /// Default() times are less than all numeric times,
180  /// Numeric times are ordered by their value,
181  /// If numeric times are equal, pre-time times are less than non pre-time
182  /// times.
183  /// \em including EarliestTime()
184  friend bool operator<(const UsdTimeCode &lhs, const UsdTimeCode &rhs) {
185  if (lhs.IsDefault() || rhs.IsDefault()) {
186  return lhs.IsDefault() && !rhs.IsDefault();
187  }
188  return lhs._value < rhs._value ||
189  (lhs._value == rhs._value &&
190  lhs._isPreTime && !rhs._isPreTime);
191  }
192 
193  /// Greater-equal. Default() times are less than all numeric times,
194  /// \em including EarliestTime().
195  friend bool operator>=(const UsdTimeCode &lhs, const UsdTimeCode &rhs) {
196  return !(lhs < rhs);
197  }
198 
199  /// Less-equal.
200  friend bool operator<=(const UsdTimeCode &lhs, const UsdTimeCode &rhs) {
201  return !(rhs < lhs);
202  }
203 
204  /// Greater-than. Default() times are less than all numeric times,
205  /// \em including EarliestTime().
206  friend bool operator>(const UsdTimeCode &lhs, const UsdTimeCode &rhs) {
207  return !(lhs <= rhs);
208  }
209 
210  /// Hash function.
211  friend size_t hash_value(const UsdTimeCode &time) {
212  return TfHash::Combine(time._value, time._isPreTime);
213  }
214 
215 private:
216  constexpr UsdTimeCode(double t, bool isPreTime) noexcept
217  : _value(t), _isPreTime(isPreTime) {}
218 
219  USD_API
220  void _IssueGetValueOnDefaultError() const;
221 
222  double _value;
223  bool _isPreTime = false;
224 };
225 
226 // Stream I/O operators.
227 USD_API
228 std::ostream& operator<<(std::ostream& os, const UsdTimeCode& time);
229 
230 USD_API
231 std::istream& operator>>(std::istream& is, UsdTimeCode& time);
232 
233 
235 
236 #endif // PXR_USD_USD_TIME_CODE_H
#define USD_TIME_CODE_TOKENS
Definition: timeCode.h:25
friend bool operator==(const UsdTimeCode &lhs, const UsdTimeCode &rhs)
Equality comparison.
Definition: timeCode.h:164
static constexpr UsdTimeCode Default()
Definition: timeCode.h:113
#define USD_API
Definition: api.h:23
double GetValue() const
Definition: timeCode.h:157
static constexpr UsdTimeCode EarliestTime()
Definition: timeCode.h:102
GT_API const UT_StringHolder time
friend bool operator>=(const UsdTimeCode &lhs, const UsdTimeCode &rhs)
Definition: timeCode.h:195
friend bool operator<=(const UsdTimeCode &lhs, const UsdTimeCode &rhs)
Less-equal.
Definition: timeCode.h:200
bool IsEarliestTime() const
Definition: timeCode.h:139
USD_API std::istream & operator>>(std::istream &is, UsdTimeCode &time)
constexpr UsdTimeCode(double t=0.0) noexcept
Construct with optional time value. Impilicitly convert from double.
Definition: timeCode.h:75
bool IsPreTime() const
Return true if this timeCode represents a pre-value, false otherwise.
Definition: timeCode.h:133
TF_DECLARE_PUBLIC_TOKENS(UsdTimeCodeTokens, USD_API, USD_TIME_CODE_TOKENS)
#define ARCH_UNLIKELY(x)
Definition: hints.h:30
bool IsDefault() const
Definition: timeCode.h:145
static constexpr UsdTimeCode PreTime(const SdfTimeCode &timeCode) noexcept
Definition: timeCode.h:90
friend size_t hash_value(const UsdTimeCode &time)
Hash function.
Definition: timeCode.h:211
GLdouble t
Definition: glad.h:2397
bool IsNumeric() const
Definition: timeCode.h:151
static size_t Combine(Args &&...args)
Produce a hash code by combining the hash codes of several objects.
Definition: hash.h:487
PXR_NAMESPACE_CLOSE_SCOPE PXR_NAMESPACE_OPEN_SCOPE
Definition: path.h:1425
static constexpr UsdTimeCode PreTime(double t) noexcept
Definition: timeCode.h:84
friend bool operator!=(const UsdTimeCode &lhs, const UsdTimeCode &rhs)
Inequality comparison.
Definition: timeCode.h:173
#define PXR_NAMESPACE_CLOSE_SCOPE
Definition: pxr.h:74
SDF_API std::ostream & operator<<(std::ostream &out, const SdfTimeCode &ap)
Stream insertion operator for the string representation of this time code.
friend bool operator<(const UsdTimeCode &lhs, const UsdTimeCode &rhs)
Definition: timeCode.h:184
friend bool operator>(const UsdTimeCode &lhs, const UsdTimeCode &rhs)
Definition: timeCode.h:206
static constexpr double SafeStep(double maxValue=1e6, double maxCompression=10.0)
Definition: timeCode.h:127
constexpr UsdTimeCode(const SdfTimeCode &sdfTimeCode) noexcept
Construct and implicitly cast from SdfTimeCode.
Definition: timeCode.h:78