/// <summary>
        /// Create a translation and rotation.
        /// </summary>
        static public Matrix4x4f TranslateRotate(Vector3f t, Quaternion3f r)
        {
            Matrix4x4f T = Translate(t);
            Matrix4x4f R = r.ToMatrix4x4f();

            return(T * R);
        }
        /// <summary>
        /// Create a rotation and scale.
        /// </summary>
        static public Matrix4x4f RotateScale(Quaternion3f r, Vector3f s)
        {
            Matrix4x4f R = r.ToMatrix4x4f();
            Matrix4x4f S = Scale(s);

            return(R * S);
        }
 /// <summary>
 /// A Quaternion copied another quaternion.
 /// </summary>
 public Quaternion3f(Quaternion3f q)
 {
     this.x = q.x;
     this.y = q.y;
     this.z = q.z;
     this.w = q.w;
 }
        /// <summary>
        /// Create a translation, rotation and scale.
        /// </summary>
        static public Matrix4x4f TranslateRotateScale(Vector3f t, Quaternion3f r, Vector3f s)
        {
            Matrix4x4f T = Translate(t);
            Matrix4x4f R = r.ToMatrix4x4f();
            Matrix4x4f S = Scale(s);

            return(T * R * S);
        }
        /// <summary>
        /// Are these Quaternions equal.
        /// </summary>
        public override bool Equals(object obj)
        {
            if (!(obj is Quaternion3f))
            {
                return(false);
            }

            Quaternion3f v = (Quaternion3f)obj;

            return(this == v);
        }
        /// <summary>
        /// Slerp the quaternion from the from rotation to the to rotation by t.
        /// </summary>
        public Quaternion3f Slerp(Quaternion3f from, Quaternion3f to, float t)
        {
            if (t <= 0)
            {
                return(new Quaternion3f(from));
            }
            else if (t >= 1)
            {
                return(new Quaternion3f(to));
            }
            else
            {
                float cosom    = from.x * to.x + from.y * to.y + from.z * to.z + from.w * to.w;
                float absCosom = Math.Abs(cosom);

                float scale0;
                float scale1;

                if ((1 - absCosom) > 1e-6f)
                {
                    float omega = Safe_Acos(absCosom);
                    float sinom = 1.0f / (float)Math.Sin(omega);
                    scale0 = (float)Math.Sin((1.0f - t) * omega) * sinom;
                    scale1 = (float)Math.Sin(t * omega) * sinom;
                }
                else
                {
                    scale0 = 1 - t;
                    scale1 = t;
                }
                Quaternion3f res = new Quaternion3f(scale0 * from.x + scale1 * to.x,
                                                    scale0 * from.y + scale1 * to.y,
                                                    scale0 * from.z + scale1 * to.z,
                                                    scale0 * from.w + scale1 * to.w);

                return(res.Normalized);
            }
        }
 /// <summary>
 /// Create a rotation out of a vector.
 /// </summary>
 static public Matrix4x4f Rotate(Vector3f euler)
 {
     return(Quaternion3f.FromEuler(euler).ToMatrix4x4f());
 }