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);
    }
예제 #2
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);
    }
예제 #3
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);
 }
예제 #4
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);
    }
예제 #5
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);
    }
예제 #6
0
    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);
    }
예제 #7
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;
        }
    }
예제 #8
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);
    }