{-# OPTIONS -Wall #-}

module Raylib.Util.Math
  ( -- * Utility constants

    epsilon,
    deg2Rad,
    rad2Deg,

    -- * Float math

    clamp,
    lerp,
    normalize,
    remap,
    wrap,
    floatEquals,

    -- * General vector math

    Vector (..),

    -- * Vector2 math

    vector2Angle,
    vector2LineAngle,
    vector2Transform,
    vector2Reflect,
    vector2Rotate,

    -- * 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 Raylib.Types (Matrix (..), Quaternion, Vector2 (Vector2), Vector3 (Vector3), Vector4 (Vector4))

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

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

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

------------------------------------------------

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

------------------------------------------------


-- | Clamp float to range

clamp ::
  -- | Value to clamp

  Float ->
  -- | Lower bound

  Float ->
  -- | Upper bound

  Float ->
  Float
clamp :: Float -> Float -> Float -> Float
clamp Float
value Float
low Float
high
  | Float
value forall a. Ord a => a -> a -> Bool
< Float
low = Float
low
  | Float
value 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 forall a. Num a => a -> a -> a
+ Float
amount forall a. Num a => a -> a -> a
* (Float
end forall a. Num a => a -> a -> a
- Float
start)

-- | Normalize input value within input range

normalize ::
  -- | Value to normalize

  Float ->
  -- | Starting value of range

  Float ->
  -- | Ending value of range

  Float ->
  Float
normalize :: Float -> Float -> Float -> Float
normalize Float
value Float
start Float
end = (Float
value forall a. Num a => a -> a -> a
- Float
start) forall a. Fractional a => a -> a -> a
/ (Float
end forall a. Num a => a -> a -> a
- Float
start)

-- | Remap input value within input range to output range

remap ::
  -- | Input value

  Float ->
  -- | Input range start

  Float ->
  -- | Input range end

  Float ->
  -- | Output range start

  Float ->
  -- | Output range end

  Float ->
  Float
remap :: Float -> Float -> Float -> Float -> Float -> Float
remap Float
value Float
inputStart Float
inputEnd Float
outputStart Float
outputEnd = (Float
value forall a. Num a => a -> a -> a
- Float
inputStart) forall a. Fractional a => a -> a -> a
/ (Float
inputEnd forall a. Num a => a -> a -> a
- Float
inputStart) forall a. Num a => a -> a -> a
* (Float
outputEnd forall a. Num a => a -> a -> a
- Float
outputStart) forall a. Num a => a -> a -> a
+ Float
outputStart

-- | Wrap input value from min to max

wrap ::
  -- | Input value

  Float ->
  -- | Min value

  Float ->
  -- | Max value

  Float ->
  Float
wrap :: Float -> Float -> Float -> Float
wrap Float
value Float
low Float
high = Float
value forall a. Num a => a -> a -> a
- (Float
high forall a. Num a => a -> a -> a
- Float
low) forall a. Num a => a -> a -> a
* forall a b. (Integral a, Num b) => a -> b
fromIntegral (forall a b. (RealFrac a, Integral b) => a -> b
floor ((Float
value forall a. Num a => a -> a -> a
- Float
low) forall a. Fractional a => a -> a -> a
/ (Float
high 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 = forall a. Num a => a -> a
abs (Float
x forall a. Num a => a -> a -> a
- Float
y) forall a. Ord a => a -> a -> Bool
<= (Float
epsilon forall a. Num a => a -> a -> a
* forall a. Ord a => a -> a -> a
max Float
1 (forall a. Ord a => a -> a -> a
max (forall a. Num a => a -> a
abs Float
x) (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

  -- | Vector-vector addition

  (|+|) :: a -> a -> a
  a
a |+| a
b = forall a. Vector a => [Float] -> a
fromList forall a b. (a -> b) -> a -> b
$ forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith forall a. Num a => a -> a -> a
(+) (forall a. Vector a => a -> [Float]
asList a
a) (forall a. Vector a => a -> [Float]
asList a
b)

  -- | Vector-vector subtraction

  (|-|) :: a -> a -> a
  a
a |-| a
b = forall a. Vector a => [Float] -> a
fromList forall a b. (a -> b) -> a -> b
$ forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith (-) (forall a. Vector a => a -> [Float]
asList a
a) (forall a. Vector a => a -> [Float]
asList a
b)

  -- | Vector-scalar addition

  (|+) :: a -> Float -> a
  a
a |+ Float
b = a
a forall a. Vector a => a -> a -> a
|+| forall a. Vector a => Float -> a
constant Float
b

  -- | Vector-scalar subtraction

  (|-) :: a -> Float -> a
  a
a |- Float
b = a
a forall a. Vector a => a -> a -> a
|-| forall a. Vector a => Float -> a
constant Float
b

  -- | Vector-vector multiplication

  (|*|) :: a -> a -> a
  a
a |*| a
b = forall a. Vector a => [Float] -> a
fromList forall a b. (a -> b) -> a -> b
$ forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith forall a. Num a => a -> a -> a
(*) (forall a. Vector a => a -> [Float]
asList a
a) (forall a. Vector a => a -> [Float]
asList a
b)

  -- | Vector-vector division

  (|/|) :: a -> a -> a
  a
a |/| a
b = forall a. Vector a => [Float] -> a
fromList forall a b. (a -> b) -> a -> b
$ forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith forall a. Fractional a => a -> a -> a
(/) (forall a. Vector a => a -> [Float]
asList a
a) (forall a. Vector a => a -> [Float]
asList a
b)

  -- | Vector-scalar multiplication

  (|*) :: a -> Float -> a
  a
a |* Float
b = a
a forall a. Vector a => a -> a -> a
|*| forall a. Vector a => Float -> a
constant Float
b

  -- | Vector-scalar division

  (|/) :: a -> Float -> a
  a
a |/ Float
b = a
a forall a. Vector a => a -> a -> a
|/| forall a. Vector a => Float -> a
constant Float
b

  -- | Vector-vector dot product

  (|.|) :: a -> a -> Float
  a
a |.| a
b = forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Vector a => a -> [Float]
asList forall a b. (a -> b) -> a -> b
$ a
a forall a. Vector a => a -> a -> a
|*| a
b

  -- | Zero vector

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

  -- | One vector

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

  -- | Scalar to vector (all elements are set to the scalar)

  constant :: Float -> a
  constant Float
val = forall a. Vector a => [Float] -> a
fromList forall a b. (a -> b) -> a -> b
$ forall a. a -> [a]
repeat Float
val

  -- | Vector additive inverse

  additiveInverse :: a -> a
  additiveInverse a
v = forall a. Vector a => [Float] -> a
fromList forall a b. (a -> b) -> a -> b
$ forall a b. (a -> b) -> [a] -> [b]
map forall a. Num a => a -> a
negate (forall a. Vector a => a -> [Float]
asList a
v)

  -- | Vector multiplicative inverse

  multiplicativeInverse :: a -> a
  multiplicativeInverse a
v = forall a. Vector a => [Float] -> a
fromList forall a b. (a -> b) -> a -> b
$ forall a b. (a -> b) -> [a] -> [b]
map (Float
1 forall a. Fractional a => a -> a -> a
/) (forall a. Vector a => a -> [Float]
asList a
v)

  -- | Squared magnitude of a vector

  magnitudeSqr :: a -> Float
  magnitudeSqr a
v = a
v forall a. Vector a => a -> a -> Float
|.| a
v

  -- | Vector magnitude

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

  -- | Squared distance between two vectors

  vectorDistanceSqr :: a -> a -> Float
  vectorDistanceSqr a
a a
b = forall a. Vector a => a -> Float
magnitudeSqr forall a b. (a -> b) -> a -> b
$ a
a forall a. Vector a => a -> a -> a
|-| a
b

  -- | Distance between two vectors

  vectorDistance :: a -> a -> Float
  vectorDistance a
a a
b = forall a. Floating a => a -> a
sqrt forall a b. (a -> b) -> a -> b
$ 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 forall a. Vector a => a -> Float -> a
|/ 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 = forall a. Vector a => [Float] -> a
fromList forall a b. (a -> b) -> a -> b
$ forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith (\Float
v1 Float
v2 -> Float -> Float -> Float -> Float
lerp Float
v1 Float
v2 Float
amount) (forall a. Vector a => a -> [Float]
asList a
a) (forall a. Vector a => a -> [Float]
asList 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 forall a. Ord a => a -> a -> Bool
<= Float
maxDistance forall a. Num a => a -> a -> a
* Float
maxDistance
      then a
target
      else a
v forall a. Vector a => a -> a -> a
|+| forall a. Vector a => [Float] -> a
fromList (forall a b. (a -> b) -> [a] -> [b]
map (forall a. Num a => a -> a -> a
* (Float
maxDistance forall a. Fractional a => a -> a -> a
/ Float
dist)) (forall a. Vector a => a -> [Float]
asList a
diff))
    where
      diff :: a
diff = a
target forall a. Vector a => a -> a -> a
|-| a
v
      distSquared :: Float
distSquared = forall a. Vector a => a -> Float
magnitudeSqr a
diff
      dist :: Float
dist = 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 = forall a. Vector a => [Float] -> a
fromList forall a b. (a -> b) -> a -> b
$ forall a b c d. (a -> b -> c -> d) -> [a] -> [b] -> [c] -> [d]
zipWith3 Float -> Float -> Float -> Float
clamp (forall a. Vector a => a -> [Float]
asList a
v) (forall a. Vector a => a -> [Float]
asList a
low) (forall a. Vector a => a -> [Float]
asList 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 forall a. Vector a => a -> Float -> a
|* (Float -> Float -> Float -> Float
clamp Float
size Float
low Float
high forall a. Fractional a => a -> a -> a
/ Float
size)
    where
      size :: Float
size = 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 = forall a. Vector a => [Float] -> a
fromList forall a b. (a -> b) -> a -> b
$ forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith forall a. Ord a => a -> a -> a
min (forall a. Vector a => a -> [Float]
asList a
v1) (forall a. Vector a => a -> [Float]
asList a
v2)

  -- | Max value for each pair of components

  vectorMax :: a -> a -> a
  vectorMax a
v1 a
v2 = forall a. Vector a => [Float] -> a
fromList forall a b. (a -> b) -> a -> b
$ forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith forall a. Ord a => a -> a -> a
max (forall a. Vector a => a -> [Float]
asList a
v1) (forall a. Vector a => a -> [Float]
asList 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]
_ = forall a. HasCallStack => [Char] -> a
error [Char]
"(Vector2.fromList) Input list must have at least two elements!"

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]
_ = forall a. HasCallStack => [Char] -> a
error [Char]
"(Vector3.fromList) Input list must have at least three elements!"

instance Vector Vector4 where
  asList :: Vector4 -> [Float]
asList (Vector4 Float
x Float
y Float
z Float
w) = [Float
x, Float
y, Float
z, Float
w]
  fromList :: [Float] -> Vector4
fromList (Float
x : Float
y : Float
z : Float
w : [Float]
_) = Float -> Float -> Float -> Float -> Vector4
Vector4 Float
x Float
y Float
z Float
w
  fromList [Float]
_ = forall a. HasCallStack => [Char] -> a
error [Char]
"(Vector4.fromList) Input list must have at least four elements!"

------------------------------------------------

-- 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) = forall a. RealFloat a => a -> a -> a
atan2 (Float
y2 forall a. Num a => a -> a -> a
- Float
y1) (Float
x2 forall a. Num a => a -> a -> a
- Float
x1)

-- | Angle created by the line between two 2D vectors (parameters must be normalized)

vector2LineAngle :: Vector2 -> Vector2 -> Float
vector2LineAngle :: Vector2 -> Vector2 -> Float
vector2LineAngle Vector2
a Vector2
b = forall a. Floating a => a -> a
acos forall a b. (a -> b) -> a -> b
$ Float -> Float -> Float -> Float
clamp (Vector2
a forall a. Vector a => a -> a -> Float
|.| Vector2
b) (-Float
1) Float
1

-- | 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 forall a. Num a => a -> a -> a
* Matrix -> Float
matrix'm0 Matrix
mat) forall a. Num a => a -> a -> a
+ (Float
y forall a. Num a => a -> a -> a
* Matrix -> Float
matrix'm4 Matrix
mat) forall a. Num a => a -> a -> a
+ Matrix -> Float
matrix'm12 Matrix
mat) ((Float
x forall a. Num a => a -> a -> a
* Matrix -> Float
matrix'm1 Matrix
mat) forall a. Num a => a -> a -> a
+ (Float
y forall a. Num a => a -> a -> a
* Matrix -> Float
matrix'm5 Matrix
mat) 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 forall a. Vector a => a -> a -> a
|-| (Vector2
normal forall a. Vector a => a -> Float -> a
|* (Float
2 forall a. Num a => a -> a -> a
* (Vector2
v 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 forall a. Num a => a -> a -> a
* Float
c forall a. Num a => a -> a -> a
- Float
y forall a. Num a => a -> a -> a
* Float
s) (Float
x forall a. Num a => a -> a -> a
* Float
s forall a. Num a => a -> a -> a
+ Float
y forall a. Num a => a -> a -> a
* Float
c)
  where
    c :: Float
c = forall a. Floating a => a -> a
cos Float
angle
    s :: Float
s = forall a. Floating a => a -> a
sin Float
angle

------------------------------------------------

-- 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 forall a. Num a => a -> a -> a
* Float
z2 forall a. Num a => a -> a -> a
- Float
z1 forall a. Num a => a -> a -> a
* Float
y2) (Float
z1 forall a. Num a => a -> a -> a
* Float
x2 forall a. Num a => a -> a -> a
- Float
x1 forall a. Num a => a -> a -> a
* Float
z2) (Float
x1 forall a. Num a => a -> a -> a
* Float
y2 forall a. Num a => a -> a -> a
- Float
y1 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
      | forall a. Num a => a -> a
abs Float
y forall a. Ord a => a -> a -> Bool
< forall a. Num a => a -> a
abs Float
x = Float -> Float -> Float -> Vector3
Vector3 Float
0 Float
1 Float
0
      | forall a. Num a => a -> a
abs Float
z forall a. Ord a => a -> a -> Bool
< 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 = 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 = forall a. Vector a => a -> Float
magnitude Vector3
cross
    dot :: Float
dot = Vector3
v1 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' = forall a. Vector a => a -> a
vectorNormalize Vector3
v1
    v2' :: Vector3
v2' = Vector3 -> Vector3 -> Vector3
vector3CrossProduct Vector3
vn1 Vector3
v1'
    vn1 :: Vector3
vn1 = forall a. Vector a => a -> a
vectorNormalize 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 forall a. Num a => a -> a -> a
* Float
m0 forall a. Num a => a -> a -> a
+ Float
y forall a. Num a => a -> a -> a
* Float
m4 forall a. Num a => a -> a -> a
+ Float
z forall a. Num a => a -> a -> a
* Float
m8 forall a. Num a => a -> a -> a
+ Float
m12)
      (Float
x forall a. Num a => a -> a -> a
* Float
m1 forall a. Num a => a -> a -> a
+ Float
y forall a. Num a => a -> a -> a
* Float
m5 forall a. Num a => a -> a -> a
+ Float
z forall a. Num a => a -> a -> a
* Float
m9 forall a. Num a => a -> a -> a
+ Float
m13)
      (Float
x forall a. Num a => a -> a -> a
* Float
m2 forall a. Num a => a -> a -> a
+ Float
y forall a. Num a => a -> a -> a
* Float
m6 forall a. Num a => a -> a -> a
+ Float
z forall a. Num a => a -> a -> a
* Float
m10 forall a. Num a => a -> a -> a
+ Float
m14)

-- | Transform a 3D vector by quaternion rotation

vector3RotateByQuaternion :: Vector3 -> Quaternion -> Vector3
vector3RotateByQuaternion :: Vector3 -> Vector4 -> 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 forall a. Num a => a -> a -> a
* (Float
x forall a. Num a => a -> a -> a
* Float
x forall a. Num a => a -> a -> a
+ Float
w forall a. Num a => a -> a -> a
* Float
w forall a. Num a => a -> a -> a
- Float
y forall a. Num a => a -> a -> a
* Float
y forall a. Num a => a -> a -> a
- Float
z forall a. Num a => a -> a -> a
* Float
z) forall a. Num a => a -> a -> a
+ Float
b forall a. Num a => a -> a -> a
* (Float
2 forall a. Num a => a -> a -> a
* Float
x forall a. Num a => a -> a -> a
* Float
y forall a. Num a => a -> a -> a
- Float
2 forall a. Num a => a -> a -> a
* Float
w forall a. Num a => a -> a -> a
* Float
z) forall a. Num a => a -> a -> a
+ Float
c forall a. Num a => a -> a -> a
* (Float
2 forall a. Num a => a -> a -> a
* Float
x forall a. Num a => a -> a -> a
* Float
z forall a. Num a => a -> a -> a
+ Float
2 forall a. Num a => a -> a -> a
* Float
w forall a. Num a => a -> a -> a
* Float
y))
    (Float
a forall a. Num a => a -> a -> a
* (Float
2 forall a. Num a => a -> a -> a
* Float
w forall a. Num a => a -> a -> a
* Float
z forall a. Num a => a -> a -> a
+ Float
2 forall a. Num a => a -> a -> a
* Float
x forall a. Num a => a -> a -> a
* Float
y) forall a. Num a => a -> a -> a
+ Float
b forall a. Num a => a -> a -> a
* (Float
w forall a. Num a => a -> a -> a
* Float
w forall a. Num a => a -> a -> a
- Float
x forall a. Num a => a -> a -> a
* Float
x forall a. Num a => a -> a -> a
+ Float
y forall a. Num a => a -> a -> a
* Float
y forall a. Num a => a -> a -> a
- Float
z forall a. Num a => a -> a -> a
* Float
z) forall a. Num a => a -> a -> a
+ Float
c forall a. Num a => a -> a -> a
* ((-Float
2) forall a. Num a => a -> a -> a
* Float
w forall a. Num a => a -> a -> a
* Float
x forall a. Num a => a -> a -> a
+ Float
2 forall a. Num a => a -> a -> a
* Float
y forall a. Num a => a -> a -> a
* Float
z))
    (Float
a forall a. Num a => a -> a -> a
* ((-Float
2) forall a. Num a => a -> a -> a
* Float
w forall a. Num a => a -> a -> a
* Float
y forall a. Num a => a -> a -> a
+ Float
2 forall a. Num a => a -> a -> a
* Float
x forall a. Num a => a -> a -> a
* Float
z) forall a. Num a => a -> a -> a
+ Float
b forall a. Num a => a -> a -> a
* (Float
2 forall a. Num a => a -> a -> a
* Float
w forall a. Num a => a -> a -> a
* Float
x forall a. Num a => a -> a -> a
+ Float
2 forall a. Num a => a -> a -> a
* Float
y forall a. Num a => a -> a -> a
* Float
z) forall a. Num a => a -> a -> a
+ Float
c forall a. Num a => a -> a -> a
* (Float
w forall a. Num a => a -> a -> a
* Float
w forall a. Num a => a -> a -> a
- Float
x forall a. Num a => a -> a -> a
* Float
x forall a. Num a => a -> a -> a
- Float
y forall a. Num a => a -> a -> a
* Float
y forall a. Num a => a -> a -> a
+ Float
z 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 forall a. Vector a => a -> a -> a
|+| (Vector3
wv forall a. Vector a => a -> Float -> a
|* (Float
2 forall a. Num a => a -> a -> a
* Float
a)) forall a. Vector a => a -> a -> a
|+| (Vector3
wwv forall a. Vector a => a -> Float -> a
|* Float
2)
  where
    (Vector3 Float
ax Float
ay Float
az) = forall a. Vector a => a -> a
vectorNormalize Vector3
axis
    s :: Float
s = forall a. Floating a => a -> a
sin (Float
angle forall a. Fractional a => a -> a -> a
/ Float
2)
    a :: Float
a = forall a. Floating a => a -> a
cos (Float
angle forall a. Fractional a => a -> a -> a
/ Float
2)
    b :: Float
b = Float
ax forall a. Num a => a -> a -> a
* Float
s
    c :: Float
c = Float
ay forall a. Num a => a -> a -> a
* Float
s
    d :: Float
d = Float
az 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 forall a. Vector a => a -> a -> a
|-| (Vector3
normal forall a. Vector a => a -> Float -> a
|* (Float
2 forall a. Num a => a -> a -> a
* Vector3
v 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 forall a. Num a => a -> a -> a
- Float
y forall a. Num a => a -> a -> a
- Float
z) Float
y Float
z
  where
    v0 :: Vector3
v0 = Vector3
b forall a. Vector a => a -> a -> a
|-| Vector3
a
    v1 :: Vector3
v1 = Vector3
c forall a. Vector a => a -> a -> a
|-| Vector3
a
    v2 :: Vector3
v2 = Vector3
p forall a. Vector a => a -> a -> a
|-| Vector3
a
    d00 :: Float
d00 = Vector3
v0 forall a. Vector a => a -> a -> Float
|.| Vector3
v0
    d01 :: Float
d01 = Vector3
v0 forall a. Vector a => a -> a -> Float
|.| Vector3
v1
    d11 :: Float
d11 = Vector3
v1 forall a. Vector a => a -> a -> Float
|.| Vector3
v1
    d20 :: Float
d20 = Vector3
v2 forall a. Vector a => a -> a -> Float
|.| Vector3
v0
    d21 :: Float
d21 = Vector3
v2 forall a. Vector a => a -> a -> Float
|.| Vector3
v1
    denom :: Float
denom = Float
d00 forall a. Num a => a -> a -> a
* Float
d11 forall a. Num a => a -> a -> a
- Float
d01 forall a. Num a => a -> a -> a
* Float
d01
    y :: Float
y = (Float
d11 forall a. Num a => a -> a -> a
* Float
d20 forall a. Num a => a -> a -> a
- Float
d01 forall a. Num a => a -> a -> a
* Float
d21) forall a. Fractional a => a -> a -> a
/ Float
denom
    z :: Float
z = (Float
d00 forall a. Num a => a -> a -> a
* Float
d21 forall a. Num a => a -> a -> a
- Float
d01 forall a. Num a => a -> a -> a
* Float
d20) 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 forall a. Fractional a => a -> a -> a
/ Float
rw) (Float
ry forall a. Fractional a => a -> a -> a
/ Float
rw) (Float
rz 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 forall a. Num a => a -> a -> a
* Float
a11 forall a. Num a => a -> a -> a
- Float
a01 forall a. Num a => a -> a -> a
* Float
a10
    b01 :: Float
b01 = Float
a00 forall a. Num a => a -> a -> a
* Float
a12 forall a. Num a => a -> a -> a
- Float
a02 forall a. Num a => a -> a -> a
* Float
a10
    b02 :: Float
b02 = Float
a00 forall a. Num a => a -> a -> a
* Float
a13 forall a. Num a => a -> a -> a
- Float
a03 forall a. Num a => a -> a -> a
* Float
a10
    b03 :: Float
b03 = Float
a01 forall a. Num a => a -> a -> a
* Float
a12 forall a. Num a => a -> a -> a
- Float
a02 forall a. Num a => a -> a -> a
* Float
a11
    b04 :: Float
b04 = Float
a01 forall a. Num a => a -> a -> a
* Float
a13 forall a. Num a => a -> a -> a
- Float
a03 forall a. Num a => a -> a -> a
* Float
a11
    b05 :: Float
b05 = Float
a02 forall a. Num a => a -> a -> a
* Float
a13 forall a. Num a => a -> a -> a
- Float
a03 forall a. Num a => a -> a -> a
* Float
a12
    b06 :: Float
b06 = Float
a20 forall a. Num a => a -> a -> a
* Float
a31 forall a. Num a => a -> a -> a
- Float
a21 forall a. Num a => a -> a -> a
* Float
a30
    b07 :: Float
b07 = Float
a20 forall a. Num a => a -> a -> a
* Float
a32 forall a. Num a => a -> a -> a
- Float
a22 forall a. Num a => a -> a -> a
* Float
a30
    b08 :: Float
b08 = Float
a20 forall a. Num a => a -> a -> a
* Float
a33 forall a. Num a => a -> a -> a
- Float
a23 forall a. Num a => a -> a -> a
* Float
a30
    b09 :: Float
b09 = Float
a21 forall a. Num a => a -> a -> a
* Float
a32 forall a. Num a => a -> a -> a
- Float
a22 forall a. Num a => a -> a -> a
* Float
a31
    b10 :: Float
b10 = Float
a21 forall a. Num a => a -> a -> a
* Float
a33 forall a. Num a => a -> a -> a
- Float
a23 forall a. Num a => a -> a -> a
* Float
a31
    b11 :: Float
b11 = Float
a22 forall a. Num a => a -> a -> a
* Float
a33 forall a. Num a => a -> a -> a
- Float
a23 forall a. Num a => a -> a -> a
* Float
a32
    invDet :: Float
invDet = Float
1 forall a. Fractional a => a -> a -> a
/ (Float
b00 forall a. Num a => a -> a -> a
* Float
b11 forall a. Num a => a -> a -> a
- Float
b01 forall a. Num a => a -> a -> a
* Float
b10 forall a. Num a => a -> a -> a
+ Float
b02 forall a. Num a => a -> a -> a
* Float
b09 forall a. Num a => a -> a -> a
+ Float
b03 forall a. Num a => a -> a -> a
* Float
b08 forall a. Num a => a -> a -> a
- Float
b04 forall a. Num a => a -> a -> a
* Float
b07 forall a. Num a => a -> a -> a
+ Float
b05 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 forall a. Num a => a -> a -> a
* Float
b11 forall a. Num a => a -> a -> a
- Float
a12 forall a. Num a => a -> a -> a
* Float
b10 forall a. Num a => a -> a -> a
+ Float
a13 forall a. Num a => a -> a -> a
* Float
b09) forall a. Num a => a -> a -> a
* Float
invDet)
        ((- Float
a01 forall a. Num a => a -> a -> a
* Float
b11 forall a. Num a => a -> a -> a
+ Float
a02 forall a. Num a => a -> a -> a
* Float
b10 forall a. Num a => a -> a -> a
- Float
a03 forall a. Num a => a -> a -> a
* Float
b09) forall a. Num a => a -> a -> a
* Float
invDet)
        ((Float
a31 forall a. Num a => a -> a -> a
* Float
b05 forall a. Num a => a -> a -> a
- Float
a32 forall a. Num a => a -> a -> a
* Float
b04 forall a. Num a => a -> a -> a
+ Float
a33 forall a. Num a => a -> a -> a
* Float
b03) forall a. Num a => a -> a -> a
* Float
invDet)
        ((- Float
a21 forall a. Num a => a -> a -> a
* Float
b05 forall a. Num a => a -> a -> a
+ Float
a22 forall a. Num a => a -> a -> a
* Float
b04 forall a. Num a => a -> a -> a
- Float
a23 forall a. Num a => a -> a -> a
* Float
b03) forall a. Num a => a -> a -> a
* Float
invDet)
        ((- Float
a10 forall a. Num a => a -> a -> a
* Float
b11 forall a. Num a => a -> a -> a
+ Float
a12 forall a. Num a => a -> a -> a
* Float
b08 forall a. Num a => a -> a -> a
- Float
a13 forall a. Num a => a -> a -> a
* Float
b07) forall a. Num a => a -> a -> a
* Float
invDet)
        ((Float
a00 forall a. Num a => a -> a -> a
* Float
b11 forall a. Num a => a -> a -> a
- Float
a02 forall a. Num a => a -> a -> a
* Float
b08 forall a. Num a => a -> a -> a
+ Float
a03 forall a. Num a => a -> a -> a
* Float
b07) forall a. Num a => a -> a -> a
* Float
invDet)
        ((- Float
a30 forall a. Num a => a -> a -> a
* Float
b05 forall a. Num a => a -> a -> a
+ Float
a32 forall a. Num a => a -> a -> a
* Float
b02 forall a. Num a => a -> a -> a
- Float
a33 forall a. Num a => a -> a -> a
* Float
b01) forall a. Num a => a -> a -> a
* Float
invDet)
        ((Float
a20 forall a. Num a => a -> a -> a
* Float
b05 forall a. Num a => a -> a -> a
- Float
a22 forall a. Num a => a -> a -> a
* Float
b02 forall a. Num a => a -> a -> a
+ Float
a23 forall a. Num a => a -> a -> a
* Float
b01) forall a. Num a => a -> a -> a
* Float
invDet)
        ((Float
a10 forall a. Num a => a -> a -> a
* Float
b10 forall a. Num a => a -> a -> a
- Float
a11 forall a. Num a => a -> a -> a
* Float
b08 forall a. Num a => a -> a -> a
+ Float
a13 forall a. Num a => a -> a -> a
* Float
b06) forall a. Num a => a -> a -> a
* Float
invDet)
        ((- Float
a00 forall a. Num a => a -> a -> a
* Float
b10 forall a. Num a => a -> a -> a
+ Float
a01 forall a. Num a => a -> a -> a
* Float
b08 forall a. Num a => a -> a -> a
- Float
a03 forall a. Num a => a -> a -> a
* Float
b06) forall a. Num a => a -> a -> a
* Float
invDet)
        ((Float
a30 forall a. Num a => a -> a -> a
* Float
b04 forall a. Num a => a -> a -> a
- Float
a31 forall a. Num a => a -> a -> a
* Float
b02 forall a. Num a => a -> a -> a
+ Float
a33 forall a. Num a => a -> a -> a
* Float
b00) forall a. Num a => a -> a -> a
* Float
invDet)
        ((- Float
a20 forall a. Num a => a -> a -> a
* Float
b04 forall a. Num a => a -> a -> a
+ Float
a21 forall a. Num a => a -> a -> a
* Float
b02 forall a. Num a => a -> a -> a
- Float
a23 forall a. Num a => a -> a -> a
* Float
b00) forall a. Num a => a -> a -> a
* Float
invDet)
        ((- Float
a10 forall a. Num a => a -> a -> a
* Float
b09 forall a. Num a => a -> a -> a
+ Float
a11 forall a. Num a => a -> a -> a
* Float
b07 forall a. Num a => a -> a -> a
- Float
a12 forall a. Num a => a -> a -> a
* Float
b06) forall a. Num a => a -> a -> a
* Float
invDet)
        ((Float
a00 forall a. Num a => a -> a -> a
* Float
b09 forall a. Num a => a -> a -> a
- Float
a01 forall a. Num a => a -> a -> a
* Float
b07 forall a. Num a => a -> a -> a
+ Float
a02 forall a. Num a => a -> a -> a
* Float
b06) forall a. Num a => a -> a -> a
* Float
invDet)
        ((- Float
a30 forall a. Num a => a -> a -> a
* Float
b03 forall a. Num a => a -> a -> a
+ Float
a31 forall a. Num a => a -> a -> a
* Float
b01 forall a. Num a => a -> a -> a
- Float
a32 forall a. Num a => a -> a -> a
* Float
b00) forall a. Num a => a -> a -> a
* Float
invDet)
        ((Float
a20 forall a. Num a => a -> a -> a
* Float
b03 forall a. Num a => a -> a -> a
- Float
a21 forall a. Num a => a -> a -> a
* Float
b01 forall a. Num a => a -> a -> a
+ Float
a22 forall a. Num a => a -> a -> a
* Float
b00) forall a. Num a => a -> a -> a
* Float
invDet)
    (Vector4 Float
rx Float
ry Float
rz Float
rw) = Vector4 -> Matrix -> Vector4
quaternionTransform (Float -> Float -> Float -> Float -> Vector4
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 forall a. Num a => a -> a -> a
* Float
x forall a. Num a => a -> a -> a
- (Float
r forall a. Num a => a -> a -> a
* Float
dot forall a. Num a => a -> a -> a
+ Float
d) forall a. Num a => a -> a -> a
* Float
nx) (Float
r forall a. Num a => a -> a -> a
* Float
y forall a. Num a => a -> a -> a
- (Float
r forall a. Num a => a -> a -> a
* Float
dot forall a. Num a => a -> a -> a
+ Float
d) forall a. Num a => a -> a -> a
* Float
ny) (Float
r forall a. Num a => a -> a -> a
* Float
z forall a. Num a => a -> a -> a
- (Float
r forall a. Num a => a -> a -> a
* Float
dot forall a. Num a => a -> a -> a
+ Float
d) forall a. Num a => a -> a -> a
* Float
nz)
  where
    dot :: Float
dot = Float
x forall a. Num a => a -> a -> a
* Float
nx forall a. Num a => a -> a -> a
+ Float
y forall a. Num a => a -> a -> a
* Float
ny forall a. Num a => a -> a -> a
+ Float
z forall a. Num a => a -> a -> a
* Float
nz
    d :: Float
d = forall a. Floating a => a -> a
sqrt forall a b. (a -> b) -> a -> b
$ Float
1 forall a. Num a => a -> a -> a
- Float
r forall a. Num a => a -> a -> a
* Float
r forall a. Num a => a -> a -> a
* (Float
1 forall a. Num a => a -> a -> a
- Float
dot 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]
_ = forall a. HasCallStack => [Char] -> a
error [Char]
"matrixFromList expects 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 forall a b. (a -> b) -> a -> b
$ 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 forall a. Num a => a -> a -> a
* Float
a21 forall a. Num a => a -> a -> a
* Float
a12 forall a. Num a => a -> a -> a
* Float
a03 forall a. Num a => a -> a -> a
- Float
a20 forall a. Num a => a -> a -> a
* Float
a31 forall a. Num a => a -> a -> a
* Float
a12 forall a. Num a => a -> a -> a
* Float
a03 forall a. Num a => a -> a -> a
- Float
a30 forall a. Num a => a -> a -> a
* Float
a11 forall a. Num a => a -> a -> a
* Float
a22 forall a. Num a => a -> a -> a
* Float
a03 forall a. Num a => a -> a -> a
+ Float
a10 forall a. Num a => a -> a -> a
* Float
a31 forall a. Num a => a -> a -> a
* Float
a22 forall a. Num a => a -> a -> a
* Float
a03
      forall a. Num a => a -> a -> a
+ Float
a20 forall a. Num a => a -> a -> a
* Float
a11 forall a. Num a => a -> a -> a
* Float
a32 forall a. Num a => a -> a -> a
* Float
a03 forall a. Num a => a -> a -> a
- Float
a10 forall a. Num a => a -> a -> a
* Float
a21 forall a. Num a => a -> a -> a
* Float
a32 forall a. Num a => a -> a -> a
* Float
a03 forall a. Num a => a -> a -> a
- Float
a30 forall a. Num a => a -> a -> a
* Float
a21 forall a. Num a => a -> a -> a
* Float
a02 forall a. Num a => a -> a -> a
* Float
a13
      forall a. Num a => a -> a -> a
+ Float
a20 forall a. Num a => a -> a -> a
* Float
a31 forall a. Num a => a -> a -> a
* Float
a02 forall a. Num a => a -> a -> a
* Float
a13
      forall a. Num a => a -> a -> a
+ Float
a30 forall a. Num a => a -> a -> a
* Float
a01 forall a. Num a => a -> a -> a
* Float
a22 forall a. Num a => a -> a -> a
* Float
a13 forall a. Num a => a -> a -> a
- Float
a00 forall a. Num a => a -> a -> a
* Float
a31 forall a. Num a => a -> a -> a
* Float
a22 forall a. Num a => a -> a -> a
* Float
a13 forall a. Num a => a -> a -> a
- Float
a20 forall a. Num a => a -> a -> a
* Float
a01 forall a. Num a => a -> a -> a
* Float
a32 forall a. Num a => a -> a -> a
* Float
a13
      forall a. Num a => a -> a -> a
+ Float
a00 forall a. Num a => a -> a -> a
* Float
a21 forall a. Num a => a -> a -> a
* Float
a32 forall a. Num a => a -> a -> a
* Float
a13
      forall a. Num a => a -> a -> a
+ Float
a30 forall a. Num a => a -> a -> a
* Float
a11 forall a. Num a => a -> a -> a
* Float
a02 forall a. Num a => a -> a -> a
* Float
a23 forall a. Num a => a -> a -> a
- Float
a10 forall a. Num a => a -> a -> a
* Float
a31 forall a. Num a => a -> a -> a
* Float
a02 forall a. Num a => a -> a -> a
* Float
a23 forall a. Num a => a -> a -> a
- Float
a30 forall a. Num a => a -> a -> a
* Float
a01 forall a. Num a => a -> a -> a
* Float
a12 forall a. Num a => a -> a -> a
* Float
a23
      forall a. Num a => a -> a -> a
+ Float
a00 forall a. Num a => a -> a -> a
* Float
a31 forall a. Num a => a -> a -> a
* Float
a12 forall a. Num a => a -> a -> a
* Float
a23
      forall a. Num a => a -> a -> a
+ Float
a10 forall a. Num a => a -> a -> a
* Float
a01 forall a. Num a => a -> a -> a
* Float
a32 forall a. Num a => a -> a -> a
* Float
a23 forall a. Num a => a -> a -> a
- Float
a00 forall a. Num a => a -> a -> a
* Float
a11 forall a. Num a => a -> a -> a
* Float
a32 forall a. Num a => a -> a -> a
* Float
a23 forall a. Num a => a -> a -> a
- Float
a20 forall a. Num a => a -> a -> a
* Float
a11 forall a. Num a => a -> a -> a
* Float
a02 forall a. Num a => a -> a -> a
* Float
a33
      forall a. Num a => a -> a -> a
+ Float
a10 forall a. Num a => a -> a -> a
* Float
a21 forall a. Num a => a -> a -> a
* Float
a02 forall a. Num a => a -> a -> a
* Float
a33
      forall a. Num a => a -> a -> a
+ Float
a20 forall a. Num a => a -> a -> a
* Float
a01 forall a. Num a => a -> a -> a
* Float
a12 forall a. Num a => a -> a -> a
* Float
a33 forall a. Num a => a -> a -> a
- Float
a00 forall a. Num a => a -> a -> a
* Float
a21 forall a. Num a => a -> a -> a
* Float
a12 forall a. Num a => a -> a -> a
* Float
a33 forall a. Num a => a -> a -> a
- Float
a10 forall a. Num a => a -> a -> a
* Float
a01 forall a. Num a => a -> a -> a
* Float
a22 forall a. Num a => a -> a -> a
* Float
a33
      forall a. Num a => a -> a -> a
+ Float
a00 forall a. Num a => a -> a -> a
* Float
a11 forall a. Num a => a -> a -> a
* Float
a22 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 forall a. Num a => a -> a -> a
+ Matrix -> Float
matrix'm5 Matrix
mat forall a. Num a => a -> a -> a
+ Matrix -> Float
matrix'm10 Matrix
mat 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 forall a. Num a => a -> a -> a
* Float
b11 forall a. Num a => a -> a -> a
- Float
a12 forall a. Num a => a -> a -> a
* Float
b10 forall a. Num a => a -> a -> a
+ Float
a13 forall a. Num a => a -> a -> a
* Float
b09) forall a. Num a => a -> a -> a
* Float
invDet)
      ((- Float
a10 forall a. Num a => a -> a -> a
* Float
b11 forall a. Num a => a -> a -> a
+ Float
a12 forall a. Num a => a -> a -> a
* Float
b08 forall a. Num a => a -> a -> a
- Float
a13 forall a. Num a => a -> a -> a
* Float
b07) forall a. Num a => a -> a -> a
* Float
invDet)
      ((Float
a10 forall a. Num a => a -> a -> a
* Float
b10 forall a. Num a => a -> a -> a
- Float
a11 forall a. Num a => a -> a -> a
* Float
b08 forall a. Num a => a -> a -> a
+ Float
a13 forall a. Num a => a -> a -> a
* Float
b06) forall a. Num a => a -> a -> a
* Float
invDet)
      ((- Float
a10 forall a. Num a => a -> a -> a
* Float
b09 forall a. Num a => a -> a -> a
+ Float
a11 forall a. Num a => a -> a -> a
* Float
b07 forall a. Num a => a -> a -> a
- Float
a12 forall a. Num a => a -> a -> a
* Float
b06) forall a. Num a => a -> a -> a
* Float
invDet)
      ((- Float
a01 forall a. Num a => a -> a -> a
* Float
b11 forall a. Num a => a -> a -> a
+ Float
a02 forall a. Num a => a -> a -> a
* Float
b10 forall a. Num a => a -> a -> a
- Float
a03 forall a. Num a => a -> a -> a
* Float
b09) forall a. Num a => a -> a -> a
* Float
invDet)
      ((Float
a00 forall a. Num a => a -> a -> a
* Float
b11 forall a. Num a => a -> a -> a
- Float
a02 forall a. Num a => a -> a -> a
* Float
b08 forall a. Num a => a -> a -> a
+ Float
a03 forall a. Num a => a -> a -> a
* Float
b07) forall a. Num a => a -> a -> a
* Float
invDet)
      ((- Float
a00 forall a. Num a => a -> a -> a
* Float
b10 forall a. Num a => a -> a -> a
+ Float
a01 forall a. Num a => a -> a -> a
* Float
b08 forall a. Num a => a -> a -> a
- Float
a03 forall a. Num a => a -> a -> a
* Float
b06) forall a. Num a => a -> a -> a
* Float
invDet)
      ((Float
a00 forall a. Num a => a -> a -> a
* Float
b09 forall a. Num a => a -> a -> a
- Float
a01 forall a. Num a => a -> a -> a
* Float
b07 forall a. Num a => a -> a -> a
+ Float
a02 forall a. Num a => a -> a -> a
* Float
b06) forall a. Num a => a -> a -> a
* Float
invDet)
      ((Float
a31 forall a. Num a => a -> a -> a
* Float
b05 forall a. Num a => a -> a -> a
- Float
a32 forall a. Num a => a -> a -> a
* Float
b04 forall a. Num a => a -> a -> a
+ Float
a33 forall a. Num a => a -> a -> a
* Float
b03) forall a. Num a => a -> a -> a
* Float
invDet)
      ((- Float
a30 forall a. Num a => a -> a -> a
* Float
b05 forall a. Num a => a -> a -> a
+ Float
a32 forall a. Num a => a -> a -> a
* Float
b02 forall a. Num a => a -> a -> a
- Float
a33 forall a. Num a => a -> a -> a
* Float
b01) forall a. Num a => a -> a -> a
* Float
invDet)
      ((Float
a30 forall a. Num a => a -> a -> a
* Float
b04 forall a. Num a => a -> a -> a
- Float
a31 forall a. Num a => a -> a -> a
* Float
b02 forall a. Num a => a -> a -> a
+ Float
a33 forall a. Num a => a -> a -> a
* Float
b00) forall a. Num a => a -> a -> a
* Float
invDet)
      ((- Float
a30 forall a. Num a => a -> a -> a
* Float
b03 forall a. Num a => a -> a -> a
+ Float
a31 forall a. Num a => a -> a -> a
* Float
b01 forall a. Num a => a -> a -> a
- Float
a32 forall a. Num a => a -> a -> a
* Float
b00) forall a. Num a => a -> a -> a
* Float
invDet)
      ((- Float
a21 forall a. Num a => a -> a -> a
* Float
b05 forall a. Num a => a -> a -> a
+ Float
a22 forall a. Num a => a -> a -> a
* Float
b04 forall a. Num a => a -> a -> a
- Float
a23 forall a. Num a => a -> a -> a
* Float
b03) forall a. Num a => a -> a -> a
* Float
invDet)
      ((Float
a20 forall a. Num a => a -> a -> a
* Float
b05 forall a. Num a => a -> a -> a
- Float
a22 forall a. Num a => a -> a -> a
* Float
b02 forall a. Num a => a -> a -> a
+ Float
a23 forall a. Num a => a -> a -> a
* Float
b01) forall a. Num a => a -> a -> a
* Float
invDet)
      ((- Float
a20 forall a. Num a => a -> a -> a
* Float
b04 forall a. Num a => a -> a -> a
+ Float
a21 forall a. Num a => a -> a -> a
* Float
b02 forall a. Num a => a -> a -> a
- Float
a23 forall a. Num a => a -> a -> a
* Float
b00) forall a. Num a => a -> a -> a
* Float
invDet)
      ((Float
a20 forall a. Num a => a -> a -> a
* Float
b03 forall a. Num a => a -> a -> a
- Float
a21 forall a. Num a => a -> a -> a
* Float
b01 forall a. Num a => a -> a -> a
+ Float
a22 forall a. Num a => a -> a -> a
* Float
b00) forall a. Num a => a -> a -> a
* Float
invDet)
    where
      b00 :: Float
b00 = Float
a00 forall a. Num a => a -> a -> a
* Float
a11 forall a. Num a => a -> a -> a
- Float
a01 forall a. Num a => a -> a -> a
* Float
a10
      b01 :: Float
b01 = Float
a00 forall a. Num a => a -> a -> a
* Float
a12 forall a. Num a => a -> a -> a
- Float
a02 forall a. Num a => a -> a -> a
* Float
a10
      b02 :: Float
b02 = Float
a00 forall a. Num a => a -> a -> a
* Float
a13 forall a. Num a => a -> a -> a
- Float
a03 forall a. Num a => a -> a -> a
* Float
a10
      b03 :: Float
b03 = Float
a01 forall a. Num a => a -> a -> a
* Float
a12 forall a. Num a => a -> a -> a
- Float
a02 forall a. Num a => a -> a -> a
* Float
a11
      b04 :: Float
b04 = Float
a01 forall a. Num a => a -> a -> a
* Float
a13 forall a. Num a => a -> a -> a
- Float
a03 forall a. Num a => a -> a -> a
* Float
a11
      b05 :: Float
b05 = Float
a02 forall a. Num a => a -> a -> a
* Float
a13 forall a. Num a => a -> a -> a
- Float
a03 forall a. Num a => a -> a -> a
* Float
a12
      b06 :: Float
b06 = Float
a20 forall a. Num a => a -> a -> a
* Float
a31 forall a. Num a => a -> a -> a
- Float
a21 forall a. Num a => a -> a -> a
* Float
a30
      b07 :: Float
b07 = Float
a20 forall a. Num a => a -> a -> a
* Float
a32 forall a. Num a => a -> a -> a
- Float
a22 forall a. Num a => a -> a -> a
* Float
a30
      b08 :: Float
b08 = Float
a20 forall a. Num a => a -> a -> a
* Float
a33 forall a. Num a => a -> a -> a
- Float
a23 forall a. Num a => a -> a -> a
* Float
a30
      b09 :: Float
b09 = Float
a21 forall a. Num a => a -> a -> a
* Float
a32 forall a. Num a => a -> a -> a
- Float
a22 forall a. Num a => a -> a -> a
* Float
a31
      b10 :: Float
b10 = Float
a21 forall a. Num a => a -> a -> a
* Float
a33 forall a. Num a => a -> a -> a
- Float
a23 forall a. Num a => a -> a -> a
* Float
a31
      b11 :: Float
b11 = Float
a22 forall a. Num a => a -> a -> a
* Float
a33 forall a. Num a => a -> a -> a
- Float
a23 forall a. Num a => a -> a -> a
* Float
a32
      invDet :: Float
invDet = Float
1 forall a. Fractional a => a -> a -> a
/ (Float
b00 forall a. Num a => a -> a -> a
* Float
b11 forall a. Num a => a -> a -> a
- Float
b01 forall a. Num a => a -> a -> a
* Float
b10 forall a. Num a => a -> a -> a
+ Float
b02 forall a. Num a => a -> a -> a
* Float
b09 forall a. Num a => a -> a -> a
+ Float
b03 forall a. Num a => a -> a -> a
* Float
b08 forall a. Num a => a -> a -> a
- Float
b04 forall a. Num a => a -> a -> a
* Float
b07 forall a. Num a => a -> a -> a
+ Float
b05 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 forall a b. (a -> b) -> a -> b
$ forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith 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 forall a b. (a -> b) -> a -> b
$ 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 forall a. Num a => a -> a -> a
* Float
r0 forall a. Num a => a -> a -> a
+ Float
l1 forall a. Num a => a -> a -> a
* Float
r4 forall a. Num a => a -> a -> a
+ Float
l2 forall a. Num a => a -> a -> a
* Float
r8 forall a. Num a => a -> a -> a
+ Float
l3 forall a. Num a => a -> a -> a
* Float
r12)
      (Float
l4 forall a. Num a => a -> a -> a
* Float
r0 forall a. Num a => a -> a -> a
+ Float
l5 forall a. Num a => a -> a -> a
* Float
r4 forall a. Num a => a -> a -> a
+ Float
l6 forall a. Num a => a -> a -> a
* Float
r8 forall a. Num a => a -> a -> a
+ Float
l7 forall a. Num a => a -> a -> a
* Float
r12)
      (Float
l8 forall a. Num a => a -> a -> a
* Float
r0 forall a. Num a => a -> a -> a
+ Float
l9 forall a. Num a => a -> a -> a
* Float
r4 forall a. Num a => a -> a -> a
+ Float
l10 forall a. Num a => a -> a -> a
* Float
r8 forall a. Num a => a -> a -> a
+ Float
l11 forall a. Num a => a -> a -> a
* Float
r12)
      (Float
l12 forall a. Num a => a -> a -> a
* Float
r0 forall a. Num a => a -> a -> a
+ Float
l13 forall a. Num a => a -> a -> a
* Float
r4 forall a. Num a => a -> a -> a
+ Float
l14 forall a. Num a => a -> a -> a
* Float
r8 forall a. Num a => a -> a -> a
+ Float
l15 forall a. Num a => a -> a -> a
* Float
r12)
      (Float
l0 forall a. Num a => a -> a -> a
* Float
r1 forall a. Num a => a -> a -> a
+ Float
l1 forall a. Num a => a -> a -> a
* Float
r5 forall a. Num a => a -> a -> a
+ Float
l2 forall a. Num a => a -> a -> a
* Float
r9 forall a. Num a => a -> a -> a
+ Float
l3 forall a. Num a => a -> a -> a
* Float
r13)
      (Float
l4 forall a. Num a => a -> a -> a
* Float
r1 forall a. Num a => a -> a -> a
+ Float
l5 forall a. Num a => a -> a -> a
* Float
r5 forall a. Num a => a -> a -> a
+ Float
l6 forall a. Num a => a -> a -> a
* Float
r9 forall a. Num a => a -> a -> a
+ Float
l7 forall a. Num a => a -> a -> a
* Float
r13)
      (Float
l8 forall a. Num a => a -> a -> a
* Float
r1 forall a. Num a => a -> a -> a
+ Float
l9 forall a. Num a => a -> a -> a
* Float
r5 forall a. Num a => a -> a -> a
+ Float
l10 forall a. Num a => a -> a -> a
* Float
r9 forall a. Num a => a -> a -> a
+ Float
l11 forall a. Num a => a -> a -> a
* Float
r13)
      (Float
l12 forall a. Num a => a -> a -> a
* Float
r1 forall a. Num a => a -> a -> a
+ Float
l13 forall a. Num a => a -> a -> a
* Float
r5 forall a. Num a => a -> a -> a
+ Float
l14 forall a. Num a => a -> a -> a
* Float
r9 forall a. Num a => a -> a -> a
+ Float
l15 forall a. Num a => a -> a -> a
* Float
r13)
      (Float
l0 forall a. Num a => a -> a -> a
* Float
r2 forall a. Num a => a -> a -> a
+ Float
l1 forall a. Num a => a -> a -> a
* Float
r6 forall a. Num a => a -> a -> a
+ Float
l2 forall a. Num a => a -> a -> a
* Float
r10 forall a. Num a => a -> a -> a
+ Float
l3 forall a. Num a => a -> a -> a
* Float
r14)
      (Float
l4 forall a. Num a => a -> a -> a
* Float
r2 forall a. Num a => a -> a -> a
+ Float
l5 forall a. Num a => a -> a -> a
* Float
r6 forall a. Num a => a -> a -> a
+ Float
l6 forall a. Num a => a -> a -> a
* Float
r10 forall a. Num a => a -> a -> a
+ Float
l7 forall a. Num a => a -> a -> a
* Float
r14)
      (Float
l8 forall a. Num a => a -> a -> a
* Float
r2 forall a. Num a => a -> a -> a
+ Float
l9 forall a. Num a => a -> a -> a
* Float
r6 forall a. Num a => a -> a -> a
+ Float
l10 forall a. Num a => a -> a -> a
* Float
r10 forall a. Num a => a -> a -> a
+ Float
l11 forall a. Num a => a -> a -> a
* Float
r14)
      (Float
l12 forall a. Num a => a -> a -> a
* Float
r2 forall a. Num a => a -> a -> a
+ Float
l13 forall a. Num a => a -> a -> a
* Float
r6 forall a. Num a => a -> a -> a
+ Float
l14 forall a. Num a => a -> a -> a
* Float
r10 forall a. Num a => a -> a -> a
+ Float
l15 forall a. Num a => a -> a -> a
* Float
r14)
      (Float
l0 forall a. Num a => a -> a -> a
* Float
r3 forall a. Num a => a -> a -> a
+ Float
l1 forall a. Num a => a -> a -> a
* Float
r7 forall a. Num a => a -> a -> a
+ Float
l2 forall a. Num a => a -> a -> a
* Float
r11 forall a. Num a => a -> a -> a
+ Float
l3 forall a. Num a => a -> a -> a
* Float
r15)
      (Float
l4 forall a. Num a => a -> a -> a
* Float
r3 forall a. Num a => a -> a -> a
+ Float
l5 forall a. Num a => a -> a -> a
* Float
r7 forall a. Num a => a -> a -> a
+ Float
l6 forall a. Num a => a -> a -> a
* Float
r11 forall a. Num a => a -> a -> a
+ Float
l7 forall a. Num a => a -> a -> a
* Float
r15)
      (Float
l8 forall a. Num a => a -> a -> a
* Float
r3 forall a. Num a => a -> a -> a
+ Float
l9 forall a. Num a => a -> a -> a
* Float
r7 forall a. Num a => a -> a -> a
+ Float
l10 forall a. Num a => a -> a -> a
* Float
r11 forall a. Num a => a -> a -> a
+ Float
l11 forall a. Num a => a -> a -> a
* Float
r15)
      (Float
l12 forall a. Num a => a -> a -> a
* Float
r3 forall a. Num a => a -> a -> a
+ Float
l13 forall a. Num a => a -> a -> a
* Float
r7 forall a. Num a => a -> a -> a
+ Float
l14 forall a. Num a => a -> a -> a
* Float
r11 forall a. Num a => a -> a -> a
+ Float
l15 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 forall a. Num a => a -> a -> a
* Float
x forall a. Num a => a -> a -> a
* Float
t forall a. Num a => a -> a -> a
+ Float
c) (Float
x forall a. Num a => a -> a -> a
* Float
y forall a. Num a => a -> a -> a
* Float
t forall a. Num a => a -> a -> a
- Float
z forall a. Num a => a -> a -> a
* Float
s) (Float
x forall a. Num a => a -> a -> a
* Float
z forall a. Num a => a -> a -> a
* Float
t forall a. Num a => a -> a -> a
+ Float
y forall a. Num a => a -> a -> a
* Float
s) Float
0 (Float
y forall a. Num a => a -> a -> a
* Float
x forall a. Num a => a -> a -> a
* Float
t forall a. Num a => a -> a -> a
+ Float
z forall a. Num a => a -> a -> a
* Float
s) (Float
y forall a. Num a => a -> a -> a
* Float
y forall a. Num a => a -> a -> a
* Float
t forall a. Num a => a -> a -> a
+ Float
c) (Float
y forall a. Num a => a -> a -> a
* Float
z forall a. Num a => a -> a -> a
* Float
t forall a. Num a => a -> a -> a
- Float
x forall a. Num a => a -> a -> a
* Float
s) Float
0 (Float
z forall a. Num a => a -> a -> a
* Float
x forall a. Num a => a -> a -> a
* Float
t forall a. Num a => a -> a -> a
- Float
y forall a. Num a => a -> a -> a
* Float
s) (Float
z forall a. Num a => a -> a -> a
* Float
y forall a. Num a => a -> a -> a
* Float
t forall a. Num a => a -> a -> a
+ Float
x forall a. Num a => a -> a -> a
* Float
s) (Float
z forall a. Num a => a -> a -> a
* Float
z forall a. Num a => a -> a -> a
* Float
t 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) = forall a. Vector a => a -> a
vectorNormalize Vector3
axis
    s :: Float
s = forall a. Floating a => a -> a
sin Float
angle
    c :: Float
c = forall a. Floating a => a -> a
cos Float
angle
    t :: Float
t = Float
1 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 = forall a. Floating a => a -> a
sin Float
angle
    c :: Float
c = 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 = forall a. Floating a => a -> a
sin Float
angle
    c :: Float
c = 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 = forall a. Floating a => a -> a
sin Float
angle
    c :: Float
c = 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 forall a. Num a => a -> a -> a
- Float
cy) (Float
sz forall a. Num a => a -> a -> a
* Float
cy) (- Float
sy) Float
0 (Float
cz forall a. Num a => a -> a -> a
* Float
sy forall a. Num a => a -> a -> a
* Float
sx forall a. Num a => a -> a -> a
- Float
sz forall a. Num a => a -> a -> a
* Float
cx) (Float
sz forall a. Num a => a -> a -> a
* Float
sy forall a. Num a => a -> a -> a
* Float
sx forall a. Num a => a -> a -> a
+ Float
cz forall a. Num a => a -> a -> a
* Float
cx) (Float
cy forall a. Num a => a -> a -> a
* Float
sx) Float
0 (Float
cz forall a. Num a => a -> a -> a
* Float
sy forall a. Num a => a -> a -> a
* Float
cx forall a. Num a => a -> a -> a
+ Float
sz forall a. Num a => a -> a -> a
* Float
sx) (Float
sz forall a. Num a => a -> a -> a
* Float
sy forall a. Num a => a -> a -> a
* Float
cx forall a. Num a => a -> a -> a
- Float
cz forall a. Num a => a -> a -> a
* Float
sx) (Float
cy forall a. Num a => a -> a -> a
* Float
cx) Float
0 Float
0 Float
0 Float
0 Float
1
  where
    cx :: Float
cx = forall a. Floating a => a -> a
cos (- Float
x)
    sx :: Float
sx = forall a. Floating a => a -> a
sin (- Float
x)
    cy :: Float
cy = forall a. Floating a => a -> a
cos (- Float
y)
    sy :: Float
sy = forall a. Floating a => a -> a
sin (- Float
y)
    cz :: Float
cz = forall a. Floating a => a -> a
cos (- Float
z)
    sz :: Float
sz = 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 forall a. Num a => a -> a -> a
* Float
cy) (Float
cz forall a. Num a => a -> a -> a
* Float
sy forall a. Num a => a -> a -> a
* Float
sx forall a. Num a => a -> a -> a
- Float
cx forall a. Num a => a -> a -> a
* Float
sz) (Float
sz forall a. Num a => a -> a -> a
* Float
sx forall a. Num a => a -> a -> a
+ Float
cz forall a. Num a => a -> a -> a
* Float
cx forall a. Num a => a -> a -> a
* Float
sy) Float
0 (Float
cy forall a. Num a => a -> a -> a
* Float
sz) (Float
cz forall a. Num a => a -> a -> a
* Float
cx forall a. Num a => a -> a -> a
+ Float
sz forall a. Num a => a -> a -> a
* Float
sy forall a. Num a => a -> a -> a
* Float
sx) (Float
cx forall a. Num a => a -> a -> a
* Float
sz forall a. Num a => a -> a -> a
* Float
sy forall a. Num a => a -> a -> a
- Float
cz forall a. Num a => a -> a -> a
* Float
sx) Float
0 (- Float
sy) (Float
cy forall a. Num a => a -> a -> a
* Float
sx) (Float
cy forall a. Num a => a -> a -> a
* Float
cx) Float
0 Float
0 Float
0 Float
0 Float
1
  where
    cz :: Float
cz = forall a. Floating a => a -> a
cos Float
z
    sz :: Float
sz = forall a. Floating a => a -> a
sin Float
z
    cy :: Float
cy = forall a. Floating a => a -> a
cos Float
y
    sy :: Float
sy = forall a. Floating a => a -> a
sin Float
y
    cx :: Float
cx = forall a. Floating a => a -> a
cos Float
x
    sx :: Float
sx = 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 forall a. Num a => a -> a -> a
* Float
2 forall a. Fractional a => a -> a -> a
/ Float
x)
    Float
0
    ((Float
right forall a. Num a => a -> a -> a
+ Float
left) forall a. Fractional a => a -> a -> a
/ Float
x)
    Float
0
    Float
0
    (Float
near forall a. Num a => a -> a -> a
* Float
2 forall a. Fractional a => a -> a -> a
/ Float
y)
    ((Float
top forall a. Num a => a -> a -> a
+ Float
bottom) forall a. Fractional a => a -> a -> a
/ Float
y)
    Float
0
    Float
0
    Float
0
    (- (Float
far forall a. Num a => a -> a -> a
+ Float
near) forall a. Fractional a => a -> a -> a
/ Float
z)
    (- Float
far forall a. Num a => a -> a -> a
* Float
near forall a. Num a => a -> a -> a
* Float
2 forall a. Fractional a => a -> a -> a
/ Float
z)
    Float
0
    Float
0
    (-Float
1)
    Float
0
  where
    x :: Float
x = Float
right forall a. Num a => a -> a -> a
- Float
left
    y :: Float
y = Float
top forall a. Num a => a -> a -> a
- Float
bottom
    z :: Float
z = Float
far 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 forall a. Num a => a -> a -> a
* forall a. Floating a => a -> a
tan (Float
fovy forall a. Fractional a => a -> a -> a
/ Float
2)
    bottom :: Float
bottom = - Float
top
    right :: Float
right = Float
top 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 forall a. Fractional a => a -> a -> a
/ Float
x) Float
0 Float
0 (- (Float
left forall a. Num a => a -> a -> a
+ Float
right) forall a. Fractional a => a -> a -> a
/ Float
x) Float
0 (Float
2 forall a. Fractional a => a -> a -> a
/ Float
y) Float
0 (- (Float
top forall a. Num a => a -> a -> a
+ Float
bottom) forall a. Fractional a => a -> a -> a
/ Float
y) Float
0 Float
0 (-Float
2 forall a. Fractional a => a -> a -> a
/ Float
z) (- (Float
far forall a. Num a => a -> a -> a
+ Float
near) forall a. Fractional a => a -> a -> a
/ Float
z) Float
0 Float
0 Float
0 Float
1
  where
    x :: Float
x = Float
right forall a. Num a => a -> a -> a
- Float
left
    y :: Float
y = Float
top forall a. Num a => a -> a -> a
- Float
bottom
    z :: Float
z = Float
far 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 forall a. Vector a => a -> a -> Float
|.| Vector3
eye) Float
yx Float
yy Float
yz (- Vector3
vy forall a. Vector a => a -> a -> Float
|.| Vector3
eye) Float
zx Float
zy Float
zz (- Vector3
vz 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) = forall a. Vector a => a -> a
vectorNormalize forall a b. (a -> b) -> a -> b
$ Vector3
eye forall a. Vector a => a -> a -> a
|-| Vector3
target
    vx :: Vector3
vx@(Vector3 Float
xx Float
xy Float
xz) = forall a. Vector a => a -> a
vectorNormalize 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 :: Vector4
quaternionIdentity = Float -> Float -> Float -> Float -> Vector4
Vector4 Float
0 Float
0 Float
0 Float
1

-- | Invert a quaternion

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

-- | Multiply two quaternions

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

-- | Normalize a quaternion (alias for 'vectorNormalize')

quaternionNormalize :: Quaternion -> Quaternion
quaternionNormalize :: Vector4 -> Vector4
quaternionNormalize = 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 :: Vector4 -> Vector4 -> Float -> Vector4
quaternionLerp = 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 :: Vector4 -> Vector4 -> Float -> Vector4
quaternionNLerp Vector4
q1 Vector4
q2 Float
amount = forall a. Vector a => a -> a
vectorNormalize forall a b. (a -> b) -> a -> b
$ Vector4 -> Vector4 -> Float -> Vector4
quaternionLerp Vector4
q1 Vector4
q2 Float
amount

-- | Spherical linear interpolation between two quaternions

quaternionSLerp ::
  -- | Lerp start value

  Quaternion ->
  -- | Lerp end value

  Quaternion ->
  -- | Lerp amount

  Float ->
  Quaternion
quaternionSLerp :: Vector4 -> Vector4 -> Float -> Vector4
quaternionSLerp Vector4
q1 Vector4
q2 Float
amount
  | Float
cosHalfTheta forall a. Ord a => a -> a -> Bool
>= Float
1 = Vector4
q1
  | Float
cosHalfTheta forall a. Ord a => a -> a -> Bool
> Float
0.95 = Vector4 -> Vector4 -> Float -> Vector4
quaternionNLerp Vector4
q1 Vector4
q2' Float
amount
  | forall a. Num a => a -> a
abs Float
sinHalfTheta forall a. Ord a => a -> a -> Bool
< Float
0.001 = (Vector4
q1 forall a. Vector a => a -> a -> a
|+| Vector4
q2') forall a. Vector a => a -> Float -> a
|/ Float
2
  | Bool
otherwise = (Vector4
q1 forall a. Vector a => a -> Float -> a
|* Float
ratioA) forall a. Vector a => a -> a -> a
|+| (Vector4
q2 forall a. Vector a => a -> Float -> a
|* Float
ratioB)
  where
    cosHalfTheta :: Float
cosHalfTheta = if Float
dot forall a. Ord a => a -> a -> Bool
< Float
0 then - Float
dot else Float
dot
    sinHalfTheta :: Float
sinHalfTheta = forall a. Floating a => a -> a
sqrt (Float
1 forall a. Num a => a -> a -> a
- Float
cosHalfTheta forall a. Num a => a -> a -> a
* Float
cosHalfTheta)
    halfTheta :: Float
halfTheta = forall a. Floating a => a -> a
acos Float
cosHalfTheta

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

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

-- | Quaternion based on the rotation between two vectors

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

-- | Create a rotation matrix from a quaternion

quaternionToMatrix :: Quaternion -> Matrix
quaternionToMatrix :: Vector4 -> 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 forall a. Num a => a -> a -> a
- Float
2 forall a. Num a => a -> a -> a
* (Float
b2 forall a. Num a => a -> a -> a
+ Float
c2)) (Float
2 forall a. Num a => a -> a -> a
* (Float
ab forall a. Num a => a -> a -> a
- Float
cd)) (Float
2 forall a. Num a => a -> a -> a
* (Float
ac forall a. Num a => a -> a -> a
+ Float
bd)) Float
0 (Float
2 forall a. Num a => a -> a -> a
* (Float
ab forall a. Num a => a -> a -> a
+ Float
cd)) (Float
1 forall a. Num a => a -> a -> a
- Float
2 forall a. Num a => a -> a -> a
* (Float
a2 forall a. Num a => a -> a -> a
+ Float
c2)) (Float
2 forall a. Num a => a -> a -> a
* (Float
bc forall a. Num a => a -> a -> a
- Float
ad)) Float
0 (Float
2 forall a. Num a => a -> a -> a
* (Float
ac forall a. Num a => a -> a -> a
- Float
bd)) (Float
2 forall a. Num a => a -> a -> a
* (Float
bc forall a. Num a => a -> a -> a
+ Float
ad)) (Float
1 forall a. Num a => a -> a -> a
- Float
2 forall a. Num a => a -> a -> a
* (Float
a2 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 forall a. Num a => a -> a -> a
* Float
x
    b2 :: Float
b2 = Float
y forall a. Num a => a -> a -> a
* Float
y
    c2 :: Float
c2 = Float
z forall a. Num a => a -> a -> a
* Float
z
    ac :: Float
ac = Float
x forall a. Num a => a -> a -> a
* Float
z
    ab :: Float
ab = Float
x forall a. Num a => a -> a -> a
* Float
y
    bc :: Float
bc = Float
y forall a. Num a => a -> a -> a
* Float
z
    ad :: Float
ad = Float
w forall a. Num a => a -> a -> a
* Float
x
    bd :: Float
bd = Float
w forall a. Num a => a -> a -> a
* Float
y
    cd :: Float
cd = Float
w 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 -> Vector4
quaternionFromAxisAngle Vector3
axis Float
angle = Vector4 -> Vector4
quaternionNormalize forall a b. (a -> b) -> a -> b
$ Float -> Float -> Float -> Float -> Vector4
Vector4 (Float
x forall a. Num a => a -> a -> a
* Float
s) (Float
y forall a. Num a => a -> a -> a
* Float
s) (Float
z forall a. Num a => a -> a -> a
* Float
s) Float
c -- I'm pretty sure normalizing the quaternion here is redundant

  where
    (Vector3 Float
x Float
y Float
z) = forall a. Vector a => a -> a
vectorNormalize Vector3
axis
    s :: Float
s = forall a. Floating a => a -> a
sin (Float
angle forall a. Fractional a => a -> a -> a
/ Float
2)
    c :: Float
c = forall a. Floating a => a -> a
cos (Float
angle forall a. Fractional a => a -> a -> a
/ Float
2)

-- | Convert a quaternion to axis-angle representation

quaternionToAxisAngle :: Quaternion -> (Vector3, Float)
quaternionToAxisAngle :: Vector4 -> (Vector3, Float)
quaternionToAxisAngle Vector4
q = (Vector3
axis, Float
angle)
  where
    (Vector4 Float
x Float
y Float
z Float
w) = Vector4 -> Vector4
quaternionNormalize Vector4
q
    s :: Float
s = forall a. Floating a => a -> a
sqrt (Float
1 forall a. Num a => a -> a -> a
- Float
w forall a. Num a => a -> a -> a
* Float
w)
    axis :: Vector3
axis = if Float
w 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 forall a. Fractional a => a -> a -> a
/ Float
s) (Float
y forall a. Fractional a => a -> a -> a
/ Float
s) (Float
z forall a. Fractional a => a -> a -> a
/ Float
s)
    angle :: Float
angle = forall a. Floating a => a -> a
acos Float
w 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 -> Vector4
quaternionFromEuler Float
pitch Float
yaw Float
roll = Float -> Float -> Float -> Float -> Vector4
Vector4 (Float
x1 forall a. Num a => a -> a -> a
* Float
y0 forall a. Num a => a -> a -> a
* Float
z0 forall a. Num a => a -> a -> a
- Float
x0 forall a. Num a => a -> a -> a
* Float
y1 forall a. Num a => a -> a -> a
* Float
z1) (Float
x0 forall a. Num a => a -> a -> a
* Float
y1 forall a. Num a => a -> a -> a
* Float
z0 forall a. Num a => a -> a -> a
+ Float
x1 forall a. Num a => a -> a -> a
* Float
y0 forall a. Num a => a -> a -> a
* Float
z1) (Float
x0 forall a. Num a => a -> a -> a
* Float
y0 forall a. Num a => a -> a -> a
* Float
z1 forall a. Num a => a -> a -> a
- Float
x1 forall a. Num a => a -> a -> a
* Float
y1 forall a. Num a => a -> a -> a
* Float
z0) (Float
x0 forall a. Num a => a -> a -> a
* Float
y0 forall a. Num a => a -> a -> a
* Float
z0 forall a. Num a => a -> a -> a
+ Float
x1 forall a. Num a => a -> a -> a
* Float
y1 forall a. Num a => a -> a -> a
* Float
z1)
  where
    x0 :: Float
x0 = forall a. Floating a => a -> a
cos (Float
pitch forall a. Num a => a -> a -> a
* Float
0.5)
    x1 :: Float
x1 = forall a. Floating a => a -> a
sin (Float
pitch forall a. Num a => a -> a -> a
* Float
0.5)
    y0 :: Float
y0 = forall a. Floating a => a -> a
cos (Float
yaw forall a. Num a => a -> a -> a
* Float
0.5)
    y1 :: Float
y1 = forall a. Floating a => a -> a
sin (Float
yaw forall a. Num a => a -> a -> a
* Float
0.5)
    z0 :: Float
z0 = forall a. Floating a => a -> a
cos (Float
roll forall a. Num a => a -> a -> a
* Float
0.5)
    z1 :: Float
z1 = forall a. Floating a => a -> a
sin (Float
roll 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 :: Vector4 -> Vector3
quaternionToEuler (Vector4 Float
x Float
y Float
z Float
w) = Float -> Float -> Float -> Vector3
Vector3 (forall a. RealFloat a => a -> a -> a
atan2 Float
x0 Float
x1) (forall a. Floating a => a -> a
asin Float
y0) (forall a. RealFloat a => a -> a -> a
atan2 Float
z0 Float
z1)
  where
    x0 :: Float
x0 = Float
2 forall a. Num a => a -> a -> a
* (Float
w forall a. Num a => a -> a -> a
* Float
x forall a. Num a => a -> a -> a
+ Float
y forall a. Num a => a -> a -> a
* Float
z)
    x1 :: Float
x1 = Float
1 forall a. Num a => a -> a -> a
- Float
2 forall a. Num a => a -> a -> a
* (Float
x forall a. Num a => a -> a -> a
* Float
x forall a. Num a => a -> a -> a
+ Float
y forall a. Num a => a -> a -> a
* Float
y)
    y0 :: Float
y0 = Float -> Float -> Float -> Float
clamp (Float
2 forall a. Num a => a -> a -> a
* (Float
w forall a. Num a => a -> a -> a
* Float
y forall a. Num a => a -> a -> a
- Float
z forall a. Num a => a -> a -> a
* Float
x)) (-Float
1) Float
1
    z0 :: Float
z0 = Float
2 forall a. Num a => a -> a -> a
* (Float
w forall a. Num a => a -> a -> a
* Float
z forall a. Num a => a -> a -> a
+ Float
x forall a. Num a => a -> a -> a
* Float
y)
    z1 :: Float
z1 = Float
1 forall a. Num a => a -> a -> a
- Float
2 forall a. Num a => a -> a -> a
* (Float
y forall a. Num a => a -> a -> a
* Float
y forall a. Num a => a -> a -> a
+ Float
z forall a. Num a => a -> a -> a
* Float
z)

-- | Transform a quaternion given a transformation matrix

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