public static Matrix4x4f LookAt(Vector3 eye, Vector3 target, Vector3 up)
        {
            var direction = (eye - target).normalized;
            var left      = Vector3.Cross(up, direction).normalized;

            // Coverage for special case where up and direction are parallel.
            if (float.IsNaN(left.x) || float.IsNaN(left.y) || float.IsNaN(left.z))
            {
                left = up == direction ? Vector3.left : Vector3.right;
            }

            var newUp = Vector3.Cross(direction, left).normalized;

            // Coverage for special case where direction and left are parallel.
            if (float.IsNaN(newUp.x) || float.IsNaN(newUp.y) || float.IsNaN(newUp.z))
            {
                newUp = direction == left ? Vector3.up : Vector3.down;
            }

            var result = new Matrix4x4f
            {
                x00 = left.x,
                x01 = newUp.x,
                x02 = direction.x,
                x10 = left.y,
                x11 = newUp.y,
                x12 = direction.y,
                x20 = left.z,
                x21 = newUp.z,
                x22 = direction.z,
                x33 = 1
            };

            return(Translation(-eye) * result);
        }
        public static Matrix4x4f FromRows(Vector4 row0, Vector4 row1, Vector4 row2, Vector4 row3)
        {
            var result = new Matrix4x4f {
                Row0 = row0, Row1 = row1, Row2 = row2, Row3 = row3
            };

            return(result);
        }
        public static Matrix4x4f FromColumns(Vector4 column0, Vector4 column1, Vector4 column2, Vector4 column3)
        {
            var result = new Matrix4x4f {
                Column0 = column0, Column1 = column1, Column2 = column2, Column3 = column3
            };

            return(result);
        }
        public static Matrix4x4f Scale(Vector3 scale)
        {
            var result = new Matrix4x4f {
                x00 = scale.x, x11 = scale.y, x22 = scale.z, x33 = 1.0f
            };

            return(result);
        }
        public static Matrix4x4f Orthographic(float left, float right, float bottom, float top, float near, float far)
        {
            var invWidth  = 1.0f / (right - left);
            var invHeight = 1.0f / (top - bottom);
            var invLength = 1.0f / (far - near);

            var result = new Matrix4x4f
            {
                x00 = 2.0f * invWidth,
                x11 = 2.0f * invHeight,
                x22 = -2.0f * invLength,
                x30 = -(right + left) * invWidth,
                x31 = -(top + bottom) * invHeight,
                x32 = -(far + near) * invLength
            };

            return(result);
        }
        /// <inheritdoc />
        public override MatrixF Multiply(float scale)
        {
            var result = new Matrix4x4f
            {
                x00 = this.x00 * scale,
                x01 = this.x01 * scale,
                x02 = this.x02 * scale,
                x03 = this.x03 * scale,
                x10 = this.x10 * scale,
                x11 = this.x11 * scale,
                x12 = this.x12 * scale,
                x13 = this.x13 * scale,
                x20 = this.x20 * scale,
                x21 = this.x21 * scale,
                x22 = this.x22 * scale,
                x23 = this.x23 * scale,
                x30 = this.x30 * scale,
                x31 = this.x31 * scale,
                x32 = this.x32 * scale,
                x33 = this.x33 * scale
            };

            return(result);
        }