{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE BlockArguments #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE MagicHash #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE UnboxedTuples #-}
{-# LANGUAGE UnliftedFFITypes #-}
{-# LANGUAGE ViewPatterns #-}

-- | General matrix storage and operations.

module Geomancy.Mat4
  ( Mat4

  , rowMajor
  , withRowMajor
  , toListRowMajor
  , toListRowMajor2d
  , fromRowMajor2d

  , colMajor
  , withColMajor
  , toListColMajor
  , toListColMajor2d

  , identity
  , transpose
  , inverse
  , pointwise
  , zipWith
  , matrixProduct
  , scalarMultiply
  , (!*)
  ) where

import Prelude hiding (zipWith)
import GHC.Exts hiding (VecCount(..), toList)

import Control.DeepSeq (NFData(rnf))
import Foreign (Storable(..))
import GHC.IO (IO(..))
import System.IO.Unsafe (unsafePerformIO)
import Text.Printf (printf)

import qualified Data.Foldable as Foldable
import qualified Data.List as List

import Geomancy.Vec4 (Vec4(..), unsafeNewVec4)

data Mat4 = Mat4 ByteArray#

{- | Construct 'Mat4' from @row@ notation.
-}
rowMajor
  :: Coercible Mat4 a
  => Float -> Float -> Float -> Float
  -> Float -> Float -> Float -> Float
  -> Float -> Float -> Float -> Float
  -> Float -> Float -> Float -> Float
  -> a
rowMajor :: Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> a
rowMajor = (Float
 -> Float
 -> Float
 -> Float
 -> Float
 -> Float
 -> Float
 -> Float
 -> Float
 -> Float
 -> Float
 -> Float
 -> Float
 -> Float
 -> Float
 -> Float
 -> Mat4)
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> a
coerce Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Mat4
mat4

{- | Reduce 'Mat4' with a function with @row@ notation of arguments.
-}
withRowMajor
  :: Coercible a Mat4
  => a
  ->
    ( Float -> Float -> Float -> Float ->
      Float -> Float -> Float -> Float ->
      Float -> Float -> Float -> Float ->
      Float -> Float -> Float -> Float ->
      r
    )
  -> r
withRowMajor :: a
-> (Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> r)
-> r
withRowMajor a
m = Mat4
-> (Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> r)
-> r
forall r.
Mat4
-> (Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> r)
-> r
withMat4 (a -> Mat4
coerce a
m)

toListRowMajor :: Coercible a Mat4 => a -> [Float]
toListRowMajor :: a -> [Float]
toListRowMajor = Mat4 -> [Float]
toList (Mat4 -> [Float]) -> (a -> Mat4) -> a -> [Float]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Mat4
coerce

toListRowMajor2d :: Coercible a Mat4 => a -> [[Float]]
toListRowMajor2d :: a -> [[Float]]
toListRowMajor2d = Mat4 -> [[Float]]
toList2d (Mat4 -> [[Float]]) -> (a -> Mat4) -> a -> [[Float]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Mat4
coerce

{- |
  Build a Mat4 from a list-of-lists kind of container
  with row-major ordering of elements.

@
  fromRowMajor2d (Linear.mkTransformation dir pos) :: Transform
@
-}
fromRowMajor2d
  :: forall t a
  .  ( Foldable t
     , Coercible Mat4 a
     )
  => t (t Float)
  -> Maybe a
fromRowMajor2d :: t (t Float) -> Maybe a
fromRowMajor2d t (t Float)
rows =
  case t (t Float) -> [t Float]
forall (t :: * -> *) a. Foldable t => t a -> [a]
Foldable.toList t (t Float)
rows of
    [t Float
r0, t Float
r1, t Float
r2, t Float
r3] ->
      t Float -> (Float -> Float -> Float -> Float -> Maybe a) -> Maybe a
forall (t :: * -> *) t a.
Foldable t =>
t t -> (t -> t -> t -> t -> Maybe a) -> Maybe a
withRow t Float
r0 \Float
m00 Float
m01 Float
m02 Float
m03 ->
      t Float -> (Float -> Float -> Float -> Float -> Maybe a) -> Maybe a
forall (t :: * -> *) t a.
Foldable t =>
t t -> (t -> t -> t -> t -> Maybe a) -> Maybe a
withRow t Float
r1 \Float
m10 Float
m11 Float
m12 Float
m13 ->
      t Float -> (Float -> Float -> Float -> Float -> Maybe a) -> Maybe a
forall (t :: * -> *) t a.
Foldable t =>
t t -> (t -> t -> t -> t -> Maybe a) -> Maybe a
withRow t Float
r2 \Float
m20 Float
m21 Float
m22 Float
m23 ->
      t Float -> (Float -> Float -> Float -> Float -> Maybe a) -> Maybe a
forall (t :: * -> *) t a.
Foldable t =>
t t -> (t -> t -> t -> t -> Maybe a) -> Maybe a
withRow t Float
r3 \Float
m30 Float
m31 Float
m32 Float
m33 ->
        a -> Maybe a
forall a. a -> Maybe a
Just (a -> Maybe a) -> (Mat4 -> a) -> Mat4 -> Maybe a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Mat4 -> a
coerce (Mat4 -> Maybe a) -> Mat4 -> Maybe a
forall a b. (a -> b) -> a -> b
$ Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Mat4
mat4
          Float
m00 Float
m01 Float
m02 Float
m03
          Float
m10 Float
m11 Float
m12 Float
m13
          Float
m20 Float
m21 Float
m22 Float
m23
          Float
m30 Float
m31 Float
m32 Float
m33
    [t Float]
_ ->
      Maybe a
forall a. Maybe a
Nothing
  where
    withRow :: t t -> (t -> t -> t -> t -> Maybe a) -> Maybe a
withRow t t
row t -> t -> t -> t -> Maybe a
f =
      case t t -> [t]
forall (t :: * -> *) a. Foldable t => t a -> [a]
Foldable.toList t t
row of
        [t
c0, t
c1, t
c2, t
c3] ->
          t -> t -> t -> t -> Maybe a
f t
c0 t
c1 t
c2 t
c3
        [t]
_ ->
          Maybe a
forall a. Maybe a
Nothing

{- | Construct a 'Mat4' from @column@ notation.
-}
{-# INLINE colMajor #-}
colMajor
  :: Coercible Mat4 a
  => Float -> Float -> Float -> Float
  -> Float -> Float -> Float -> Float
  -> Float -> Float -> Float -> Float
  -> Float -> Float -> Float -> Float
  -> a
colMajor :: Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> a
colMajor
  Float
m00 Float
m01 Float
m02 Float
m03
  Float
m10 Float
m11 Float
m12 Float
m13
  Float
m20 Float
m21 Float
m22 Float
m23
  Float
m30 Float
m31 Float
m32 Float
m33 =
    Mat4 -> a
coerce (Mat4 -> a) -> Mat4 -> a
forall a b. (a -> b) -> a -> b
$ Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Mat4
mat4
      Float
m00 Float
m10 Float
m20 Float
m30
      Float
m01 Float
m11 Float
m21 Float
m31
      Float
m02 Float
m12 Float
m22 Float
m32
      Float
m03 Float
m13 Float
m23 Float
m33

{- | Reduce 'Mat4' with a function with @column@ notation for arguments.
-}
{-# INLINE withColMajor #-}
withColMajor
  :: Coercible a Mat4
  => a
  ->
    ( Float -> Float -> Float -> Float ->
      Float -> Float -> Float -> Float ->
      Float -> Float -> Float -> Float ->
      Float -> Float -> Float -> Float ->
      r
    )
  -> r
withColMajor :: a
-> (Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> r)
-> r
withColMajor a
m Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> r
f = Mat4
-> (Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> r)
-> r
forall r.
Mat4
-> (Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> r)
-> r
withMat4 (a -> Mat4
coerce a
m)
  \ Float
m00 Float
m01 Float
m02 Float
m03
    Float
m10 Float
m11 Float
m12 Float
m13
    Float
m20 Float
m21 Float
m22 Float
m23
    Float
m30 Float
m31 Float
m32 Float
m33 ->
  Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> r
f
    Float
m00 Float
m10 Float
m20 Float
m30
    Float
m01 Float
m11 Float
m21 Float
m31
    Float
m02 Float
m12 Float
m22 Float
m32
    Float
m03 Float
m13 Float
m23 Float
m33

toListColMajor :: Coercible a Mat4 => a -> [Float]
toListColMajor :: a -> [Float]
toListColMajor = Mat4 -> [Float]
toListTrans (Mat4 -> [Float]) -> (a -> Mat4) -> a -> [Float]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Mat4
coerce

toListColMajor2d :: Coercible a Mat4 => a -> [[Float]]
toListColMajor2d :: a -> [[Float]]
toListColMajor2d = Mat4 -> [[Float]]
toList2dTrans (Mat4 -> [[Float]]) -> (a -> Mat4) -> a -> [[Float]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Mat4
coerce

{- | Construct 'Mat4' from elements in memory order.
-}
{-# INLINE mat4 #-}
mat4
  :: Float -> Float -> Float -> Float
  -> Float -> Float -> Float -> Float
  -> Float -> Float -> Float -> Float
  -> Float -> Float -> Float -> Float
  -> Mat4
mat4 :: Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Mat4
mat4
  (F# Float#
m00) (F# Float#
m01) (F# Float#
m02) (F# Float#
m03)
  (F# Float#
m10) (F# Float#
m11) (F# Float#
m12) (F# Float#
m13)
  (F# Float#
m20) (F# Float#
m21) (F# Float#
m22) (F# Float#
m23)
  (F# Float#
m30) (F# Float#
m31) (F# Float#
m32) (F# Float#
m33) =
  (State# RealWorld -> Mat4) -> Mat4
forall o. (State# RealWorld -> o) -> o
runRW# \State# RealWorld
world ->
    let
      !(# State# RealWorld
world_, MutableByteArray# RealWorld
arr #) = Int#
-> Int#
-> State# RealWorld
-> (# State# RealWorld, MutableByteArray# RealWorld #)
forall d.
Int# -> Int# -> State# d -> (# State# d, MutableByteArray# d #)
newAlignedPinnedByteArray# Int#
64# Int#
16# State# RealWorld
world

      world00 :: State# RealWorld
world00 = MutableByteArray# RealWorld
-> Int# -> Float# -> State# RealWorld -> State# RealWorld
forall d.
MutableByteArray# d -> Int# -> Float# -> State# d -> State# d
writeFloatArray# MutableByteArray# RealWorld
arr Int#
0x0# Float#
m00 State# RealWorld
world_
      world01 :: State# RealWorld
world01 = MutableByteArray# RealWorld
-> Int# -> Float# -> State# RealWorld -> State# RealWorld
forall d.
MutableByteArray# d -> Int# -> Float# -> State# d -> State# d
writeFloatArray# MutableByteArray# RealWorld
arr Int#
0x1# Float#
m01 State# RealWorld
world00
      world02 :: State# RealWorld
world02 = MutableByteArray# RealWorld
-> Int# -> Float# -> State# RealWorld -> State# RealWorld
forall d.
MutableByteArray# d -> Int# -> Float# -> State# d -> State# d
writeFloatArray# MutableByteArray# RealWorld
arr Int#
0x2# Float#
m02 State# RealWorld
world01
      world03 :: State# RealWorld
world03 = MutableByteArray# RealWorld
-> Int# -> Float# -> State# RealWorld -> State# RealWorld
forall d.
MutableByteArray# d -> Int# -> Float# -> State# d -> State# d
writeFloatArray# MutableByteArray# RealWorld
arr Int#
0x3# Float#
m03 State# RealWorld
world02

      world10 :: State# RealWorld
world10 = MutableByteArray# RealWorld
-> Int# -> Float# -> State# RealWorld -> State# RealWorld
forall d.
MutableByteArray# d -> Int# -> Float# -> State# d -> State# d
writeFloatArray# MutableByteArray# RealWorld
arr Int#
0x4# Float#
m10 State# RealWorld
world03
      world11 :: State# RealWorld
world11 = MutableByteArray# RealWorld
-> Int# -> Float# -> State# RealWorld -> State# RealWorld
forall d.
MutableByteArray# d -> Int# -> Float# -> State# d -> State# d
writeFloatArray# MutableByteArray# RealWorld
arr Int#
0x5# Float#
m11 State# RealWorld
world10
      world12 :: State# RealWorld
world12 = MutableByteArray# RealWorld
-> Int# -> Float# -> State# RealWorld -> State# RealWorld
forall d.
MutableByteArray# d -> Int# -> Float# -> State# d -> State# d
writeFloatArray# MutableByteArray# RealWorld
arr Int#
0x6# Float#
m12 State# RealWorld
world11
      world13 :: State# RealWorld
world13 = MutableByteArray# RealWorld
-> Int# -> Float# -> State# RealWorld -> State# RealWorld
forall d.
MutableByteArray# d -> Int# -> Float# -> State# d -> State# d
writeFloatArray# MutableByteArray# RealWorld
arr Int#
0x7# Float#
m13 State# RealWorld
world12

      world20 :: State# RealWorld
world20 = MutableByteArray# RealWorld
-> Int# -> Float# -> State# RealWorld -> State# RealWorld
forall d.
MutableByteArray# d -> Int# -> Float# -> State# d -> State# d
writeFloatArray# MutableByteArray# RealWorld
arr Int#
0x8# Float#
m20 State# RealWorld
world13
      world21 :: State# RealWorld
world21 = MutableByteArray# RealWorld
-> Int# -> Float# -> State# RealWorld -> State# RealWorld
forall d.
MutableByteArray# d -> Int# -> Float# -> State# d -> State# d
writeFloatArray# MutableByteArray# RealWorld
arr Int#
0x9# Float#
m21 State# RealWorld
world20
      world22 :: State# RealWorld
world22 = MutableByteArray# RealWorld
-> Int# -> Float# -> State# RealWorld -> State# RealWorld
forall d.
MutableByteArray# d -> Int# -> Float# -> State# d -> State# d
writeFloatArray# MutableByteArray# RealWorld
arr Int#
0xA# Float#
m22 State# RealWorld
world21
      world23 :: State# RealWorld
world23 = MutableByteArray# RealWorld
-> Int# -> Float# -> State# RealWorld -> State# RealWorld
forall d.
MutableByteArray# d -> Int# -> Float# -> State# d -> State# d
writeFloatArray# MutableByteArray# RealWorld
arr Int#
0xB# Float#
m23 State# RealWorld
world22

      world30 :: State# RealWorld
world30 = MutableByteArray# RealWorld
-> Int# -> Float# -> State# RealWorld -> State# RealWorld
forall d.
MutableByteArray# d -> Int# -> Float# -> State# d -> State# d
writeFloatArray# MutableByteArray# RealWorld
arr Int#
0xC# Float#
m30 State# RealWorld
world23
      world31 :: State# RealWorld
world31 = MutableByteArray# RealWorld
-> Int# -> Float# -> State# RealWorld -> State# RealWorld
forall d.
MutableByteArray# d -> Int# -> Float# -> State# d -> State# d
writeFloatArray# MutableByteArray# RealWorld
arr Int#
0xD# Float#
m31 State# RealWorld
world30
      world32 :: State# RealWorld
world32 = MutableByteArray# RealWorld
-> Int# -> Float# -> State# RealWorld -> State# RealWorld
forall d.
MutableByteArray# d -> Int# -> Float# -> State# d -> State# d
writeFloatArray# MutableByteArray# RealWorld
arr Int#
0xE# Float#
m32 State# RealWorld
world31
      world33 :: State# RealWorld
world33 = MutableByteArray# RealWorld
-> Int# -> Float# -> State# RealWorld -> State# RealWorld
forall d.
MutableByteArray# d -> Int# -> Float# -> State# d -> State# d
writeFloatArray# MutableByteArray# RealWorld
arr Int#
0xF# Float#
m33 State# RealWorld
world32

      !(# State# RealWorld
_world', ByteArray#
arr' #) = MutableByteArray# RealWorld
-> State# RealWorld -> (# State# RealWorld, ByteArray# #)
forall d.
MutableByteArray# d -> State# d -> (# State# d, ByteArray# #)
unsafeFreezeByteArray# MutableByteArray# RealWorld
arr State# RealWorld
world33
    in
      ByteArray# -> Mat4
Mat4 ByteArray#
arr'

{- | Reduce 'Mat4' with a function with @memory@ notation for arguments.
-}
{-# INLINE withMat4 #-}
withMat4
  :: Mat4
  ->
    ( Float -> Float -> Float -> Float ->
      Float -> Float -> Float -> Float ->
      Float -> Float -> Float -> Float ->
      Float -> Float -> Float -> Float ->
      r
    )
  -> r
withMat4 :: Mat4
-> (Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> r)
-> r
withMat4 (Mat4 ByteArray#
arr) Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> r
f =
  Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> r
f
    (Float# -> Float
F# (ByteArray# -> Int# -> Float#
indexFloatArray# ByteArray#
arr Int#
0x0#))
    (Float# -> Float
F# (ByteArray# -> Int# -> Float#
indexFloatArray# ByteArray#
arr Int#
0x1#))
    (Float# -> Float
F# (ByteArray# -> Int# -> Float#
indexFloatArray# ByteArray#
arr Int#
0x2#))
    (Float# -> Float
F# (ByteArray# -> Int# -> Float#
indexFloatArray# ByteArray#
arr Int#
0x3#))

    (Float# -> Float
F# (ByteArray# -> Int# -> Float#
indexFloatArray# ByteArray#
arr Int#
0x4#))
    (Float# -> Float
F# (ByteArray# -> Int# -> Float#
indexFloatArray# ByteArray#
arr Int#
0x5#))
    (Float# -> Float
F# (ByteArray# -> Int# -> Float#
indexFloatArray# ByteArray#
arr Int#
0x6#))
    (Float# -> Float
F# (ByteArray# -> Int# -> Float#
indexFloatArray# ByteArray#
arr Int#
0x7#))

    (Float# -> Float
F# (ByteArray# -> Int# -> Float#
indexFloatArray# ByteArray#
arr Int#
0x8#))
    (Float# -> Float
F# (ByteArray# -> Int# -> Float#
indexFloatArray# ByteArray#
arr Int#
0x9#))
    (Float# -> Float
F# (ByteArray# -> Int# -> Float#
indexFloatArray# ByteArray#
arr Int#
0xA#))
    (Float# -> Float
F# (ByteArray# -> Int# -> Float#
indexFloatArray# ByteArray#
arr Int#
0xB#))

    (Float# -> Float
F# (ByteArray# -> Int# -> Float#
indexFloatArray# ByteArray#
arr Int#
0xC#))
    (Float# -> Float
F# (ByteArray# -> Int# -> Float#
indexFloatArray# ByteArray#
arr Int#
0xD#))
    (Float# -> Float
F# (ByteArray# -> Int# -> Float#
indexFloatArray# ByteArray#
arr Int#
0xE#))
    (Float# -> Float
F# (ByteArray# -> Int# -> Float#
indexFloatArray# ByteArray#
arr Int#
0xF#))

{- | @I@, the identity matrix.

Neutral element of its monoid, so you can use 'mempty'.
-}
{-# INLINE identity #-}
identity :: Mat4
identity :: Mat4
identity = Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Mat4
mat4
  Float
1 Float
0 Float
0 Float
0
  Float
0 Float
1 Float
0 Float
0
  Float
0 Float
0 Float
1 Float
0
  Float
0 Float
0 Float
0 Float
1

{-# INLINE transpose #-}
transpose :: Mat4 -> Mat4
transpose :: Mat4 -> Mat4
transpose =
  (Mat4
 -> (Float
     -> Float
     -> Float
     -> Float
     -> Float
     -> Float
     -> Float
     -> Float
     -> Float
     -> Float
     -> Float
     -> Float
     -> Float
     -> Float
     -> Float
     -> Float
     -> Mat4)
 -> Mat4)
-> (Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Mat4)
-> Mat4
-> Mat4
forall a b c. (a -> b -> c) -> b -> a -> c
flip Mat4
-> (Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Mat4)
-> Mat4
forall r.
Mat4
-> (Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> r)
-> r
withMat4
    \ Float
m00 Float
m01 Float
m02 Float
m03
      Float
m10 Float
m11 Float
m12 Float
m13
      Float
m20 Float
m21 Float
m22 Float
m23
      Float
m30 Float
m31 Float
m32 Float
m33 ->
    Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Mat4
mat4
      Float
m00 Float
m10 Float
m20 Float
m30
      Float
m01 Float
m11 Float
m21 Float
m31
      Float
m02 Float
m12 Float
m22 Float
m32
      Float
m03 Float
m13 Float
m23 Float
m33

{- | Compute an inverse matrix, slowly.
-}
inverse :: (Coercible Mat4 a, Coercible Mat4 a) => a -> a
inverse :: a -> a
inverse a
m =
  Mat4 -> a
coerce (Mat4 -> a) -> Mat4 -> a
forall a b. (a -> b) -> a -> b
$ Mat4
-> (Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Mat4)
-> Mat4
forall r.
Mat4
-> (Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> r)
-> r
withMat4 (a -> Mat4
coerce a
m)
    \ Float
m00 Float
m01 Float
m02 Float
m03
      Float
m10 Float
m11 Float
m12 Float
m13
      Float
m20 Float
m21 Float
m22 Float
m23
      Float
m30 Float
m31 Float
m32 Float
m33 ->
        let
          invDet :: Float
invDet = Float -> Float
forall a. Fractional a => a -> a
recip Float
det

          det :: Float
det
            = Float
s0 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
c5
            Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
s1 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
c4
            Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
s2 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
c3
            Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
s3 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
c2
            Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
s4 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
c1
            Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
s5 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
c0

          s0 :: Float
s0 = Float
m00 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
m11 Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
m10 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
m01
          s1 :: Float
s1 = Float
m00 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
m12 Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
m10 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
m02
          s2 :: Float
s2 = Float
m00 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
m13 Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
m10 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
m03
          s3 :: Float
s3 = Float
m01 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
m12 Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
m11 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
m02
          s4 :: Float
s4 = Float
m01 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
m13 Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
m11 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
m03
          s5 :: Float
s5 = Float
m02 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
m13 Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
m12 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
m03

          c5 :: Float
c5 = Float
m22 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
m33 Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
m32 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
m23
          c4 :: Float
c4 = Float
m21 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
m33 Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
m31 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
m23
          c3 :: Float
c3 = Float
m21 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
m32 Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
m31 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
m22
          c2 :: Float
c2 = Float
m20 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
m33 Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
m30 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
m23
          c1 :: Float
c1 = Float
m20 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
m32 Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
m30 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
m22
          c0 :: Float
c0 = Float
m20 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
m31 Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
m30 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
m21

          i00 :: Float
i00 = ( Float
m11 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
c5 Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
m12 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
c4 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
m13 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
c3) Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
invDet
          i01 :: Float
i01 = (-Float
m01 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
c5 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
m02 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
c4 Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
m03 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
c3) Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
invDet
          i02 :: Float
i02 = ( Float
m31 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
s5 Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
m32 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
s4 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
m33 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
s3) Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
invDet
          i03 :: Float
i03 = (-Float
m21 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
s5 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
m22 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
s4 Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
m23 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
s3) Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
invDet

          i10 :: Float
i10 = (-Float
m10 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
c5 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
m12 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
c2 Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
m13 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
c1) Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
invDet
          i11 :: Float
i11 = ( Float
m00 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
c5 Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
m02 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
c2 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
m03 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
c1) Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
invDet
          i12 :: Float
i12 = (-Float
m30 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
s5 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
m32 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
s2 Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
m33 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
s1) Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
invDet
          i13 :: Float
i13 = ( Float
m20 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
s5 Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
m22 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
s2 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
m23 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
s1) Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
invDet

          i20 :: Float
i20 = ( Float
m10 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
c4 Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
m11 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
c2 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
m13 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
c0) Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
invDet
          i21 :: Float
i21 = (-Float
m00 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
c4 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
m01 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
c2 Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
m03 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
c0) Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
invDet
          i22 :: Float
i22 = ( Float
m30 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
s4 Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
m31 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
s2 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
m33 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
s0) Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
invDet
          i23 :: Float
i23 = (-Float
m20 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
s4 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
m21 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
s2 Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
m23 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
s0) Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
invDet

          i30 :: Float
i30 = (-Float
m10 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
c3 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
m11 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
c1 Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
m12 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
c0) Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
invDet
          i31 :: Float
i31 = ( Float
m00 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
c3 Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
m01 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
c1 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
m02 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
c0) Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
invDet
          i32 :: Float
i32 = (-Float
m30 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
s3 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
m31 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
s1 Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
m32 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
s0) Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
invDet
          i33 :: Float
i33 = ( Float
m20 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
s3 Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
m21 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
s1 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
m22 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
s0) Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
invDet
        in
          Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Mat4
mat4
            Float
i00 Float
i01 Float
i02 Float
i03
            Float
i10 Float
i11 Float
i12 Float
i13
            Float
i20 Float
i21 Float
i22 Float
i23
            Float
i30 Float
i31 Float
i32 Float
i33

pointwise :: Mat4 -> Mat4 -> (Float -> Float -> Float) -> Mat4
pointwise :: Mat4 -> Mat4 -> (Float -> Float -> Float) -> Mat4
pointwise Mat4
a Mat4
b Float -> Float -> Float
f =
  Mat4
-> (Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Mat4)
-> Mat4
forall r.
Mat4
-> (Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> r)
-> r
withMat4 Mat4
a
    \ Float
a00 Float
a01 Float
a02 Float
a03
      Float
a10 Float
a11 Float
a12 Float
a13
      Float
a20 Float
a21 Float
a22 Float
a23
      Float
a30 Float
a31 Float
a32 Float
a33 ->
  Mat4
-> (Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Mat4)
-> Mat4
forall r.
Mat4
-> (Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> r)
-> r
withMat4 Mat4
b
    \ Float
b00 Float
b01 Float
b02 Float
b03
      Float
b10 Float
b11 Float
b12 Float
b13
      Float
b20 Float
b21 Float
b22 Float
b23
      Float
b30 Float
b31 Float
b32 Float
b33 ->
  Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Mat4
mat4
    (Float -> Float -> Float
f Float
a00 Float
b00) (Float -> Float -> Float
f Float
a01 Float
b01) (Float -> Float -> Float
f Float
a02 Float
b02) (Float -> Float -> Float
f Float
a03 Float
b03)
    (Float -> Float -> Float
f Float
a10 Float
b10) (Float -> Float -> Float
f Float
a11 Float
b11) (Float -> Float -> Float
f Float
a12 Float
b12) (Float -> Float -> Float
f Float
a13 Float
b13)
    (Float -> Float -> Float
f Float
a20 Float
b20) (Float -> Float -> Float
f Float
a21 Float
b21) (Float -> Float -> Float
f Float
a22 Float
b22) (Float -> Float -> Float
f Float
a23 Float
b23)
    (Float -> Float -> Float
f Float
a30 Float
b30) (Float -> Float -> Float
f Float
a31 Float
b31) (Float -> Float -> Float
f Float
a32 Float
b32) (Float -> Float -> Float
f Float
a33 Float
b33)

toList :: Mat4 -> [Float]
toList :: Mat4 -> [Float]
toList = (Mat4
 -> (Float
     -> Float
     -> Float
     -> Float
     -> Float
     -> Float
     -> Float
     -> Float
     -> Float
     -> Float
     -> Float
     -> Float
     -> Float
     -> Float
     -> Float
     -> Float
     -> [Float])
 -> [Float])
-> (Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> [Float])
-> Mat4
-> [Float]
forall a b c. (a -> b -> c) -> b -> a -> c
flip Mat4
-> (Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> [Float])
-> [Float]
forall r.
Mat4
-> (Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> r)
-> r
withMat4
    \ Float
a00 Float
a01 Float
a02 Float
a03
      Float
a10 Float
a11 Float
a12 Float
a13
      Float
a20 Float
a21 Float
a22 Float
a23
      Float
a30 Float
a31 Float
a32 Float
a33 ->
    [ Float
a00, Float
a01, Float
a02, Float
a03
    , Float
a10, Float
a11, Float
a12, Float
a13
    , Float
a20, Float
a21, Float
a22, Float
a23
    , Float
a30, Float
a31, Float
a32, Float
a33
    ]

toList2d :: Mat4 -> [[Float]]
toList2d :: Mat4 -> [[Float]]
toList2d = (Mat4
 -> (Float
     -> Float
     -> Float
     -> Float
     -> Float
     -> Float
     -> Float
     -> Float
     -> Float
     -> Float
     -> Float
     -> Float
     -> Float
     -> Float
     -> Float
     -> Float
     -> [[Float]])
 -> [[Float]])
-> (Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> [[Float]])
-> Mat4
-> [[Float]]
forall a b c. (a -> b -> c) -> b -> a -> c
flip Mat4
-> (Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> [[Float]])
-> [[Float]]
forall r.
Mat4
-> (Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> r)
-> r
withMat4
    \ Float
a00 Float
a01 Float
a02 Float
a03
      Float
a10 Float
a11 Float
a12 Float
a13
      Float
a20 Float
a21 Float
a22 Float
a23
      Float
a30 Float
a31 Float
a32 Float
a33 ->
    [ [Float
a00, Float
a01, Float
a02, Float
a03]
    , [Float
a10, Float
a11, Float
a12, Float
a13]
    , [Float
a20, Float
a21, Float
a22, Float
a23]
    , [Float
a30, Float
a31, Float
a32, Float
a33]
    ]

toListTrans :: Mat4 -> [Float]
toListTrans :: Mat4 -> [Float]
toListTrans = (Mat4
 -> (Float
     -> Float
     -> Float
     -> Float
     -> Float
     -> Float
     -> Float
     -> Float
     -> Float
     -> Float
     -> Float
     -> Float
     -> Float
     -> Float
     -> Float
     -> Float
     -> [Float])
 -> [Float])
-> (Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> [Float])
-> Mat4
-> [Float]
forall a b c. (a -> b -> c) -> b -> a -> c
flip Mat4
-> (Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> [Float])
-> [Float]
forall r.
Mat4
-> (Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> r)
-> r
withMat4
    \ Float
a00 Float
a01 Float
a02 Float
a03
      Float
a10 Float
a11 Float
a12 Float
a13
      Float
a20 Float
a21 Float
a22 Float
a23
      Float
a30 Float
a31 Float
a32 Float
a33 ->
    [ Float
a00, Float
a10, Float
a20, Float
a30
    , Float
a01, Float
a11, Float
a21, Float
a31
    , Float
a02, Float
a12, Float
a22, Float
a32
    , Float
a03, Float
a13, Float
a23, Float
a33
    ]

toList2dTrans :: Mat4 -> [[Float]]
toList2dTrans :: Mat4 -> [[Float]]
toList2dTrans = (Mat4
 -> (Float
     -> Float
     -> Float
     -> Float
     -> Float
     -> Float
     -> Float
     -> Float
     -> Float
     -> Float
     -> Float
     -> Float
     -> Float
     -> Float
     -> Float
     -> Float
     -> [[Float]])
 -> [[Float]])
-> (Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> [[Float]])
-> Mat4
-> [[Float]]
forall a b c. (a -> b -> c) -> b -> a -> c
flip Mat4
-> (Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> [[Float]])
-> [[Float]]
forall r.
Mat4
-> (Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> r)
-> r
withMat4
    \ Float
a00 Float
a01 Float
a02 Float
a03
      Float
a10 Float
a11 Float
a12 Float
a13
      Float
a20 Float
a21 Float
a22 Float
a23
      Float
a30 Float
a31 Float
a32 Float
a33 ->
    [ [Float
a00, Float
a10, Float
a20, Float
a30]
    , [Float
a01, Float
a11, Float
a21, Float
a31]
    , [Float
a02, Float
a12, Float
a22, Float
a32]
    , [Float
a03, Float
a13, Float
a23, Float
a33]
    ]

zipWith :: (Float -> Float -> c) -> Mat4 -> Mat4 -> [c]
zipWith :: (Float -> Float -> c) -> Mat4 -> Mat4 -> [c]
zipWith Float -> Float -> c
f Mat4
a Mat4
b = (Float -> Float -> c) -> [Float] -> [Float] -> [c]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
List.zipWith Float -> Float -> c
f (Mat4 -> [Float]
toList Mat4
a) (Mat4 -> [Float]
toList Mat4
b)

foreign import ccall unsafe "Mat4xMat4_SSE" m4m4sse :: Addr# -> Addr# -> Addr# -> IO ()

{-# INLINE matrixProduct #-}
matrixProduct :: Mat4 -> Mat4 -> Mat4
matrixProduct :: Mat4 -> Mat4 -> Mat4
matrixProduct (Mat4 ByteArray#
l) (Mat4 ByteArray#
r) = IO Mat4 -> Mat4
forall a. IO a -> a
unsafePerformIO do
  result :: Mat4
result@(Mat4 ByteArray#
m) <- IO Mat4
unsafeNewMat4
  Addr# -> Addr# -> Addr# -> IO ()
m4m4sse
    (ByteArray# -> Addr#
byteArrayContents# ByteArray#
l)
    (ByteArray# -> Addr#
byteArrayContents# ByteArray#
r)
    (ByteArray# -> Addr#
byteArrayContents# ByteArray#
m)
  Mat4 -> IO Mat4
forall (f :: * -> *) a. Applicative f => a -> f a
pure Mat4
result

{-# INLINE unsafeNewMat4 #-}
unsafeNewMat4 :: IO Mat4
unsafeNewMat4 :: IO Mat4
unsafeNewMat4 =
  (State# RealWorld -> (# State# RealWorld, Mat4 #)) -> IO Mat4
forall a. (State# RealWorld -> (# State# RealWorld, a #)) -> IO a
IO \State# RealWorld
world ->
    let
      !(# State# RealWorld
world_, MutableByteArray# RealWorld
arr_ #) = Int#
-> Int#
-> State# RealWorld
-> (# State# RealWorld, MutableByteArray# RealWorld #)
forall d.
Int# -> Int# -> State# d -> (# State# d, MutableByteArray# d #)
newAlignedPinnedByteArray# Int#
64# Int#
16# State# RealWorld
world
      !(# State# RealWorld
_world', ByteArray#
arr #) = MutableByteArray# RealWorld
-> State# RealWorld -> (# State# RealWorld, ByteArray# #)
forall d.
MutableByteArray# d -> State# d -> (# State# d, ByteArray# #)
unsafeFreezeByteArray# MutableByteArray# RealWorld
arr_ State# RealWorld
world_
    in
      (# State# RealWorld
world, ByteArray# -> Mat4
Mat4 ByteArray#
arr #)

{-# INLINE scalarMultiply #-}
scalarMultiply :: Float -> Mat4 -> Mat4
scalarMultiply :: Float -> Mat4 -> Mat4
scalarMultiply Float
x Mat4
m =
  Mat4
-> (Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Mat4)
-> Mat4
forall r.
Mat4
-> (Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> r)
-> r
withMat4 Mat4
m
    \ Float
m00 Float
m01 Float
m02 Float
m03
      Float
m10 Float
m11 Float
m12 Float
m13
      Float
m20 Float
m21 Float
m22 Float
m23
      Float
m30 Float
m31 Float
m32 Float
m33 ->
      Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Mat4
mat4
        (Float
m00 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
x) (Float
m10 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
x) (Float
m20 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
x) (Float
m30 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
x)
        (Float
m01 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
x) (Float
m11 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
x) (Float
m21 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
x) (Float
m31 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
x)
        (Float
m02 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
x) (Float
m12 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
x) (Float
m22 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
x) (Float
m32 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
x)
        (Float
m03 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
x) (Float
m13 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
x) (Float
m23 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
x) (Float
m33 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
x)

foreign import ccall unsafe "Mat4xVec4_SSE" m4v4sse :: Addr# -> Addr# -> Addr# -> IO ()

-- | Matrix - column vector multiplication
(!*) :: Coercible a Mat4 => a -> Vec4 -> Vec4
!* :: a -> Vec4 -> Vec4
(!*) (a -> Mat4
coerce -> Mat4 ByteArray#
m) (Vec4 ByteArray#
v) = IO Vec4 -> Vec4
forall a. IO a -> a
unsafePerformIO do
  result :: Vec4
result@(Vec4 ByteArray#
o) <- IO Vec4
unsafeNewVec4
  Addr# -> Addr# -> Addr# -> IO ()
m4v4sse
    (ByteArray# -> Addr#
byteArrayContents# ByteArray#
m)
    (ByteArray# -> Addr#
byteArrayContents# ByteArray#
v)
    (ByteArray# -> Addr#
byteArrayContents# ByteArray#
o)
  Vec4 -> IO Vec4
forall (f :: * -> *) a. Applicative f => a -> f a
pure Vec4
result

  -- withVec4 vec \v1 v2 v3 v4 ->
  --   withColMajor mat
  --     \ m11 m12 m13 m14
  --       m21 m22 m23 m24
  --       m31 m32 m33 m34
  --       m41 m42 m43 m44 ->
  --         vec4
  --           (m11 * v1 + m12 * v2 + m13 * v3 + m14 * v4)
  --           (m21 * v1 + m22 * v2 + m23 * v3 + m24 * v4)
  --           (m31 * v1 + m32 * v2 + m33 * v3 + m34 * v4)
  --           (m41 * v1 + m42 * v2 + m43 * v3 + m44 * v4)

instance NFData Mat4 where
  rnf :: Mat4 -> ()
rnf Mat4{} = ()

instance Semigroup Mat4 where
  {-# INLINE (<>) #-}
  <> :: Mat4 -> Mat4 -> Mat4
(<>) = Mat4 -> Mat4 -> Mat4
matrixProduct

instance Monoid Mat4 where
  {-# INLINE mempty #-}
  mempty :: Mat4
mempty = Mat4
identity

instance Show Mat4 where
  show :: Mat4 -> String
show = (Mat4
 -> (Float
     -> Float
     -> Float
     -> Float
     -> Float
     -> Float
     -> Float
     -> Float
     -> Float
     -> Float
     -> Float
     -> Float
     -> Float
     -> Float
     -> Float
     -> Float
     -> String)
 -> String)
-> (Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> String)
-> Mat4
-> String
forall a b c. (a -> b -> c) -> b -> a -> c
flip Mat4
-> (Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> String)
-> String
forall r.
Mat4
-> (Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> Float
    -> r)
-> r
withMat4
    \ Float
m00 Float
m01 Float
m02 Float
m03
      Float
m10 Float
m11 Float
m12 Float
m13
      Float
m20 Float
m21 Float
m22 Float
m23
      Float
m30 Float
m31 Float
m32 Float
m33 ->
    [String] -> String
unlines
      [ String -> Float -> Float -> Float -> Float -> String
forall r. PrintfType r => String -> r
printf String
"| %.4f %.4f %.4f %.4f |" Float
m00 Float
m01 Float
m02 Float
m03
      , String -> Float -> Float -> Float -> Float -> String
forall r. PrintfType r => String -> r
printf String
"| %.4f %.4f %.4f %.4f |" Float
m10 Float
m11 Float
m12 Float
m13
      , String -> Float -> Float -> Float -> Float -> String
forall r. PrintfType r => String -> r
printf String
"| %.4f %.4f %.4f %.4f |" Float
m20 Float
m21 Float
m22 Float
m23
      , String -> Float -> Float -> Float -> Float -> String
forall r. PrintfType r => String -> r
printf String
"| %.4f %.4f %.4f %.4f |" Float
m30 Float
m31 Float
m32 Float
m33
      ]

instance Storable Mat4 where
  sizeOf :: Mat4 -> Int
sizeOf Mat4
_mat4 = Int
64

  alignment :: Mat4 -> Int
alignment Mat4
_mat4 = Int
16

  {-# INLINE poke #-}
  poke :: Ptr Mat4 -> Mat4 -> IO ()
poke (Ptr Addr#
addr) (Mat4 ByteArray#
arr) = (State# RealWorld -> (# State# RealWorld, () #)) -> IO ()
forall a. (State# RealWorld -> (# State# RealWorld, a #)) -> IO a
IO \State# RealWorld
world ->
    let
      world' :: State# RealWorld
world' = ByteArray#
-> Int# -> Addr# -> Int# -> State# RealWorld -> State# RealWorld
forall d.
ByteArray# -> Int# -> Addr# -> Int# -> State# d -> State# d
copyByteArrayToAddr# ByteArray#
arr Int#
0# Addr#
addr Int#
64# State# RealWorld
world
    in
      (# State# RealWorld
world', () #)

  {-# INLINE peek #-}
  peek :: Ptr Mat4 -> IO Mat4
peek (Ptr Addr#
addr) = (State# RealWorld -> (# State# RealWorld, Mat4 #)) -> IO Mat4
forall a. (State# RealWorld -> (# State# RealWorld, a #)) -> IO a
IO \State# RealWorld
world ->
    let
      !(# State# RealWorld
world0, MutableByteArray# RealWorld
arr #)  = Int#
-> Int#
-> State# RealWorld
-> (# State# RealWorld, MutableByteArray# RealWorld #)
forall d.
Int# -> Int# -> State# d -> (# State# d, MutableByteArray# d #)
newAlignedPinnedByteArray# Int#
64# Int#
16# State# RealWorld
world
      world1 :: State# RealWorld
world1              = Addr#
-> MutableByteArray# RealWorld
-> Int#
-> Int#
-> State# RealWorld
-> State# RealWorld
forall d.
Addr#
-> MutableByteArray# d -> Int# -> Int# -> State# d -> State# d
copyAddrToByteArray# Addr#
addr MutableByteArray# RealWorld
arr Int#
0# Int#
64# State# RealWorld
world0
      !(# State# RealWorld
world', ByteArray#
arr' #) = MutableByteArray# RealWorld
-> State# RealWorld -> (# State# RealWorld, ByteArray# #)
forall d.
MutableByteArray# d -> State# d -> (# State# d, ByteArray# #)
unsafeFreezeByteArray# MutableByteArray# RealWorld
arr State# RealWorld
world1
    in
      (# State# RealWorld
world', ByteArray# -> Mat4
Mat4 ByteArray#
arr' #)