/// Copy-construct from another quaternion.
 public Quaternion(Quaternion quat)
 {
     w_ = quat.w_;
     x_ = quat.x_;
     y_ = quat.y_;
     z_ = quat.z_;
 }
        /// Spherical interpolation with another quaternion.
        public Quaternion Slerp(Quaternion rhs, float t)
        {
            float cosAngle = DotProduct(rhs);
            // Enable shortest path rotation
            if (cosAngle < 0.0f)
            {
                cosAngle = -cosAngle;
                rhs = -rhs;
            }

            float angle = (float)Math.Acos(cosAngle);
            float sinAngle = (float)Math.Sin(angle);
            float t1, t2;

            if (sinAngle > 0.001f)
            {
                float invSinAngle = 1.0f / sinAngle;
                t1 = (float)Math.Sin((1.0f - t) * angle) * invSinAngle;
                t2 = (float)Math.Sin(t * angle) * invSinAngle;
            }
            else
            {
                t1 = 1.0f - t;
                t2 = t;
            }

            return this * t1 + rhs * t2;
        }
 /// Assign from another quaternion.
 public Quaternion Set(Quaternion rhs)
 {
     w_ = rhs.w_;
     x_ = rhs.x_;
     y_ = rhs.y_;
     z_ = rhs.z_;
     return this;
 }
 /// Normalized linear interpolation with another quaternion.
 public Quaternion Nlerp(Quaternion rhs, float t, bool shortestPath = false)
 {
     Quaternion result;
     float fCos = DotProduct(rhs);
     if (fCos < 0.0f && shortestPath)
         result = (this) + (((-rhs) - (this)) * t);
     else
         result = (this) + ((rhs - (this)) * t);
     result.Normalize();
     return result;
 }
 /// Test for equality with another quaternion with epsilon.
 public bool Equals(Quaternion rhs)
 {
     return MathUtils.FloatEquals(w_, rhs.w_) && MathUtils.FloatEquals(x_, rhs.x_) && MathUtils.FloatEquals(y_, rhs.y_) && MathUtils.FloatEquals(z_, rhs.z_);
 }
        /// Define from a direction to look in and an up direction. Return true if successful, or false if would result in a NaN, in which case the current value remains.
        public bool FromLookRotation(Vector3 direction, Vector3 upDirection)
        {
            Vector3 forward = direction.Normalized();
            Vector3 v = forward.Cross(upDirection).Normalized();
            Vector3 up = v.Cross(forward);
            Vector3 right = up.Cross(forward);

            Quaternion ret = new Quaternion();
            ret.FromAxes(right, up, forward);

            if (!ret.IsNaN())
            {
                this.Set(ret);
                return true;
            }
            else
                return false;
        }
 /// Calculate dot product.
 public float DotProduct(Quaternion rhs)
 {
     return w_ * rhs.w_ + x_ * rhs.x_ + y_ * rhs.y_ + z_ * rhs.z_;
 }
 /// Add-assign a quaternion.
 public static Quaternion operator +(Quaternion lhs, Quaternion rhs)
 {
     Quaternion ret = new Quaternion(lhs);
     ret.w_ += rhs.w_;
     ret.x_ += rhs.x_;
     ret.y_ += rhs.y_;
     ret.z_ += rhs.z_;
     return ret;
 }
 /// Multiply-assign a scalar.
 public static Quaternion operator *(Quaternion lhs, float rhs)
 {
     Quaternion ret = new Quaternion(lhs);
     ret.w_ *= rhs;
     ret.x_ *= rhs;
     ret.y_ *= rhs;
     ret.z_ *= rhs;
     return lhs;
 }
        /// Return decomposition to translation, rotation and scale.
        public void Decompose(out Vector3 translation, out Quaternion rotation, out Vector3 scale)
        {
            translation = new Vector3();
            translation.x = m03_;
            translation.y = m13_;
            translation.z = m23_;

            scale = new Vector3();
            scale.x = (float)Math.Sqrt(m00_ * m00_ + m10_ * m10_ + m20_ * m20_);
            scale.y = (float)Math.Sqrt(m01_ * m01_ + m11_ * m11_ + m21_ * m21_);
            scale.z = (float)Math.Sqrt(m02_ * m02_ + m12_ * m12_ + m22_ * m22_);

            Vector3 invScale = new Vector3(1.0f / scale.x, 1.0f / scale.y, 1.0f / scale.z);
            rotation = new Quaternion(ToMatrix3().Scaled(invScale));
        }
 /// Construct from translation, rotation and nonuniform scale.
 public Matrix3x4(Vector3 translation, Quaternion rotation, Vector3 scale)
 {
 }