@@ -51,6 +51,17 @@ _TransformPoints(TfSpan<GfVec3f> points, const GfMatrix4d& xform)
5151 }, /* grainSize*/ 1000 );
5252}
5353
54+ static
55+ void
56+ _TransformNormals (TfSpan<GfVec3f> normals, const GfMatrix3d& xformInvTranspose)
57+ {
58+ WorkParallelForN (normals.size (), [&](size_t start, size_t end) {
59+ for (size_t i = start; i < end; ++i) {
60+ normals[i] = GfVec3f (normals[i] * xformInvTranspose);
61+ }
62+ }, /* grainSize*/ 1000 );
63+ }
64+
5465static
5566void
5667_ApplyPackedBlendShapes (const TfSpan<const GfVec4f>& offsets,
@@ -73,13 +84,12 @@ _ApplyPackedBlendShapes(const TfSpan<const GfVec4f>& offsets,
7384 }
7485}
7586
87+ static
7688void
77- UsdSkelImagingInvokeExtComputation (
89+ _InvokeSkinningComputationPoints (
7890 const TfToken &skinningMethod,
7991 HdExtComputationContext * const ctx)
8092{
81- TRACE_FUNCTION ();
82-
8393 const VtValue restPointsValue =
8494 ctx->GetInputValue (
8595 UsdSkelImagingExtAggregatorComputationInputNameTokens
@@ -214,6 +224,205 @@ UsdSkelImagingInvokeExtComputation(
214224 VtValue (skinnedPoints));
215225}
216226
227+ static
228+ void
229+ _DeformNormalsWithSkinning (
230+ const TfToken& skinningMethod,
231+ const GfMatrix4f& geomBindXform,
232+ const VtMatrix4fArray& skinningXforms,
233+ const VtVec2fArray& influences,
234+ bool hasConstantInfluences,
235+ const int numInfluencesPerComponent,
236+ const VtIntArray& faceVertexIndices,
237+ const GfMatrix4d& seklToPrimLocalXform,
238+ const bool hasFaceVaryingNormals,
239+ VtVec3fArray& skinnedNormals)
240+ {
241+ if (hasConstantInfluences) {
242+ // Have constant influences. Compute a rigid deformation.
243+ GfMatrix4f skinnedTransform;
244+ if (UsdSkelSkinTransform (
245+ skinningMethod,
246+ geomBindXform,
247+ skinningXforms,
248+ influences,
249+ &skinnedTransform)) {
250+
251+ // The computed skinnedTransform is the transform which, when
252+ // applied to the normals of the skinned prim, results in skinned
253+ // normals in *skel* space, and need to be xformed to prim
254+ // local space.
255+
256+ const GfMatrix4d restToPrimLocalSkinnedXf =
257+ GfMatrix4d (skinnedTransform) * seklToPrimLocalXform;
258+ const GfMatrix3d restToPrimLocalSkinnedXfInvTranspose =
259+ restToPrimLocalSkinnedXf.ExtractRotationMatrix ().GetInverse ().GetTranspose ();
260+
261+ _TransformNormals (skinnedNormals, restToPrimLocalSkinnedXfInvTranspose);
262+ }
263+ } else {
264+ // Get geomBindInvTransposeXform
265+ const GfMatrix3d& geomBindInvTransposeXform = GfMatrix4d (geomBindXform)
266+ .ExtractRotationMatrix ().GetInverse ().GetTranspose ();
267+
268+ // Get skinningInvTransposeXforms in parallel
269+ VtMatrix3dArray skinningInvTransposeXforms (skinningXforms.size ());
270+ {
271+ auto skinningDst = TfMakeSpan (skinningInvTransposeXforms);
272+ WorkParallelForN (
273+ skinningXforms.size (),
274+ [&](size_t start, size_t end) {
275+ for (size_t i = start; i < end; ++i) {
276+ skinningDst[i] = GfMatrix4d (skinningXforms[i]).ExtractRotationMatrix ()
277+ .GetInverse ().GetTranspose ();
278+ }
279+ });
280+ }
281+
282+ if (hasFaceVaryingNormals) {
283+ UsdSkelSkinFaceVaryingNormals (skinningMethod, geomBindInvTransposeXform,
284+ skinningInvTransposeXforms, influences,
285+ numInfluencesPerComponent,
286+ faceVertexIndices, skinnedNormals);
287+ } else {
288+ UsdSkelSkinNormals (skinningMethod, geomBindInvTransposeXform,
289+ skinningInvTransposeXforms, influences,
290+ numInfluencesPerComponent,
291+ skinnedNormals);
292+ }
293+
294+ // Output of skinning is in *skel* space.
295+ // Transform the result into gprim space.
296+ const GfMatrix3d& skelToGprimInvTransposeXform =
297+ seklToPrimLocalXform.ExtractRotationMatrix ().GetInverse ().GetTranspose ();
298+ _TransformNormals (skinnedNormals, skelToGprimInvTransposeXform);
299+ }
300+ }
301+
302+ static
303+ void
304+ _InvokeSkinningComputationNormals (
305+ const TfToken &skinningMethod,
306+ HdExtComputationContext * const ctx)
307+ {
308+ const VtValue restNormalsValue =
309+ ctx->GetInputValue (
310+ UsdSkelImagingExtAggregatorComputationInputNameTokens
311+ ->restNormals );
312+ const VtValue geomBindXformValue =
313+ ctx->GetInputValue (
314+ UsdSkelImagingExtAggregatorComputationInputNameTokens
315+ ->geomBindXform );
316+ const VtValue influencesValue =
317+ ctx->GetInputValue (
318+ UsdSkelImagingExtAggregatorComputationInputNameTokens
319+ ->influences );
320+ const VtValue numInfluencesPerComponentValue =
321+ ctx->GetInputValue (
322+ UsdSkelImagingExtAggregatorComputationInputNameTokens
323+ ->numInfluencesPerComponent );
324+ const VtValue hasConstantInfluencesValue =
325+ ctx->GetInputValue (
326+ UsdSkelImagingExtAggregatorComputationInputNameTokens
327+ ->hasConstantInfluences );
328+ const VtValue primWorldToLocalValue =
329+ ctx->GetInputValue (
330+ UsdSkelImagingExtComputationInputNameTokens
331+ ->primWorldToLocal );
332+ const VtValue skinningXformsValue =
333+ ctx->GetInputValue (
334+ UsdSkelImagingExtComputationInputNameTokens
335+ ->skinningXforms );
336+ const VtValue skelLocalToWorldValue =
337+ ctx->GetInputValue (
338+ UsdSkelImagingExtComputationInputNameTokens
339+ ->skelLocalToWorld );
340+ const VtValue faceVertexIndicesValue =
341+ ctx->GetInputValue (
342+ UsdSkelImagingExtAggregatorComputationInputNameTokens
343+ ->faceVertexIndices );
344+ const VtValue hasFaceVaryingNormalsValue =
345+ ctx->GetInputValue (
346+ UsdSkelImagingExtAggregatorComputationInputNameTokens
347+ ->hasFaceVaryingNormals );
348+
349+ // Ensure inputs are holding the right value types.
350+ if (!restNormalsValue.IsHolding <VtVec3fArray>() ||
351+ !geomBindXformValue.IsHolding <GfMatrix4f>() ||
352+ !influencesValue.IsHolding <VtVec2fArray>() ||
353+ !numInfluencesPerComponentValue.IsHolding <int >() ||
354+ !hasConstantInfluencesValue.IsHolding <bool >() ||
355+ !primWorldToLocalValue.IsHolding <GfMatrix4d>() ||
356+ !skinningXformsValue.IsHolding <VtMatrix4fArray>() ||
357+ !skelLocalToWorldValue.IsHolding <GfMatrix4d>() ||
358+ !faceVertexIndicesValue.IsHolding <VtIntArray>() ||
359+ !hasFaceVaryingNormalsValue.IsHolding <bool >()) {
360+ ctx->RaiseComputationError ();
361+ return ;
362+ }
363+
364+ VtVec3fArray skinnedNormals =
365+ restNormalsValue.UncheckedGet <VtVec3fArray>();
366+
367+ const int numInfluencesPerComponent =
368+ numInfluencesPerComponentValue.UncheckedGet <int >();
369+
370+ if (numInfluencesPerComponent <= 0 ) {
371+ ctx->SetOutputValue (
372+ UsdSkelImagingExtComputationOutputNameTokens->skinnedNormals ,
373+ VtValue (skinnedNormals));
374+ return ;
375+ }
376+
377+ // The points returned above are in skel space, and need to be
378+ // transformed to prim local space.
379+ const GfMatrix4d skelToPrimLocal =
380+ skelLocalToWorldValue.UncheckedGet <GfMatrix4d>() *
381+ primWorldToLocalValue.UncheckedGet <GfMatrix4d>();
382+ _DeformNormalsWithSkinning (
383+ skinningMethod,
384+ geomBindXformValue.UncheckedGet <GfMatrix4f>(),
385+ skinningXformsValue.UncheckedGet <VtMatrix4fArray>(),
386+ influencesValue.UncheckedGet <VtVec2fArray>(),
387+ hasConstantInfluencesValue.UncheckedGet <bool >(),
388+ numInfluencesPerComponent,
389+ faceVertexIndicesValue.UncheckedGet <VtIntArray>(),
390+ skelToPrimLocal,
391+ hasFaceVaryingNormalsValue.UncheckedGet <bool >(),
392+ skinnedNormals);
393+
394+ ctx->SetOutputValue (
395+ UsdSkelImagingExtComputationOutputNameTokens->skinnedNormals ,
396+ VtValue (skinnedNormals));
397+ }
398+
399+ void
400+ UsdSkelImagingInvokeExtComputation (
401+ const TfToken &skinningMethod,
402+ HdExtComputationContext * const ctx)
403+ {
404+ TRACE_FUNCTION ();
405+
406+ const VtValue* restPointsValuePtr =
407+ ctx->GetOptionalInputValuePtr (
408+ UsdSkelImagingExtAggregatorComputationInputNameTokens->restPoints );
409+ const VtValue* restNormalsValuePtr =
410+ ctx->GetOptionalInputValuePtr (
411+ UsdSkelImagingExtAggregatorComputationInputNameTokens->restNormals );
412+ if (!restPointsValuePtr && !restNormalsValuePtr) {
413+ TF_CODING_ERROR (" No rest points or normals provided" );
414+ ctx->RaiseComputationError ();
415+ return ;
416+ }
417+
418+ bool computePoints = restPointsValuePtr != nullptr ;
419+ if (computePoints) {
420+ _InvokeSkinningComputationPoints (skinningMethod, ctx);
421+ } else {
422+ _InvokeSkinningComputationNormals (skinningMethod, ctx);
423+ }
424+ }
425+
217426// /////////////////////////////////////////////////////////////////////////////
218427// / UsdSkelImagingExtComputationCpuCallback
219428
0 commit comments