public static Matrix4 FromQuaternion(Quaternion quaternion)
{
var squared = new Vector4(quaternion.X*quaternion.X, quaternion.Y*quaternion.Y, quaternion.Z*quaternion.Z, quaternion.W*quaternion.W);
float invSqLength = 1 / (squared.X + squared.Y + squared.Z + squared.W);
float temp1 = quaternion.X * quaternion.Y;
float temp2 = quaternion.Z * quaternion.W;
float temp3 = quaternion.X * quaternion.Z;
float temp4 = quaternion.Y * quaternion.W;
float temp5 = quaternion.Y * quaternion.Z;
float temp6 = quaternion.X * quaternion.W;
return new Matrix4
(
new Vector4((squared.X-squared.Y-squared.Z+squared.W) * invSqLength, 2*(temp1-temp2) * invSqLength, 2*(temp3+temp4) * invSqLength, 0),
new Vector4(2*(temp1+temp2) * invSqLength, (-squared.X+squared.Y-squared.Z+squared.W) * invSqLength, 2*(temp5-temp6) * invSqLength, 0),
new Vector4(2*(temp3-temp4) * invSqLength, 2*(temp5+temp6) * invSqLength, (-squared.X-squared.Y+squared.Z+squared.W) * invSqLength, 0),
new Vector4(0, 0, 0, 1)
);
}