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_GEOM_XFORM_CACHE_H 25 #define PXR_USD_USD_GEOM_XFORM_CACHE_H 26 27 #include "pxr/pxr.h" 28 #include "pxr/usd/usdGeom/api.h" 29 #include "pxr/usd/usd/attributeQuery.h" 30 #include "pxr/usd/usd/prim.h" 31 32 #include "pxr/usd/usdGeom/xformable.h" 33 34 #include "pxr/base/gf/matrix4d.h" 35 #include "pxr/base/tf/hashmap.h" 36 #include "pxr/base/tf/token.h" 37 38 #include <boost/functional/hash.hpp> 39 40 PXR_NAMESPACE_OPEN_SCOPE 41 42 43 /// \class UsdGeomXformCache 44 /// 45 /// A caching mechanism for transform matrices. For best performance, this 46 /// object should be reused for multiple CTM queries. 47 /// 48 /// Instances of this type can be copied, though using Swap() may result in 49 /// better performance. 50 /// 51 /// It is valid to cache prims from multiple stages in a single XformCache. 52 /// 53 /// WARNING: this class does not automatically invalidate cached values based 54 /// on changes to the stage from which values were cached. Additionally, a 55 /// separate instance of this class should be used per-thread, calling the Get* 56 /// methods from multiple threads is not safe, as they mutate internal state. 57 /// 58 class UsdGeomXformCache 59 { 60 public: 61 /// Construct a new XformCache for the specified \p time. 62 USDGEOM_API 63 explicit UsdGeomXformCache(const UsdTimeCode time); 64 65 /// Construct a new XformCache for UsdTimeCode::Default(). 66 USDGEOM_API 67 UsdGeomXformCache(); 68 69 /// Compute the transformation matrix for the given \p prim, including the 70 /// transform authored on the Prim itself, if present. 71 /// 72 /// \note This method may mutate internal cache state and is not thread 73 /// safe. 74 USDGEOM_API 75 GfMatrix4d GetLocalToWorldTransform(const UsdPrim& prim); 76 77 /// Compute the transformation matrix for the given \p prim, but do NOT 78 /// include the transform authored on the prim itself. 79 /// 80 /// \note This method may mutate internal cache state and is not thread 81 /// safe. 82 USDGEOM_API 83 GfMatrix4d GetParentToWorldTransform(const UsdPrim& prim); 84 85 /// Returns the local transformation of the prim. Uses the cached 86 /// XformQuery to compute the result quickly. The \p resetsXformStack 87 /// pointer must be valid. It will be set to true if \p prim resets 88 /// the transform stack. 89 /// The result of this call is cached. 90 USDGEOM_API 91 GfMatrix4d GetLocalTransformation(const UsdPrim &prim, 92 bool *resetsXformStack); 93 94 /// Returns the result of concatenating all transforms beneath \p ancestor 95 /// that affect \p prim. This includes the local transform of \p prim 96 /// itself, but not the local transform of \p ancestor. If \p ancestor is 97 /// not an ancestor of \p prim, the resulting transform is the 98 /// local-to-world transformation of \p prim. 99 /// The \p resetXformTsack pointer must be valid. If any intermediate prims 100 /// reset the transform stack, \p resetXformStack will be set to true. 101 /// Intermediate transforms are cached, but the result of this call itself 102 /// is not cached. 103 USDGEOM_API 104 GfMatrix4d ComputeRelativeTransform(const UsdPrim &prim, 105 const UsdPrim &ancestor, 106 bool *resetXformStack); 107 108 /// Whether the attribute named \p attrName, belonging to the 109 /// given \p prim affects the local transform value at the prim. 110 /// 111 /// \note This method may mutate internal cache state and is not thread 112 /// safe. 113 USDGEOM_API 114 bool IsAttributeIncludedInLocalTransform(const UsdPrim &prim, 115 const TfToken &attrName); 116 117 /// Whether the local transformation value at the prim may vary over time. 118 /// 119 /// \note This method may mutate internal cache state and is not thread 120 /// safe. 121 USDGEOM_API 122 bool TransformMightBeTimeVarying(const UsdPrim &prim); 123 124 /// Whether the xform stack is reset at the given prim. 125 /// 126 /// \note This method may mutate internal cache state and is not thread 127 /// safe. 128 USDGEOM_API 129 bool GetResetXformStack(const UsdPrim &prim); 130 131 /// Clears all pre-cached values. 132 USDGEOM_API 133 void Clear(); 134 135 /// Use the new \p time when computing values and may clear any existing 136 /// values cached for the previous time. Setting \p time to the current time 137 /// is a no-op. 138 USDGEOM_API 139 void SetTime(UsdTimeCode time); 140 141 /// Get the current time from which this cache is reading values. GetTime()142 UsdTimeCode GetTime() { return _time; } 143 144 /// Swap the contents of this XformCache with \p other. 145 USDGEOM_API 146 void Swap(UsdGeomXformCache& other); 147 148 private: 149 150 // Traverses backwards the hierarchy starting from prim 151 // all the way to the root and computes the ctm 152 GfMatrix4d const* _GetCtm(const UsdPrim& prim); 153 154 // Map of cached values. 155 struct _Entry { 156 _Entry() = default; _Entry_Entry157 _Entry(const UsdGeomXformable::XformQuery & query_, 158 const GfMatrix4d& ctm_, 159 bool ctmIsValid_) 160 : query(query_) 161 , ctm(ctm_) 162 , ctmIsValid(ctmIsValid_) 163 { } 164 165 UsdGeomXformable::XformQuery query; 166 GfMatrix4d ctm; 167 bool ctmIsValid; 168 }; 169 170 // Helper function to get or create a new entry for a prim in the ctm cache. 171 _Entry * _GetCacheEntryForPrim(const UsdPrim &prim); 172 173 typedef TfHashMap<UsdPrim, _Entry, boost::hash<UsdPrim> > _PrimHashMap; 174 _PrimHashMap _ctmCache; 175 176 // The time at which this stack is querying and caching attribute values. 177 UsdTimeCode _time; 178 }; 179 180 #define USDGEOM_XFORM_CACHE_API_VERSION 1 181 182 183 PXR_NAMESPACE_CLOSE_SCOPE 184 185 #endif // PXR_USD_USD_GEOM_XFORM_CACHE_H 186