Exemplo n.º 1
0
    public IEnumerator TwistChainConstraint_FollowsTargets()
    {
        var data       = SetupConstraintRig();
        var constraint = data.constraint;

        var tipTarget  = constraint.data.tipTarget;
        var rootTarget = constraint.data.rootTarget;

        var tip  = constraint.data.tip;
        var root = constraint.data.root;

        var quaternionComparer = new RuntimeRiggingTestFixture.QuaternionEqualityComparer(k_Epsilon);

        for (int i = 0; i < 5; ++i)
        {
            tipTarget.rotation = tipTarget.rotation * Quaternion.Euler(0, 0, 10);
            yield return(RuntimeRiggingTestFixture.YieldTwoFrames());

            Assert.That(tip.rotation, Is.EqualTo(tipTarget.rotation).Using(quaternionComparer));
            Assert.That(root.rotation, Is.EqualTo(rootTarget.rotation).Using(quaternionComparer));
        }

        for (int i = 0; i < 5; ++i)
        {
            rootTarget.rotation = rootTarget.rotation * Quaternion.Euler(0, 0, -10);
            yield return(RuntimeRiggingTestFixture.YieldTwoFrames());

            Assert.That(root.rotation, Is.EqualTo(rootTarget.rotation).Using(quaternionComparer));
            Assert.That(tip.rotation, Is.EqualTo(tipTarget.rotation).Using(quaternionComparer));
        }
    }
Exemplo n.º 2
0
    public IEnumerator MultiRotationConstraint_ApplyWeight()
    {
        var data       = SetupConstraintRig();
        var constraint = data.constraint;

        var constrainedObject = constraint.data.constrainedObject;
        var sources           = constraint.data.sourceObjects;

        var rotationComparer = new RuntimeRiggingTestFixture.QuaternionEqualityComparer(k_Epsilon);

        sources[0].transform.rotation *= Quaternion.AngleAxis(90, Vector3.up);
        sources[0] = new WeightedTransform(sources[0].transform, 1f);
        constraint.data.sourceObjects = sources;

        for (int i = 0; i <= 5; ++i)
        {
            float w = i / 5.0f;

            data.constraint.weight = w;
            yield return(null);

            Quaternion weightedRot = Quaternion.Lerp(data.constrainedObjectRestRotation, sources[0].transform.rotation, w);
            Assert.That(
                constrainedObject.rotation,
                Is.EqualTo(weightedRot).Using(rotationComparer),
                String.Format("Expected constrainedObject rotation to be {0} for a weight of {1}, but was {2}", weightedRot, w, constrainedObject.rotation)
                );
        }
    }
Exemplo n.º 3
0
    public IEnumerator BlendConstraint_ApplyWeight()
    {
        var data           = SetupConstraintRig();
        var constraint     = data.constraint;
        var srcObjB        = constraint.data.sourceObjectB;
        var constrainedObj = constraint.data.constrainedObject;

        var positionComparer = new RuntimeRiggingTestFixture.Vector3EqualityComparer(k_Epsilon);
        var rotationComparer = new RuntimeRiggingTestFixture.QuaternionEqualityComparer(k_Epsilon);

        // SourceB has full influence
        constraint.data.positionWeight = 1f;
        constraint.data.rotationWeight = 1f;
        srcObjB.rotation *= Quaternion.AngleAxis(90, Vector3.right);
        yield return(null);

        for (int i = 0; i <= 5; ++i)
        {
            float w = i / 5.0f;

            data.constraint.weight = w;
            yield return(null);

            var weightedPos = Vector3.Lerp(data.restPose.translation, srcObjB.position, w);
            var weightedRot = Quaternion.Lerp(data.restPose.rotation, srcObjB.rotation, w);
            Assert.That(constrainedObj.position, Is.EqualTo(weightedPos).Using(positionComparer));
            Assert.That(constrainedObj.rotation, Is.EqualTo(weightedRot).Using(rotationComparer));
        }
    }
    public IEnumerator MultiReferentialConstraint_ApplyWeight()
    {
        var data       = SetupConstraintRig();
        var constraint = data.constraint;

        var sources = constraint.data.sourceObjects;

        constraint.data.driver = 1;
        constraint.weight      = 0f;
        yield return(null);

        sources[1].position += Vector3.right;
        sources[1].rotation *= Quaternion.AngleAxis(-90, Vector3.up);

        var positionComparer = new RuntimeRiggingTestFixture.Vector3EqualityComparer(k_Epsilon);
        var rotationComparer = new RuntimeRiggingTestFixture.QuaternionEqualityComparer(k_Epsilon);

        for (int i = 0; i <= 5; ++i)
        {
            float w = i / 5.0f;

            constraint.weight = w;
            yield return(null);

            var weightedPos = Vector3.Lerp(data.restPose.translation, sources[1].position, w);

            Assert.That(
                sources[0].position,
                Is.EqualTo(weightedPos).Using(positionComparer),
                String.Format("Expected Source0 to be at {0} for a weight of {1}, but was {2}", weightedPos, w, sources[0].position)
                );
            Assert.That(
                sources[2].position,
                Is.EqualTo(weightedPos).Using(positionComparer),
                String.Format("Expected Source2 to be at {0} for a weight of {1}, but was {2}", weightedPos, w, sources[2].position)
                );

            var weightedRot = Quaternion.Lerp(data.restPose.rotation, sources[1].rotation, w);
            Assert.That(
                sources[0].rotation,
                Is.EqualTo(weightedRot).Using(rotationComparer),
                String.Format("Expected rotations to be equal for a weight of {0}", w)
                );
            Assert.That(
                sources[2].rotation,
                Is.EqualTo(weightedRot).Using(rotationComparer),
                String.Format("Expected rotations to be equal for a weight of {0}", w)
                );

            // Since we have no animation in the stream the new rest pose
            // should be the last evaluated one.
            data.restPose.translation = sources[0].position;
            data.restPose.rotation    = sources[0].rotation;
        }
    }
Exemplo n.º 5
0
    public IEnumerator TwistCorrection_FollowsSourceObject()
    {
        var data       = SetupConstraintRig();
        var constraint = data.constraint;

        var sourceObject = constraint.data.sourceObject;
        var twistNodes   = constraint.data.twistNodes;

        var rotationComparer = new RuntimeRiggingTestFixture.QuaternionEqualityComparer(k_Epsilon);
        var floatComparer    = new RuntimeRiggingTestFixture.FloatEqualityComparer(k_Epsilon);

        // Apply rotation to source object
        sourceObject.localRotation = sourceObject.localRotation * Quaternion.AngleAxis(90, Vector3.left);

        // twistNode0.w = 0.0f, twistNode1.w = 0.0f [does not influence twist nodes]
        Assert.AreEqual(twistNodes[0].weight, 0.0f);
        Assert.AreEqual(twistNodes[1].weight, 0.0f);
        yield return(RuntimeRiggingTestFixture.YieldTwoFrames());

        Assert.That(sourceObject.localRotation, Is.Not.EqualTo(data.restLocalRotation).Using(rotationComparer));
        Assert.That(twistNodes[0].transform.localRotation, Is.EqualTo(Quaternion.identity).Using(rotationComparer));
        Assert.That(twistNodes[1].transform.localRotation, Is.EqualTo(Quaternion.identity).Using(rotationComparer));

        // twistNode0.w = 1f, twistNode1.w = 1f [twist nodes should be equal to source]
        twistNodes.SetWeight(0, 1f);
        twistNodes.SetWeight(1, 1f);
        constraint.data.twistNodes = twistNodes;
        yield return(RuntimeRiggingTestFixture.YieldTwoFrames());

        // Verify twist on X axis
        Assert.That(twistNodes[0].transform.localRotation.x, Is.EqualTo(sourceObject.localRotation.x).Using(floatComparer));
        Assert.That(twistNodes[0].transform.localRotation.w, Is.EqualTo(sourceObject.localRotation.w).Using(floatComparer));
        Assert.That(twistNodes[1].transform.localRotation.x, Is.EqualTo(sourceObject.localRotation.x).Using(floatComparer));
        Assert.That(twistNodes[1].transform.localRotation.w, Is.EqualTo(sourceObject.localRotation.w).Using(floatComparer));

        // twistNode0.w = -1f, twistNode1.w = -1f [twist nodes should be inverse to source]
        twistNodes.SetWeight(0, -1f);
        twistNodes.SetWeight(1, -1f);
        constraint.data.twistNodes = twistNodes;
        yield return(RuntimeRiggingTestFixture.YieldTwoFrames());

        var invTwist = Quaternion.Inverse(sourceObject.localRotation);

        // Verify twist on X axis
        Assert.That(twistNodes[0].transform.localRotation.x, Is.EqualTo(invTwist.x).Using(floatComparer));
        Assert.That(twistNodes[0].transform.localRotation.w, Is.EqualTo(invTwist.w).Using(floatComparer));
        Assert.That(twistNodes[1].transform.localRotation.x, Is.EqualTo(invTwist.x).Using(floatComparer));
        Assert.That(twistNodes[1].transform.localRotation.w, Is.EqualTo(invTwist.w).Using(floatComparer));
    }
Exemplo n.º 6
0
    public IEnumerator MultiAimConstraint_FollowSourceObjects()
    {
        var data       = SetupConstraintRig();
        var constraint = data.constraint;

        var constrainedObject = constraint.data.constrainedObject;
        var sources           = constraint.data.sourceObjects;

        var positionComparer = new RuntimeRiggingTestFixture.Vector3EqualityComparer(k_Epsilon);
        var rotationComparer = new RuntimeRiggingTestFixture.QuaternionEqualityComparer(k_Epsilon);
        var floatComparer    = new RuntimeRiggingTestFixture.FloatEqualityComparer(k_Epsilon);

        // Add displacement to source objects
        sources[0].transform.position += Vector3.left;
        sources[1].transform.position += Vector3.right;

        // src0.w = 0, src1.w = 0
        Assert.Zero(sources[0].weight);
        Assert.Zero(sources[1].weight);
        yield return(RuntimeRiggingTestFixture.YieldTwoFrames());

        Assert.That(constrainedObject.position, Is.EqualTo(data.constrainedObjectRestTx.translation).Using(positionComparer));
        Assert.That(constrainedObject.rotation, Is.EqualTo(data.constrainedObjectRestTx.rotation).Using(rotationComparer));

        // src0.w = 1, src1.w = 0
        sources.SetWeight(0, 1f);
        constraint.data.sourceObjects = sources;
        yield return(RuntimeRiggingTestFixture.YieldTwoFrames());

        Vector3 currAim = constrainedObject.rotation * Vector3.forward;
        Vector3 src0Dir = (sources[0].transform.position - constrainedObject.position).normalized;
        Vector3 src1Dir = (sources[1].transform.position - constrainedObject.position).normalized;

        Assert.That(Vector3.Angle(currAim, src0Dir), Is.EqualTo(0f).Using(floatComparer));
        Assert.That(Vector3.Angle(currAim, src1Dir), Is.Not.EqualTo(0f).Using(floatComparer));

        // src0.w = 0, src1.w = 1
        sources.SetWeight(0, 0f);
        sources.SetWeight(1, 1f);
        constraint.data.sourceObjects = sources;
        yield return(RuntimeRiggingTestFixture.YieldTwoFrames());

        currAim = constrainedObject.rotation * Vector3.forward;
        src0Dir = (sources[0].transform.position - constrainedObject.position).normalized;
        src1Dir = (sources[1].transform.position - constrainedObject.position).normalized;
        Assert.That(Vector3.Angle(currAim, src0Dir), Is.Not.EqualTo(0f).Using(floatComparer));
        Assert.That(Vector3.Angle(currAim, src1Dir), Is.EqualTo(0f).Using(floatComparer));
    }
    public IEnumerator MultiReferentialConstraint_FollowSourceObjects()
    {
        var data       = SetupConstraintRig();
        var constraint = data.constraint;

        var positionComparer = new RuntimeRiggingTestFixture.Vector3EqualityComparer(k_Epsilon);
        var rotationComparer = new RuntimeRiggingTestFixture.QuaternionEqualityComparer(k_Epsilon);

        var sources = constraint.data.sourceObjects;

        constraint.data.driver = 0;
        var driver = sources[0];

        driver.position += Vector3.forward;
        driver.rotation *= Quaternion.AngleAxis(90, Vector3.up);
        yield return(RuntimeRiggingTestFixture.YieldTwoFrames());

        Assert.That(driver.position, Is.EqualTo(sources[1].position).Using(positionComparer));
        Assert.That(driver.rotation, Is.EqualTo(sources[1].rotation).Using(rotationComparer));
        Assert.That(driver.position, Is.EqualTo(sources[2].position).Using(positionComparer));
        Assert.That(driver.rotation, Is.EqualTo(sources[2].rotation).Using(rotationComparer));

        constraint.data.driver = 1;
        driver           = sources[1];
        driver.position += Vector3.back;
        driver.rotation *= Quaternion.AngleAxis(-90, Vector3.up);
        yield return(RuntimeRiggingTestFixture.YieldTwoFrames());

        Assert.That(driver.position, Is.EqualTo(sources[0].position).Using(positionComparer));
        Assert.That(driver.rotation, Is.EqualTo(sources[0].rotation).Using(rotationComparer));
        Assert.That(driver.position, Is.EqualTo(sources[2].position).Using(positionComparer));
        Assert.That(driver.rotation, Is.EqualTo(sources[2].rotation).Using(rotationComparer));

        constraint.data.driver = 2;
        driver           = sources[2];
        driver.position += Vector3.up;
        driver.rotation *= Quaternion.AngleAxis(90, Vector3.left);
        yield return(RuntimeRiggingTestFixture.YieldTwoFrames());

        Assert.That(driver.position, Is.EqualTo(sources[0].position).Using(positionComparer));
        Assert.That(driver.rotation, Is.EqualTo(sources[0].rotation).Using(rotationComparer));
        Assert.That(driver.position, Is.EqualTo(sources[1].position).Using(positionComparer));
        Assert.That(driver.rotation, Is.EqualTo(sources[1].rotation).Using(rotationComparer));
    }
    public IEnumerator MultiParentConstraint_FollowSourceObjects()
    {
        var data       = SetupConstraintRig();
        var constraint = data.constraint;

        var constrainedObject = constraint.data.constrainedObject;
        var sources           = constraint.data.sourceObjects;

        var positionComparer  = new RuntimeRiggingTestFixture.Vector3EqualityComparer(k_Epsilon);
        var rotationComprarer = new RuntimeRiggingTestFixture.QuaternionEqualityComparer(k_Epsilon);

        // src0.w = 0, src1.w = 0
        Assert.Zero(sources[0].weight);
        Assert.Zero(sources[1].weight);
        yield return(RuntimeRiggingTestFixture.YieldTwoFrames());

        Assert.That(constrainedObject.position, Is.EqualTo(data.constrainedObjectRestTx.translation).Using(positionComparer));
        Assert.That(constrainedObject.rotation, Is.EqualTo(data.constrainedObjectRestTx.rotation).Using(rotationComprarer));

        // Add displacement to source objects
        sources[0].transform.position += Vector3.right;
        sources[0].transform.rotation *= Quaternion.AngleAxis(-90, Vector3.up);
        sources[1].transform.position += Vector3.left;
        sources[1].transform.rotation *= Quaternion.AngleAxis(90, Vector3.up);

        // src0.w = 1, src1.w = 0
        sources.SetWeight(0, 1f);
        constraint.data.sourceObjects = sources;
        yield return(RuntimeRiggingTestFixture.YieldTwoFrames());

        Assert.That(constrainedObject.position, Is.EqualTo(sources[0].transform.position).Using(positionComparer));
        Assert.That(constrainedObject.rotation, Is.EqualTo(sources[0].transform.rotation).Using(rotationComprarer));

        // src0.w = 0, src1.w = 1
        sources.SetWeight(0, 0f);
        sources.SetWeight(1, 1f);
        constraint.data.sourceObjects = sources;
        yield return(RuntimeRiggingTestFixture.YieldTwoFrames());

        Assert.That(constrainedObject.position, Is.EqualTo(sources[1].transform.position).Using(positionComparer));
        Assert.That(constrainedObject.rotation, Is.EqualTo(sources[1].transform.rotation).Using(rotationComprarer));
    }
Exemplo n.º 9
0
    public IEnumerator BlendConstraint_FollowsSourceObjects()
    {
        var data           = SetupConstraintRig();
        var constraint     = data.constraint;
        var srcObjA        = constraint.data.sourceObjectA;
        var srcObjB        = constraint.data.sourceObjectB;
        var constrainedObj = constraint.data.constrainedObject;

        var positionComparer = new RuntimeRiggingTestFixture.Vector3EqualityComparer(k_Epsilon);
        var rotationComparer = new RuntimeRiggingTestFixture.QuaternionEqualityComparer(k_Epsilon);

        // Apply rotation on sourceB
        srcObjB.rotation *= Quaternion.AngleAxis(90, Vector3.right);
        yield return(null);

        // SourceA has full influence
        constraint.data.positionWeight = 0f;
        constraint.data.rotationWeight = 0f;
        yield return(null);

        Assert.That(constrainedObj.position, Is.EqualTo(srcObjA.position).Using(positionComparer));
        Assert.That(constrainedObj.rotation, Is.EqualTo(srcObjA.rotation).Using(rotationComparer));

        // SourceB has full influence
        constraint.data.positionWeight = 1f;
        constraint.data.rotationWeight = 1f;
        yield return(null);

        Assert.That(constrainedObj.position, Is.EqualTo(srcObjB.position).Using(positionComparer));
        Assert.That(constrainedObj.rotation, Is.EqualTo(srcObjB.rotation).Using(rotationComparer));

        // Translation/Rotation blending between sources is disabled
        constraint.data.blendPosition = false;
        constraint.data.blendRotation = false;
        yield return(null);

        Assert.That(constrainedObj.position, Is.EqualTo(data.restPose.translation).Using(positionComparer));
        Assert.That(constrainedObj.rotation, Is.EqualTo(data.restPose.rotation).Using(rotationComparer));
    }
Exemplo n.º 10
0
    public IEnumerator MultiRotationConstraint_FollowSourceObjects()
    {
        var data       = SetupConstraintRig();
        var constraint = data.constraint;

        var constrainedObject = constraint.data.constrainedObject;
        var sources           = constraint.data.sourceObjects;

        var rotationComparer = new RuntimeRiggingTestFixture.QuaternionEqualityComparer(k_Epsilon);

        // src0.w = 0, src1.w = 0
        Assert.Zero(sources[0].weight);
        Assert.Zero(sources[1].weight);
        yield return(RuntimeRiggingTestFixture.YieldTwoFrames());

        Assert.That(constrainedObject.rotation, Is.EqualTo(data.constrainedObjectRestRotation).Using(rotationComparer));

        // Add rotation to source objects
        sources[0].transform.rotation *= Quaternion.AngleAxis(90, Vector3.up);
        sources[1].transform.rotation *= Quaternion.AngleAxis(-90, Vector3.up);

        // src0.w = 1, src1.w = 0
        sources[0] = new WeightedTransform(sources[0].transform, 1f);
        constraint.data.sourceObjects = sources;
        yield return(RuntimeRiggingTestFixture.YieldTwoFrames());

        Assert.That(constrainedObject.rotation, Is.EqualTo(sources[0].transform.rotation).Using(rotationComparer));

        // src0.w = 0, src1.w = 1
        sources[0] = new WeightedTransform(sources[0].transform, 0f);
        sources[1] = new WeightedTransform(sources[1].transform, 1f);
        constraint.data.sourceObjects = sources;
        yield return(RuntimeRiggingTestFixture.YieldTwoFrames());

        Assert.That(constrainedObject.rotation, Is.EqualTo(sources[1].transform.rotation).Using(rotationComparer));
    }
    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]));
                }
            }
        }
    }