public static void RestoreDefaultPose(Animator animator, AnimationClip defaultPoseClip) { using (var graph = new EvaluationGraph(animator, defaultPoseClip)) { graph.Evaluate(0f); } }
public static void TestTransferMotionToConstraint <T>(T constraint, RigBuilder rigBuilder, AnimationClip clip, IList <Transform> targetTransforms, CompareFlags flags) where T : MonoBehaviour, IRigConstraint { Animator animator = rigBuilder.GetComponent <Animator>(); int numberOfFrames = 60; float dt = 1f / numberOfFrames; var defaultPoseClip = CreateDefaultPose(rigBuilder.gameObject); #if DEBUG_BAKE_TO_CONSTRAINT AssetDatabase.CreateAsset(clip, "Assets/bakeToConstraintBefore.anim"); clip = UnityEngine.Object.Instantiate(clip) as AnimationClip; #endif // Evaluate clip without constraint and take snapshots. var translationsBeforeBaking = new Vector3[targetTransforms.Count, numberOfFrames + 1]; var rotationsBeforeBaking = new Quaternion[targetTransforms.Count, numberOfFrames + 1]; using (var graph = new EvaluationGraph(rigBuilder.GetComponent <Animator>(), clip)) { graph.Evaluate(0f); for (int transformIndex = 0; transformIndex < targetTransforms.Count; ++transformIndex) { translationsBeforeBaking[transformIndex, 0] = targetTransforms[transformIndex].position; rotationsBeforeBaking[transformIndex, 0] = targetTransforms[transformIndex].rotation; } for (int frame = 1; frame <= numberOfFrames; ++frame) { graph.Evaluate(dt); for (int transformIndex = 0; transformIndex < targetTransforms.Count; ++transformIndex) { translationsBeforeBaking[transformIndex, frame] = targetTransforms[transformIndex].position; rotationsBeforeBaking[transformIndex, frame] = targetTransforms[transformIndex].rotation; } } } RestoreDefaultPose(animator, defaultPoseClip); // Bake and inverse solve to constraint. var bakeParameters = BakeUtils.FindBakeParameters(constraint); Assert.That(bakeParameters, Is.Not.Null); var bindings = bakeParameters.GetSourceCurveBindings(rigBuilder, constraint); AnimationMode.StartAnimationMode(); BakeUtils.BakeToConstraint(constraint, clip, defaultPoseClip, bindings, k_DefaultCurveFilterOptions); AnimationMode.StopAnimationMode(); #if DEBUG_BAKE_TO_CONSTRAINT AssetDatabase.CreateAsset(clip, "Assets/bakeToConstraintAfter.anim"); #endif RestoreDefaultPose(animator, defaultPoseClip); // Evaluate again with constraint active and take snapshots. var translationsAfterBaking = new Vector3[targetTransforms.Count, numberOfFrames + 1]; var rotationsAfterBaking = new Quaternion[targetTransforms.Count, numberOfFrames + 1]; using (var graph = new EvaluationGraph(rigBuilder, clip)) { graph.Evaluate(0f); for (int transformIndex = 0; transformIndex < targetTransforms.Count; ++transformIndex) { translationsAfterBaking[transformIndex, 0] = targetTransforms[transformIndex].position; rotationsAfterBaking[transformIndex, 0] = targetTransforms[transformIndex].rotation; } for (int frame = 1; frame <= numberOfFrames; ++frame) { graph.Evaluate(dt); for (int transformIndex = 0; transformIndex < targetTransforms.Count; ++transformIndex) { translationsAfterBaking[transformIndex, frame] = targetTransforms[transformIndex].position; rotationsAfterBaking[transformIndex, frame] = targetTransforms[transformIndex].rotation; } } } RestoreDefaultPose(animator, defaultPoseClip); if ((flags & CompareFlags.Rotation) != 0) { // Compare rotations var quaternionComparer = new RuntimeRiggingTestFixture.QuaternionEqualityComparer(k_RotationEpsilon); for (int transformIndex = 0; transformIndex < targetTransforms.Count; ++transformIndex) { for (int frame = 0; frame <= numberOfFrames; ++frame) { Assert.That(rotationsAfterBaking[transformIndex, frame], Is.EqualTo(rotationsBeforeBaking[transformIndex, frame]).Using(quaternionComparer), String.Format("Transform '{0}' rotation is set to {1} at frame {2}, but was expected to be {3}", targetTransforms[transformIndex].name, rotationsAfterBaking[transformIndex, frame].eulerAngles, frame, rotationsBeforeBaking[transformIndex, frame].eulerAngles)); } } } if ((flags & CompareFlags.Translation) != 0) { // Compare translations var positionComparer = new RuntimeRiggingTestFixture.Vector3EqualityComparer(k_Epsilon); for (int transformIndex = 0; transformIndex < targetTransforms.Count; ++transformIndex) { for (int frame = 0; frame <= numberOfFrames; ++frame) { Assert.That(translationsAfterBaking[transformIndex, frame], Is.EqualTo(translationsBeforeBaking[transformIndex, frame]).Using(positionComparer), String.Format("Transform '{0}' position is set to {1} at frame {2}, but was expected to be {3}", targetTransforms[transformIndex].name, translationsAfterBaking[transformIndex, frame], frame, translationsBeforeBaking[transformIndex, frame])); } } } }