{-# OPTIONS -Wall #-}

-- | Bindings to @raymath@
--
--   These were rewritten in Haskell instead of binding to C. All the functions
--   are pure. This may not be an exact one-to-one mapping to the C code; some
--   of the functions and high-level structures have been changed to be more
--   idiomatic Haskell.
module Raylib.Util.Math
  ( -- * Utility constants
    epsilon,
    deg2Rad,
    rad2Deg,

    -- * Float math
    clamp,
    lerp,
    normalize,
    remap,
    wrap,
    floatEquals,

    -- * Vector math
    Vector (..),

    -- ** Vector2 math
    vector2Angle,
    vector2LineAngle,
    vector2Transform,
    vector2Reflect,
    vector2Rotate,
    vector2Refract,

    -- ** Vector3 math
    vector3CrossProduct,
    vector3Perpendicular,
    vector3Angle,
    vector3OrthoNormalize,
    vector3Transform,
    vector3RotateByQuaternion,
    vector3RotateByAxisAngle,
    vector3Reflect,
    vector3Barycenter,
    vector3Unproject,
    vector3Refract,

    -- * Matrix math
    matrixToList,
    matrixFromList,
    matrixConstant,
    matrixDeterminant,
    matrixTrace,
    matrixTranspose,
    matrixInvert,
    matrixIdentity,
    matrixAdd,
    (/+/),
    matrixSubtract,
    (/-/),
    matrixMultiply,
    (/*/),
    matrixTranslate,
    matrixRotate,
    matrixRotateX,
    matrixRotateY,
    matrixRotateZ,
    matrixRotateXYZ,
    matrixRotateZYX,
    matrixScale,
    matrixFrustum,
    matrixPerspective,
    matrixOrtho,
    matrixLookAt,

    -- * Quaternion math
    quaternionIdentity,
    quaternionInvert,
    quaternionMultiply,
    quaternionNormalize,
    quaternionLerp,
    quaternionNLerp,
    quaternionSLerp,
    quaternionFromVector3ToVector3,
    quaternionFromMatrix,
    quaternionToMatrix,
    quaternionFromAxisAngle,
    quaternionToAxisAngle,
    quaternionFromEuler,
    quaternionToEuler,
    quaternionTransform,
  )
where

import Data.Foldable (foldl')
import Raylib.Types (Matrix (..), Quaternion, Vector2 (Vector2), Vector3 (Vector3), Vector4 (Vector4))

epsilon :: Float
epsilon :: Float
epsilon = Float
0.000001

deg2Rad :: Float
deg2Rad :: Float
deg2Rad = Float
forall a. Floating a => a
pi Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/ Float
180

rad2Deg :: Float
rad2Deg :: Float
rad2Deg = Float
180 Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/ Float
forall a. Floating a => a
pi

------------------------------------------------
-- Float math ----------------------------------
------------------------------------------------

-- | Clamp float to range (WARNING: this does not use the same argument order
--   as raymath)
clamp ::
  -- | Lower bound
  Float ->
  -- | Upper bound
  Float ->
  -- | Value to clamp
  Float ->
  Float
clamp :: Float -> Float -> Float -> Float
clamp Float
low Float
high Float
value
  | Float
value Float -> Float -> Bool
forall a. Ord a => a -> a -> Bool
< Float
low = Float
low
  | Float
value Float -> Float -> Bool
forall a. Ord a => a -> a -> Bool
> Float
high = Float
high
  | Bool
otherwise = Float
value

-- | Calculate linear interpolation between two floats
lerp ::
  -- | Starting value
  Float ->
  -- | Ending value
  Float ->
  -- | Lerp amount
  Float ->
  Float
lerp :: Float -> Float -> Float -> Float
lerp Float
start Float
end Float
amount = Float
start Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
amount Float -> Float -> Float
forall a. Num a => a -> a -> a
* (Float
end Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
start)

-- | Normalize input value within input range
normalize ::
  -- | Starting value of range
  Float ->
  -- | Ending value of range
  Float ->
  -- | Value to normalize
  Float ->
  Float
normalize :: Float -> Float -> Float -> Float
normalize Float
start Float
end Float
value = (Float
value Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
start) Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/ (Float
end Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
start)

-- | Remap input value within input range to output range
remap ::
  -- | Input range start
  Float ->
  -- | Input range end
  Float ->
  -- | Output range start
  Float ->
  -- | Output range end
  Float ->
  -- | Input value
  Float ->
  Float
remap :: Float -> Float -> Float -> Float -> Float -> Float
remap Float
inputStart Float
inputEnd Float
outputStart Float
outputEnd Float
value = (Float
value Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
inputStart) Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/ (Float
inputEnd Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
inputStart) Float -> Float -> Float
forall a. Num a => a -> a -> a
* (Float
outputEnd Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
outputStart) Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
outputStart

-- | Wrap input value from min to max
wrap ::
  -- | Min value
  Float ->
  -- | Max value
  Float ->
  -- | Input value
  Float ->
  Float
wrap :: Float -> Float -> Float -> Float
wrap Float
low Float
high Float
value = Float
value Float -> Float -> Float
forall a. Num a => a -> a -> a
- (Float
high Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
low) Float -> Float -> Float
forall a. Num a => a -> a -> a
* Integer -> Float
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Float -> Integer
forall b. Integral b => Float -> b
forall a b. (RealFrac a, Integral b) => a -> b
floor ((Float
value Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
low) Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/ (Float
high Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
low)) :: Integer)

-- | Check if two floats are close to equal
floatEquals :: Float -> Float -> Bool
floatEquals :: Float -> Float -> Bool
floatEquals Float
x Float
y = Float -> Float
forall a. Num a => a -> a
abs (Float
x Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
y) Float -> Float -> Bool
forall a. Ord a => a -> a -> Bool
<= (Float
epsilon Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float -> Float -> Float
forall a. Ord a => a -> a -> a
max Float
1 (Float -> Float -> Float
forall a. Ord a => a -> a -> a
max (Float -> Float
forall a. Num a => a -> a
abs Float
x) (Float -> Float
forall a. Num a => a -> a
abs Float
y)))

------------------------------------------------
-- Vector math ---------------------------------
------------------------------------------------

class Vector a where
  -- | List representation of a vector
  asList :: a -> [Float]

  -- | Vector representation of a list
  fromList :: [Float] -> a

  -- | Left fold over a vector
  foldlV :: (b -> Float -> b) -> b -> a -> b

  -- | Right fold over a vector
  foldrV :: (Float -> b -> b) -> b -> a -> b

  -- | Map over a vector
  mapV :: (Float -> Float) -> a -> a

  -- | Equivalent of `zipWith` over a vector
  zipWithV :: (Float -> Float -> Float) -> a -> a -> a
  
  -- | Equivalent of `zipWith3` over a vector
  zipWithV3 :: (Float -> Float -> Float -> Float) -> a -> a -> a -> a

  -- | Vector-vector addition
  (|+|) :: a -> a -> a
  a
a |+| a
b = (Float -> Float -> Float) -> a -> a -> a
forall a. Vector a => (Float -> Float -> Float) -> a -> a -> a
zipWithV Float -> Float -> Float
forall a. Num a => a -> a -> a
(+) a
a a
b

  -- | Vector-vector subtraction
  (|-|) :: a -> a -> a
  a
a |-| a
b = (Float -> Float -> Float) -> a -> a -> a
forall a. Vector a => (Float -> Float -> Float) -> a -> a -> a
zipWithV (-) a
a a
b

  -- | Vector-scalar addition
  (|+) :: a -> Float -> a
  a
a |+ Float
b = (Float -> Float) -> a -> a
forall a. Vector a => (Float -> Float) -> a -> a
mapV (Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
b) a
a

  -- | Vector-scalar subtraction
  (|-) :: a -> Float -> a
  a
a |- Float
b = (Float -> Float) -> a -> a
forall a. Vector a => (Float -> Float) -> a -> a
mapV (\Float
x -> Float
x Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
b) a
a

  -- | Vector-vector multiplication
  (|*|) :: a -> a -> a
  a
a |*| a
b = (Float -> Float -> Float) -> a -> a -> a
forall a. Vector a => (Float -> Float -> Float) -> a -> a -> a
zipWithV Float -> Float -> Float
forall a. Num a => a -> a -> a
(*) a
a a
b

  -- | Vector-vector division
  (|/|) :: a -> a -> a
  a
a |/| a
b = (Float -> Float -> Float) -> a -> a -> a
forall a. Vector a => (Float -> Float -> Float) -> a -> a -> a
zipWithV Float -> Float -> Float
forall a. Fractional a => a -> a -> a
(/) a
a a
b

  -- | Vector-scalar multiplication
  (|*) :: a -> Float -> a
  a
a |* Float
b = (Float -> Float) -> a -> a
forall a. Vector a => (Float -> Float) -> a -> a
mapV (Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
b) a
a

  -- | Vector-scalar division
  (|/) :: a -> Float -> a
  a
a |/ Float
b = (Float -> Float) -> a -> a
forall a. Vector a => (Float -> Float) -> a -> a
mapV (Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/ Float
b) a
a

  -- | Vector-vector dot product
  (|.|) :: a -> a -> Float
  a
a |.| a
b = (Float -> Float -> Float) -> Float -> a -> Float
forall a b. Vector a => (b -> Float -> b) -> b -> a -> b
forall b. (b -> Float -> b) -> b -> a -> b
foldlV Float -> Float -> Float
forall a. Num a => a -> a -> a
(+) Float
0 (a
a a -> a -> a
forall a. Vector a => a -> a -> a
|*| a
b)

  -- | Zero vector
  zero :: a
  zero = Float -> a
forall a. Vector a => Float -> a
constant Float
0

  -- | One vector
  one :: a
  one = Float -> a
forall a. Vector a => Float -> a
constant Float
1

  -- | Scalar to vector (all elements are set to the scalar)
  constant :: Float -> a

  -- | Sum of all vectors in a structure
  vectorSum :: (Foldable t) => t a -> a
  vectorSum = (a -> a -> a) -> a -> t a -> a
forall b a. (b -> a -> b) -> b -> t a -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' a -> a -> a
forall a. Vector a => a -> a -> a
(|+|) a
forall a. Vector a => a
zero

  -- | Vector additive inverse
  additiveInverse :: a -> a
  additiveInverse a
v = (Float -> Float) -> a -> a
forall a. Vector a => (Float -> Float) -> a -> a
mapV Float -> Float
forall a. Num a => a -> a
negate a
v

  -- | Vector multiplicative inverse
  multiplicativeInverse :: a -> a
  multiplicativeInverse a
v = (Float -> Float) -> a -> a
forall a. Vector a => (Float -> Float) -> a -> a
mapV (Float
1 Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/) a
v

  -- | Squared magnitude of a vector
  magnitudeSqr :: a -> Float
  magnitudeSqr a
v = a
v a -> a -> Float
forall a. Vector a => a -> a -> Float
|.| a
v

  -- | Vector magnitude
  magnitude :: a -> Float
  magnitude a
v = if Float
m Float -> Float -> Bool
forall a. Eq a => a -> a -> Bool
== Float
1 then Float
m else Float -> Float
forall a. Floating a => a -> a
sqrt Float
m
    where
      m :: Float
m = a -> Float
forall a. Vector a => a -> Float
magnitudeSqr a
v

  -- | Squared distance between two vectors
  vectorDistanceSqr :: a -> a -> Float
  vectorDistanceSqr a
a a
b = a -> Float
forall a. Vector a => a -> Float
magnitudeSqr (a -> Float) -> a -> Float
forall a b. (a -> b) -> a -> b
$ a
a a -> a -> a
forall a. Vector a => a -> a -> a
|-| a
b

  -- | Distance between two vectors
  vectorDistance :: a -> a -> Float
  vectorDistance a
a a
b = if Float
v Float -> Float -> Bool
forall a. Eq a => a -> a -> Bool
== Float
1 then Float
v else Float -> Float
forall a. Floating a => a -> a
sqrt Float
v
    where
      v :: Float
v = a -> a -> Float
forall a. Vector a => a -> a -> Float
vectorDistanceSqr a
a a
b

  -- | Normalize vector (same direction, magnitude 1)
  vectorNormalize :: a -> a
  vectorNormalize a
v = a
v a -> Float -> a
forall a. Vector a => a -> Float -> a
|/ a -> Float
forall a. Vector a => a -> Float
magnitude a
v

  -- | Lerp between two vectors
  vectorLerp :: a -> a -> Float -> a
  vectorLerp a
a a
b Float
amount = (Float -> Float -> Float) -> a -> a -> a
forall a. Vector a => (Float -> Float -> Float) -> a -> a -> a
zipWithV (\Float
v1 Float
v2 -> Float -> Float -> Float -> Float
lerp Float
v1 Float
v2 Float
amount) a
a a
b

  -- | Move vector towards target
  vectorMoveTowards ::
    -- | Vector to move
    a ->
    -- | Target vector
    a ->
    -- | Max distance to move by
    Float ->
    a
  vectorMoveTowards a
v a
target Float
maxDistance =
    if Float
distSquared Float -> Float -> Bool
forall a. Ord a => a -> a -> Bool
<= Float
maxDistance Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
maxDistance
      then a
target
      else a
v a -> a -> a
forall a. Vector a => a -> a -> a
|+| (Float -> Float) -> a -> a
forall a. Vector a => (Float -> Float) -> a -> a
mapV (Float -> Float -> Float
forall a. Num a => a -> a -> a
* (Float
maxDistance Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/ Float
dist)) a
diff
    where
      diff :: a
diff = a
target a -> a -> a
forall a. Vector a => a -> a -> a
|-| a
v
      distSquared :: Float
distSquared = a -> Float
forall a. Vector a => a -> Float
magnitudeSqr a
diff
      dist :: Float
dist = Float -> Float
forall a. Floating a => a -> a
sqrt Float
distSquared

  -- | Clamp vector to range
  vectorClamp ::
    -- | Vector to clamp
    a ->
    -- | Lower bound
    a ->
    -- | Upper bound
    a ->
    a
  vectorClamp a
v a
low a
high = (Float -> Float -> Float -> Float) -> a -> a -> a -> a
forall a.
Vector a =>
(Float -> Float -> Float -> Float) -> a -> a -> a -> a
zipWithV3 Float -> Float -> Float -> Float
clamp a
v a
low a
high

  -- | Clamp the magnitude of a vector to a range
  vectorClampValue ::
    -- | Vector to clamp
    a ->
    -- | Lower bound
    Float ->
    -- | Upper bound
    Float ->
    a
  vectorClampValue a
v Float
low Float
high = a
v a -> Float -> a
forall a. Vector a => a -> Float -> a
|* (Float -> Float -> Float -> Float
clamp Float
size Float
low Float
high Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/ Float
size)
    where
      size :: Float
size = a -> Float
forall a. Vector a => a -> Float
magnitude a
v

  -- | Min value for each pair of components
  vectorMin :: a -> a -> a
  vectorMin a
v1 a
v2 = (Float -> Float -> Float) -> a -> a -> a
forall a. Vector a => (Float -> Float -> Float) -> a -> a -> a
zipWithV Float -> Float -> Float
forall a. Ord a => a -> a -> a
min a
v1 a
v2

  -- | Max value for each pair of components
  vectorMax :: a -> a -> a
  vectorMax a
v1 a
v2 = (Float -> Float -> Float) -> a -> a -> a
forall a. Vector a => (Float -> Float -> Float) -> a -> a -> a
zipWithV Float -> Float -> Float
forall a. Ord a => a -> a -> a
max a
v1 a
v2

instance Vector Vector2 where
  asList :: Vector2 -> [Float]
asList (Vector2 Float
x Float
y) = [Float
x, Float
y]
  fromList :: [Float] -> Vector2
fromList (Float
x : Float
y : [Float]
_) = Float -> Float -> Vector2
Vector2 Float
x Float
y
  fromList [Float]
_ = [Char] -> Vector2
forall a. HasCallStack => [Char] -> a
error [Char]
"(Vector2.fromList) Input list must have at least two elements!"
  foldlV :: forall b. (b -> Float -> b) -> b -> Vector2 -> b
foldlV b -> Float -> b
f b
val (Vector2 Float
x Float
y) = b -> Float -> b
f (b -> Float -> b
f b
val Float
x) Float
y
  foldrV :: forall b. (Float -> b -> b) -> b -> Vector2 -> b
foldrV Float -> b -> b
f b
val (Vector2 Float
x Float
y) = Float -> b -> b
f Float
x (Float -> b -> b
f Float
y b
val)
  mapV :: (Float -> Float) -> Vector2 -> Vector2
mapV Float -> Float
f (Vector2 Float
x Float
y) = Float -> Float -> Vector2
Vector2 (Float -> Float
f Float
x) (Float -> Float
f Float
y)
  zipWithV :: (Float -> Float -> Float) -> Vector2 -> Vector2 -> Vector2
zipWithV Float -> Float -> Float
f (Vector2 Float
x1 Float
y1) (Vector2 Float
x2 Float
y2) = Float -> Float -> Vector2
Vector2 (Float -> Float -> Float
f Float
x1 Float
x2) (Float -> Float -> Float
f Float
y1 Float
y2)
  zipWithV3 :: (Float -> Float -> Float -> Float)
-> Vector2 -> Vector2 -> Vector2 -> Vector2
zipWithV3 Float -> Float -> Float -> Float
f (Vector2 Float
x1 Float
y1) (Vector2 Float
x2 Float
y2) (Vector2 Float
x3 Float
y3) = Float -> Float -> Vector2
Vector2 (Float -> Float -> Float -> Float
f Float
x1 Float
x2 Float
x3) (Float -> Float -> Float -> Float
f Float
y1 Float
y2 Float
y3)
  constant :: Float -> Vector2
constant Float
x = Float -> Float -> Vector2
Vector2 Float
x Float
x

instance Vector Vector3 where
  asList :: Vector3 -> [Float]
asList (Vector3 Float
x Float
y Float
z) = [Float
x, Float
y, Float
z]
  fromList :: [Float] -> Vector3
fromList (Float
x : Float
y : Float
z : [Float]
_) = Float -> Float -> Float -> Vector3
Vector3 Float
x Float
y Float
z
  fromList [Float]
_ = [Char] -> Vector3
forall a. HasCallStack => [Char] -> a
error [Char]
"(Vector3.fromList) Input list must have at least three elements!"
  foldlV :: forall b. (b -> Float -> b) -> b -> Vector3 -> b
foldlV b -> Float -> b
f b
val (Vector3 Float
x Float
y Float
z) = b -> Float -> b
f (b -> Float -> b
f (b -> Float -> b
f b
val Float
x) Float
y) Float
z
  foldrV :: forall b. (Float -> b -> b) -> b -> Vector3 -> b
foldrV Float -> b -> b
f b
val (Vector3 Float
x Float
y Float
z) = Float -> b -> b
f Float
x (Float -> b -> b
f Float
y (Float -> b -> b
f Float
z b
val))
  mapV :: (Float -> Float) -> Vector3 -> Vector3
mapV Float -> Float
f (Vector3 Float
x Float
y Float
z) = Float -> Float -> Float -> Vector3
Vector3 (Float -> Float
f Float
x) (Float -> Float
f Float
y) (Float -> Float
f Float
z)
  zipWithV :: (Float -> Float -> Float) -> Vector3 -> Vector3 -> Vector3
zipWithV Float -> Float -> Float
f (Vector3 Float
x1 Float
y1 Float
z1) (Vector3 Float
x2 Float
y2 Float
z2) = Float -> Float -> Float -> Vector3
Vector3 (Float -> Float -> Float
f Float
x1 Float
x2) (Float -> Float -> Float
f Float
y1 Float
y2) (Float -> Float -> Float
f Float
z1 Float
z2)
  zipWithV3 :: (Float -> Float -> Float -> Float)
-> Vector3 -> Vector3 -> Vector3 -> Vector3
zipWithV3 Float -> Float -> Float -> Float
f (Vector3 Float
x1 Float
y1 Float
z1) (Vector3 Float
x2 Float
y2 Float
z2) (Vector3 Float
x3 Float
y3 Float
z3) = Float -> Float -> Float -> Vector3
Vector3 (Float -> Float -> Float -> Float
f Float
x1 Float
x2 Float
x3) (Float -> Float -> Float -> Float
f Float
y1 Float
y2 Float
y3) (Float -> Float -> Float -> Float
f Float
z1 Float
z2 Float
z3)
  constant :: Float -> Vector3
constant Float
x = Float -> Float -> Float -> Vector3
Vector3 Float
x Float
x Float
x

instance Vector Vector4 where
  asList :: Quaternion -> [Float]
asList (Vector4 Float
x Float
y Float
z Float
w) = [Float
x, Float
y, Float
z, Float
w]
  fromList :: [Float] -> Quaternion
fromList (Float
x : Float
y : Float
z : Float
w : [Float]
_) = Float -> Float -> Float -> Float -> Quaternion
Vector4 Float
x Float
y Float
z Float
w
  fromList [Float]
_ = [Char] -> Quaternion
forall a. HasCallStack => [Char] -> a
error [Char]
"(Vector4.fromList) Input list must have at least four elements!"
  foldlV :: forall b. (b -> Float -> b) -> b -> Quaternion -> b
foldlV b -> Float -> b
f b
val (Vector4 Float
x Float
y Float
z Float
w) = b -> Float -> b
f (b -> Float -> b
f (b -> Float -> b
f (b -> Float -> b
f b
val Float
x) Float
y) Float
z) Float
w
  foldrV :: forall b. (Float -> b -> b) -> b -> Quaternion -> b
foldrV Float -> b -> b
f b
val (Vector4 Float
x Float
y Float
z Float
w) = Float -> b -> b
f Float
x (Float -> b -> b
f Float
y (Float -> b -> b
f Float
z (Float -> b -> b
f Float
w b
val)))
  mapV :: (Float -> Float) -> Quaternion -> Quaternion
mapV Float -> Float
f (Vector4 Float
x Float
y Float
z Float
w) = Float -> Float -> Float -> Float -> Quaternion
Vector4 (Float -> Float
f Float
x) (Float -> Float
f Float
y) (Float -> Float
f Float
z) (Float -> Float
f Float
w)
  zipWithV :: (Float -> Float -> Float) -> Quaternion -> Quaternion -> Quaternion
zipWithV Float -> Float -> Float
f (Vector4 Float
x1 Float
y1 Float
z1 Float
w1) (Vector4 Float
x2 Float
y2 Float
z2 Float
w2) = Float -> Float -> Float -> Float -> Quaternion
Vector4 (Float -> Float -> Float
f Float
x1 Float
x2) (Float -> Float -> Float
f Float
y1 Float
y2) (Float -> Float -> Float
f Float
z1 Float
z2) (Float -> Float -> Float
f Float
w1 Float
w2)
  zipWithV3 :: (Float -> Float -> Float -> Float)
-> Quaternion -> Quaternion -> Quaternion -> Quaternion
zipWithV3 Float -> Float -> Float -> Float
f (Vector4 Float
x1 Float
y1 Float
z1 Float
w1) (Vector4 Float
x2 Float
y2 Float
z2 Float
w2) (Vector4 Float
x3 Float
y3 Float
z3 Float
w3) = Float -> Float -> Float -> Float -> Quaternion
Vector4 (Float -> Float -> Float -> Float
f Float
x1 Float
x2 Float
x3) (Float -> Float -> Float -> Float
f Float
y1 Float
y2 Float
y3) (Float -> Float -> Float -> Float
f Float
z1 Float
z2 Float
z3) (Float -> Float -> Float -> Float
f Float
w1 Float
w2 Float
w3)
  constant :: Float -> Quaternion
constant Float
x = Float -> Float -> Float -> Float -> Quaternion
Vector4 Float
x Float
x Float
x Float
x

------------------------------------------------
-- Vector2 math --------------------------------
------------------------------------------------

-- | Angle between two 2D vectors
vector2Angle :: Vector2 -> Vector2 -> Float
vector2Angle :: Vector2 -> Vector2 -> Float
vector2Angle (Vector2 Float
x1 Float
y1) (Vector2 Float
x2 Float
y2) = Float -> Float -> Float
forall a. RealFloat a => a -> a -> a
atan2 (Float
x1 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
x2 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
y1 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
y2) (Float
x1 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
y2 Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
y1 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
x2)

-- | Angle created by the line between two 2D vectors (parameters must be normalized)
vector2LineAngle :: Vector2 -> Vector2 -> Float
vector2LineAngle :: Vector2 -> Vector2 -> Float
vector2LineAngle (Vector2 Float
sx Float
sy) (Vector2 Float
ex Float
ey) = -Float -> Float -> Float
forall a. RealFloat a => a -> a -> a
atan2 (Float
ey Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
sy) (Float
ex Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
sx)

-- | Transform a 2D vector by the given matrix
vector2Transform :: Vector2 -> Matrix -> Vector2
vector2Transform :: Vector2 -> Matrix -> Vector2
vector2Transform (Vector2 Float
x Float
y) Matrix
mat = Float -> Float -> Vector2
Vector2 ((Float
x Float -> Float -> Float
forall a. Num a => a -> a -> a
* Matrix -> Float
matrix'm0 Matrix
mat) Float -> Float -> Float
forall a. Num a => a -> a -> a
+ (Float
y Float -> Float -> Float
forall a. Num a => a -> a -> a
* Matrix -> Float
matrix'm4 Matrix
mat) Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Matrix -> Float
matrix'm12 Matrix
mat) ((Float
x Float -> Float -> Float
forall a. Num a => a -> a -> a
* Matrix -> Float
matrix'm1 Matrix
mat) Float -> Float -> Float
forall a. Num a => a -> a -> a
+ (Float
y Float -> Float -> Float
forall a. Num a => a -> a -> a
* Matrix -> Float
matrix'm5 Matrix
mat) Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Matrix -> Float
matrix'm13 Matrix
mat)

-- | Reflect 2D vector to normal
vector2Reflect ::
  -- | Input vector
  Vector2 ->
  -- | Normal vector
  Vector2 ->
  Vector2
vector2Reflect :: Vector2 -> Vector2 -> Vector2
vector2Reflect Vector2
v Vector2
normal = Vector2
v Vector2 -> Vector2 -> Vector2
forall a. Vector a => a -> a -> a
|-| (Vector2
normal Vector2 -> Float -> Vector2
forall a. Vector a => a -> Float -> a
|* (Float
2 Float -> Float -> Float
forall a. Num a => a -> a -> a
* (Vector2
v Vector2 -> Vector2 -> Float
forall a. Vector a => a -> a -> Float
|.| Vector2
normal)))

-- | Rotate 2D vector by angle
vector2Rotate :: Vector2 -> Float -> Vector2
vector2Rotate :: Vector2 -> Float -> Vector2
vector2Rotate (Vector2 Float
x Float
y) Float
angle = Float -> Float -> Vector2
Vector2 (Float
x Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
c Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
y Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
s) (Float
x Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
s Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
y Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
c)
  where
    c :: Float
c = Float -> Float
forall a. Floating a => a -> a
cos Float
angle
    s :: Float
s = Float -> Float
forall a. Floating a => a -> a
sin Float
angle

-- | Compute the direction of a refracted ray
vector2Refract ::
  -- | Normalized direction of the incoming ray
  Vector2 ->
  -- | Normalized normal vector of the interface of two optical media
  Vector2 ->
  -- | Ratio of the refractive index of the medium from where the ray comes
  --    to the refractive index of the medium on the other side of the surface
  Float ->
  Vector2
vector2Refract :: Vector2 -> Vector2 -> Float -> Vector2
vector2Refract (Vector2 Float
vx Float
vy) (Vector2 Float
nx Float
ny) Float
r = if Float
d Float -> Float -> Bool
forall a. Ord a => a -> a -> Bool
>= Float
0 then Float -> Float -> Vector2
Vector2 (Float
r Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
vx Float -> Float -> Float
forall a. Num a => a -> a -> a
- (Float
r Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
dot Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
d') Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
nx) (Float
r Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
vy Float -> Float -> Float
forall a. Num a => a -> a -> a
- (Float
r Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
dot Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
d') Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
ny) else Float -> Float -> Vector2
Vector2 Float
0 Float
0
  where
    dot :: Float
dot = Float
vx Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
nx Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
vy Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
ny
    d :: Float
d = Float
1 Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
r Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
r Float -> Float -> Float
forall a. Num a => a -> a -> a
* (Float
1 Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
dot Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
dot)
    d' :: Float
d' = Float -> Float
forall a. Floating a => a -> a
sqrt Float
d

------------------------------------------------
-- Vector3 math --------------------------------
------------------------------------------------

-- | 3D vector cross-product
vector3CrossProduct :: Vector3 -> Vector3 -> Vector3
vector3CrossProduct :: Vector3 -> Vector3 -> Vector3
vector3CrossProduct (Vector3 Float
x1 Float
y1 Float
z1) (Vector3 Float
x2 Float
y2 Float
z2) = Float -> Float -> Float -> Vector3
Vector3 (Float
y1 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
z2 Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
z1 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
y2) (Float
z1 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
x2 Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
x1 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
z2) (Float
x1 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
y2 Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
y1 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
x2)

-- | Perpendicular to given 3D vector
vector3Perpendicular :: Vector3 -> Vector3
vector3Perpendicular :: Vector3 -> Vector3
vector3Perpendicular v :: Vector3
v@(Vector3 Float
x Float
y Float
z) = Vector3 -> Vector3 -> Vector3
vector3CrossProduct Vector3
v Vector3
cardinalAxis
  where
    cardinalAxis :: Vector3
cardinalAxis
      | Float -> Float
forall a. Num a => a -> a
abs Float
y Float -> Float -> Bool
forall a. Ord a => a -> a -> Bool
< Float -> Float
forall a. Num a => a -> a
abs Float
x = Float -> Float -> Float -> Vector3
Vector3 Float
0 Float
1 Float
0
      | Float -> Float
forall a. Num a => a -> a
abs Float
z Float -> Float -> Bool
forall a. Ord a => a -> a -> Bool
< Float -> Float
forall a. Num a => a -> a
abs Float
x = Float -> Float -> Float -> Vector3
Vector3 Float
0 Float
0 Float
1
      | Bool
otherwise = Float -> Float -> Float -> Vector3
Vector3 Float
1 Float
0 Float
0

-- | Angle between two 3D vectors
vector3Angle :: Vector3 -> Vector3 -> Float
vector3Angle :: Vector3 -> Vector3 -> Float
vector3Angle Vector3
v1 Vector3
v2 = Float -> Float -> Float
forall a. RealFloat a => a -> a -> a
atan2 Float
len Float
dot
  where
    cross :: Vector3
cross = Vector3 -> Vector3 -> Vector3
vector3CrossProduct Vector3
v1 Vector3
v2
    len :: Float
len = Vector3 -> Float
forall a. Vector a => a -> Float
magnitude Vector3
cross
    dot :: Float
dot = Vector3
v1 Vector3 -> Vector3 -> Float
forall a. Vector a => a -> a -> Float
|.| Vector3
v2

-- | Orthonormalize provided vectors.
--   Makes vectors normalized and orthogonal to each other.
--   Gram-Schmidt function implementation.
vector3OrthoNormalize :: Vector3 -> Vector3 -> (Vector3, Vector3)
vector3OrthoNormalize :: Vector3 -> Vector3 -> (Vector3, Vector3)
vector3OrthoNormalize Vector3
v1 Vector3
v2 = (Vector3
v1', Vector3
v2')
  where
    v1' :: Vector3
v1' = Vector3 -> Vector3
forall a. Vector a => a -> a
vectorNormalize Vector3
v1
    v2' :: Vector3
v2' = Vector3 -> Vector3 -> Vector3
vector3CrossProduct Vector3
vn1 Vector3
v1'
    vn1 :: Vector3
vn1 = Vector3 -> Vector3
forall a. Vector a => a -> a
vectorNormalize (Vector3 -> Vector3) -> Vector3 -> Vector3
forall a b. (a -> b) -> a -> b
$ Vector3 -> Vector3 -> Vector3
vector3CrossProduct Vector3
v1' Vector3
v2

-- | Transform a 3D vector by a matrix
vector3Transform :: Vector3 -> Matrix -> Vector3
vector3Transform :: Vector3 -> Matrix -> Vector3
vector3Transform
  (Vector3 Float
x Float
y Float
z)
  (Matrix Float
m0 Float
m4 Float
m8 Float
m12 Float
m1 Float
m5 Float
m9 Float
m13 Float
m2 Float
m6 Float
m10 Float
m14 Float
_ Float
_ Float
_ Float
_) =
    Float -> Float -> Float -> Vector3
Vector3
      (Float
x Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
m0 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
y Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
m4 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
z Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
m8 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
m12)
      (Float
x Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
m1 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
y Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
m5 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
z Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
m9 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
m13)
      (Float
x Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
m2 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
y Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
m6 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
z Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
m10 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
m14)

-- | Transform a 3D vector by quaternion rotation
vector3RotateByQuaternion :: Vector3 -> Quaternion -> Vector3
vector3RotateByQuaternion :: Vector3 -> Quaternion -> Vector3
vector3RotateByQuaternion (Vector3 Float
a Float
b Float
c) (Vector4 Float
x Float
y Float
z Float
w) =
  Float -> Float -> Float -> Vector3
Vector3
    (Float
a Float -> Float -> Float
forall a. Num a => a -> a -> a
* (Float
x Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
x Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
w Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
w Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
y Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
y Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
z Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
z) Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
b Float -> Float -> Float
forall a. Num a => a -> a -> a
* (Float
2 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
x Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
y Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
2 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
w Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
z) Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
c Float -> Float -> Float
forall a. Num a => a -> a -> a
* (Float
2 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
x Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
z Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
2 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
w Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
y))
    (Float
a Float -> Float -> Float
forall a. Num a => a -> a -> a
* (Float
2 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
w Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
z Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
2 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
x Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
y) Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
b Float -> Float -> Float
forall a. Num a => a -> a -> a
* (Float
w Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
w Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
x Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
x Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
y Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
y Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
z Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
z) Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
c Float -> Float -> Float
forall a. Num a => a -> a -> a
* ((-Float
2) Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
w Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
x Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
2 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
y Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
z))
    (Float
a Float -> Float -> Float
forall a. Num a => a -> a -> a
* ((-Float
2) Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
w Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
y Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
2 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
x Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
z) Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
b Float -> Float -> Float
forall a. Num a => a -> a -> a
* (Float
2 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
w Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
x Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
2 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
y Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
z) Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
c Float -> Float -> Float
forall a. Num a => a -> a -> a
* (Float
w Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
w Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
x Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
x Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
y Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
y Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
z Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
z))

-- | Rotate a 3D vector around an axis
vector3RotateByAxisAngle ::
  -- | Vector to rotate
  Vector3 ->
  -- | Axis to rotate around
  Vector3 ->
  -- | Angle to rotate by
  Float ->
  Vector3
vector3RotateByAxisAngle :: Vector3 -> Vector3 -> Float -> Vector3
vector3RotateByAxisAngle Vector3
v Vector3
axis Float
angle = Vector3
v Vector3 -> Vector3 -> Vector3
forall a. Vector a => a -> a -> a
|+| (Vector3
wv Vector3 -> Float -> Vector3
forall a. Vector a => a -> Float -> a
|* (Float
2 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
a)) Vector3 -> Vector3 -> Vector3
forall a. Vector a => a -> a -> a
|+| (Vector3
wwv Vector3 -> Float -> Vector3
forall a. Vector a => a -> Float -> a
|* Float
2)
  where
    (Vector3 Float
ax Float
ay Float
az) = Vector3 -> Vector3
forall a. Vector a => a -> a
vectorNormalize Vector3
axis
    s :: Float
s = Float -> Float
forall a. Floating a => a -> a
sin (Float
angle Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/ Float
2)
    a :: Float
a = Float -> Float
forall a. Floating a => a -> a
cos (Float
angle Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/ Float
2)
    b :: Float
b = Float
ax Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
s
    c :: Float
c = Float
ay Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
s
    d :: Float
d = Float
az Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
s
    w :: Vector3
w = Float -> Float -> Float -> Vector3
Vector3 Float
b Float
c Float
d
    wv :: Vector3
wv = Vector3 -> Vector3 -> Vector3
vector3CrossProduct Vector3
w Vector3
v
    wwv :: Vector3
wwv = Vector3 -> Vector3 -> Vector3
vector3CrossProduct Vector3
w Vector3
wv

-- | Reflect 3D vector to normal
vector3Reflect ::
  -- | Input vector
  Vector3 ->
  -- | Normal vector
  Vector3 ->
  Vector3
vector3Reflect :: Vector3 -> Vector3 -> Vector3
vector3Reflect Vector3
v Vector3
normal = Vector3
v Vector3 -> Vector3 -> Vector3
forall a. Vector a => a -> a -> a
|-| (Vector3
normal Vector3 -> Float -> Vector3
forall a. Vector a => a -> Float -> a
|* (Float
2 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Vector3
v Vector3 -> Vector3 -> Float
forall a. Vector a => a -> a -> Float
|.| Vector3
normal))

-- | Compute barycenter coordinates (u, v, w) for a point with respect to a triangle.
--   NOTE: Assumes the point is on the plane of the triangle.
vector3Barycenter ::
  -- | Input point
  Vector3 ->
  -- | Triangle vertices
  (Vector3, Vector3, Vector3) ->
  Vector3
vector3Barycenter :: Vector3 -> (Vector3, Vector3, Vector3) -> Vector3
vector3Barycenter Vector3
p (Vector3
a, Vector3
b, Vector3
c) = Float -> Float -> Float -> Vector3
Vector3 (Float
1 Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
y Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
z) Float
y Float
z
  where
    v0 :: Vector3
v0 = Vector3
b Vector3 -> Vector3 -> Vector3
forall a. Vector a => a -> a -> a
|-| Vector3
a
    v1 :: Vector3
v1 = Vector3
c Vector3 -> Vector3 -> Vector3
forall a. Vector a => a -> a -> a
|-| Vector3
a
    v2 :: Vector3
v2 = Vector3
p Vector3 -> Vector3 -> Vector3
forall a. Vector a => a -> a -> a
|-| Vector3
a
    d00 :: Float
d00 = Vector3
v0 Vector3 -> Vector3 -> Float
forall a. Vector a => a -> a -> Float
|.| Vector3
v0
    d01 :: Float
d01 = Vector3
v0 Vector3 -> Vector3 -> Float
forall a. Vector a => a -> a -> Float
|.| Vector3
v1
    d11 :: Float
d11 = Vector3
v1 Vector3 -> Vector3 -> Float
forall a. Vector a => a -> a -> Float
|.| Vector3
v1
    d20 :: Float
d20 = Vector3
v2 Vector3 -> Vector3 -> Float
forall a. Vector a => a -> a -> Float
|.| Vector3
v0
    d21 :: Float
d21 = Vector3
v2 Vector3 -> Vector3 -> Float
forall a. Vector a => a -> a -> Float
|.| Vector3
v1
    denom :: Float
denom = Float
d00 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
d11 Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
d01 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
d01
    y :: Float
y = (Float
d11 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
d20 Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
d01 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
d21) Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/ Float
denom
    z :: Float
z = (Float
d00 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
d21 Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
d01 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
d20) Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/ Float
denom

-- | Project a Vector3 from screen space into object space
vector3Unproject ::
  -- | Vector to unproject
  Vector3 ->
  -- | Projection matrix
  Matrix ->
  -- | View matrix
  Matrix ->
  Vector3
vector3Unproject :: Vector3 -> Matrix -> Matrix -> Vector3
vector3Unproject (Vector3 Float
x Float
y Float
z) Matrix
projection Matrix
view = Float -> Float -> Float -> Vector3
Vector3 (Float
rx Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/ Float
rw) (Float
ry Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/ Float
rw) (Float
rz Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/ Float
rw)
  where
    matViewProj :: Matrix
matViewProj = Matrix
view Matrix -> Matrix -> Matrix
/*/ Matrix
projection
    a00 :: Float
a00 = Matrix -> Float
matrix'm0 Matrix
matViewProj
    a01 :: Float
a01 = Matrix -> Float
matrix'm1 Matrix
matViewProj
    a02 :: Float
a02 = Matrix -> Float
matrix'm2 Matrix
matViewProj
    a03 :: Float
a03 = Matrix -> Float
matrix'm3 Matrix
matViewProj
    a10 :: Float
a10 = Matrix -> Float
matrix'm4 Matrix
matViewProj
    a11 :: Float
a11 = Matrix -> Float
matrix'm5 Matrix
matViewProj
    a12 :: Float
a12 = Matrix -> Float
matrix'm6 Matrix
matViewProj
    a13 :: Float
a13 = Matrix -> Float
matrix'm7 Matrix
matViewProj
    a20 :: Float
a20 = Matrix -> Float
matrix'm8 Matrix
matViewProj
    a21 :: Float
a21 = Matrix -> Float
matrix'm9 Matrix
matViewProj
    a22 :: Float
a22 = Matrix -> Float
matrix'm10 Matrix
matViewProj
    a23 :: Float
a23 = Matrix -> Float
matrix'm11 Matrix
matViewProj
    a30 :: Float
a30 = Matrix -> Float
matrix'm12 Matrix
matViewProj
    a31 :: Float
a31 = Matrix -> Float
matrix'm13 Matrix
matViewProj
    a32 :: Float
a32 = Matrix -> Float
matrix'm14 Matrix
matViewProj
    a33 :: Float
a33 = Matrix -> Float
matrix'm15 Matrix
matViewProj
    b00 :: Float
b00 = Float
a00 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
a11 Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
a01 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
a10
    b01 :: Float
b01 = Float
a00 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
a12 Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
a02 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
a10
    b02 :: Float
b02 = Float
a00 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
a13 Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
a03 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
a10
    b03 :: Float
b03 = Float
a01 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
a12 Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
a02 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
a11
    b04 :: Float
b04 = Float
a01 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
a13 Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
a03 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
a11
    b05 :: Float
b05 = Float
a02 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
a13 Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
a03 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
a12
    b06 :: Float
b06 = Float
a20 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
a31 Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
a21 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
a30
    b07 :: Float
b07 = Float
a20 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
a32 Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
a22 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
a30
    b08 :: Float
b08 = Float
a20 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
a33 Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
a23 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
a30
    b09 :: Float
b09 = Float
a21 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
a32 Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
a22 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
a31
    b10 :: Float
b10 = Float
a21 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
a33 Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
a23 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
a31
    b11 :: Float
b11 = Float
a22 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
a33 Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
a23 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
a32
    invDet :: Float
invDet = Float
1 Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/ (Float
b00 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
b11 Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
b01 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
b10 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
b02 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
b09 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
b03 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
b08 Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
b04 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
b07 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
b05 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
b06)
    matViewProjInv :: Matrix
matViewProjInv =
      Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Matrix
Matrix
        ((Float
a11 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
b11 Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
a12 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
b10 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
a13 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
b09) Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
invDet)
        ((-Float
a01 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
b11 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
a02 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
b10 Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
a03 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
b09) Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
invDet)
        ((Float
a31 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
b05 Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
a32 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
b04 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
a33 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
b03) Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
invDet)
        ((-Float
a21 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
b05 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
a22 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
b04 Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
a23 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
b03) Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
invDet)
        ((-Float
a10 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
b11 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
a12 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
b08 Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
a13 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
b07) Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
invDet)
        ((Float
a00 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
b11 Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
a02 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
b08 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
a03 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
b07) Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
invDet)
        ((-Float
a30 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
b05 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
a32 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
b02 Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
a33 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
b01) Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
invDet)
        ((Float
a20 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
b05 Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
a22 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
b02 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
a23 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
b01) Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
invDet)
        ((Float
a10 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
b10 Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
a11 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
b08 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
a13 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
b06) Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
invDet)
        ((-Float
a00 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
b10 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
a01 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
b08 Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
a03 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
b06) Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
invDet)
        ((Float
a30 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
b04 Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
a31 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
b02 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
a33 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
b00) Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
invDet)
        ((-Float
a20 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
b04 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
a21 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
b02 Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
a23 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
b00) Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
invDet)
        ((-Float
a10 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
b09 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
a11 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
b07 Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
a12 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
b06) Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
invDet)
        ((Float
a00 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
b09 Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
a01 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
b07 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
a02 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
b06) Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
invDet)
        ((-Float
a30 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
b03 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
a31 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
b01 Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
a32 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
b00) Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
invDet)
        ((Float
a20 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
b03 Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
a21 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
b01 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
a22 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
b00) Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
invDet)
    (Vector4 Float
rx Float
ry Float
rz Float
rw) = Quaternion -> Matrix -> Quaternion
quaternionTransform (Float -> Float -> Float -> Float -> Quaternion
Vector4 Float
x Float
y Float
z Float
1) Matrix
matViewProjInv

-- | Compute the direction of a refracted ray
vector3Refract ::
  -- | Normalized direction of the incoming ray
  Vector3 ->
  -- | Normalized normal vector of the interface of two optical media
  Vector3 ->
  -- | Ratio of the refractive index of the medium from where the ray
  --   comes to the refractive index of the medium on the other side of
  --   the surface
  Float ->
  Vector3
vector3Refract :: Vector3 -> Vector3 -> Float -> Vector3
vector3Refract (Vector3 Float
x Float
y Float
z) (Vector3 Float
nx Float
ny Float
nz) Float
r = Float -> Float -> Float -> Vector3
Vector3 (Float
r Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
x Float -> Float -> Float
forall a. Num a => a -> a -> a
- (Float
r Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
dot Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
d) Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
nx) (Float
r Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
y Float -> Float -> Float
forall a. Num a => a -> a -> a
- (Float
r Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
dot Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
d) Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
ny) (Float
r Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
z Float -> Float -> Float
forall a. Num a => a -> a -> a
- (Float
r Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
dot Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
d) Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
nz)
  where
    dot :: Float
dot = Float
x Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
nx Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
y Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
ny Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
z Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
nz
    d :: Float
d = Float -> Float
forall a. Floating a => a -> a
sqrt (Float -> Float) -> Float -> Float
forall a b. (a -> b) -> a -> b
$ Float
1 Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
r Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
r Float -> Float -> Float
forall a. Num a => a -> a -> a
* (Float
1 Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
dot Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
dot)

------------------------------------------------
-- Matrix math ---------------------------------
------------------------------------------------

-- | Utility function
matrixToList :: Matrix -> [Float]
matrixToList :: Matrix -> [Float]
matrixToList
  (Matrix 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) =
    [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]

-- | Utility function
matrixFromList :: [Float] -> Matrix
matrixFromList :: [Float] -> Matrix
matrixFromList
  (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 : [Float]
_) =
    Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Matrix
Matrix 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
matrixFromList [Float]
_ = [Char] -> Matrix
forall a. HasCallStack => [Char] -> a
error [Char]
"(matrixFromList) Expected a list of at least 16 elements!"

-- | Scalar to matrix (all elements are set to the scalar)
matrixConstant :: Float -> Matrix
matrixConstant :: Float -> Matrix
matrixConstant Float
n = [Float] -> Matrix
matrixFromList ([Float] -> Matrix) -> [Float] -> Matrix
forall a b. (a -> b) -> a -> b
$ Float -> [Float]
forall a. a -> [a]
repeat Float
n

-- | Compute matrix determinant
matrixDeterminant :: Matrix -> Float
matrixDeterminant :: Matrix -> Float
matrixDeterminant
  (Matrix 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) =
    Float
a30 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
a21 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
a12 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
a03
      Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
a20 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
a31 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
a12 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
a03
      Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
a30 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
a11 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
a22 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
a03
      Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
a10 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
a31 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
a22 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
a03
      Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
a20 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
a11 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
a32 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
a03
      Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
a10 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
a21 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
a32 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
a03
      Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
a30 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
a21 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
a02 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
a13
      Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
a20 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
a31 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
a02 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
a13
      Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
a30 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
a01 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
a22 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
a13
      Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
a00 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
a31 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
a22 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
a13
      Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
a20 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
a01 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
a32 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
a13
      Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
a00 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
a21 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
a32 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
a13
      Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
a30 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
a11 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
a02 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
a23
      Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
a10 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
a31 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
a02 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
a23
      Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
a30 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
a01 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
a12 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
a23
      Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
a00 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
a31 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
a12 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
a23
      Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
a10 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
a01 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
a32 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
a23
      Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
a00 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
a11 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
a32 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
a23
      Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
a20 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
a11 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
a02 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
a33
      Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
a10 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
a21 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
a02 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
a33
      Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
a20 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
a01 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
a12 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
a33
      Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
a00 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
a21 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
a12 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
a33
      Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
a10 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
a01 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
a22 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
a33
      Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
a00 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
a11 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
a22 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
a33

-- | Trace of a matrix (sum of the values along the diagonal)
matrixTrace :: Matrix -> Float
matrixTrace :: Matrix -> Float
matrixTrace Matrix
mat = Matrix -> Float
matrix'm0 Matrix
mat Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Matrix -> Float
matrix'm5 Matrix
mat Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Matrix -> Float
matrix'm10 Matrix
mat Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Matrix -> Float
matrix'm15 Matrix
mat

-- | Transpose a matrix
matrixTranspose :: Matrix -> Matrix
matrixTranspose :: Matrix -> Matrix
matrixTranspose
  (Matrix Float
m0 Float
m4 Float
m8 Float
m12 Float
m1 Float
m5 Float
m9 Float
m13 Float
m2 Float
m6 Float
m10 Float
m14 Float
m3 Float
m7 Float
m11 Float
m15) =
    Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Matrix
Matrix Float
m0 Float
m1 Float
m2 Float
m3 Float
m4 Float
m5 Float
m6 Float
m7 Float
m8 Float
m9 Float
m10 Float
m11 Float
m12 Float
m13 Float
m14 Float
m15

-- | Invert a matrix
matrixInvert :: Matrix -> Matrix
matrixInvert :: Matrix -> Matrix
matrixInvert
  (Matrix 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) =
    Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Matrix
Matrix
      ((Float
a11 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
b11 Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
a12 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
b10 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
a13 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
b09) Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
invDet)
      ((-Float
a10 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
b11 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
a12 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
b08 Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
a13 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
b07) Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
invDet)
      ((Float
a10 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
b10 Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
a11 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
b08 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
a13 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
b06) Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
invDet)
      ((-Float
a10 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
b09 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
a11 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
b07 Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
a12 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
b06) Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
invDet)
      ((-Float
a01 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
b11 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
a02 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
b10 Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
a03 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
b09) Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
invDet)
      ((Float
a00 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
b11 Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
a02 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
b08 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
a03 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
b07) Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
invDet)
      ((-Float
a00 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
b10 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
a01 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
b08 Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
a03 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
b06) Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
invDet)
      ((Float
a00 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
b09 Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
a01 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
b07 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
a02 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
b06) Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
invDet)
      ((Float
a31 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
b05 Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
a32 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
b04 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
a33 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
b03) Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
invDet)
      ((-Float
a30 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
b05 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
a32 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
b02 Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
a33 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
b01) Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
invDet)
      ((Float
a30 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
b04 Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
a31 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
b02 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
a33 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
b00) Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
invDet)
      ((-Float
a30 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
b03 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
a31 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
b01 Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
a32 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
b00) Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
invDet)
      ((-Float
a21 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
b05 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
a22 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
b04 Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
a23 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
b03) Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
invDet)
      ((Float
a20 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
b05 Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
a22 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
b02 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
a23 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
b01) Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
invDet)
      ((-Float
a20 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
b04 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
a21 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
b02 Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
a23 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
b00) Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
invDet)
      ((Float
a20 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
b03 Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
a21 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
b01 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
a22 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
b00) Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
invDet)
    where
      b00 :: Float
b00 = Float
a00 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
a11 Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
a01 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
a10
      b01 :: Float
b01 = Float
a00 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
a12 Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
a02 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
a10
      b02 :: Float
b02 = Float
a00 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
a13 Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
a03 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
a10
      b03 :: Float
b03 = Float
a01 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
a12 Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
a02 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
a11
      b04 :: Float
b04 = Float
a01 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
a13 Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
a03 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
a11
      b05 :: Float
b05 = Float
a02 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
a13 Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
a03 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
a12
      b06 :: Float
b06 = Float
a20 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
a31 Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
a21 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
a30
      b07 :: Float
b07 = Float
a20 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
a32 Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
a22 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
a30
      b08 :: Float
b08 = Float
a20 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
a33 Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
a23 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
a30
      b09 :: Float
b09 = Float
a21 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
a32 Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
a22 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
a31
      b10 :: Float
b10 = Float
a21 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
a33 Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
a23 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
a31
      b11 :: Float
b11 = Float
a22 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
a33 Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
a23 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
a32
      invDet :: Float
invDet = Float
1 Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/ (Float
b00 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
b11 Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
b01 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
b10 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
b02 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
b09 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
b03 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
b08 Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
b04 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
b07 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
b05 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
b06)

-- | Identity matrix
matrixIdentity :: Matrix
matrixIdentity :: Matrix
matrixIdentity = Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Matrix
Matrix 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

-- | Add two matrices
matrixAdd :: Matrix -> Matrix -> Matrix
matrixAdd :: Matrix -> Matrix -> Matrix
matrixAdd Matrix
left Matrix
right = [Float] -> Matrix
matrixFromList ([Float] -> Matrix) -> [Float] -> Matrix
forall a b. (a -> b) -> a -> b
$ (Float -> Float -> Float) -> [Float] -> [Float] -> [Float]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith Float -> Float -> Float
forall a. Num a => a -> a -> a
(+) (Matrix -> [Float]
matrixToList Matrix
left) (Matrix -> [Float]
matrixToList Matrix
right)

-- | Alias for 'matrixAdd'
(/+/) :: Matrix -> Matrix -> Matrix
/+/ :: Matrix -> Matrix -> Matrix
(/+/) = Matrix -> Matrix -> Matrix
matrixAdd

-- | Subtract two matrices
matrixSubtract :: Matrix -> Matrix -> Matrix
matrixSubtract :: Matrix -> Matrix -> Matrix
matrixSubtract Matrix
left Matrix
right = [Float] -> Matrix
matrixFromList ([Float] -> Matrix) -> [Float] -> Matrix
forall a b. (a -> b) -> a -> b
$ (Float -> Float -> Float) -> [Float] -> [Float] -> [Float]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith (-) (Matrix -> [Float]
matrixToList Matrix
left) (Matrix -> [Float]
matrixToList Matrix
right)

-- | Alias for 'matrixSubtract'
(/-/) :: Matrix -> Matrix -> Matrix
/-/ :: Matrix -> Matrix -> Matrix
(/-/) = Matrix -> Matrix -> Matrix
matrixSubtract

-- | Multiply two matrices (order matters!)
matrixMultiply :: Matrix -> Matrix -> Matrix
matrixMultiply :: Matrix -> Matrix -> Matrix
matrixMultiply
  (Matrix Float
l0 Float
l4 Float
l8 Float
l12 Float
l1 Float
l5 Float
l9 Float
l13 Float
l2 Float
l6 Float
l10 Float
l14 Float
l3 Float
l7 Float
l11 Float
l15)
  (Matrix Float
r0 Float
r4 Float
r8 Float
r12 Float
r1 Float
r5 Float
r9 Float
r13 Float
r2 Float
r6 Float
r10 Float
r14 Float
r3 Float
r7 Float
r11 Float
r15) =
    Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Matrix
Matrix
      (Float
l0 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
r0 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
l1 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
r4 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
l2 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
r8 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
l3 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
r12)
      (Float
l4 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
r0 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
l5 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
r4 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
l6 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
r8 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
l7 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
r12)
      (Float
l8 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
r0 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
l9 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
r4 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
l10 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
r8 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
l11 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
r12)
      (Float
l12 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
r0 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
l13 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
r4 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
l14 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
r8 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
l15 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
r12)
      (Float
l0 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
r1 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
l1 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
r5 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
l2 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
r9 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
l3 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
r13)
      (Float
l4 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
r1 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
l5 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
r5 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
l6 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
r9 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
l7 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
r13)
      (Float
l8 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
r1 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
l9 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
r5 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
l10 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
r9 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
l11 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
r13)
      (Float
l12 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
r1 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
l13 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
r5 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
l14 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
r9 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
l15 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
r13)
      (Float
l0 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
r2 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
l1 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
r6 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
l2 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
r10 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
l3 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
r14)
      (Float
l4 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
r2 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
l5 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
r6 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
l6 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
r10 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
l7 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
r14)
      (Float
l8 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
r2 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
l9 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
r6 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
l10 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
r10 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
l11 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
r14)
      (Float
l12 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
r2 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
l13 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
r6 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
l14 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
r10 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
l15 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
r14)
      (Float
l0 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
r3 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
l1 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
r7 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
l2 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
r11 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
l3 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
r15)
      (Float
l4 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
r3 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
l5 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
r7 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
l6 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
r11 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
l7 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
r15)
      (Float
l8 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
r3 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
l9 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
r7 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
l10 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
r11 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
l11 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
r15)
      (Float
l12 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
r3 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
l13 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
r7 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
l14 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
r11 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
l15 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
r15)

-- | Alias for 'matrixMultiply'
(/*/) :: Matrix -> Matrix -> Matrix
/*/ :: Matrix -> Matrix -> Matrix
(/*/) = Matrix -> Matrix -> Matrix
matrixMultiply

-- | Translation matrix
matrixTranslate ::
  -- | x translation
  Float ->
  -- | y translation
  Float ->
  -- | z translation
  Float ->
  Matrix
matrixTranslate :: Float -> Float -> Float -> Matrix
matrixTranslate Float
x Float
y Float
z = Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Matrix
Matrix Float
1 Float
0 Float
0 Float
x Float
0 Float
1 Float
0 Float
y Float
0 Float
0 Float
1 Float
z Float
0 Float
0 Float
0 Float
1

-- | Axis-angle rotation matrix (angle should be in radians)
matrixRotate ::
  -- | Axis to rotate around
  Vector3 ->
  -- | Angle to rotate by
  Float ->
  Matrix
matrixRotate :: Vector3 -> Float -> Matrix
matrixRotate Vector3
axis Float
angle = Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Matrix
Matrix (Float
x Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
x Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
t Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
c) (Float
x Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
y Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
t Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
z Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
s) (Float
x Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
z Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
t Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
y Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
s) Float
0 (Float
y Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
x Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
t Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
z Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
s) (Float
y Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
y Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
t Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
c) (Float
y Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
z Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
t Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
x Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
s) Float
0 (Float
z Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
x Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
t Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
y Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
s) (Float
z Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
y Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
t Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
x Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
s) (Float
z Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
z Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
t Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
c) Float
0 Float
0 Float
0 Float
0 Float
1
  where
    (Vector3 Float
x Float
y Float
z) = Vector3 -> Vector3
forall a. Vector a => a -> a
vectorNormalize Vector3
axis
    s :: Float
s = Float -> Float
forall a. Floating a => a -> a
sin Float
angle
    c :: Float
c = Float -> Float
forall a. Floating a => a -> a
cos Float
angle
    t :: Float
t = Float
1 Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
c

-- | x-rotation matrix (angle should be in radians)
matrixRotateX :: Float -> Matrix
matrixRotateX :: Float -> Matrix
matrixRotateX Float
angle = Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Matrix
Matrix Float
1 Float
0 Float
0 Float
0 Float
0 Float
c (-Float
s) Float
0 Float
0 Float
s Float
c Float
0 Float
0 Float
0 Float
0 Float
1
  where
    s :: Float
s = Float -> Float
forall a. Floating a => a -> a
sin Float
angle
    c :: Float
c = Float -> Float
forall a. Floating a => a -> a
cos Float
angle

-- | y-rotation matrix (angle should be in radians)
matrixRotateY :: Float -> Matrix
matrixRotateY :: Float -> Matrix
matrixRotateY Float
angle = Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Matrix
Matrix Float
c Float
0 Float
s Float
0 Float
0 Float
1 Float
0 Float
0 (-Float
s) Float
0 Float
c Float
0 Float
0 Float
0 Float
0 Float
1
  where
    s :: Float
s = Float -> Float
forall a. Floating a => a -> a
sin Float
angle
    c :: Float
c = Float -> Float
forall a. Floating a => a -> a
cos Float
angle

-- | z-rotation matrix (angle should be in radians)
matrixRotateZ :: Float -> Matrix
matrixRotateZ :: Float -> Matrix
matrixRotateZ Float
angle = Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Matrix
Matrix Float
c (-Float
s) Float
0 Float
0 Float
s Float
c Float
0 Float
0 Float
0 Float
0 Float
1 Float
0 Float
0 Float
0 Float
0 Float
1
  where
    s :: Float
s = Float -> Float
forall a. Floating a => a -> a
sin Float
angle
    c :: Float
c = Float -> Float
forall a. Floating a => a -> a
cos Float
angle

-- | Euler angle xyz rotation matrix (angles should be in radians)
matrixRotateXYZ :: Vector3 -> Matrix
matrixRotateXYZ :: Vector3 -> Matrix
matrixRotateXYZ (Vector3 Float
x Float
y Float
z) = Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Matrix
Matrix (Float
cz Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
cy) (Float
sz Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
cy) (-Float
sy) Float
0 (Float
cz Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
sy Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
sx Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
sz Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
cx) (Float
sz Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
sy Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
sx Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
cz Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
cx) (Float
cy Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
sx) Float
0 (Float
cz Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
sy Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
cx Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
sz Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
sx) (Float
sz Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
sy Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
cx Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
cz Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
sx) (Float
cy Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
cx) Float
0 Float
0 Float
0 Float
0 Float
1
  where
    cx :: Float
cx = Float -> Float
forall a. Floating a => a -> a
cos (-Float
x)
    sx :: Float
sx = Float -> Float
forall a. Floating a => a -> a
sin (-Float
x)
    cy :: Float
cy = Float -> Float
forall a. Floating a => a -> a
cos (-Float
y)
    sy :: Float
sy = Float -> Float
forall a. Floating a => a -> a
sin (-Float
y)
    cz :: Float
cz = Float -> Float
forall a. Floating a => a -> a
cos (-Float
z)
    sz :: Float
sz = Float -> Float
forall a. Floating a => a -> a
sin (-Float
z)

-- | Euler angle zyx rotation matrix (angles should be in radians)
matrixRotateZYX :: Vector3 -> Matrix
matrixRotateZYX :: Vector3 -> Matrix
matrixRotateZYX (Vector3 Float
x Float
y Float
z) = Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Matrix
Matrix (Float
cz Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
cy) (Float
cz Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
sy Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
sx Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
cx Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
sz) (Float
sz Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
sx Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
cz Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
cx Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
sy) Float
0 (Float
cy Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
sz) (Float
cz Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
cx Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
sz Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
sy Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
sx) (Float
cx Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
sz Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
sy Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
cz Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
sx) Float
0 (-Float
sy) (Float
cy Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
sx) (Float
cy Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
cx) Float
0 Float
0 Float
0 Float
0 Float
1
  where
    cz :: Float
cz = Float -> Float
forall a. Floating a => a -> a
cos Float
z
    sz :: Float
sz = Float -> Float
forall a. Floating a => a -> a
sin Float
z
    cy :: Float
cy = Float -> Float
forall a. Floating a => a -> a
cos Float
y
    sy :: Float
sy = Float -> Float
forall a. Floating a => a -> a
sin Float
y
    cx :: Float
cx = Float -> Float
forall a. Floating a => a -> a
cos Float
x
    sx :: Float
sx = Float -> Float
forall a. Floating a => a -> a
sin Float
x

-- | Scaling matrix
matrixScale :: Vector3 -> Matrix
matrixScale :: Vector3 -> Matrix
matrixScale (Vector3 Float
x Float
y Float
z) = Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Matrix
Matrix Float
x Float
0 Float
0 Float
0 Float
0 Float
y Float
0 Float
0 Float
0 Float
0 Float
z Float
0 Float
0 Float
0 Float
0 Float
1

-- | Frustum projection matrix
matrixFrustum ::
  -- | Left edge distance
  Float ->
  -- | Right edge distance
  Float ->
  -- | Bottom edge distance
  Float ->
  -- | Top edge distance
  Float ->
  -- | Near clipping plane distance
  Float ->
  -- | Far clipping plane distance
  Float ->
  Matrix
matrixFrustum :: Float -> Float -> Float -> Float -> Float -> Float -> Matrix
matrixFrustum Float
left Float
right Float
bottom Float
top Float
near Float
far =
  Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Matrix
Matrix
    (Float
near Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
2 Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/ Float
x)
    Float
0
    ((Float
right Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
left) Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/ Float
x)
    Float
0
    Float
0
    (Float
near Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
2 Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/ Float
y)
    ((Float
top Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
bottom) Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/ Float
y)
    Float
0
    Float
0
    Float
0
    (-(Float
far Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
near) Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/ Float
z)
    (-Float
far Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
near Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
2 Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/ Float
z)
    Float
0
    Float
0
    (-Float
1)
    Float
0
  where
    x :: Float
x = Float
right Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
left
    y :: Float
y = Float
top Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
bottom
    z :: Float
z = Float
far Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
near

-- | Perspective projection matrix
matrixPerspective ::
  -- | y-fov angle (should be in radians)
  Float ->
  -- | Aspect ratio
  Float ->
  -- | Near clipping plane distance
  Float ->
  -- | Far clipping plane distance
  Float ->
  Matrix
matrixPerspective :: Float -> Float -> Float -> Float -> Matrix
matrixPerspective Float
fovy Float
aspect Float
near Float
far = Float -> Float -> Float -> Float -> Float -> Float -> Matrix
matrixFrustum Float
left Float
right Float
bottom Float
top Float
near Float
far
  where
    top :: Float
top = Float
near Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float -> Float
forall a. Floating a => a -> a
tan (Float
fovy Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/ Float
2)
    bottom :: Float
bottom = -Float
top
    right :: Float
right = Float
top Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
aspect
    left :: Float
left = -Float
right

-- | Orthographic projection matrix
matrixOrtho ::
  -- | Left edge distance
  Float ->
  -- | Right edge distance
  Float ->
  -- | Bottom edge distance
  Float ->
  -- | Top edge distance
  Float ->
  -- | Near clipping plane distance
  Float ->
  -- | Far clipping plane distance
  Float ->
  Matrix
matrixOrtho :: Float -> Float -> Float -> Float -> Float -> Float -> Matrix
matrixOrtho Float
left Float
right Float
bottom Float
top Float
near Float
far =
  Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Matrix
Matrix (Float
2 Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/ Float
x) Float
0 Float
0 (-(Float
left Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
right) Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/ Float
x) Float
0 (Float
2 Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/ Float
y) Float
0 (-(Float
top Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
bottom) Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/ Float
y) Float
0 Float
0 (-Float
2 Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/ Float
z) (-(Float
far Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
near) Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/ Float
z) Float
0 Float
0 Float
0 Float
1
  where
    x :: Float
x = Float
right Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
left
    y :: Float
y = Float
top Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
bottom
    z :: Float
z = Float
far Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
near

-- | Camera look-at matrix (view matrix)
matrixLookAt ::
  -- | Camera position
  Vector3 ->
  -- | Camera target
  Vector3 ->
  -- | World up vector
  Vector3 ->
  Matrix
matrixLookAt :: Vector3 -> Vector3 -> Vector3 -> Matrix
matrixLookAt Vector3
eye Vector3
target Vector3
up = Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Matrix
Matrix Float
xx Float
xy Float
xz (-Vector3
vx Vector3 -> Vector3 -> Float
forall a. Vector a => a -> a -> Float
|.| Vector3
eye) Float
yx Float
yy Float
yz (-Vector3
vy Vector3 -> Vector3 -> Float
forall a. Vector a => a -> a -> Float
|.| Vector3
eye) Float
zx Float
zy Float
zz (-Vector3
vz Vector3 -> Vector3 -> Float
forall a. Vector a => a -> a -> Float
|.| Vector3
eye) Float
0 Float
0 Float
0 Float
1
  where
    vz :: Vector3
vz@(Vector3 Float
zx Float
zy Float
zz) = Vector3 -> Vector3
forall a. Vector a => a -> a
vectorNormalize (Vector3 -> Vector3) -> Vector3 -> Vector3
forall a b. (a -> b) -> a -> b
$ Vector3
eye Vector3 -> Vector3 -> Vector3
forall a. Vector a => a -> a -> a
|-| Vector3
target
    vx :: Vector3
vx@(Vector3 Float
xx Float
xy Float
xz) = Vector3 -> Vector3
forall a. Vector a => a -> a
vectorNormalize (Vector3 -> Vector3) -> Vector3 -> Vector3
forall a b. (a -> b) -> a -> b
$ Vector3 -> Vector3 -> Vector3
vector3CrossProduct Vector3
up Vector3
vz
    vy :: Vector3
vy@(Vector3 Float
yx Float
yy Float
yz) = Vector3 -> Vector3 -> Vector3
vector3CrossProduct Vector3
vz Vector3
vx

------------------------------------------------
-- Quaternion math -----------------------------
------------------------------------------------

-- | Identity quaternion
quaternionIdentity :: Quaternion
quaternionIdentity :: Quaternion
quaternionIdentity = Float -> Float -> Float -> Float -> Quaternion
Vector4 Float
0 Float
0 Float
0 Float
1

-- | Invert a quaternion
quaternionInvert :: Quaternion -> Quaternion
quaternionInvert :: Quaternion -> Quaternion
quaternionInvert q :: Quaternion
q@(Vector4 Float
x Float
y Float
z Float
w) = Float -> Float -> Float -> Float -> Quaternion
Vector4 (-Float
x Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
invLength) (-Float
y Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
invLength) (-Float
z Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
invLength) (Float
w Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
invLength)
  where
    invLength :: Float
invLength = Float
1 Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/ Quaternion -> Float
forall a. Vector a => a -> Float
magnitudeSqr Quaternion
q

-- | Multiply two quaternions
quaternionMultiply :: Quaternion -> Quaternion -> Quaternion
quaternionMultiply :: Quaternion -> Quaternion -> Quaternion
quaternionMultiply (Vector4 Float
qax Float
qay Float
qaz Float
qaw) (Vector4 Float
qbx Float
qby Float
qbz Float
qbw) = Float -> Float -> Float -> Float -> Quaternion
Vector4 (Float
qax Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
qbw Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
qaw Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
qbx Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
qay Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
qbz Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
qaz Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
qby) (Float
qay Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
qbw Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
qaw Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
qby Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
qaz Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
qbx Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
qax Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
qbz) (Float
qaz Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
qbw Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
qaw Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
qbz Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
qax Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
qby Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
qay Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
qbx) (Float
qaw Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
qbw Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
qax Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
qbx Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
qay Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
qby Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
qaz Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
qbz)

-- | Normalize a quaternion (alias for 'vectorNormalize')
quaternionNormalize :: Quaternion -> Quaternion
quaternionNormalize :: Quaternion -> Quaternion
quaternionNormalize = Quaternion -> Quaternion
forall a. Vector a => a -> a
vectorNormalize

-- | Lerp between two quaternions (alias for 'quaternionLerp')
quaternionLerp ::
  -- | Lerp start value
  Quaternion ->
  -- | Lerp end value
  Quaternion ->
  -- | Lerp amount
  Float ->
  Quaternion
quaternionLerp :: Quaternion -> Quaternion -> Float -> Quaternion
quaternionLerp = Quaternion -> Quaternion -> Float -> Quaternion
forall a. Vector a => a -> a -> Float -> a
vectorLerp

-- | Slerp-optimized interpolation between two quaternions
quaternionNLerp ::
  -- | Lerp start value
  Quaternion ->
  -- | Lerp end value
  Quaternion ->
  -- | Lerp amount
  Float ->
  Quaternion
quaternionNLerp :: Quaternion -> Quaternion -> Float -> Quaternion
quaternionNLerp Quaternion
q1 Quaternion
q2 Float
amount = Quaternion -> Quaternion
forall a. Vector a => a -> a
vectorNormalize (Quaternion -> Quaternion) -> Quaternion -> Quaternion
forall a b. (a -> b) -> a -> b
$ Quaternion -> Quaternion -> Float -> Quaternion
quaternionLerp Quaternion
q1 Quaternion
q2 Float
amount

-- | Spherical linear interpolation between two quaternions
quaternionSLerp ::
  -- | Lerp start value
  Quaternion ->
  -- | Lerp end value
  Quaternion ->
  -- | Lerp amount
  Float ->
  Quaternion
quaternionSLerp :: Quaternion -> Quaternion -> Float -> Quaternion
quaternionSLerp Quaternion
q1 Quaternion
q2 Float
amount
  | Float
cosHalfTheta Float -> Float -> Bool
forall a. Ord a => a -> a -> Bool
>= Float
1 = Quaternion
q1
  | Float
cosHalfTheta Float -> Float -> Bool
forall a. Ord a => a -> a -> Bool
> Float
0.95 = Quaternion -> Quaternion -> Float -> Quaternion
quaternionNLerp Quaternion
q1 Quaternion
q2' Float
amount
  | Float -> Float
forall a. Num a => a -> a
abs Float
sinHalfTheta Float -> Float -> Bool
forall a. Ord a => a -> a -> Bool
< Float
epsilon = (Quaternion
q1 Quaternion -> Quaternion -> Quaternion
forall a. Vector a => a -> a -> a
|+| Quaternion
q2') Quaternion -> Float -> Quaternion
forall a. Vector a => a -> Float -> a
|/ Float
2
  | Bool
otherwise = (Quaternion
q1 Quaternion -> Float -> Quaternion
forall a. Vector a => a -> Float -> a
|* Float
ratioA) Quaternion -> Quaternion -> Quaternion
forall a. Vector a => a -> a -> a
|+| (Quaternion
q2 Quaternion -> Float -> Quaternion
forall a. Vector a => a -> Float -> a
|* Float
ratioB)
  where
    cosHalfTheta :: Float
cosHalfTheta = if Float
dot Float -> Float -> Bool
forall a. Ord a => a -> a -> Bool
< Float
0 then -Float
dot else Float
dot
    sinHalfTheta :: Float
sinHalfTheta = Float -> Float
forall a. Floating a => a -> a
sqrt (Float
1 Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
cosHalfTheta Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
cosHalfTheta)
    halfTheta :: Float
halfTheta = Float -> Float
forall a. Floating a => a -> a
acos Float
cosHalfTheta

    ratioA :: Float
ratioA = Float -> Float
forall a. Floating a => a -> a
sin ((Float
1 Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
amount) Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
halfTheta) Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/ Float
sinHalfTheta
    ratioB :: Float
ratioB = Float -> Float
forall a. Floating a => a -> a
sin (Float
amount Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
halfTheta) Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/ Float
sinHalfTheta

    q2' :: Quaternion
q2' = if Float
dot Float -> Float -> Bool
forall a. Ord a => a -> a -> Bool
< Float
0 then Quaternion -> Quaternion
forall a. Vector a => a -> a
additiveInverse Quaternion
q2 else Quaternion
q2
    dot :: Float
dot = Quaternion
q1 Quaternion -> Quaternion -> Float
forall a. Vector a => a -> a -> Float
|.| Quaternion
q2

-- | Quaternion based on the rotation between two vectors
quaternionFromVector3ToVector3 :: Vector3 -> Vector3 -> Quaternion
quaternionFromVector3ToVector3 :: Vector3 -> Vector3 -> Quaternion
quaternionFromVector3ToVector3 Vector3
from Vector3
to = Quaternion -> Quaternion
quaternionNormalize (Float -> Float -> Float -> Float -> Quaternion
Vector4 Float
x Float
y Float
z (Float
1 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
cos2Theta))
  where
    cos2Theta :: Float
cos2Theta = Vector3
from Vector3 -> Vector3 -> Float
forall a. Vector a => a -> a -> Float
|.| Vector3
to
    (Vector3 Float
x Float
y Float
z) = Vector3 -> Vector3 -> Vector3
vector3CrossProduct Vector3
from Vector3
to

-- | Create a quaternion from a rotation matrix
quaternionFromMatrix :: Matrix -> Quaternion
quaternionFromMatrix :: Matrix -> Quaternion
quaternionFromMatrix Matrix
mat
  | Float
fourBiggestSquaredMinus1 Float -> Float -> Bool
forall a. Eq a => a -> a -> Bool
== Float
fourWSquaredMinus1 = Float -> Float -> Float -> Float -> Quaternion
Vector4 ((Matrix -> Float
matrix'm6 Matrix
mat Float -> Float -> Float
forall a. Num a => a -> a -> a
- Matrix -> Float
matrix'm9 Matrix
mat) Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
mult) ((Matrix -> Float
matrix'm8 Matrix
mat Float -> Float -> Float
forall a. Num a => a -> a -> a
- Matrix -> Float
matrix'm2 Matrix
mat) Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
mult) ((Matrix -> Float
matrix'm1 Matrix
mat Float -> Float -> Float
forall a. Num a => a -> a -> a
- Matrix -> Float
matrix'm4 Matrix
mat) Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
mult) Float
biggestVal
  | Float
fourBiggestSquaredMinus1 Float -> Float -> Bool
forall a. Eq a => a -> a -> Bool
== Float
fourXSquaredMinus1 = Float -> Float -> Float -> Float -> Quaternion
Vector4 Float
biggestVal ((Matrix -> Float
matrix'm1 Matrix
mat Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Matrix -> Float
matrix'm4 Matrix
mat) Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
mult) ((Matrix -> Float
matrix'm8 Matrix
mat Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Matrix -> Float
matrix'm2 Matrix
mat) Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
mult) ((Matrix -> Float
matrix'm6 Matrix
mat Float -> Float -> Float
forall a. Num a => a -> a -> a
- Matrix -> Float
matrix'm9 Matrix
mat) Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
mult)
  | Float
fourBiggestSquaredMinus1 Float -> Float -> Bool
forall a. Eq a => a -> a -> Bool
== Float
fourYSquaredMinus1 = Float -> Float -> Float -> Float -> Quaternion
Vector4 ((Matrix -> Float
matrix'm1 Matrix
mat Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Matrix -> Float
matrix'm4 Matrix
mat) Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
mult) Float
biggestVal ((Matrix -> Float
matrix'm6 Matrix
mat Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Matrix -> Float
matrix'm9 Matrix
mat) Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
mult) ((Matrix -> Float
matrix'm8 Matrix
mat Float -> Float -> Float
forall a. Num a => a -> a -> a
- Matrix -> Float
matrix'm2 Matrix
mat) Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
mult)
  | Float
fourBiggestSquaredMinus1 Float -> Float -> Bool
forall a. Eq a => a -> a -> Bool
== Float
fourZSquaredMinus1 = Float -> Float -> Float -> Float -> Quaternion
Vector4 ((Matrix -> Float
matrix'm8 Matrix
mat Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Matrix -> Float
matrix'm2 Matrix
mat) Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
mult) ((Matrix -> Float
matrix'm6 Matrix
mat Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Matrix -> Float
matrix'm9 Matrix
mat) Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
mult) Float
biggestVal ((Matrix -> Float
matrix'm1 Matrix
mat Float -> Float -> Float
forall a. Num a => a -> a -> a
- Matrix -> Float
matrix'm4 Matrix
mat) Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
mult)
  | Bool
otherwise = [Char] -> Quaternion
forall a. HasCallStack => [Char] -> a
error [Char]
"(quaternionFromMatrix) This error should never happen"
  where
    fourWSquaredMinus1 :: Float
fourWSquaredMinus1 = Matrix -> Float
matrix'm0 Matrix
mat Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Matrix -> Float
matrix'm5 Matrix
mat Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Matrix -> Float
matrix'm10 Matrix
mat
    fourXSquaredMinus1 :: Float
fourXSquaredMinus1 = Matrix -> Float
matrix'm0 Matrix
mat Float -> Float -> Float
forall a. Num a => a -> a -> a
- Matrix -> Float
matrix'm5 Matrix
mat Float -> Float -> Float
forall a. Num a => a -> a -> a
- Matrix -> Float
matrix'm10 Matrix
mat
    fourYSquaredMinus1 :: Float
fourYSquaredMinus1 = Matrix -> Float
matrix'm5 Matrix
mat Float -> Float -> Float
forall a. Num a => a -> a -> a
- Matrix -> Float
matrix'm0 Matrix
mat Float -> Float -> Float
forall a. Num a => a -> a -> a
- Matrix -> Float
matrix'm10 Matrix
mat
    fourZSquaredMinus1 :: Float
fourZSquaredMinus1 = Matrix -> Float
matrix'm10 Matrix
mat Float -> Float -> Float
forall a. Num a => a -> a -> a
- Matrix -> Float
matrix'm0 Matrix
mat Float -> Float -> Float
forall a. Num a => a -> a -> a
- Matrix -> Float
matrix'm5 Matrix
mat
    fourBiggestSquaredMinus1 :: Float
fourBiggestSquaredMinus1 =
      [Float] -> Float
forall a. Ord a => [a] -> a
forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
maximum
        [ Float
fourWSquaredMinus1,
          Float
fourXSquaredMinus1,
          Float
fourYSquaredMinus1,
          Float
fourZSquaredMinus1
        ]
    biggestVal :: Float
biggestVal = Float -> Float
forall a. Floating a => a -> a
sqrt (Float
fourBiggestSquaredMinus1 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
1) Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/ Float
2
    mult :: Float
mult = Float
0.5 Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/ Float
biggestVal

-- | Create a rotation matrix from a quaternion
quaternionToMatrix :: Quaternion -> Matrix
quaternionToMatrix :: Quaternion -> Matrix
quaternionToMatrix (Vector4 Float
x Float
y Float
z Float
w) = Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Float
-> Matrix
Matrix (Float
1 Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
2 Float -> Float -> Float
forall a. Num a => a -> a -> a
* (Float
b2 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
c2)) (Float
2 Float -> Float -> Float
forall a. Num a => a -> a -> a
* (Float
ab Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
cd)) (Float
2 Float -> Float -> Float
forall a. Num a => a -> a -> a
* (Float
ac Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
bd)) Float
0 (Float
2 Float -> Float -> Float
forall a. Num a => a -> a -> a
* (Float
ab Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
cd)) (Float
1 Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
2 Float -> Float -> Float
forall a. Num a => a -> a -> a
* (Float
a2 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
c2)) (Float
2 Float -> Float -> Float
forall a. Num a => a -> a -> a
* (Float
bc Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
ad)) Float
0 (Float
2 Float -> Float -> Float
forall a. Num a => a -> a -> a
* (Float
ac Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
bd)) (Float
2 Float -> Float -> Float
forall a. Num a => a -> a -> a
* (Float
bc Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
ad)) (Float
1 Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
2 Float -> Float -> Float
forall a. Num a => a -> a -> a
* (Float
a2 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
b2)) Float
0 Float
0 Float
0 Float
0 Float
1
  where
    a2 :: Float
a2 = Float
x Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
x
    b2 :: Float
b2 = Float
y Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
y
    c2 :: Float
c2 = Float
z Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
z
    ac :: Float
ac = Float
x Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
z
    ab :: Float
ab = Float
x Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
y
    bc :: Float
bc = Float
y Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
z
    ad :: Float
ad = Float
w Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
x
    bd :: Float
bd = Float
w Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
y
    cd :: Float
cd = Float
w Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
z

-- | Create a quaternion for an angle and axis
quaternionFromAxisAngle ::
  -- | Rotation axis
  Vector3 ->
  -- | Angle in radians
  Float ->
  Quaternion
quaternionFromAxisAngle :: Vector3 -> Float -> Quaternion
quaternionFromAxisAngle Vector3
axis Float
angle = Float -> Float -> Float -> Float -> Quaternion
Vector4 (Float
x Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
s) (Float
y Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
s) (Float
z Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
s) Float
c
  where
    (Vector3 Float
x Float
y Float
z) = Vector3 -> Vector3
forall a. Vector a => a -> a
vectorNormalize Vector3
axis
    s :: Float
s = Float -> Float
forall a. Floating a => a -> a
sin (Float
angle Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/ Float
2)
    c :: Float
c = Float -> Float
forall a. Floating a => a -> a
cos (Float
angle Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/ Float
2)

-- | Convert a quaternion to axis-angle representation
quaternionToAxisAngle :: Quaternion -> (Vector3, Float)
quaternionToAxisAngle :: Quaternion -> (Vector3, Float)
quaternionToAxisAngle Quaternion
q = (Vector3
axis, Float
angle)
  where
    (Vector4 Float
x Float
y Float
z Float
w) = Quaternion -> Quaternion
quaternionNormalize Quaternion
q
    s :: Float
s = Float -> Float
forall a. Floating a => a -> a
sqrt (Float
1 Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
w Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
w)
    axis :: Vector3
axis = if Float
w Float -> Float -> Bool
forall a. Ord a => a -> a -> Bool
> Float
0.9999 then Float -> Float -> Float -> Vector3
Vector3 Float
1 Float
0 Float
0 else Float -> Float -> Float -> Vector3
Vector3 (Float
x Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/ Float
s) (Float
y Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/ Float
s) (Float
z Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/ Float
s)
    angle :: Float
angle = Float -> Float
forall a. Floating a => a -> a
acos Float
w Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
2

-- | Create a quaternion from Euler angles (ZYX rotation order, angles should be in radians)
quaternionFromEuler ::
  -- | Pitch
  Float ->
  -- | Yaw
  Float ->
  -- | Roll
  Float ->
  Quaternion
quaternionFromEuler :: Float -> Float -> Float -> Quaternion
quaternionFromEuler Float
pitch Float
yaw Float
roll = Float -> Float -> Float -> Float -> Quaternion
Vector4 (Float
x1 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
y0 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
z0 Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
x0 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
y1 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
z1) (Float
x0 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
y1 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
z0 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
x1 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
y0 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
z1) (Float
x0 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
y0 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
z1 Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
x1 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
y1 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
z0) (Float
x0 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
y0 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
z0 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
x1 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
y1 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
z1)
  where
    x0 :: Float
x0 = Float -> Float
forall a. Floating a => a -> a
cos (Float
pitch Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
0.5)
    x1 :: Float
x1 = Float -> Float
forall a. Floating a => a -> a
sin (Float
pitch Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
0.5)
    y0 :: Float
y0 = Float -> Float
forall a. Floating a => a -> a
cos (Float
yaw Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
0.5)
    y1 :: Float
y1 = Float -> Float
forall a. Floating a => a -> a
sin (Float
yaw Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
0.5)
    z0 :: Float
z0 = Float -> Float
forall a. Floating a => a -> a
cos (Float
roll Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
0.5)
    z1 :: Float
z1 = Float -> Float
forall a. Floating a => a -> a
sin (Float
roll Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
0.5)

-- | Convert a quaternion to Euler angle representation (Vector3 roll pitch yaw, all angles in radians)
quaternionToEuler :: Quaternion -> Vector3
quaternionToEuler :: Quaternion -> Vector3
quaternionToEuler (Vector4 Float
x Float
y Float
z Float
w) = Float -> Float -> Float -> Vector3
Vector3 (Float -> Float -> Float
forall a. RealFloat a => a -> a -> a
atan2 Float
x0 Float
x1) (Float -> Float
forall a. Floating a => a -> a
asin Float
y0) (Float -> Float -> Float
forall a. RealFloat a => a -> a -> a
atan2 Float
z0 Float
z1)
  where
    x0 :: Float
x0 = Float
2 Float -> Float -> Float
forall a. Num a => a -> a -> a
* (Float
w Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
x Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
y Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
z)
    x1 :: Float
x1 = Float
1 Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
2 Float -> Float -> Float
forall a. Num a => a -> a -> a
* (Float
x Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
x Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
y Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
y)
    y0 :: Float
y0 = Float -> Float -> Float -> Float
clamp (Float
2 Float -> Float -> Float
forall a. Num a => a -> a -> a
* (Float
w Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
y Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
z Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
x)) (-Float
1) Float
1
    z0 :: Float
z0 = Float
2 Float -> Float -> Float
forall a. Num a => a -> a -> a
* (Float
w Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
z Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
x Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
y)
    z1 :: Float
z1 = Float
1 Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
2 Float -> Float -> Float
forall a. Num a => a -> a -> a
* (Float
y Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
y Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
z Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
z)

-- | Transform a quaternion given a transformation matrix
quaternionTransform :: Quaternion -> Matrix -> Quaternion
quaternionTransform :: Quaternion -> Matrix -> Quaternion
quaternionTransform (Vector4 Float
x Float
y Float
z Float
w) Matrix
mat =
  Float -> Float -> Float -> Float -> Quaternion
Vector4
    (Matrix -> Float
matrix'm0 Matrix
mat Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
x Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Matrix -> Float
matrix'm4 Matrix
mat Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
y Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Matrix -> Float
matrix'm8 Matrix
mat Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
z Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Matrix -> Float
matrix'm12 Matrix
mat Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
w)
    (Matrix -> Float
matrix'm1 Matrix
mat Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
x Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Matrix -> Float
matrix'm5 Matrix
mat Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
y Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Matrix -> Float
matrix'm9 Matrix
mat Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
z Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Matrix -> Float
matrix'm13 Matrix
mat Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
w)
    (Matrix -> Float
matrix'm2 Matrix
mat Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
x Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Matrix -> Float
matrix'm6 Matrix
mat Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
y Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Matrix -> Float
matrix'm10 Matrix
mat Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
z Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Matrix -> Float
matrix'm14 Matrix
mat Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
w)
    (Matrix -> Float
matrix'm3 Matrix
mat Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
x Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Matrix -> Float
matrix'm7 Matrix
mat Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
y Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Matrix -> Float
matrix'm11 Matrix
mat Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
z Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Matrix -> Float
matrix'm15 Matrix
mat Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
w)