Ejemplo n.º 1
0
        /// <summary>
        /// Return the FRotator orientation corresponding to the direction in which the vector points.
        /// Sets Yaw and Pitch to the proper numbers, and sets roll to zero because the roll can't be determined from a vector.
        /// </summary>
        /// <returns>FRotator from the Vector's direction.</returns>
        public FRotator ToOrientationRotator()
        {
            FRotator r;

            // Find yaw.
            r.Yaw = FMath.Atan2(Y, X) * (180.0f / FMath.PI);

            // Find pitch.
            r.Pitch = FMath.Atan2(Z, FMath.Sqrt(X * X + Y * Y)) * (180.0f / FMath.PI);

            // Find roll.
            r.Roll = 0;

            r.DiagnosticCheckNaN("FVector4::Rotation(): Rotator result " + r + " contains NaN! Input FVector4 = " + this);

            return(r);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Get the FRotator representation of this Quaternion.
        /// </summary>
        public FRotator Rotator()
        {
            DiagnosticCheckNaN();

            float singularityTest = Z * X - W * Y;
            float yawY            = 2.0f * (W * Z + X * Y);
            float yawX            = (1.0f - 2.0f * (FMath.Square(Y) + FMath.Square(Z)));

            // reference
            // http://en.wikipedia.org/wiki/Conversion_between_quaternions_and_Euler_angles
            // http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToEuler/

            // this value was found from experience, the above websites recommend different values
            // but that isn't the case for us, so I went through different testing, and finally found the case
            // where both of world lives happily.
            const float singularityThreshold = 0.4999995f;
            const float radToDeg             = (180.0f) / FMath.PI;
            FRotator    rotatorFromQuat;

            if (singularityTest < -singularityThreshold)
            {
                rotatorFromQuat.Pitch = -90.0f;
                rotatorFromQuat.Yaw   = FMath.Atan2(yawY, yawX) * radToDeg;
                rotatorFromQuat.Roll  = FRotator.NormalizeAxis(-rotatorFromQuat.Yaw - (2.0f * FMath.Atan2(X, W) * radToDeg));
            }
            else if (singularityTest > singularityThreshold)
            {
                rotatorFromQuat.Pitch = 90.0f;
                rotatorFromQuat.Yaw   = FMath.Atan2(yawY, yawX) * radToDeg;
                rotatorFromQuat.Roll  = FRotator.NormalizeAxis(rotatorFromQuat.Yaw - (2.0f * FMath.Atan2(X, W) * radToDeg));
            }
            else
            {
                rotatorFromQuat.Pitch = FMath.FastAsin(2.0f * (singularityTest)) * radToDeg;
                rotatorFromQuat.Yaw   = FMath.Atan2(yawY, yawX) * radToDeg;
                rotatorFromQuat.Roll  = FMath.Atan2(-2.0f * (W * X + Y * Z), (1.0f - 2.0f * (FMath.Square(X) + FMath.Square(Y)))) * radToDeg;
            }

            rotatorFromQuat.DiagnosticCheckNaN("FQuat::Rotator(): Rotator result " + rotatorFromQuat + " contains NaN! Quat = " + this.ToString() +
                                               ", YawY = " + yawY + ", YawX = " + yawX);

            return(rotatorFromQuat);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Return the Quaternion orientation corresponding to the direction in which the vector points.
        /// </summary>
        /// <returns>Quaternion from the Vector's direction.</returns>
        public FQuat ToOrientationQuat()
        {
            // Essentially an optimized Vector->Rotator->Quat made possible by knowing Roll == 0, and avoiding radians->degrees->radians.
            // This is done to avoid adding any roll (which our API states as a constraint).
            float yawRad   = FMath.Atan2(Y, X);
            float pitchRad = FMath.Atan2(Z, FMath.Sqrt(X * X + Y * Y));

            float divideByTwo = 0.5f;
            float sp, sy;
            float cp, cy;

            FMath.SinCos(out sp, out cp, pitchRad * divideByTwo);
            FMath.SinCos(out sy, out cy, yawRad * divideByTwo);

            FQuat rotationQuat;

            rotationQuat.X = sp * sy;
            rotationQuat.Y = -sp * cy;
            rotationQuat.Z = cp * sy;
            rotationQuat.W = cp * cy;
            return(rotationQuat);
        }