-- | Transform quaternion to rotation matrix
quatMatrix :: Quaternion Float -> M44 Float
quatMatrix q@(Quaternion !w (V3 !x !y !z)) = V4
  (V4 m00 m01 m02 0)
  (V4 m10 m11 m12 0)
  (V4 m20 m21 m22 0)
  (V4 0 0 0 1)
  where
    s = 2 / norm q
    x2 = x * s
    y2 = y * s
    z2 = z * s
    xx = x * x2
    xy = x * y2
    xz = x * z2
    yy = y * y2
    yz = y * z2
    zz = z * z2
    wx = w * x2
    wy = w * y2
    wz = w * z2

    m00 = 1 - (yy + zz)
    m10 = xy - wz
    m20 = xz + wy

    m01 = xy + wz
    m11 = 1 - (xx + zz)
    m21 = yz - wx

    m02 = xz - wy
    m12 = yz + wx
    m22 = 1 - (xx + yy)
quatMatrix :: Quaternion Float -> M44 Float
quatMatrix q@(Quaternion !w (V3 !x !y !z)) = V4
  (V4 m00 m01 m02 0)
  (V4 m10 m11 m12 0)
  (V4 m20 m21 m22 0)
  (V4 0 0 0 1)
  where
    s = 2 / norm q
    x2 = x * s
    y2 = y * s
    z2 = z * s
    xx = x * x2
    xy = x * y2
    xz = x * z2
    yy = y * y2
    yz = y * z2
    zz = z * z2
    wx = w * x2
    wy = w * y2
    wz = w * z2

    m00 = 1 - (yy + zz)
    m10 = xy - wz
    m20 = xz + wy

    m01 = xy + wz
    m11 = 1 - (xx + zz)
    m21 = yz - wx

    m02 = xz - wy
    m12 = yz + wx
    m22 = 1 - (xx + yy)
quatMatrix q@(Quaternion !w (V3 !x !y !z)) = V4
  (V4 m00 m01 m02 0)
  (V4 m10 m11 m12 0)
  (V4 m20 m21 m22 0)
  (V4 0 0 0 1)
  where
    s = 2 / norm q
    x2 = x * s
    y2 = y * s
    z2 = z * s
    xx = x * x2
    xy = x * y2
    xz = x * z2
    yy = y * y2
    yz = y * z2
    zz = z * z2
    wx = w * x2
    wy = w * y2
    wz = w * z2

    m00 = 1 - (yy + zz)
    m10 = xy - wz
    m20 = xz + wy

    m01 = xy + wz
    m11 = 1 - (xx + zz)
    m21 = yz - wx

    m02 = xz - wy
    m12 = yz + wx
    m22 = 1 - (xx + yy)