コード例 #1
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));
        }
    }
    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);
    }
コード例 #3
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;
        }
    }
コード例 #4
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));
        }
    }
コード例 #5
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));
        }
    }
コード例 #6
0
    private ConstraintTestData SetupConstraintRig()
    {
        var data = new ConstraintTestData();

        data.rigData = RuntimeRiggingTestFixture.SetupRigHierarchy();

        var dampedTransformGO = new GameObject("dampedTransform");
        var dampedTransform   = dampedTransformGO.AddComponent <DampedTransform>();

        dampedTransform.Reset();

        dampedTransformGO.transform.parent = data.rigData.rigGO.transform;

        dampedTransform.data.constrainedObject = data.rigData.hipsGO.transform.Find("Chest/LeftArm/LeftForeArm/LeftHand");

        var dampedSourceGO = new GameObject("source");

        dampedSourceGO.transform.parent = dampedTransformGO.transform;

        dampedTransform.data.sourceObject = new JobTransform(dampedSourceGO.transform, true);

        data.rigData.rootGO.GetComponent <RigBuilder>().Build();

        data.constraint = dampedTransform;

        return(data);
    }
コード例 #7
0
    public static ConstraintTestData SetupConstraintRig()
    {
        var data = new ConstraintTestData();

        data.rigData = RuntimeRiggingTestFixture.SetupRigHierarchy();

        var overrideTransformGO = new GameObject("overrideTransform");
        var overrideTransform   = overrideTransformGO.AddComponent <OverrideTransform>();

        overrideTransform.Reset();

        overrideTransformGO.transform.parent     = data.rigData.rigGO.transform;
        overrideTransform.data.constrainedObject = data.rigData.hipsGO.transform.Find("Chest");

        var overrideSourceGO = new GameObject("source");

        overrideSourceGO.transform.parent = overrideTransformGO.transform;

        overrideTransform.data.sourceObject = overrideSourceGO.transform;

        data.rigData.rootGO.GetComponent <RigBuilder>().Build();

        data.constraint = overrideTransform;

        return(data);
    }
コード例 #8
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);
        }
    }
コード例 #9
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));
        }
    }
コード例 #10
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));
        }
    }
コード例 #11
0
    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)
                );
        }
    }
コード例 #12
0
    private ConstraintTestData SetupConstraintRig()
    {
        var data = new ConstraintTestData();

        data.rigData = RuntimeRiggingTestFixture.SetupRigHierarchy();

        var chainIKGO = new GameObject("chainIK");
        var chainIK   = chainIKGO.AddComponent <ChainIKConstraint>();

        chainIK.Reset();

        chainIKGO.transform.parent = data.rigData.rigGO.transform;

        chainIK.data.root = data.rigData.hipsGO.transform.Find("Chest");
        Assert.IsNotNull(chainIK.data.root.transform, "Could not find root transform");

        chainIK.data.tip = chainIK.data.root.transform.Find("LeftArm/LeftForeArm/LeftHand");
        Assert.IsNotNull(chainIK.data.tip.transform, "Could not find tip transform");

        var targetGO = new GameObject("target");

        targetGO.transform.parent = chainIKGO.transform;

        chainIK.data.target = new JobTransform(targetGO.transform, true);

        data.rigData.rootGO.GetComponent <RigBuilder>().Build();
        targetGO.transform.position = chainIK.data.tip.transform.position;

        data.constraint = chainIK;

        return(data);
    }
    private ConstraintTestData SetupConstraintRig()
    {
        var data = new ConstraintTestData();

        data.rigData = RuntimeRiggingTestFixture.SetupRigHierarchy();

        var multiRotationGO = new GameObject("multiPosition");
        var multiRotation   = multiRotationGO.AddComponent <MultiRotationConstraint>();

        multiRotation.Reset();

        multiRotationGO.transform.parent = data.rigData.rigGO.transform;

        multiRotation.data.constrainedObject = data.rigData.hipsGO.transform;
        data.constrainedObjectRestRotation   = multiRotation.data.constrainedObject.rotation;

        var sources = new WeightedTransformArray();
        var src0GO  = new GameObject("source0");
        var src1GO  = new GameObject("source1");

        src0GO.transform.parent = multiRotationGO.transform;
        src1GO.transform.parent = multiRotationGO.transform;
        sources.Add(new WeightedTransform(src0GO.transform, 0f));
        sources.Add(new WeightedTransform(src1GO.transform, 0f));
        multiRotation.data.sourceObjects = sources;

        src0GO.transform.rotation = data.rigData.hipsGO.transform.rotation;
        src1GO.transform.rotation = data.rigData.hipsGO.transform.rotation;

        data.rigData.rootGO.GetComponent <RigBuilder>().Build();

        data.constraint = multiRotation;

        return(data);
    }
コード例 #14
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)
                );
        }
    }
コード例 #15
0
    public static ConstraintTestData SetupConstraintRig()
    {
        var data = new ConstraintTestData();

        data.rigData = RuntimeRiggingTestFixture.SetupRigHierarchy();

        var blendConstraintGO = new GameObject("blendConstraint");
        var blendConstraint   = blendConstraintGO.AddComponent <BlendConstraint>();

        blendConstraint.Reset();

        blendConstraintGO.transform.parent = data.rigData.rigGO.transform;

        var leftForeArm = data.rigData.hipsGO.transform.Find("Chest/LeftArm/LeftForeArm");
        var leftHand    = leftForeArm.Find("LeftHand");

        blendConstraint.data.sourceObjectA = leftForeArm;
        blendConstraint.data.sourceObjectB = leftHand;

        var constrainedObject = new GameObject("constrainedBlendObj");

        constrainedObject.transform.parent     = blendConstraintGO.transform;
        blendConstraint.data.constrainedObject = constrainedObject.transform;
        data.restPose = new AffineTransform(constrainedObject.transform.position, constrainedObject.transform.rotation);

        blendConstraint.data.positionWeight = blendConstraint.data.rotationWeight = 0.5f;
        blendConstraint.data.blendPosition  = blendConstraint.data.blendRotation = true;

        data.rigData.rootGO.GetComponent <RigBuilder>().Build();
        data.constraint = blendConstraint;

        return(data);
    }
コード例 #16
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);
        }
    }
コード例 #17
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));
    }
コード例 #18
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));
    }
コード例 #19
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);
    }
コード例 #20
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"));
    }
コード例 #21
0
    private ConstraintTestData SetupConstraintRig()
    {
        var data = new ConstraintTestData();

        data.rigData = RuntimeRiggingTestFixture.SetupRigHierarchy();

        var twistCorrectionGO = new GameObject("twistCorrection");
        var twistCorrection   = twistCorrectionGO.AddComponent <TwistCorrection>();

        twistCorrection.Reset();

        twistCorrectionGO.transform.parent = data.rigData.rigGO.transform;

        var leftArm     = data.rigData.hipsGO.transform.Find("Chest/LeftArm");
        var leftForeArm = leftArm.Find("LeftForeArm");
        var leftHand    = leftForeArm.Find("LeftHand");

        // Force zero rotation to simplify testing
        leftHand.rotation    = Quaternion.identity;
        leftForeArm.rotation = Quaternion.identity;
        leftArm.rotation     = Quaternion.identity;

        twistCorrection.data.sourceObject = leftHand;
        twistCorrection.data.twistAxis    = TwistCorrectionData.Axis.X;
        data.restLocalRotation            = leftHand.localRotation;

        var twistNodes   = new WeightedTransformArray();
        var twistNode0GO = new GameObject("twistNode0");
        var twistNode1GO = new GameObject("twistNode1");

        twistNode0GO.transform.parent = leftForeArm;
        twistNode1GO.transform.parent = leftForeArm;
        twistNode0GO.transform.SetPositionAndRotation(Vector3.Lerp(leftForeArm.position, leftHand.position, 0.25f), leftHand.rotation);
        twistNode1GO.transform.SetPositionAndRotation(Vector3.Lerp(leftForeArm.position, leftHand.position, 0.75f), leftHand.rotation);
        twistNodes.Add(new WeightedTransform(twistNode0GO.transform, 0f));
        twistNodes.Add(new WeightedTransform(twistNode1GO.transform, 0f));
        twistCorrection.data.twistNodes = twistNodes;

        data.rigData.rootGO.GetComponent <RigBuilder>().Build();

        data.constraint = twistCorrection;

        return(data);
    }
    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));
    }
コード例 #23
0
    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));
    }
コード例 #24
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);
    }
コード例 #25
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)
                );
        }
    }
コード例 #26
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);
    }
コード例 #27
0
    public static ConstraintTestData SetupConstraintRig()
    {
        var data = new ConstraintTestData();

        data.rigData = RuntimeRiggingTestFixture.SetupRigHierarchy();

        var twistChainGO = new GameObject("twistChain");
        var twistChain   = twistChainGO.AddComponent <TwistChainConstraint>();

        twistChain.Reset();

        twistChainGO.transform.parent = data.rigData.rigGO.transform;

        twistChain.data.root = data.rigData.hipsGO.transform.Find("Chest/LeftArm");
        Assert.IsNotNull(twistChain.data.root, "Could not find root transform");

        twistChain.data.tip = twistChain.data.root.transform.Find("LeftForeArm/LeftHand");
        Assert.IsNotNull(twistChain.data.tip, "Could not find tip transform");

        var rootTargetGO = new GameObject("rootTarget");

        rootTargetGO.transform.parent = twistChainGO.transform;

        var tipTargetGO = new GameObject("tipTarget");

        tipTargetGO.transform.parent = twistChainGO.transform;

        twistChain.data.rootTarget = rootTargetGO.transform;
        twistChain.data.tipTarget  = tipTargetGO.transform;

        data.rigData.rootGO.GetComponent <RigBuilder>().Build();

        rootTargetGO.transform.position = twistChain.data.root.position;
        rootTargetGO.transform.rotation = twistChain.data.root.rotation;

        tipTargetGO.transform.position = twistChain.data.tip.position;
        tipTargetGO.transform.rotation = twistChain.data.tip.rotation;

        data.constraint = twistChain;

        return(data);
    }
コード例 #28
0
    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));
    }
コード例 #29
0
    public static ConstraintTestData SetupConstraintRig()
    {
        var data = new ConstraintTestData();

        data.rigData = RuntimeRiggingTestFixture.SetupRigHierarchy();

        var multiParentGO = new GameObject("multiParent");
        var multiParent   = multiParentGO.AddComponent <MultiParentConstraint>();

        multiParent.Reset();

        multiParentGO.transform.parent = data.rigData.rigGO.transform;

        multiParent.data.constrainedObject = data.rigData.hipsGO.transform;
        data.constrainedObjectRestTx       = new AffineTransform(
            multiParent.data.constrainedObject.position,
            multiParent.data.constrainedObject.rotation
            );

        var sources = new WeightedTransformArray();
        var src0GO  = new GameObject("source0");
        var src1GO  = new GameObject("source1");

        src0GO.transform.parent = multiParentGO.transform;
        src1GO.transform.parent = multiParentGO.transform;
        sources.Add(new WeightedTransform(src0GO.transform, 0f));
        sources.Add(new WeightedTransform(src1GO.transform, 0f));
        multiParent.data.sourceObjects = sources;

        var pos = data.rigData.hipsGO.transform.position;
        var rot = data.rigData.hipsGO.transform.rotation;

        src0GO.transform.SetPositionAndRotation(pos, rot);
        src1GO.transform.SetPositionAndRotation(pos, rot);

        data.rigData.rootGO.GetComponent <RigBuilder>().Build();

        data.constraint = multiParent;

        return(data);
    }
コード例 #30
0
    private ConstraintTestData SetupConstraintRig()
    {
        var data = new ConstraintTestData();

        data.rigData = RuntimeRiggingTestFixture.SetupRigHierarchy();

        var twoBoneIKGO = new GameObject("twoBoneIK");
        var twoBoneIK   = twoBoneIKGO.AddComponent <TwoBoneIKConstraint>();

        twoBoneIK.Reset();

        twoBoneIKGO.transform.parent = data.rigData.rigGO.transform;

        twoBoneIK.data.root = data.rigData.hipsGO.transform.Find("Chest/LeftArm");
        Assert.IsNotNull(twoBoneIK.data.root, "Could not find root transform");

        twoBoneIK.data.mid = twoBoneIK.data.root.transform.Find("LeftForeArm");
        Assert.IsNotNull(twoBoneIK.data.mid, "Could not find mid transform");

        twoBoneIK.data.tip = twoBoneIK.data.mid.transform.Find("LeftHand");
        Assert.IsNotNull(twoBoneIK.data.tip, "Could not find tip transform");

        var targetGO = new GameObject("target");

        targetGO.transform.parent = twoBoneIKGO.transform;

        var hintGO = new GameObject("hint");

        hintGO.transform.parent = twoBoneIKGO.transform;

        twoBoneIK.data.target = targetGO.transform;
        twoBoneIK.data.hint   = hintGO.transform;

        data.rigData.rootGO.GetComponent <RigBuilder>().Build();

        targetGO.transform.position = twoBoneIK.data.tip.position;

        data.constraint = twoBoneIK;

        return(data);
    }