def _create_keyframe_transform_node(self, gltf_node, animation_channels, input_sample): matrix = gltf_node.matrix if matrix: translation = Gf.Vec3f() rotation = Gf.Quatf() scale = Gf.Vec3h() usd_matrix = self._convert_to_usd_matrix(matrix) UsdSkel.DecomposeTransform(usd_matrix, translation, rotation, scale) else: translation = Gf.Vec3f(gltf_node.translation) rotation = Gf.Quatf(gltf_node.rotation[3], gltf_node.rotation[0], gltf_node.rotation[1], gltf_node.rotation[2]) scale = Gf.Vec3h(gltf_node.scale) for animation_channel in animation_channels: if animation_channel.target.path == 'translation': translation = animation_channel.sampler.get_interpolated_output_data( input_sample) elif animation_channel.target.path == 'rotation': rotation = animation_channel.sampler.get_interpolated_output_data( input_sample) elif animation_channel.target.path == 'scale': scale = animation_channel.sampler.get_interpolated_output_data( input_sample) return UsdSkel.MakeTransform(translation, rotation, scale)
def test_TransformCompositionAndDecomposition(self): """ Tests UsdSkelMakeTransform(), UsdSkelDecomposeTransform() and their array forms. """ random.seed(0) count = 100 # Make some random transforms. translations = RandomTranslations(count) rotations = RandomRotations(count) scales = RandomScales(count) xforms = UsdSkel.MakeTransforms(translations, rotations, scales) assert xforms xformsBuiltIndividually = Vt.Matrix4dArray( [UsdSkel.MakeTransform(translations[i], rotations[i], scales[i]) for i in range(count)]) self.assertArrayIsClose(xforms, xformsBuiltIndividually) # Decompose back into components. decomposedComponents = UsdSkel.DecomposeTransforms(xforms) assert decomposedComponents decomposedTranslations,_,_ = decomposedComponents self.assertArrayIsClose(translations, decomposedTranslations) # Make sure the non-array decomposition matches. for i,xf in enumerate(xforms): t,_,_ = UsdSkel.DecomposeTransform(xf) self.assertTrue(Gf.IsClose(t, translations[i],1e-5)) # We can't really directly compare the decomposed rotations and scales # against the original components used to build our matrices: # Decomposition might produce different scales and rotations, but # which still give the same composed matrix result. # Instead, we rebuild xforms and validate that they give us the # xforms that the components were decomposed from. rebuiltXforms = UsdSkel.MakeTransforms(*decomposedComponents) assert rebuiltXforms self.assertArrayIsClose(xforms, rebuiltXforms) # And rebuilding each matrix individually... rebuiltXforms = Vt.Matrix4dArray( [UsdSkel.MakeTransform(*UsdSkel.DecomposeTransform(xf)) for xf in xforms]) self.assertArrayIsClose(xforms, rebuiltXforms) # Decomposing singular matrices should fail! with self.assertRaises(Tf.ErrorException): print("expect a warning about decomposing a singular matrix") UsdSkel.DecomposeTransform(Gf.Matrix4d(0)) with self.assertRaises(Tf.ErrorException): UsdSkel.DecomposeTransforms( Vt.Matrix4dArray([Gf.Matrix4d(1), Gf.Matrix4d(0)]))