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_USD_USD_CLIP_H 25 #define PXR_USD_USD_CLIP_H 26 27 #include "pxr/pxr.h" 28 29 #include "pxr/usd/sdf/assetPath.h" 30 #include "pxr/usd/sdf/layer.h" 31 #include "pxr/usd/sdf/path.h" 32 #include "pxr/usd/sdf/propertySpec.h" 33 #include "pxr/base/tf/declarePtrs.h" 34 35 #include <iosfwd> 36 #include <memory> 37 #include <mutex> 38 #include <vector> 39 40 PXR_NAMESPACE_OPEN_SCOPE 41 42 TF_DECLARE_WEAK_PTRS(PcpLayerStack); 43 44 class Usd_InterpolatorBase; 45 46 /// Returns true if the given scene description metadata \p fieldName is 47 /// associated with value clip functionality. 48 bool 49 UsdIsClipRelatedField(const TfToken& fieldName); 50 51 /// Returns list of all field names associated with value clip functionality. 52 std::vector<TfToken> 53 UsdGetClipRelatedFields(); 54 55 /// Sentinel values authored on the edges of a clipTimes range. 56 constexpr double Usd_ClipTimesEarliest = -std::numeric_limits<double>::max(); 57 constexpr double Usd_ClipTimesLatest = std::numeric_limits<double>::max(); 58 59 /// \class Usd_Clip 60 /// 61 /// Represents a clip from which time samples may be read during 62 /// value resolution. 63 /// 64 struct Usd_Clip 65 { 66 Usd_Clip(Usd_Clip const &) = delete; 67 Usd_Clip &operator=(Usd_Clip const &) = delete; 68 public: 69 /// A clip has two time domains: an external and an internal domain. 70 /// The internal time domain is what is authored in the clip layer. 71 /// The external time domain is what is used by clients of Usd_Clip. 72 /// 73 /// The TimeMapping object specifies a mapping from external time to 74 /// internal time. For example, mapping [ 0:10 ] means that a request 75 /// for time samples at time 0 should retrieve the sample authored at 76 /// time 10 in the clip layer. Consumers of Usd_Clip will always deal 77 /// with external times. Usd_Clip will convert between time domains as 78 /// needed. 79 /// 80 /// The mappings that apply to a clip are given in a TimeMappings object. 81 /// Times are linearly interpolated between entries in this object. 82 /// For instance, given a mapping [ 0:10, 10:20 ], external time 0 maps 83 /// to internal time 10, time 5 maps to time 15, and time 10 to time 20. 84 /// The simplest way to visualize this is to imagine that TimeMappings 85 /// specifies a piecewise-linear function, with each pair of TimeMapping 86 /// entries specifying a single segment. 87 /// 88 /// Time mappings are authored in the 'clipTimes' metadata. This allows 89 /// users to control the timing of animation from clips, potentially 90 /// offsetting or scaling the animation. 91 typedef double ExternalTime; 92 typedef double InternalTime; 93 struct TimeMapping { 94 ExternalTime externalTime; 95 InternalTime internalTime; 96 bool isJumpDiscontinuity; 97 TimeMappingUsd_Clip::TimeMapping98 TimeMapping() {} TimeMappingUsd_Clip::TimeMapping99 TimeMapping(const ExternalTime e, const InternalTime i) 100 : externalTime(e) 101 , internalTime(i) 102 , isJumpDiscontinuity(false) 103 {} 104 }; 105 106 typedef std::vector<TimeMapping> TimeMappings; 107 108 Usd_Clip(); 109 Usd_Clip( 110 const PcpLayerStackPtr& clipSourceLayerStack, 111 const SdfPath& clipSourcePrimPath, 112 size_t clipSourceLayerIndex, 113 const SdfAssetPath& clipAssetPath, 114 const SdfPath& clipPrimPath, 115 ExternalTime clipAuthoredStartTime, 116 ExternalTime clipStartTime, 117 ExternalTime clipEndTime, 118 const TimeMappings& timeMapping); 119 120 bool HasField(const SdfPath& path, const TfToken& field) const; 121 122 SdfPropertySpecHandle GetPropertyAtPath(const SdfPath& path) const; 123 124 template <class T> HasFieldUsd_Clip125 bool HasField( 126 const SdfPath& path, const TfToken& field, 127 T* value) const 128 { 129 return _GetLayerForClip()->HasField( 130 _TranslatePathToClip(path), field, value); 131 } 132 133 std::type_info const & GetFieldTypeidUsd_Clip134 GetFieldTypeid(const SdfPath& path, const TfToken& field) const { 135 return _GetLayerForClip()->GetFieldTypeid( 136 _TranslatePathToClip(path), field); 137 } 138 139 size_t GetNumTimeSamplesForPath(const SdfPath& path) const; 140 141 std::set<ExternalTime> 142 ListTimeSamplesForPath(const SdfPath& path) const; 143 144 bool GetBracketingTimeSamplesForPath( 145 const SdfPath& path, ExternalTime time, 146 ExternalTime* tLower, ExternalTime* tUpper) const; 147 148 template <class T> 149 bool QueryTimeSample( 150 const SdfPath& path, ExternalTime time, 151 Usd_InterpolatorBase* interpolator, T* value) const; 152 153 /// Return true if this clip has authored time samples for the attribute 154 /// corresponding to the given \p path. Clips may add time sample times 155 /// at their boundaries and time mappings even if there are no samples 156 /// in the clip. This method ignores these time samples and returns 157 /// whether there truly is a time sample value for the attribute. 158 bool HasAuthoredTimeSamples(const SdfPath& path) const; 159 160 /// Return true if a value block is authored for the attribute 161 /// corresponding to the given \p path at \p time. 162 bool IsBlocked(const SdfPath& path, ExternalTime time) const; 163 164 /// Return the layer associated with this clip, opening it if it hasn't 165 /// been opened already. 166 SdfLayerHandle GetLayer() const; 167 168 /// Return the layer associated with this clip iff it has already been 169 /// opened successfully. 170 /// 171 /// USD tries to be as lazy as possible about opening clip layers to 172 /// avoid unnecessary latency and memory bloat; however, once a layer is 173 /// open, it will generally be kept open for the life of the stage. 174 SdfLayerHandle GetLayerIfOpen() const; 175 176 /// Layer stack, prim spec path, and index of layer where this clip 177 /// was introduced. 178 PcpLayerStackPtr sourceLayerStack; 179 SdfPath sourcePrimPath; 180 size_t sourceLayerIndex; 181 182 /// Asset path for the clip and the path to the prim in the clip 183 /// that provides data. 184 SdfAssetPath assetPath; 185 SdfPath primPath; 186 187 /// The authored start time for this clip. This generally is equivalent 188 /// to the clip's startTime, but for the earliest active clip: 189 /// 190 /// - authoredStartTime: the stage time value authored in the clip set's 191 /// active metadata 192 /// - startTime: Usd_ClipTimesEarliest 193 /// 194 /// This distinction is needed for time samples for the earliest clip. 195 ExternalTime authoredStartTime; 196 197 /// A clip is active in the time range [startTime, endTime). For the 198 /// earliest clip in a clip set, startTime will be Usd_ClipTimesEarliest, 199 /// for the latest clip in a clip set, endTime will be Usd_ClipTimesLatest. 200 ExternalTime startTime; 201 ExternalTime endTime; 202 203 /// Mapping of external to internal times. 204 TimeMappings times; 205 206 private: 207 friend class UsdStage; 208 209 // Helpers for retrieving time sample information from within 210 // clip layers and translating them to external times. 211 bool 212 _GetBracketingTimeSamplesForPathFromClipLayer( 213 const SdfPath& path, 214 ExternalTime time, ExternalTime* tLower, ExternalTime* tUpper) const; 215 216 void 217 _ListTimeSamplesForPathFromClipLayer( 218 const SdfPath& path, 219 std::set<ExternalTime>* samples) const; 220 221 SdfPath _TranslatePathToClip(const SdfPath &path) const; 222 223 // Helpers to translate between internal and external time domains. 224 InternalTime _TranslateTimeToInternal( 225 ExternalTime extTime) const; 226 ExternalTime _TranslateTimeToExternal( 227 InternalTime clipTime, size_t i1, size_t i2) const; 228 229 SdfLayerRefPtr _GetLayerForClip() const; 230 231 private: 232 mutable bool _hasLayer; 233 mutable std::mutex _layerMutex; 234 mutable SdfLayerRefPtr _layer; 235 }; 236 237 typedef std::shared_ptr<Usd_Clip> Usd_ClipRefPtr; 238 typedef std::vector<Usd_ClipRefPtr> Usd_ClipRefPtrVector; 239 240 std::ostream& 241 operator<<(std::ostream& out, const Usd_ClipRefPtr& clip); 242 243 PXR_NAMESPACE_CLOSE_SCOPE 244 245 #endif // PXR_USD_USD_CLIP_H 246