public IEnumerator MultiRotationConstraint_FollowSourceObjects()
    {
        var data       = SetupConstraintRig();
        var constraint = data.constraint;

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

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

        Assert.AreEqual(constrainedObject.rotation, data.constrainedObjectRestRotation);

        // 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.AreEqual(constrainedObject.rotation, sources[0].transform.rotation);

        // 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.AreEqual(constrainedObject.rotation, sources[1].transform.rotation);
    }
Пример #2
0
    public IEnumerator MultiAimConstraint_ApplyWeight()
    {
        var data       = SetupConstraintRig();
        var constraint = data.constraint;

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

        Assert.Zero(sources[0].weight);
        Assert.Zero(sources[1].weight);

        sources[0].transform.position += Vector3.left;
        sources[0].weight              = 1f;
        constraint.data.MarkSourceWeightsDirty();

        var src0Pos = sources[0].transform.position;

        var angle = 180f;

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

            data.constraint.weight = w;
            yield return(RuntimeRiggingTestFixture.YieldTwoFrames());

            var currAim   = constrainedObject.transform.rotation * Vector3.forward;
            var src0Dir   = (src0Pos - constrainedObject.transform.position).normalized;
            var angleTest = Vector3.Angle(currAim, src0Dir);

            Assert.Less(angleTest, angle, "Angle between currAim and src0Dir should be smaller than last frame since constraint weight is greater.");
            angle = angleTest;
        }
    }
Пример #3
0
    public IEnumerator OverrideTransform_ApplyWeight()
    {
        var data       = SetupConstraintRig();
        var constraint = data.constraint;

        var constrainedTransform = constraint.data.constrainedObject;
        var sourceTransform      = constraint.data.sourceObject;

        var positionComparer = new RuntimeRiggingTestFixture.Vector3EqualityComparer(k_Epsilon);

        Vector3 constrainedPos1 = constrainedTransform.position;

        constraint.data.space = OverrideTransformData.Space.World;
        yield return(null);

        sourceTransform.position = new Vector3(0f, 0.5f, 0f);
        yield return(null);

        Vector3 constrainedPos2 = constrainedTransform.position;

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

            data.constraint.weight = w;

            yield return(RuntimeRiggingTestFixture.YieldTwoFrames());

            Vector3 weightedConstrainedPos = Vector3.Lerp(constrainedPos1, constrainedPos2, w);
            Vector3 constrainedPos         = constrainedTransform.position;

            Assert.That(weightedConstrainedPos, Is.EqualTo(constrainedPos).Using(positionComparer), String.Format("Expected constrainedPos.x to be {0} for a weight of {1}, but was {2}", weightedConstrainedPos, w, constrainedPos));
        }
    }
Пример #4
0
    public IEnumerator TwoBoneIKConstraint_ApplyWeight()
    {
        var data       = SetupConstraintRig();
        var constraint = data.constraint;

        var tip    = constraint.data.tip;
        var target = constraint.data.target;

        Vector3 tipPos1 = tip.position;

        target.position += new Vector3(0f, 0.5f, 0f);
        yield return(RuntimeRiggingTestFixture.YieldTwoFrames());

        Vector3 tipPos2 = tip.position;

        var positionComparer = new RuntimeRiggingTestFixture.Vector3EqualityComparer(k_Epsilon);

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

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

            Vector3 weightedTipPos = Vector3.Lerp(tipPos1, tipPos2, w);
            Vector3 tipPos         = tip.position;

            Assert.That(tipPos, Is.EqualTo(weightedTipPos).Using(positionComparer), String.Format("Expected tip to be {0} for a weight of {1}, but was {2}", weightedTipPos, w, tipPos));
        }
    }
Пример #5
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));
        }
    }
Пример #6
0
    public IEnumerator OverrideTransform_ApplyWeight()
    {
        var data       = SetupConstraintRig();
        var constraint = data.constraint;

        var constrainedTransform = constraint.data.constrainedObject.transform;
        var sourceTransform      = constraint.data.sourceObject.transform;

        Vector3 constrainedPos1 = constrainedTransform.position;

        constraint.data.space = OverrideTransformData.Space.World;
        yield return(null);

        sourceTransform.position = new Vector3(0f, 0.5f, 0f);
        yield return(null);

        Vector3 constrainedPos2 = constrainedTransform.position;

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

            data.constraint.weight = w;

            yield return(RuntimeRiggingTestFixture.YieldTwoFrames());

            Vector3 weightedConstrainedPos = Vector3.Lerp(constrainedPos1, constrainedPos2, w);
            Vector3 constrainedPos         = constrainedTransform.position;

            Assert.AreEqual(weightedConstrainedPos.x, constrainedPos.x, k_Epsilon, String.Format("Expected constrainedPos.x to be {0} for a weight of {1}, but was {2}", weightedConstrainedPos.x, w, constrainedPos.x));
            Assert.AreEqual(weightedConstrainedPos.y, constrainedPos.y, k_Epsilon, String.Format("Expected constrainedPos.y to be {0} for a weight of {1}, but was {2}", weightedConstrainedPos.y, w, constrainedPos.y));
            Assert.AreEqual(weightedConstrainedPos.z, constrainedPos.z, k_Epsilon, String.Format("Expected constrainedPos.z to be {0} for a weight of {1}, but was {2}", weightedConstrainedPos.z, w, constrainedPos.z));
        }
    }
    public IEnumerator MultiRotationConstraint_ApplyWeight()
    {
        var data       = SetupConstraintRig();
        var constraint = data.constraint;

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

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

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

            data.constraint.weight = w;
            yield return(RuntimeRiggingTestFixture.YieldTwoFrames());

            Quaternion weightedRot = Quaternion.Lerp(data.constrainedObjectRestRotation, sources[0].transform.rotation, w);
            Assert.AreEqual(
                constrainedObject.transform.rotation,
                weightedRot,
                String.Format("Expected constrainedObject rotation to be {0} for a weight of {1}, but was {2}", weightedRot, w, constrainedObject.transform.rotation)
                );
        }
    }
Пример #8
0
    public IEnumerator MultiPositionConstraint_ApplyWeight()
    {
        var data       = SetupConstraintRig();
        var constraint = data.constraint;

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

        sources[0].transform.position += Vector3.forward;
        sources[0].weight              = 1f;
        constraint.data.MarkSourceWeightsDirty();

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

            data.constraint.weight = w;
            yield return(RuntimeRiggingTestFixture.YieldTwoFrames());

            Vector3 weightedPos = Vector3.Lerp(data.constrainedObjectRestPosition, sources[0].transform.position, w);
            Assert.AreEqual(
                constrainedObject.transform.position,
                weightedPos,
                String.Format("Expected constrainedObject to be at {0} for a weight of {1}, but was {2}", weightedPos, w, constrainedObject.transform.position)
                );
        }
    }
Пример #9
0
    public IEnumerator TwistCorrection_ApplyWeight()
    {
        var data       = SetupConstraintRig();
        var constraint = data.constraint;

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

        // Apply rotation to source object
        sourceObject.transform.localRotation = sourceObject.transform.localRotation * Quaternion.AngleAxis(90, Vector3.left);
        twistNodes[0].weight = 1f;
        constraint.data.MarkTwistNodeWeightsDirty();

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

            data.constraint.weight = w;
            yield return(RuntimeRiggingTestFixture.YieldTwoFrames());

            var weightedRot = Quaternion.Lerp(data.restLocalRotation, sourceObject.transform.localRotation, w);
            Assert.AreEqual(twistNodes[0].transform.localRotation.w, weightedRot.w, k_Epsilon);
            Assert.AreEqual(twistNodes[0].transform.localRotation.x, weightedRot.x, k_Epsilon);
        }
    }
Пример #10
0
    public IEnumerator BlendConstraint_ApplyWeight()
    {
        var data           = SetupConstraintRig();
        var constraint     = data.constraint;
        var srcObjB        = constraint.data.sourceObjectB;
        var constrainedObj = constraint.data.constrainedObject;

        // SourceB has full influence
        constraint.data.positionWeight = 1f;
        constraint.data.rotationWeight = 1f;
        srcObjB.transform.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(RuntimeRiggingTestFixture.YieldTwoFrames());

            var weightedPos = Vector3.Lerp(data.restPose.translation, srcObjB.transform.position, w);
            var weightedRot = Quaternion.Lerp(data.restPose.rotation, srcObjB.transform.rotation, w);
            Assert.AreEqual(constrainedObj.transform.position, weightedPos);
            RotationsAreEqual(constrainedObj.transform.rotation, weightedRot);
        }
    }
Пример #11
0
    public IEnumerator TwoBoneIKConstraint_ApplyWeight()
    {
        var data       = SetupConstraintRig();
        var constraint = data.constraint;

        var tip    = constraint.data.tip.transform;
        var target = constraint.data.target.transform;

        Vector3 tipPos1 = tip.position;

        target.position += new Vector3(0f, 0.5f, 0f);
        yield return(null);

        Vector3 tipPos2 = tip.position;

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

            data.constraint.weight = w;
            yield return(RuntimeRiggingTestFixture.YieldTwoFrames());

            Vector3 weightedTipPos = Vector3.Lerp(tipPos1, tipPos2, w);
            Vector3 tipPos         = tip.position;

            Assert.AreEqual(weightedTipPos.x, tipPos.x, k_Epsilon, String.Format("Expected tip.x to be {0} for a weight of {1}, but was {2}", weightedTipPos.x, w, tipPos.x));
            Assert.AreEqual(weightedTipPos.y, tipPos.y, k_Epsilon, String.Format("Expected tip.y to be {0} for a weight of {1}, but was {2}", weightedTipPos.y, w, tipPos.y));
            Assert.AreEqual(weightedTipPos.z, tipPos.z, k_Epsilon, String.Format("Expected tip.z to be {0} for a weight of {1}, but was {2}", weightedTipPos.z, w, tipPos.z));
        }
    }
Пример #12
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));
    }
Пример #13
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));
    }
Пример #14
0
    public IEnumerator TwistCorrection_FollowsSourceObject()
    {
        var data       = SetupConstraintRig();
        var constraint = data.constraint;

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

        // Apply rotation to source object
        sourceObject.transform.localRotation = sourceObject.transform.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.AreNotEqual(sourceObject.transform.localRotation, data.restLocalRotation);
        Assert.AreEqual(twistNodes[0].transform.localRotation, Quaternion.identity);
        Assert.AreEqual(twistNodes[1].transform.localRotation, Quaternion.identity);

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

        // Verify twist on X axis
        Assert.AreEqual(twistNodes[0].transform.localRotation.w, sourceObject.transform.localRotation.w, k_Epsilon);
        Assert.AreEqual(twistNodes[0].transform.localRotation.x, sourceObject.transform.localRotation.x, k_Epsilon);
        Assert.AreEqual(twistNodes[1].transform.localRotation.w, sourceObject.transform.localRotation.w, k_Epsilon);
        Assert.AreEqual(twistNodes[1].transform.localRotation.x, sourceObject.transform.localRotation.x, k_Epsilon);

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

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

        // Verify twist on X axis
        Assert.AreEqual(twistNodes[0].transform.localRotation.w, invTwist.w, k_Epsilon);
        Assert.AreEqual(twistNodes[0].transform.localRotation.x, invTwist.x, k_Epsilon);
        Assert.AreEqual(twistNodes[1].transform.localRotation.w, invTwist.w, k_Epsilon);
        Assert.AreEqual(twistNodes[1].transform.localRotation.x, invTwist.x, k_Epsilon);
    }
Пример #15
0
    public IEnumerator TwoBoneIKConstraint_UsesHint()
    {
        var data       = SetupConstraintRig();
        var constraint = data.constraint;

        var target = constraint.data.target;
        var hint   = constraint.data.hint;
        var mid    = constraint.data.mid;

        var floatComparer = new RuntimeRiggingTestFixture.FloatEqualityComparer(k_Epsilon);

        Vector3 midPos1 = mid.position;

        // Make left arm flex.
        target.position += new Vector3(0.2f, 0.0f, 0f);

        hint.position = mid.position + new Vector3(0f, 1f, 0f);
        yield return(RuntimeRiggingTestFixture.YieldTwoFrames());

        Vector3 midPos2 = mid.position;

        Assert.That(midPos2.y, Is.GreaterThan(midPos1.y).Using(floatComparer), String.Format("Expected mid2.y to be greater than mid1.y"));
        Assert.That(midPos1.z, Is.EqualTo(midPos2.z).Using(floatComparer), String.Format("Expected mid2.z to be {0}, but was {1}", midPos1.z, midPos2.z));

        hint.position = mid.position + new Vector3(0f, -1f, 0f);
        yield return(RuntimeRiggingTestFixture.YieldTwoFrames());

        midPos2 = mid.position;
        Assert.That(midPos2.y, Is.LessThan(midPos1.y).Using(floatComparer), String.Format("Expected mid2.y to be lower than mid1.y"));
        Assert.That(midPos1.z, Is.EqualTo(midPos2.z).Using(floatComparer), String.Format("Expected mid2.z to be {0}, but was {1}", midPos1.z, midPos2.z));

        hint.position = mid.position + new Vector3(0f, 0f, 1f);
        yield return(RuntimeRiggingTestFixture.YieldTwoFrames());

        midPos2 = mid.position;
        Assert.That(midPos1.y, Is.EqualTo(midPos2.y).Using(floatComparer), String.Format("Expected mid2.y to be {0}, but was {1}", midPos1.y, midPos2.y));
        Assert.That(midPos2.z, Is.GreaterThan(midPos1.z).Using(floatComparer), String.Format("Expected mid2.y to be greater than mid1.y"));

        hint.position = mid.position + new Vector3(0f, 0f, -1f);
        yield return(RuntimeRiggingTestFixture.YieldTwoFrames());

        midPos2 = mid.position;
        Assert.That(midPos1.y, Is.EqualTo(midPos2.y).Using(floatComparer), String.Format("Expected mid2.y to be {0}, but was {1}", midPos1.y, midPos2.y));
        Assert.That(midPos2.z, Is.LessThan(midPos1.z).Using(floatComparer), String.Format("Expected mid2.y to be greater than mid1.y"));
    }
    public IEnumerator MultiPositionConstraint_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);

        // 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.constrainedObjectRestPosition).Using(positionComparer));

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

        // 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));

        // 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));

        // src0.w = 1, src1.w = 1
        // since source object positions are mirrored, we should simply evaluate to the original rest pos.
        sources.SetWeight(0, 1f);
        constraint.data.sourceObjects = sources;
        yield return(RuntimeRiggingTestFixture.YieldTwoFrames());

        Assert.That(constrainedObject.position, Is.EqualTo(data.constrainedObjectRestPosition).Using(positionComparer));
    }
    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));
    }
Пример #18
0
    public IEnumerator MultiAimConstraint_FollowSourceObjects()
    {
        var data       = SetupConstraintRig();
        var constraint = data.constraint;

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

        // 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.AreEqual(constrainedObject.position, data.constrainedObjectRestTx.translation);
        Assert.AreEqual(constrainedObject.rotation, data.constrainedObjectRestTx.rotation);

        // 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.AreEqual(0f, Vector3.Angle(currAim, src0Dir), k_Epsilon);
        Assert.AreNotEqual(0f, Vector3.Angle(currAim, src1Dir));

        // 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.AreNotEqual(0f, Vector3.Angle(currAim, src0Dir));
        Assert.AreEqual(0f, Vector3.Angle(currAim, src1Dir), k_Epsilon);
    }
Пример #19
0
    public IEnumerator MultiReferentialConstraint_ApplyWeight()
    {
        var data       = SetupConstraintRig();
        var constraint = data.constraint;

        var sources = constraint.data.sourceObjects;

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

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

            data.constraint.weight = w;
            yield return(RuntimeRiggingTestFixture.YieldTwoFrames());

            var weightedPos = Vector3.Lerp(data.restPose.translation, sources[1].transform.position, w);
            Assert.AreEqual(
                sources[0].transform.position,
                weightedPos,
                String.Format("Expected Source0 to be at {0} for a weight of {1}, but was {2}", weightedPos, w, sources[0].transform.position)
                );
            Assert.AreEqual(
                sources[2].transform.position,
                weightedPos,
                String.Format("Expected Source2 to be at {0} for a weight of {1}, but was {2}", weightedPos, w, sources[2].transform.position)
                );

            var weightedRot = Quaternion.Lerp(data.restPose.rotation, sources[1].transform.rotation, w);
            Assert.AreEqual(
                sources[0].transform.rotation,
                weightedRot,
                String.Format("Expected Source0 to be at {0} for a weight of {1}, but was {2}", weightedRot, w, sources[0].transform.rotation)
                );
            Assert.AreEqual(
                sources[2].transform.rotation,
                weightedRot,
                String.Format("Expected Source2 to be at {0} for a weight of {1}, but was {2}", weightedRot, w, sources[2].transform.rotation)
                );
        }
    }
Пример #20
0
    public IEnumerator MultiPositionConstraint_FollowSourceObjects()
    {
        var data       = SetupConstraintRig();
        var constraint = data.constraint;

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

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

        Assert.AreEqual(constrainedObject.transform.position, data.constrainedObjectRestPosition);

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

        // src0.w = 1, src1.w = 0
        sources[0].weight = 1f;
        constraint.data.MarkSourceWeightsDirty();
        yield return(RuntimeRiggingTestFixture.YieldTwoFrames());

        Assert.AreEqual(constrainedObject.transform.position, sources[0].transform.position);

        // src0.w = 0, src1.w = 1
        sources[0].weight = 0f;
        sources[1].weight = 1f;
        constraint.data.MarkSourceWeightsDirty();
        yield return(RuntimeRiggingTestFixture.YieldTwoFrames());

        Assert.AreEqual(constrainedObject.transform.position, sources[1].transform.position);

        // src0.w = 1, src1.w = 1
        // since source object positions are mirrored, we should simply evaluate to the original rest pos.
        sources[0].weight = 1f;
        constraint.data.MarkSourceWeightsDirty();
        yield return(RuntimeRiggingTestFixture.YieldTwoFrames());

        Assert.AreEqual(constrainedObject.transform.position, data.constrainedObjectRestPosition);
    }
    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));
    }
    public IEnumerator MultiReferentialConstraint_FollowSourceObjects()
    {
        var data       = SetupConstraintRig();
        var constraint = data.constraint;

        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.AreEqual(driver.position, sources[1].position);
        Assert.AreEqual(driver.rotation, sources[1].rotation);
        Assert.AreEqual(driver.position, sources[2].position);
        Assert.AreEqual(driver.rotation, sources[2].rotation);

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

        Assert.AreEqual(driver.position, sources[0].position);
        Assert.AreEqual(driver.rotation, sources[0].rotation);
        Assert.AreEqual(driver.position, sources[2].position);
        Assert.AreEqual(driver.rotation, sources[2].rotation);

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

        Assert.AreEqual(driver.position, sources[0].position);
        Assert.AreEqual(driver.rotation, sources[0].rotation);
        Assert.AreEqual(driver.position, sources[1].position);
        Assert.AreEqual(driver.rotation, sources[1].rotation);
    }
    public IEnumerator ChainIKConstraint_FollowsTarget()
    {
        var data       = SetupConstraintRig();
        var constraint = data.constraint;

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

        var positionComparer = new RuntimeRiggingTestFixture.Vector3EqualityComparer(k_Epsilon);

        for (int i = 0; i < 5; ++i)
        {
            target.position += new Vector3(0f, 0.1f, 0f);
            yield return(RuntimeRiggingTestFixture.YieldTwoFrames());

            Vector3 rootToTip    = (tip.position - root.position).normalized;
            Vector3 rootToTarget = (target.position - root.position).normalized;

            Assert.That(rootToTarget, Is.EqualTo(rootToTip).Using(positionComparer), String.Format("Expected rootToTip to be {0}, but was {1}", rootToTip, rootToTarget));
        }
    }
Пример #24
0
    public IEnumerator MultiParentConstraint_FollowSourceObjects()
    {
        var data       = SetupConstraintRig();
        var constraint = data.constraint;

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

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

        Assert.AreEqual(constrainedObject.transform.position, data.constrainedObjectRestTx.translation);
        Assert.AreEqual(constrainedObject.transform.rotation, data.constrainedObjectRestTx.rotation);

        // 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[0].weight = 1f;
        constraint.data.MarkSourceWeightsDirty();
        yield return(RuntimeRiggingTestFixture.YieldTwoFrames());

        Assert.AreEqual(constrainedObject.transform.position, sources[0].transform.position);
        Assert.AreEqual(constrainedObject.transform.rotation, sources[0].transform.rotation);

        // src0.w = 0, src1.w = 1
        sources[0].weight = 0f;
        sources[1].weight = 1f;
        constraint.data.MarkSourceWeightsDirty();
        yield return(RuntimeRiggingTestFixture.YieldTwoFrames());

        Assert.AreEqual(constrainedObject.transform.position, sources[1].transform.position);
        Assert.AreEqual(constrainedObject.transform.rotation, sources[1].transform.rotation);
    }
    public IEnumerator ChainIKConstraint_FollowsTarget()
    {
        var data = SetupConstraintRig();
        var constraint = data.constraint;

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

        for (int i = 0; i < 5; ++i)
        {
            target.position += new Vector3(0f, 0.1f, 0f);
            yield return RuntimeRiggingTestFixture.YieldTwoFrames();

            Vector3 rootToTip = (tip.position - root.position).normalized;
            Vector3 rootToTarget = (target.position - root.position).normalized;

            Assert.AreEqual(rootToTarget.x, rootToTip.x, k_Epsilon, String.Format("Expected rootToTip.x to be {0}, but was {1}", rootToTip.x, rootToTarget.x));
            Assert.AreEqual(rootToTarget.y, rootToTip.y, k_Epsilon, String.Format("Expected rootToTip.y to be {0}, but was {1}", rootToTip.y, rootToTarget.y));
            Assert.AreEqual(rootToTarget.z, rootToTip.z, k_Epsilon, String.Format("Expected rootToTip.z to be {0}, but was {1}", rootToTip.z, rootToTarget.z));
        }
    }
Пример #26
0
    public IEnumerator DampedTransform_ApplyWeight()
    {
        var data       = SetupConstraintRig();
        var constraint = data.constraint;

        // no position damping, full rotation damp
        constraint.data.dampPosition = 0f;
        constraint.data.dampRotation = 1f;

        data.constraint.weight = 0f;
        yield return(RuntimeRiggingTestFixture.YieldTwoFrames());

        var constrainedTransform = constraint.data.constrainedObject.transform;
        var sourceTransform      = constraint.data.sourceObject.transform;

        Vector3 constrainedPos1 = constrainedTransform.position;

        Vector3 offset = new Vector3(0f, 0.5f, 0f);

        sourceTransform.localPosition += offset;
        Vector3 constrainedPos2 = constrainedPos1 + offset;

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

            data.constraint.weight = w;
            yield return(RuntimeRiggingTestFixture.YieldTwoFrames());

            Vector3 weightedConstrainedPos = Vector3.Lerp(constrainedPos1, constrainedPos2, w);
            Vector3 constrainedPos         = constrainedTransform.position;

            Assert.AreEqual(weightedConstrainedPos.x, constrainedPos.x, k_Epsilon, String.Format("Expected constrainedPos.x to be {0} for a weight of {1}, but was {2}", weightedConstrainedPos.x, w, constrainedPos.x));
            Assert.AreEqual(weightedConstrainedPos.y, constrainedPos.y, k_Epsilon, String.Format("Expected constrainedPos.y to be {0} for a weight of {1}, but was {2}", weightedConstrainedPos.y, w, constrainedPos.y));
            Assert.AreEqual(weightedConstrainedPos.z, constrainedPos.z, k_Epsilon, String.Format("Expected constrainedPos.z to be {0} for a weight of {1}, but was {2}", weightedConstrainedPos.z, w, constrainedPos.z));
        }
    }
Пример #27
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;

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

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

        Assert.AreEqual(constrainedObj.transform.position, srcObjA.transform.position);
        RotationsAreEqual(constrainedObj.transform.rotation, srcObjA.transform.rotation);

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

        Assert.AreEqual(constrainedObj.transform.position, srcObjB.transform.position);
        RotationsAreEqual(constrainedObj.transform.rotation, srcObjB.transform.rotation);

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

        Assert.AreEqual(constrainedObj.transform.position, data.restPose.translation);
        RotationsAreEqual(constrainedObj.transform.rotation, data.restPose.rotation);
    }
Пример #28
0
    public IEnumerator ChainIKConstraint_ApplyWeight()
    {
        var data       = SetupConstraintRig();
        var constraint = data.constraint;

        List <Transform> chain = new List <Transform>();
        Transform        tmp   = constraint.data.tip.transform;

        while (tmp != constraint.data.root.transform)
        {
            chain.Add(tmp);
            tmp = tmp.parent;
        }
        chain.Add(constraint.data.root.transform);
        chain.Reverse();

        // Chain with no constraint.
        Vector3[] bindPoseChain = chain.Select(transform => transform.position).ToArray();

        var target = constraint.data.target.transform;

        target.position += new Vector3(0f, 0.5f, 0f);

        yield return(null);

        // Chain with ChainIK constraint.
        Vector3[] weightedChain = chain.Select(transform => transform.position).ToArray();

        // In-between chains.
        List <Vector3[]> inBetweenChains = new List <Vector3[]>();

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

            data.constraint.weight = w;
            yield return(RuntimeRiggingTestFixture.YieldTwoFrames());

            inBetweenChains.Add(chain.Select(transform => transform.position).ToArray());
        }

        for (int i = 0; i <= 5; ++i)
        {
            Vector3[] prevChain    = (i > 0) ? inBetweenChains[i - 1] : bindPoseChain;
            Vector3[] currentChain = inBetweenChains[i];
            Vector3[] nextChain    = (i < 5) ? inBetweenChains[i + 1] : weightedChain;

            for (int j = 0; j < bindPoseChain.Length - 1; ++j)
            {
                Vector2 dir1 = prevChain[j + 1] - prevChain[j];
                Vector2 dir2 = currentChain[j + 1] - currentChain[j];
                Vector2 dir3 = nextChain[j + 1] - nextChain[j];

                float maxAngle = Vector2.Angle(dir1, dir3);
                float angle    = Vector2.Angle(dir1, dir3);

                Assert.GreaterOrEqual(angle, 0f);
                Assert.LessOrEqual(angle, maxAngle);
            }
        }
    }