public TwistSwing Clamp(TwistSwing twistSwing)
    {
        var clampedTwist = Twist.Clamp(twistSwing.Twist);
        var clampedSwing = Swing.Clamp(twistSwing.Swing);

        return(new TwistSwing(clampedTwist, clampedSwing));
    }
Example #2
0
    public RigidBoneSystemInputs ApplyDeltas(RigidBoneSystemInputs baseInputs, RigidBoneSystemInputs deltaInputs)
    {
        var sumInputs = new RigidBoneSystemInputs(bones.Length)
        {
        };

        RigidTransform baseRootTransform = RigidTransform.FromRotationTranslation(
            RootBone.GetRotation(baseInputs),
            baseInputs.RootTranslation);

        RigidTransform deltaRootTransform = RigidTransform.FromRotationTranslation(
            RootBone.GetRotation(deltaInputs),
            deltaInputs.RootTranslation);

        RigidTransform sumRootTransform = deltaRootTransform.Chain(baseRootTransform);

        sumInputs.RootTranslation = sumRootTransform.Translation;
        RootBone.SetRotation(sumInputs, sumRootTransform.Rotation);

        for (int boneIdx = 1; boneIdx < bones.Length; ++boneIdx)
        {
            var bone = bones[boneIdx];
            sumInputs.Rotations[boneIdx] = bone.Constraint.Clamp(
                TwistSwing.ApplyDelta(baseInputs.Rotations[boneIdx], deltaInputs.Rotations[boneIdx]));
        }

        return(sumInputs);
    }
    public void SetRotation(RigidBoneSystemInputs inputs, Quaternion objectSpaceRotation, bool applyClamp = false)
    {
        Quaternion orientatedSpaceRotation = orientationSpace.TransformToOrientedSpace(objectSpaceRotation);
        TwistSwing orientedSpaceTwistSwing = TwistSwing.Decompose(RotationOrder.TwistAxis, orientatedSpaceRotation);

        SetOrientedSpaceRotation(inputs, orientedSpaceTwistSwing, applyClamp);
    }
    public TwistSwing GetOrientedSpaceRotation(RigidBoneSystemInputs inputs)
    {
        TwistSwing rotationTwistSwing = inputs.Rotations[Index];

        rotationTwistSwing = Constraint.Clamp(rotationTwistSwing);
        return(rotationTwistSwing);
    }
Example #5
0
    public void TestAsQuaternion()
    {
        var twist      = new Twist(0.4f);
        var swing      = new Swing(0.2f, 0.3f);
        var twistSwing = new TwistSwing(twist, swing);

        MathAssert.AreEqual(
            twist.AsQuaternion(CartesianAxis.X).Chain(swing.AsQuaternion(CartesianAxis.X)),
            twistSwing.AsQuaternion(CartesianAxis.X),
            Acc);

        MathAssert.AreEqual(
            twist.AsQuaternion(CartesianAxis.X).Chain(swing.AsQuaternion(CartesianAxis.X)),
            twistSwing.AsQuaternion(CartesianAxis.X),
            Acc);

        MathAssert.AreEqual(
            twist.AsQuaternion(CartesianAxis.X).Chain(swing.AsQuaternion(CartesianAxis.X)),
            twistSwing.AsQuaternion(CartesianAxis.X),
            Acc);

        MathAssert.AreEqual(
            twist.AsQuaternion(CartesianAxis.X).Chain(swing.AsQuaternion(CartesianAxis.X)),
            twistSwing.AsQuaternion(CartesianAxis.X),
            Acc);
    }
Example #6
0
    public RigidBoneSystemInputs CalculateDeltas(RigidBoneSystemInputs baseInputs, RigidBoneSystemInputs sumInputs)
    {
        var deltaInputs = new RigidBoneSystemInputs(bones.Length)
        {
        };

        RigidTransform baseRootTransform = RigidTransform.FromRotationTranslation(
            RootBone.GetRotation(baseInputs),
            baseInputs.RootTranslation);

        RigidTransform sumRootTransform = RigidTransform.FromRotationTranslation(
            RootBone.GetRotation(sumInputs),
            sumInputs.RootTranslation);

        RigidTransform deltaRootTransform = sumRootTransform.Chain(baseRootTransform.Invert());

        deltaInputs.RootTranslation = deltaRootTransform.Translation;
        RootBone.SetRotation(deltaInputs, deltaRootTransform.Rotation);

        for (int boneIdx = 1; boneIdx < bones.Length; ++boneIdx)
        {
            var bone = bones[boneIdx];
            deltaInputs.Rotations[boneIdx] = TwistSwing.CalculateDelta(baseInputs.Rotations[boneIdx], sumInputs.Rotations[boneIdx]);
        }

        return(deltaInputs);
    }
    private void TestClampRotation(Vector3 input, Vector3 expected)
    {
        var inputTS    = new TwistSwing(Twist.MakeFromAngle(input.X), Swing.MakeFromAxisAngleProduct(input.Y, input.Z));
        var clampedTS  = constraint.Clamp(inputTS);
        var expectedTS = new TwistSwing(Twist.MakeFromAngle(expected.X), Swing.MakeFromAxisAngleProduct(expected.Y, expected.Z));

        MathAssert.AreEqual(expectedTS, clampedTS, 1e-4f);
    }
Example #8
0
    public void TestDecomposeHalfRevolution()
    {
        var        q          = new Quaternion(1, 0, 0, 0);
        TwistSwing twistSwing = TwistSwing.Decompose(CartesianAxis.Z, q);

        Assert.AreEqual(0, twistSwing.Twist.X, Acc);

        Assert.AreEqual(1, twistSwing.Swing.Y, Acc);
        Assert.AreEqual(0, twistSwing.Swing.Z, Acc);
    }
Example #9
0
 private void TestToTwistSwingAngles(RotationOrder order)
 {
     MathAssert.AreEqual(new Vector3(0, 0, 0), order.ToTwistSwingAngles(TwistSwing.Decompose(order.TwistAxis, Quaternion.Identity)), Acc);
     MathAssert.AreEqual(new Vector3(+1, 0, 0), order.ToTwistSwingAngles(TwistSwing.Decompose(order.TwistAxis, Quaternion.RotationAxis(Vector3.UnitX, +1))), Acc);
     MathAssert.AreEqual(new Vector3(-1, 0, 0), order.ToTwistSwingAngles(TwistSwing.Decompose(order.TwistAxis, Quaternion.RotationAxis(Vector3.UnitX, -1))), Acc);
     MathAssert.AreEqual(new Vector3(0, +1, 0), order.ToTwistSwingAngles(TwistSwing.Decompose(order.TwistAxis, Quaternion.RotationAxis(Vector3.UnitY, +1))), Acc);
     MathAssert.AreEqual(new Vector3(0, -1, 0), order.ToTwistSwingAngles(TwistSwing.Decompose(order.TwistAxis, Quaternion.RotationAxis(Vector3.UnitY, -1))), Acc);
     MathAssert.AreEqual(new Vector3(0, 0, +1), order.ToTwistSwingAngles(TwistSwing.Decompose(order.TwistAxis, Quaternion.RotationAxis(Vector3.UnitZ, +1))), Acc);
     MathAssert.AreEqual(new Vector3(0, 0, -1), order.ToTwistSwingAngles(TwistSwing.Decompose(order.TwistAxis, Quaternion.RotationAxis(Vector3.UnitZ, -1))), Acc);
 }
    public void TestCenter()
    {
        var constraint = new TwistSwingConstraint(
            new TwistConstraint(-0.1f, 0.3f),
            new SwingConstraint(
                -0.2f, 0.6f,
                -0.4f, 1.0f));

        MathAssert.AreEqual(TwistSwing.MakeFromCoordinates(0.1f, 0.2f, 0.3f), constraint.Center, 1e-4f);
    }
Example #11
0
    /**
     * Set only the twist component of a bone's rotation. The original swing is preserved.
     */
    public static void SetTwistOnly(this RigidBone bone, RigidBoneSystemInputs inputs, Quaternion localRotation)
    {
        var        orientedRotation       = bone.OrientationSpace.TransformToOrientedSpace(localRotation);
        TwistSwing twistSwing             = TwistSwing.Decompose(bone.RotationOrder.TwistAxis, orientedRotation);
        var        originalTwistSwing     = inputs.Rotations[bone.Index];
        var        twistWithOriginalSwing = new TwistSwing(
            twistSwing.Twist,
            originalTwistSwing.Swing);

        bone.SetOrientedSpaceRotation(inputs, twistWithOriginalSwing, true);
    }
    public void SetOrientedSpaceRotation(RigidBoneSystemInputs inputs, TwistSwing orientatedSpaceRotation, bool applyClamp = false)
    {
        DebugUtilities.AssertFinite(orientatedSpaceRotation);

        if (applyClamp)
        {
            orientatedSpaceRotation = Constraint.Clamp(orientatedSpaceRotation);
        }

        inputs.Rotations[Index] = orientatedSpaceRotation;
    }
Example #13
0
    public void TestDecompose()
    {
        var q = Quaternion.Normalize(new Quaternion(0.1f, 0.2f, 0.3f, 0.4f));

        MathAssert.AreEqual(q, TwistSwing.Decompose(CartesianAxis.X, q).AsQuaternion(CartesianAxis.X), Acc);
        MathAssert.AreEqual(q, TwistSwing.Decompose(CartesianAxis.Y, q).AsQuaternion(CartesianAxis.Y), Acc);
        MathAssert.AreEqual(q, TwistSwing.Decompose(CartesianAxis.Z, q).AsQuaternion(CartesianAxis.Z), Acc);

        MathAssert.AreEqual(q, TwistSwing.Decompose(CartesianAxis.X, -q).AsQuaternion(CartesianAxis.X), Acc);
        MathAssert.AreEqual(q, TwistSwing.Decompose(CartesianAxis.Y, -q).AsQuaternion(CartesianAxis.Y), Acc);
        MathAssert.AreEqual(q, TwistSwing.Decompose(CartesianAxis.Z, -q).AsQuaternion(CartesianAxis.Z), Acc);
    }
    public Vector3 ToTwistSwingAngles(TwistSwing twistSwing)
    {
        Vector2 swingAxisAngleProduct = twistSwing.Swing.AxisAngleProduct;

        Vector3 angles = default(Vector3);

        angles[primaryAxis]           = twistSwing.Twist.Angle;
        angles[(primaryAxis + 1) % 3] = swingAxisAngleProduct.X;
        angles[(primaryAxis + 2) % 3] = swingAxisAngleProduct.Y;

        return(angles);
    }
    public Quaternion GetRotation(ChannelOutputs outputs)
    {
        OrientationSpace orientationSpace = GetOrientationSpace(outputs);

        Vector3    rotationAngles     = Rotation.GetValue(outputs);
        TwistSwing rotationTwistSwing = RotationOrder.FromTwistSwingAngles(MathExtensions.DegreesToRadians(rotationAngles));

        rotationTwistSwing = RotationConstraint.Clamp(rotationTwistSwing);

        Quaternion orientedSpaceRotation = rotationTwistSwing.AsQuaternion(RotationOrder.TwistAxis);
        Quaternion worldSpaceRotation    = orientationSpace.TransformFromOrientedSpace(orientedSpaceRotation);

        return(worldSpaceRotation);
    }
    public Vector3 ConvertRotationToAngles(ChannelOutputs orientationOutputs, Quaternion objectSpaceRotation, bool applyClamp)
    {
        OrientationSpace orientationSpace         = GetOrientationSpace(orientationOutputs);
        Quaternion       orientatedSpaceRotationQ = orientationSpace.TransformToOrientedSpace(objectSpaceRotation);
        TwistSwing       orientatedSpaceRotation  = TwistSwing.Decompose(RotationOrder.TwistAxis, orientatedSpaceRotationQ);

        if (applyClamp)
        {
            orientatedSpaceRotation = RotationConstraint.Clamp(orientatedSpaceRotation);
        }

        Vector3 rotationAnglesRadians = RotationOrder.ToTwistSwingAngles(orientatedSpaceRotation);
        Vector3 rotationAnglesDegrees = MathExtensions.RadiansToDegrees(rotationAnglesRadians);

        return(rotationAnglesDegrees);
    }
Example #17
0
    private void ApplyPartialSolution(RigidBone bone, BonePartialSolution partialSolution, RigidTransform[] boneTransforms, Vector3 figureCenterOverride, RigidBoneSystemInputs inputs, float time)
    {
        var twistAxis         = bone.RotationOrder.TwistAxis;
        var originalRotationQ = inputs.Rotations[bone.Index].AsQuaternion(twistAxis);
        var rotationDelta     = QuaternionExtensions.FromRotationVector(time * partialSolution.angularVelocity);
        var newRotationQ      = originalRotationQ.Chain(rotationDelta);
        var newRotation       = TwistSwing.Decompose(twistAxis, newRotationQ);

        inputs.Rotations[bone.Index] = bone.Constraint.Clamp(newRotation);

        if (bone == boneSystem.RootBone)
        {
            var preTotalTransform           = boneTransforms[bone.Index];
            var postTotalTransform          = bone.GetChainedTransform(inputs);
            var unposedFigureCenterOverride = preTotalTransform.InverseTransform(figureCenterOverride);
            var postFigureCenterOverride    = postTotalTransform.Transform(unposedFigureCenterOverride);

            var centerDisplacement = figureCenterOverride - postFigureCenterOverride;
            inputs.RootTranslation += centerDisplacement;
        }
    }
Example #18
0
 public static TwistSwing ApplyDelta(TwistSwing initial, TwistSwing delta)
 {
     return(new TwistSwing(
                Twist.ApplyDelta(initial.Twist, delta.Twist),
                Swing.ApplyDelta(initial.Swing, delta.Swing)));
 }
Example #19
0
 public static void AssertFinite(TwistSwing ts)
 {
     AssertFinite(ts.Twist);
     AssertFinite(ts.Swing);
 }
Example #20
0
 public static void AssertSame(TwistSwing ts1, TwistSwing ts2)
 {
     AssertSame(ts1.Twist, ts2.Twist);
     AssertSame(ts1.Swing, ts2.Swing);
 }
Example #21
0
    private void TestTwistSwingRoundTrip(RotationOrder order, Quaternion q)
    {
        var ts = TwistSwing.Decompose(order.TwistAxis, q);

        MathAssert.AreEqual(q, order.FromTwistSwingAngles(order.ToTwistSwingAngles(ts)).AsQuaternion(order.TwistAxis), Acc);
    }
 public bool Test(TwistSwing twistSwing)
 {
     return(Twist.Test(twistSwing.Twist) && Swing.Test(twistSwing.Swing));
 }
Example #23
0
 public static void AreEqual(TwistSwing expected, TwistSwing actual, float delta)
 {
     MathAssert.AreEqual(expected.Twist, actual.Twist, delta);
     MathAssert.AreEqual(expected.Swing, actual.Swing, delta);
 }
Example #24
0
 public static TwistSwing CalculateDelta(TwistSwing initial, TwistSwing final)
 {
     return(new TwistSwing(
                Twist.CalculateDelta(initial.Twist, final.Twist),
                Swing.CalculateDelta(initial.Swing, final.Swing)));
 }