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_SKEL_SKINNING_QUERY_H 25 #define PXR_USD_USD_SKEL_SKINNING_QUERY_H 26 27 /// \file usdSkel/skinningQuery.h 28 29 #include "pxr/pxr.h" 30 #include "pxr/usd/usdSkel/api.h" 31 32 #include "pxr/usd/usd/attribute.h" 33 #include "pxr/usd/usd/prim.h" 34 #include "pxr/usd/usd/relationship.h" 35 36 #include "pxr/usd/usdGeom/primvar.h" 37 38 #include "pxr/usd/usdSkel/animMapper.h" 39 40 41 PXR_NAMESPACE_OPEN_SCOPE 42 43 44 class UsdGeomBoundable; 45 46 47 /// \class UsdSkelSkinningQuery 48 /// 49 /// Object used for querying resolved bindings for skinning. 50 class UsdSkelSkinningQuery 51 { 52 public: 53 USDSKEL_API 54 UsdSkelSkinningQuery(); 55 56 /// Construct a new skining query for the resolved properties 57 /// set through the UsdSkelBindingAPI, as inherited on \p prim. 58 /// The resulting query will be marked valid only if the inherited 59 /// properties provide proper valid joint influences. 60 USDSKEL_API 61 UsdSkelSkinningQuery(const UsdPrim& prim, 62 const VtTokenArray& skelJointOrder, 63 const VtTokenArray& blendShapeOrder, 64 const UsdAttribute& jointIndices, 65 const UsdAttribute& jointWeights, 66 const UsdAttribute& geomBindTransform, 67 const UsdAttribute& joints, 68 const UsdAttribute& blendShapes, 69 const UsdRelationship& blendShapeTargets); 70 71 /// Returns true if this query is valid. IsValid()72 bool IsValid() const { return bool(_prim); } 73 74 /// Boolean conversion operator. Equivalent to IsValid(). 75 explicit operator bool() const { return IsValid(); } 76 GetPrim()77 const UsdPrim& GetPrim() const { return _prim; } 78 79 /// Returns true if there are blend shapes associated with this prim. 80 USDSKEL_API 81 bool HasBlendShapes() const; 82 83 /// Returns true if joint influence data is associated with this prim. 84 USDSKEL_API 85 bool HasJointInfluences() const; 86 87 /// Returns the number of influences encoded for each component. 88 /// If the prim defines rigid joint influences, then this returns 89 /// the number of influences that map to every point. Otherwise, 90 /// this provides the number of influences per point. 91 /// \sa IsRigidlyDeformed GetNumInfluencesPerComponent()92 int GetNumInfluencesPerComponent() const { 93 return _numInfluencesPerComponent; 94 } 95 GetInterpolation()96 const TfToken& GetInterpolation() const { return _interpolation; } 97 98 /// Returns true if the held prim has the same joint influences 99 /// across all points, or false otherwise. 100 USDSKEL_API 101 bool IsRigidlyDeformed() const; 102 GetGeomBindTransformAttr()103 const UsdAttribute& GetGeomBindTransformAttr() const { 104 return _geomBindTransformAttr; 105 } 106 GetJointIndicesPrimvar()107 const UsdGeomPrimvar& GetJointIndicesPrimvar() const { 108 return _jointIndicesPrimvar; 109 } 110 GetJointWeightsPrimvar()111 const UsdGeomPrimvar& GetJointWeightsPrimvar() const { 112 return _jointWeightsPrimvar; 113 } 114 GetBlendShapesAttr()115 const UsdAttribute& GetBlendShapesAttr() const { 116 return _blendShapes; 117 } 118 GetBlendShapeTargetsRel()119 const UsdRelationship& GetBlendShapeTargetsRel() const { 120 return _blendShapeTargets; 121 } 122 123 /// Return a mapper for remapping from the joint order of the skeleton 124 /// to the local joint order of this prim, if any. Returns a null 125 /// pointer if the prim has no custom joint orer. 126 /// The mapper maps data from the order given by the \em joints order 127 /// on the Skeleton to the order given by the \em skel:joints property, 128 /// as optionally set through the UsdSkelBindingAPI. GetJointMapper()129 const UsdSkelAnimMapperRefPtr& GetJointMapper() const { 130 return _jointMapper; 131 } 132 133 /// \deprecated Use GetJointMapper. GetMapper()134 const UsdSkelAnimMapperRefPtr& GetMapper() const { return _jointMapper; } 135 136 137 /// Return the mapper for remapping blend shapes from the order of the 138 /// bound SkelAnimation to the local blend shape order of this prim. 139 /// Returns a null reference if the underlying prim has no blend shapes. 140 /// The mapper maps data from the order given by the \em blendShapes order 141 /// on the SkelAnimation to the order given by the \em skel:blendShapes 142 /// property, as set through the UsdSkelBindingAPI. GetBlendShapeMapper()143 const UsdSkelAnimMapperRefPtr& GetBlendShapeMapper() const { 144 return _blendShapeMapper; 145 } 146 147 /// Get the custom joint order for this skinning site, if any. 148 USDSKEL_API 149 bool GetJointOrder(VtTokenArray* jointOrder) const; 150 151 /// Get the blend shapes for this skinning site, if any. 152 USDSKEL_API 153 bool GetBlendShapeOrder(VtTokenArray* blendShapes) const; 154 155 /// Populate \p times with the union of time samples for all properties 156 /// that affect skinning, independent of joint transforms and any 157 /// other prim-specific properties (such as points). 158 /// 159 /// \sa UsdAttribute::GetTimeSamples 160 USDSKEL_API 161 bool GetTimeSamples(std::vector<double>* times) const; 162 163 /// Populate \p times with the union of time samples within \p interval, 164 /// for all properties that affect skinning, independent of joint 165 /// transforms and any other prim-specific properties (such as points). 166 /// 167 /// \sa UsdAttribute::GetTimeSamplesInInterval 168 USDSKEL_API 169 bool GetTimeSamplesInInterval(const GfInterval& interval, 170 std::vector<double>* times) const; 171 172 /// Convenience method for computing joint influences. 173 /// In addition to querying influences, this will also perform 174 /// validation of the basic form of the weight data -- although 175 /// the array contents is not validated. 176 USDSKEL_API 177 bool ComputeJointInfluences(VtIntArray* indices, 178 VtFloatArray* weights, 179 UsdTimeCode time=UsdTimeCode::Default()) const; 180 181 /// Convenience method for computing joint influence, where constant 182 /// influences are expanded to hold values per point. 183 /// In addition to querying influences, this will also perform 184 /// validation of the basic form of the weight data -- although 185 /// the array contents is not validated. 186 USDSKEL_API 187 bool ComputeVaryingJointInfluences( 188 size_t numPoints, 189 VtIntArray* indices, 190 VtFloatArray* weights, 191 UsdTimeCode time=UsdTimeCode::Default()) const; 192 193 /// Compute skinned points using linear blend skinning. 194 /// Both \p xforms and \p points are given in _skeleton space_, 195 /// using the joint order of the bound skeleton. 196 /// Joint influences and the (optional) binding transform are computed 197 /// at time \p time (which will typically be unvarying). 198 /// 199 /// \sa UsdSkelSkeletonQuery::ComputeSkinningTransforms 200 template <typename Matrix4> 201 USDSKEL_API 202 bool ComputeSkinnedPoints(const VtArray<Matrix4>& xforms, 203 VtVec3fArray* points, 204 UsdTimeCode time=UsdTimeCode::Default()) const; 205 206 /// Compute skinned normals using linear blend skinning. 207 /// Both \p xforms and \p points are given in _skeleton space_, 208 /// using the joint order of the bound skeleton. 209 /// Joint influences and the (optional) binding transform are computed 210 /// at time \p time (which will typically be unvarying). 211 /// 212 /// \sa UsdSkelSkeletonQuery::ComputeSkinningTransforms 213 template <typename Matrix4> 214 USDSKEL_API 215 bool ComputeSkinnedNormals(const VtArray<Matrix4>& xforms, 216 VtVec3fArray* points, 217 UsdTimeCode time=UsdTimeCode::Default()) const; 218 219 /// Compute a skinning transform using linear blend skinning. 220 /// The \p xforms are given in _skeleton space_, using the joint order of 221 /// the bound skeleton. 222 /// Joint influences and the (optional) binding transform are computed 223 /// at time \p time (which will typically be unvarying). 224 /// If this skinning query holds non-constant joint influences, 225 /// no transform will be computed, and the function will return false. 226 /// 227 /// \sa UsdSkelSkeletonQuery::ComputeSkinningTransforms 228 template <typename Matrix4> 229 USDSKEL_API 230 bool ComputeSkinnedTransform(const VtArray<Matrix4>& xforms, 231 Matrix4* xform, 232 UsdTimeCode time=UsdTimeCode::Default()) const; 233 234 /// Helper for computing an *approximate* padding for use in extents 235 /// computations. The padding is computed as the difference between the 236 /// pivots of the \p skelRestXforms -- _skeleton space_ joint transforms 237 /// at rest -- and the extents of the skinned primitive. 238 /// This is intended to provide a suitable, constant metric for padding 239 /// joint extents as computed by UsdSkelComputeJointsExtent. 240 template <typename Matrix4> 241 USDSKEL_API 242 float ComputeExtentsPadding(const VtArray<Matrix4>& skelRestXforms, 243 const UsdGeomBoundable& boundable) const; 244 245 USDSKEL_API 246 GfMatrix4d 247 GetGeomBindTransform(UsdTimeCode time=UsdTimeCode::Default()) const; 248 249 USDSKEL_API 250 std::string GetDescription() const; 251 252 private: 253 254 void _InitializeJointInfluenceBindings( 255 const UsdAttribute& jointIndices, 256 const UsdAttribute& jointWeights); 257 258 void _InitializeBlendShapeBindings( 259 const UsdAttribute& blendShapes, 260 const UsdRelationship& blendShapeTargets); 261 262 UsdPrim _prim; 263 int _numInfluencesPerComponent = 1; 264 int _flags = 0; 265 TfToken _interpolation; 266 267 UsdGeomPrimvar _jointIndicesPrimvar; 268 UsdGeomPrimvar _jointWeightsPrimvar; 269 UsdAttribute _geomBindTransformAttr; 270 UsdAttribute _blendShapes; 271 UsdRelationship _blendShapeTargets; 272 UsdSkelAnimMapperRefPtr _jointMapper; 273 UsdSkelAnimMapperRefPtr _blendShapeMapper; 274 boost::optional<VtTokenArray> _jointOrder; 275 boost::optional<VtTokenArray> _blendShapeOrder; 276 }; 277 278 PXR_NAMESPACE_CLOSE_SCOPE 279 280 #endif // PXR_USD_USD_SKEL_SKINNING_QUERY_H 281