public static void RestoreDefaultPose(Animator animator, AnimationClip defaultPoseClip)
 {
     using (var graph = new EvaluationGraph(animator, defaultPoseClip))
     {
         graph.Evaluate(0f);
     }
 }
Ejemplo n.º 2
0
        private static void BakeToSkeleton(RigBuilder rigBuilder, IRigConstraint constraint, AnimationClip clip, AnimationClip defaultPoseClip, IEnumerable <EditorCurveBinding> bindings, CurveFilterOptions filterOptions)
        {
            // Make sure the base constraint is valid
            if (constraint == null || !constraint.IsValid())
            {
                throw new InvalidOperationException(
                          string.Format("The rig constraint {0} is not a valid constraint.",
                                        constraint != null ? constraint.ToString() : ""));
            }

            var overrides = new Dictionary <IRigConstraint, IRigConstraint>();

            using (var graph = new EvaluationGraph(rigBuilder, clip, defaultPoseClip, overrides, constraint))
            {
                BakeCurvesToClip(clip, bindings, rigBuilder, graph, filterOptions);
            }
        }
Ejemplo n.º 3
0
        private static void BakeToConstraint(RigBuilder rigBuilder, IRigConstraint constraint, AnimationClip clip, AnimationClip defaultPoseClip, IEnumerable <EditorCurveBinding> bindings, CurveFilterOptions filterOptions)
        {
            // Make sure the base constraint is valid
            if (constraint == null || !constraint.IsValid())
            {
                throw new InvalidOperationException(
                          string.Format("The rig constraint {0} is not a valid constraint.",
                                        constraint != null ? constraint.ToString() : ""));
            }

            // Check if the constraint is inverse solvable
            var inverseConstraint = FindInverseRigConstraint(constraint);

            if (inverseConstraint == null)
            {
                throw new InvalidOperationException(
                          string.Format("No inverse rig constraint could be found for {0}.",
                                        constraint.ToString()));
            }
            else if (!inverseConstraint.IsValid())
            {
                throw new InvalidOperationException(
                          string.Format("The inverse rig constrain {1} for {0} is not a valid constraint.",
                                        constraint.ToString(),
                                        inverseConstraint.ToString()));
            }

            var overrides = new Dictionary <IRigConstraint, IRigConstraint>();

            overrides.Add(constraint, inverseConstraint);

            using (var graph = new EvaluationGraph(rigBuilder, clip, defaultPoseClip, overrides, constraint))
            {
                BakeCurvesToClip(clip, bindings, rigBuilder, graph, filterOptions);
            }
        }
    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]));
                }
            }
        }
    }