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); }
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; } }
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)); } }
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)); } }
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); }
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); }
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); } }
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 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)); } }
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) ); } }
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); }
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) ); } }
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); }
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); } }
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)); }
public IEnumerator MultiAimConstraint_FollowSourceObjects() { var data = SetupConstraintRig(); var constraint = data.constraint; var constrainedObject = constraint.data.constrainedObject; var sources = constraint.data.sourceObjects; var positionComparer = new RuntimeRiggingTestFixture.Vector3EqualityComparer(k_Epsilon); var rotationComparer = new RuntimeRiggingTestFixture.QuaternionEqualityComparer(k_Epsilon); var floatComparer = new RuntimeRiggingTestFixture.FloatEqualityComparer(k_Epsilon); // Add displacement to source objects sources[0].transform.position += Vector3.left; sources[1].transform.position += Vector3.right; // src0.w = 0, src1.w = 0 Assert.Zero(sources[0].weight); Assert.Zero(sources[1].weight); yield return(RuntimeRiggingTestFixture.YieldTwoFrames()); Assert.That(constrainedObject.position, Is.EqualTo(data.constrainedObjectRestTx.translation).Using(positionComparer)); Assert.That(constrainedObject.rotation, Is.EqualTo(data.constrainedObjectRestTx.rotation).Using(rotationComparer)); // src0.w = 1, src1.w = 0 sources.SetWeight(0, 1f); constraint.data.sourceObjects = sources; yield return(RuntimeRiggingTestFixture.YieldTwoFrames()); Vector3 currAim = constrainedObject.rotation * Vector3.forward; Vector3 src0Dir = (sources[0].transform.position - constrainedObject.position).normalized; Vector3 src1Dir = (sources[1].transform.position - constrainedObject.position).normalized; Assert.That(Vector3.Angle(currAim, src0Dir), Is.EqualTo(0f).Using(floatComparer)); Assert.That(Vector3.Angle(currAim, src1Dir), Is.Not.EqualTo(0f).Using(floatComparer)); // src0.w = 0, src1.w = 1 sources.SetWeight(0, 0f); sources.SetWeight(1, 1f); constraint.data.sourceObjects = sources; yield return(RuntimeRiggingTestFixture.YieldTwoFrames()); currAim = constrainedObject.rotation * Vector3.forward; src0Dir = (sources[0].transform.position - constrainedObject.position).normalized; src1Dir = (sources[1].transform.position - constrainedObject.position).normalized; Assert.That(Vector3.Angle(currAim, src0Dir), Is.Not.EqualTo(0f).Using(floatComparer)); Assert.That(Vector3.Angle(currAim, src1Dir), Is.EqualTo(0f).Using(floatComparer)); }
public IEnumerator 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); }
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")); }
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)); }
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 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); }
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) ); } }
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 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); }
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 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); }
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); }