Пример #1
0
        public static Vector3 ToIdealEulerAngles(this Quaterniond quat, string rotationOrder, bool usesX, bool usesY, bool usesZ)
        {
            // First get all possible euler representations of this quaternion rotation.
            List <Vector3> eulerReps = quat.ToEulerAnglesRobust(rotationOrder);

            // Then sort the representations by how close to ideal they are for storing.
            var eulerRepsSorted = eulerReps.OrderBy(rep =>
            {
                // First sort by how little the representation would change upon being save and reloaded.
                // e.g. (0, -135, 0) and (180, -45, 180) might be visually the same, but if we can't store the Z axis we want to use the former.
                var storableRep = new Vector3(
                    usesX ? rep.X : 0,
                    usesY ? rep.Y : 0,
                    usesZ ? rep.Z : 0
                    );
                var diff = storableRep - rep;
                return(diff.Length);
            });

            eulerRepsSorted = eulerRepsSorted.ThenBy(rep =>
            {
                // Next sort by how few axes are nonzero.
                // e.g. Between (0, 45, 90) and (-180, 135, -90), prefer the former because it looks neater and is more likely to be the original rotation read.
                var numUsedAxes = 0;
                if (Math.Abs(rep.X) >= 0.000001)
                {
                    numUsedAxes += 1;
                }
                if (Math.Abs(rep.Y) >= 0.000001)
                {
                    numUsedAxes += 1;
                }
                if (Math.Abs(rep.Z) >= 0.000001)
                {
                    numUsedAxes += 1;
                }
                return(numUsedAxes);
            });

            // Return the most ideal representation.
            return(eulerRepsSorted.First());
        }