{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE BlockArguments #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE MagicHash #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE PatternSynonyms #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE UnboxedTuples #-}
{-# LANGUAGE UnliftedFFITypes #-}
{-# LANGUAGE ViewPatterns #-}

-- | Specialized and inlined @V4 Float@.

module Geomancy.Vec4
  ( Vec4(..)
  , vec4
  , withVec4
  , pattern WithVec4
  , convert
  , fromVec2
  , fromVec22
  , fromVec3
  , fromTuple

  , (^*)
  , (^/)
  , lerp

  , dot
  , normalize

  , unsafeNewVec4
  ) where

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

import Control.DeepSeq (NFData(rnf))
import Data.MonoTraversable (Element, MonoFunctor(..), MonoPointed(..))
import Data.VectorSpace (VectorSpace)
import Foreign (Storable(..))
import Foreign.Ptr.Diff (peekDiffOff, pokeDiffOff)
import GHC.IO (IO(..))
import Text.Printf (printf)
import qualified Data.VectorSpace as VectorSpace

import Geomancy.Elementwise (Elementwise(..))
import Graphics.Gl.Block (Block(..))
import Geomancy.Gl.Funs (GlModf(..), GlNearest)
import Geomancy.Vec2 (Vec2, withVec2)
import Geomancy.Vec3 (Vec3, withVec3)

data Vec4 = Vec4 ByteArray#

{-# INLINE vec4 #-}
vec4 :: Float -> Float -> Float -> Float -> Vec4
vec4 :: Float -> Float -> Float -> Float -> Vec4
vec4 (F# Float#
v0) (F# Float#
v1) (F# Float#
v2) (F# Float#
v3) =
  forall o. (State# RealWorld -> o) -> o
runRW# \State# RealWorld
world ->
    let
      !(# State# RealWorld
world_, MutableByteArray# RealWorld
arr #) = forall d.
Int# -> Int# -> State# d -> (# State# d, MutableByteArray# d #)
newAlignedPinnedByteArray# Int#
16# Int#
16# State# RealWorld
world

      world0 :: State# RealWorld
world0 = forall d.
MutableByteArray# d -> Int# -> Float# -> State# d -> State# d
writeFloatArray# MutableByteArray# RealWorld
arr Int#
0x0# Float#
v0 State# RealWorld
world_
      world1 :: State# RealWorld
world1 = forall d.
MutableByteArray# d -> Int# -> Float# -> State# d -> State# d
writeFloatArray# MutableByteArray# RealWorld
arr Int#
0x1# Float#
v1 State# RealWorld
world0
      world2 :: State# RealWorld
world2 = forall d.
MutableByteArray# d -> Int# -> Float# -> State# d -> State# d
writeFloatArray# MutableByteArray# RealWorld
arr Int#
0x2# Float#
v2 State# RealWorld
world1
      world3 :: State# RealWorld
world3 = forall d.
MutableByteArray# d -> Int# -> Float# -> State# d -> State# d
writeFloatArray# MutableByteArray# RealWorld
arr Int#
0x3# Float#
v3 State# RealWorld
world2
      !(# State# RealWorld
_world', ByteArray#
arr' #) = forall d.
MutableByteArray# d -> State# d -> (# State# d, ByteArray# #)
unsafeFreezeByteArray# MutableByteArray# RealWorld
arr State# RealWorld
world3
    in
      ByteArray# -> Vec4
Vec4 ByteArray#
arr'

{-# INLINE withVec4 #-}
withVec4
  :: Vec4
  -> (Float -> Float -> Float -> Float -> r)
  -> r
withVec4 :: forall r. Vec4 -> (Float -> Float -> Float -> Float -> r) -> r
withVec4 (Vec4 ByteArray#
arr) Float -> Float -> Float -> Float -> r
f =
  Float -> Float -> Float -> Float -> r
f
    (Float# -> Float
F# (ByteArray# -> Int# -> Float#
indexFloatArray# ByteArray#
arr Int#
0x0#))
    (Float# -> Float
F# (ByteArray# -> Int# -> Float#
indexFloatArray# ByteArray#
arr Int#
0x1#))
    (Float# -> Float
F# (ByteArray# -> Int# -> Float#
indexFloatArray# ByteArray#
arr Int#
0x2#))
    (Float# -> Float
F# (ByteArray# -> Int# -> Float#
indexFloatArray# ByteArray#
arr Int#
0x3#))

{-# INLINE convert #-}
convert :: Coercible v Vec4 => (Float -> a) -> (a -> a -> a -> a -> r) -> v -> r
convert :: forall v a r.
Coercible v Vec4 =>
(Float -> a) -> (a -> a -> a -> a -> r) -> v -> r
convert Float -> a
f a -> a -> a -> a -> r
t v
v =
  forall r. Vec4 -> (Float -> Float -> Float -> Float -> r) -> r
withVec4 (coerce :: forall a b. Coercible a b => a -> b
coerce v
v) \Float
a Float
b Float
c Float
d->
    a -> a -> a -> a -> r
t (Float -> a
f Float
a) (Float -> a
f Float
b) (Float -> a
f Float
c) (Float -> a
f Float
d)

{-# INLINE compareVec4 #-}
compareVec4 :: Vec4 -> Vec4 -> Ordering
compareVec4 :: Vec4 -> Vec4 -> Ordering
compareVec4 (Vec4 ByteArray#
src1) (Vec4 ByteArray#
src2) =
  forall a. Ord a => a -> a -> Ordering
compare (Int# -> Int
I# (ByteArray# -> Int# -> ByteArray# -> Int# -> Int# -> Int#
compareByteArrays# ByteArray#
src1 Int#
0# ByteArray#
src2 Int#
0# Int#
16#)) Int
0

instance Eq Vec4 where
  == :: Vec4 -> Vec4 -> Bool
(==) Vec4
a Vec4
b =
    case Vec4 -> Vec4 -> Ordering
compareVec4 Vec4
a Vec4
b of
      Ordering
EQ -> Bool
True
      Ordering
_  -> Bool
False

  /= :: Vec4 -> Vec4 -> Bool
(/=) Vec4
a Vec4
b =
    case Vec4 -> Vec4 -> Ordering
compareVec4 Vec4
a Vec4
b of
      Ordering
EQ -> Bool
False
      Ordering
_  -> Bool
True

instance Ord Vec4 where
  compare :: Vec4 -> Vec4 -> Ordering
compare = Vec4 -> Vec4 -> Ordering
compareVec4

instance Show Vec4 where
  show :: Vec4 -> String
show Vec4
v =
    forall r. Vec4 -> (Float -> Float -> Float -> Float -> r) -> r
withVec4 Vec4
v forall a b. (a -> b) -> a -> b
$
      forall r. PrintfType r => String -> r
printf String
"Vec4 %.4f %.4f %.4f %.4f"

pattern WithVec4 :: Float -> Float -> Float -> Float -> Vec4
pattern $mWithVec4 :: forall {r}.
Vec4
-> (Float -> Float -> Float -> Float -> r) -> ((# #) -> r) -> r
WithVec4 a b c d <- ((`withVec4` (,,,)) -> (a, b, c, d))
{-# COMPLETE WithVec4 #-}

{-# INLINE fromVec2 #-}
fromVec2 :: Vec2 -> Float -> Float -> Vec4
fromVec2 :: Vec2 -> Float -> Float -> Vec4
fromVec2 Vec2
xy Float
z Float
w =
  forall r. Vec2 -> (Float -> Float -> r) -> r
withVec2 Vec2
xy \Float
x Float
y ->
    Float -> Float -> Float -> Float -> Vec4
vec4 Float
x Float
y Float
z Float
w

{-# INLINE fromVec22 #-}
fromVec22 :: Vec2 -> Vec2 -> Vec4
fromVec22 :: Vec2 -> Vec2 -> Vec4
fromVec22 Vec2
xy Vec2
zw =
  forall r. Vec2 -> (Float -> Float -> r) -> r
withVec2 Vec2
xy \Float
x Float
y ->
  forall r. Vec2 -> (Float -> Float -> r) -> r
withVec2 Vec2
zw \Float
z Float
w ->
    Float -> Float -> Float -> Float -> Vec4
vec4 Float
x Float
y Float
z Float
w

{-# INLINE fromVec3 #-}
fromVec3 :: Coercible a Vec3 => a -> Float -> Vec4
fromVec3 :: forall a. Coercible a Vec3 => a -> Float -> Vec4
fromVec3 a
xyz Float
w =
  forall r. Vec3 -> (Float -> Float -> Float -> r) -> r
withVec3 (coerce :: forall a b. Coercible a b => a -> b
coerce a
xyz) \Float
x Float
y Float
z ->
    Float -> Float -> Float -> Float -> Vec4
vec4 Float
x Float
y Float
z Float
w

{-# INLINE fromTuple #-}
fromTuple :: (Float, Float, Float, Float) -> Vec4
fromTuple :: (Float, Float, Float, Float) -> Vec4
fromTuple (Float
x, Float
y, Float
z, Float
w) = Float -> Float -> Float -> Float -> Vec4
vec4 Float
x Float
y Float
z Float
w

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

type instance Element Vec4 = Float

instance MonoFunctor Vec4 where
  {-# INLINE omap #-}
  omap :: (Element Vec4 -> Element Vec4) -> Vec4 -> Vec4
omap Element Vec4 -> Element Vec4
f Vec4
v =
    forall r. Vec4 -> (Float -> Float -> Float -> Float -> r) -> r
withVec4 Vec4
v \Float
x Float
y Float
z Float
w ->
      Float -> Float -> Float -> Float -> Vec4
vec4 (Element Vec4 -> Element Vec4
f Float
x) (Element Vec4 -> Element Vec4
f Float
y) (Element Vec4 -> Element Vec4
f Float
z) (Element Vec4 -> Element Vec4
f Float
w)

instance MonoPointed Vec4 where
  opoint :: Element Vec4 -> Vec4
opoint Element Vec4
x = Float -> Float -> Float -> Float -> Vec4
vec4 Element Vec4
x Element Vec4
x Element Vec4
x Element Vec4
x

instance Elementwise Vec4 where
  {-# INLINE emap2 #-}
  emap2 :: (Element Vec4 -> Element Vec4 -> Element Vec4)
-> Vec4 -> Vec4 -> Vec4
emap2 Element Vec4 -> Element Vec4 -> Element Vec4
f Vec4
p0 Vec4
p1 =
    forall r. Vec4 -> (Float -> Float -> Float -> Float -> r) -> r
withVec4 Vec4
p0 \Float
x0 Float
y0 Float
z0 Float
w0 ->
    forall r. Vec4 -> (Float -> Float -> Float -> Float -> r) -> r
withVec4 Vec4
p1 \Float
x1 Float
y1 Float
z1 Float
w1 ->
      Float -> Float -> Float -> Float -> Vec4
vec4
        (Element Vec4 -> Element Vec4 -> Element Vec4
f Float
x0 Float
x1)
        (Element Vec4 -> Element Vec4 -> Element Vec4
f Float
y0 Float
y1)
        (Element Vec4 -> Element Vec4 -> Element Vec4
f Float
z0 Float
z1)
        (Element Vec4 -> Element Vec4 -> Element Vec4
f Float
w0 Float
w1)

  {-# INLINE emap3 #-}
  emap3 :: (Element Vec4 -> Element Vec4 -> Element Vec4 -> Element Vec4)
-> Vec4 -> Vec4 -> Vec4 -> Vec4
emap3 Element Vec4 -> Element Vec4 -> Element Vec4 -> Element Vec4
f Vec4
p0 Vec4
p1 Vec4
p2 =
    forall r. Vec4 -> (Float -> Float -> Float -> Float -> r) -> r
withVec4 Vec4
p0 \Float
x0 Float
y0 Float
z0 Float
w0 ->
    forall r. Vec4 -> (Float -> Float -> Float -> Float -> r) -> r
withVec4 Vec4
p1 \Float
x1 Float
y1 Float
z1 Float
w1 ->
    forall r. Vec4 -> (Float -> Float -> Float -> Float -> r) -> r
withVec4 Vec4
p2 \Float
x2 Float
y2 Float
z2 Float
w2 ->
      Float -> Float -> Float -> Float -> Vec4
vec4
        (Element Vec4 -> Element Vec4 -> Element Vec4 -> Element Vec4
f Float
x0 Float
x1 Float
x2)
        (Element Vec4 -> Element Vec4 -> Element Vec4 -> Element Vec4
f Float
y0 Float
y1 Float
y2)
        (Element Vec4 -> Element Vec4 -> Element Vec4 -> Element Vec4
f Float
z0 Float
z1 Float
z2)
        (Element Vec4 -> Element Vec4 -> Element Vec4 -> Element Vec4
f Float
w0 Float
w1 Float
w2)

  {-# INLINE emap4 #-}
  emap4 :: (Element Vec4
 -> Element Vec4 -> Element Vec4 -> Element Vec4 -> Element Vec4)
-> Vec4 -> Vec4 -> Vec4 -> Vec4 -> Vec4
emap4 Element Vec4
-> Element Vec4 -> Element Vec4 -> Element Vec4 -> Element Vec4
f Vec4
p0 Vec4
p1 Vec4
p2 Vec4
p3 =
    forall r. Vec4 -> (Float -> Float -> Float -> Float -> r) -> r
withVec4 Vec4
p0 \Float
x0 Float
y0 Float
z0 Float
w0 ->
    forall r. Vec4 -> (Float -> Float -> Float -> Float -> r) -> r
withVec4 Vec4
p1 \Float
x1 Float
y1 Float
z1 Float
w1 ->
    forall r. Vec4 -> (Float -> Float -> Float -> Float -> r) -> r
withVec4 Vec4
p2 \Float
x2 Float
y2 Float
z2 Float
w2 ->
    forall r. Vec4 -> (Float -> Float -> Float -> Float -> r) -> r
withVec4 Vec4
p3 \Float
x3 Float
y3 Float
z3 Float
w3 ->
      Float -> Float -> Float -> Float -> Vec4
vec4
        (Element Vec4
-> Element Vec4 -> Element Vec4 -> Element Vec4 -> Element Vec4
f Float
x0 Float
x1 Float
x2 Float
x3)
        (Element Vec4
-> Element Vec4 -> Element Vec4 -> Element Vec4 -> Element Vec4
f Float
y0 Float
y1 Float
y2 Float
y3)
        (Element Vec4
-> Element Vec4 -> Element Vec4 -> Element Vec4 -> Element Vec4
f Float
z0 Float
z1 Float
z2 Float
z3)
        (Element Vec4
-> Element Vec4 -> Element Vec4 -> Element Vec4 -> Element Vec4
f Float
w0 Float
w1 Float
w2 Float
w3)

  {-# INLINE emap5 #-}
  emap5 :: (Element Vec4
 -> Element Vec4
 -> Element Vec4
 -> Element Vec4
 -> Element Vec4
 -> Element Vec4)
-> Vec4 -> Vec4 -> Vec4 -> Vec4 -> Vec4 -> Vec4
emap5 Element Vec4
-> Element Vec4
-> Element Vec4
-> Element Vec4
-> Element Vec4
-> Element Vec4
f Vec4
p0 Vec4
p1 Vec4
p2 Vec4
p3 Vec4
p4 =
    forall r. Vec4 -> (Float -> Float -> Float -> Float -> r) -> r
withVec4 Vec4
p0 \Float
x0 Float
y0 Float
z0 Float
w0 ->
    forall r. Vec4 -> (Float -> Float -> Float -> Float -> r) -> r
withVec4 Vec4
p1 \Float
x1 Float
y1 Float
z1 Float
w1 ->
    forall r. Vec4 -> (Float -> Float -> Float -> Float -> r) -> r
withVec4 Vec4
p2 \Float
x2 Float
y2 Float
z2 Float
w2 ->
    forall r. Vec4 -> (Float -> Float -> Float -> Float -> r) -> r
withVec4 Vec4
p3 \Float
x3 Float
y3 Float
z3 Float
w3 ->
    forall r. Vec4 -> (Float -> Float -> Float -> Float -> r) -> r
withVec4 Vec4
p4 \Float
x4 Float
y4 Float
z4 Float
w4 ->
      Float -> Float -> Float -> Float -> Vec4
vec4
        (Element Vec4
-> Element Vec4
-> Element Vec4
-> Element Vec4
-> Element Vec4
-> Element Vec4
f Float
x0 Float
x1 Float
x2 Float
x3 Float
x4)
        (Element Vec4
-> Element Vec4
-> Element Vec4
-> Element Vec4
-> Element Vec4
-> Element Vec4
f Float
y0 Float
y1 Float
y2 Float
y3 Float
y4)
        (Element Vec4
-> Element Vec4
-> Element Vec4
-> Element Vec4
-> Element Vec4
-> Element Vec4
f Float
z0 Float
z1 Float
z2 Float
z3 Float
z4)
        (Element Vec4
-> Element Vec4
-> Element Vec4
-> Element Vec4
-> Element Vec4
-> Element Vec4
f Float
w0 Float
w1 Float
w2 Float
w3 Float
w4)

instance Num Vec4 where
  {-# INLINE (+) #-}
  + :: Vec4 -> Vec4 -> Vec4
(+) Vec4
l Vec4
r =
    forall r. Vec4 -> (Float -> Float -> Float -> Float -> r) -> r
withVec4 Vec4
l \Float
l1 Float
l2 Float
l3 Float
l4 ->
      forall r. Vec4 -> (Float -> Float -> Float -> Float -> r) -> r
withVec4 Vec4
r \Float
r1 Float
r2 Float
r3 Float
r4 ->
        Float -> Float -> Float -> Float -> Vec4
vec4
          (Float
l1 forall a. Num a => a -> a -> a
+ Float
r1)
          (Float
l2 forall a. Num a => a -> a -> a
+ Float
r2)
          (Float
l3 forall a. Num a => a -> a -> a
+ Float
r3)
          (Float
l4 forall a. Num a => a -> a -> a
+ Float
r4)

  {-# INLINE (-) #-}
  (-) Vec4
l Vec4
r =
    forall r. Vec4 -> (Float -> Float -> Float -> Float -> r) -> r
withVec4 Vec4
l \Float
l1 Float
l2 Float
l3 Float
l4 ->
      forall r. Vec4 -> (Float -> Float -> Float -> Float -> r) -> r
withVec4 Vec4
r \Float
r1 Float
r2 Float
r3 Float
r4 ->
        Float -> Float -> Float -> Float -> Vec4
vec4
          (Float
l1 forall a. Num a => a -> a -> a
- Float
r1)
          (Float
l2 forall a. Num a => a -> a -> a
- Float
r2)
          (Float
l3 forall a. Num a => a -> a -> a
- Float
r3)
          (Float
l4 forall a. Num a => a -> a -> a
- Float
r4)

  {-# INLINE (*) #-}
  * :: Vec4 -> Vec4 -> Vec4
(*) Vec4
l Vec4
r =
    forall r. Vec4 -> (Float -> Float -> Float -> Float -> r) -> r
withVec4 Vec4
l \Float
l1 Float
l2 Float
l3 Float
l4 ->
      forall r. Vec4 -> (Float -> Float -> Float -> Float -> r) -> r
withVec4 Vec4
r \Float
r1 Float
r2 Float
r3 Float
r4 ->
        Float -> Float -> Float -> Float -> Vec4
vec4
          (Float
l1 forall a. Num a => a -> a -> a
* Float
r1)
          (Float
l2 forall a. Num a => a -> a -> a
* Float
r2)
          (Float
l3 forall a. Num a => a -> a -> a
* Float
r3)
          (Float
l4 forall a. Num a => a -> a -> a
* Float
r4)

  {-# INLINE abs #-}
  abs :: Vec4 -> Vec4
abs Vec4
v =
    forall r. Vec4 -> (Float -> Float -> Float -> Float -> r) -> r
withVec4 Vec4
v \Float
a Float
b Float
c Float
d ->
      Float -> Float -> Float -> Float -> Vec4
vec4 (forall a. Num a => a -> a
abs Float
a) (forall a. Num a => a -> a
abs Float
b) (forall a. Num a => a -> a
abs Float
c) (forall a. Num a => a -> a
abs Float
d)

  {-# INLINE signum #-}
  signum :: Vec4 -> Vec4
signum Vec4
v =
    forall r. Vec4 -> (Float -> Float -> Float -> Float -> r) -> r
withVec4 Vec4
v \Float
a Float
b Float
c Float
d ->
      Float -> Float -> Float -> Float -> Vec4
vec4 (forall a. Num a => a -> a
signum Float
a) (forall a. Num a => a -> a
signum Float
b) (forall a. Num a => a -> a
signum Float
c) (forall a. Num a => a -> a
signum Float
d)

  {-# INLINE fromInteger #-}
  fromInteger :: Integer -> Vec4
fromInteger Integer
x = Float -> Float -> Float -> Float -> Vec4
vec4 Float
x' Float
x' Float
x' Float
x'
    where
      x' :: Float
x' = forall a. Num a => Integer -> a
fromInteger Integer
x

instance Fractional Vec4 where
  {-# INLINE (/) #-}
  / :: Vec4 -> Vec4 -> Vec4
(/) Vec4
l Vec4
r =
    forall r. Vec4 -> (Float -> Float -> Float -> Float -> r) -> r
withVec4 Vec4
l \Float
l1 Float
l2 Float
l3 Float
l4 ->
      forall r. Vec4 -> (Float -> Float -> Float -> Float -> r) -> r
withVec4 Vec4
r \Float
r1 Float
r2 Float
r3 Float
r4 ->
        Float -> Float -> Float -> Float -> Vec4
vec4 (Float
l1 forall a. Fractional a => a -> a -> a
/ Float
r1) (Float
l2 forall a. Fractional a => a -> a -> a
/ Float
r2) (Float
l3 forall a. Fractional a => a -> a -> a
/ Float
r3) (Float
l4 forall a. Fractional a => a -> a -> a
/ Float
r4)

  {-# INLINE recip #-}
  recip :: Vec4 -> Vec4
recip Vec4
v =
    forall r. Vec4 -> (Float -> Float -> Float -> Float -> r) -> r
withVec4 Vec4
v \Float
a Float
b Float
c Float
d ->
      Float -> Float -> Float -> Float -> Vec4
vec4 (forall a. Fractional a => a -> a
recip Float
a) (forall a. Fractional a => a -> a
recip Float
b) (forall a. Fractional a => a -> a
recip Float
c) (forall a. Fractional a => a -> a
recip Float
d)

  {-# INLINE fromRational #-}
  fromRational :: Rational -> Vec4
fromRational Rational
x = Float -> Float -> Float -> Float -> Vec4
vec4 Float
x' Float
x' Float
x' Float
x'
    where
      x' :: Float
x' = forall a. Fractional a => Rational -> a
fromRational Rational
x

instance Floating Vec4 where
  pi :: Vec4
pi = forall mono. MonoPointed mono => Element mono -> mono
opoint forall a. Floating a => a
pi

  exp :: Vec4 -> Vec4
exp = forall mono.
MonoFunctor mono =>
(Element mono -> Element mono) -> mono -> mono
omap forall a. Floating a => a -> a
exp
  log :: Vec4 -> Vec4
log = forall mono.
MonoFunctor mono =>
(Element mono -> Element mono) -> mono -> mono
omap forall a. Floating a => a -> a
log
  sqrt :: Vec4 -> Vec4
sqrt = forall mono.
MonoFunctor mono =>
(Element mono -> Element mono) -> mono -> mono
omap forall a. Floating a => a -> a
sqrt
  sin :: Vec4 -> Vec4
sin = forall mono.
MonoFunctor mono =>
(Element mono -> Element mono) -> mono -> mono
omap forall a. Floating a => a -> a
sin
  cos :: Vec4 -> Vec4
cos = forall mono.
MonoFunctor mono =>
(Element mono -> Element mono) -> mono -> mono
omap forall a. Floating a => a -> a
cos
  asin :: Vec4 -> Vec4
asin = forall mono.
MonoFunctor mono =>
(Element mono -> Element mono) -> mono -> mono
omap forall a. Floating a => a -> a
asin
  acos :: Vec4 -> Vec4
acos = forall mono.
MonoFunctor mono =>
(Element mono -> Element mono) -> mono -> mono
omap forall a. Floating a => a -> a
acos
  atan :: Vec4 -> Vec4
atan = forall mono.
MonoFunctor mono =>
(Element mono -> Element mono) -> mono -> mono
omap forall a. Floating a => a -> a
atan
  sinh :: Vec4 -> Vec4
sinh = forall mono.
MonoFunctor mono =>
(Element mono -> Element mono) -> mono -> mono
omap forall a. Floating a => a -> a
sinh
  cosh :: Vec4 -> Vec4
cosh = forall mono.
MonoFunctor mono =>
(Element mono -> Element mono) -> mono -> mono
omap forall a. Floating a => a -> a
cosh
  asinh :: Vec4 -> Vec4
asinh = forall mono.
MonoFunctor mono =>
(Element mono -> Element mono) -> mono -> mono
omap forall a. Floating a => a -> a
asinh
  acosh :: Vec4 -> Vec4
acosh = forall mono.
MonoFunctor mono =>
(Element mono -> Element mono) -> mono -> mono
omap forall a. Floating a => a -> a
acosh
  atanh :: Vec4 -> Vec4
atanh = forall mono.
MonoFunctor mono =>
(Element mono -> Element mono) -> mono -> mono
omap forall a. Floating a => a -> a
atanh

  Vec4
a ** :: Vec4 -> Vec4 -> Vec4
** Vec4
b =
    forall r. Vec4 -> (Float -> Float -> Float -> Float -> r) -> r
withVec4 Vec4
a \Float
ax Float
ay Float
az Float
aw ->
    forall r. Vec4 -> (Float -> Float -> Float -> Float -> r) -> r
withVec4 Vec4
b \Float
bx Float
by Float
bz Float
bw ->
      Float -> Float -> Float -> Float -> Vec4
vec4
        (Float
ax forall a. Floating a => a -> a -> a
** Float
bx)
        (Float
ay forall a. Floating a => a -> a -> a
** Float
by)
        (Float
az forall a. Floating a => a -> a -> a
** Float
bz)
        (Float
aw forall a. Floating a => a -> a -> a
** Float
bw)

instance Storable Vec4 where
  {-# INLINE sizeOf #-}
  sizeOf :: Vec4 -> Int
sizeOf Vec4
_ = Int
16

  {-# INLINE alignment #-}
  alignment :: Vec4 -> Int
alignment Vec4
_ = Int
16

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

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

instance Block Vec4 where
  type PackedSize Vec4 = 16
  alignment140 :: forall (proxy :: * -> *). proxy Vec4 -> Int
alignment140 proxy Vec4
_  = Int
16
  sizeOf140 :: forall (proxy :: * -> *). proxy Vec4 -> Int
sizeOf140       = forall b (proxy :: * -> *). Block b => proxy b -> Int
sizeOfPacked
  alignment430 :: forall (proxy :: * -> *). proxy Vec4 -> Int
alignment430    = forall b (proxy :: * -> *). Block b => proxy b -> Int
alignment140
  sizeOf430 :: forall (proxy :: * -> *). proxy Vec4 -> Int
sizeOf430       = forall b (proxy :: * -> *). Block b => proxy b -> Int
sizeOf140
  isStruct :: forall (proxy :: * -> *). proxy Vec4 -> Bool
isStruct proxy Vec4
_      = Bool
False
  read140 :: forall (m :: * -> *) a. MonadIO m => Ptr a -> Diff a Vec4 -> m Vec4
read140     = forall (m :: * -> *) b a.
(MonadIO m, Storable b) =>
Ptr a -> Diff a b -> m b
peekDiffOff
  write140 :: forall (m :: * -> *) a.
MonadIO m =>
Ptr a -> Diff a Vec4 -> Vec4 -> m ()
write140    = forall (m :: * -> *) b a.
(MonadIO m, Storable b) =>
Ptr a -> Diff a b -> b -> m ()
pokeDiffOff
  read430 :: forall (m :: * -> *) a. MonadIO m => Ptr a -> Diff a Vec4 -> m Vec4
read430     = forall b (m :: * -> *) a.
(Block b, MonadIO m) =>
Ptr a -> Diff a b -> m b
read140
  write430 :: forall (m :: * -> *) a.
MonadIO m =>
Ptr a -> Diff a Vec4 -> Vec4 -> m ()
write430    = forall b (m :: * -> *) a.
(Block b, MonadIO m) =>
Ptr a -> Diff a b -> b -> m ()
write140
  readPacked :: forall (m :: * -> *) a. MonadIO m => Ptr a -> Diff a Vec4 -> m Vec4
readPacked  = forall b (m :: * -> *) a.
(Block b, MonadIO m) =>
Ptr a -> Diff a b -> m b
read140
  writePacked :: forall (m :: * -> *) a.
MonadIO m =>
Ptr a -> Diff a Vec4 -> Vec4 -> m ()
writePacked = forall b (m :: * -> *) a.
(Block b, MonadIO m) =>
Ptr a -> Diff a b -> b -> m ()
write140
  {-# INLINE alignment140 #-}
  {-# INLINE sizeOf140 #-}
  {-# INLINE alignment430 #-}
  {-# INLINE sizeOf430 #-}
  {-# INLINE isStruct #-}
  {-# INLINE read140 #-}
  {-# INLINE write140 #-}
  {-# INLINE read430 #-}
  {-# INLINE write430 #-}
  {-# INLINE readPacked #-}
  {-# INLINE writePacked #-}

instance VectorSpace Vec4 Float where
  zeroVector :: Vec4
zeroVector = forall a. Elementwise a => Element a -> a
epoint Float
0

  {-# INLINE (*^) #-}
  *^ :: Float -> Vec4 -> Vec4
(*^) = forall a b c. (a -> b -> c) -> b -> a -> c
flip Vec4 -> Float -> Vec4
(Geomancy.Vec4.^*)

  {-# INLINE (^/) #-}
  ^/ :: Vec4 -> Float -> Vec4
(^/) = Vec4 -> Float -> Vec4
(Geomancy.Vec4.^/)

  {-# INLINE (^+^) #-}
  ^+^ :: Vec4 -> Vec4 -> Vec4
(^+^) = forall a.
Elementwise a =>
(Element a -> Element a -> Element a) -> a -> a -> a
emap2 forall a. Num a => a -> a -> a
(+)

  {-# INLINE (^-^) #-}
  ^-^ :: Vec4 -> Vec4 -> Vec4
(^-^) = forall a.
Elementwise a =>
(Element a -> Element a -> Element a) -> a -> a -> a
emap2 (-)

  {-# INLINE negateVector #-}
  negateVector :: Vec4 -> Vec4
negateVector = forall a. Elementwise a => (Element a -> Element a) -> a -> a
emap forall a. Num a => a -> a
negate

  {-# INLINE dot #-}
  dot :: Vec4 -> Vec4 -> Float
dot = Vec4 -> Vec4 -> Float
Geomancy.Vec4.dot

  {-# INLINE normalize #-}
  normalize :: Vec4 -> Vec4
normalize = Vec4 -> Vec4
Geomancy.Vec4.normalize

-- TODO: SIMD
{-# INLINE (^*) #-}
(^*) :: Vec4 -> Float -> Vec4
^* :: Vec4 -> Float -> Vec4
(^*) Vec4
v Float
x =
  forall r. Vec4 -> (Float -> Float -> Float -> Float -> r) -> r
withVec4 Vec4
v \Float
a Float
b Float
c Float
d ->
    Float -> Float -> Float -> Float -> Vec4
vec4
      (Float
a forall a. Num a => a -> a -> a
* Float
x)
      (Float
b forall a. Num a => a -> a -> a
* Float
x)
      (Float
c forall a. Num a => a -> a -> a
* Float
x)
      (Float
d forall a. Num a => a -> a -> a
* Float
x)

{-# INLINE (^/) #-}
(^/) :: Vec4 -> Float -> Vec4
Vec4
v ^/ :: Vec4 -> Float -> Vec4
^/ Float
x = Vec4
v Vec4 -> Float -> Vec4
^* forall a. Fractional a => a -> a
recip Float
x

{-# INLINE lerp #-}
lerp :: Float -> Vec4 -> Vec4 -> Vec4
lerp :: Float -> Vec4 -> Vec4 -> Vec4
lerp Float
alpha Vec4
u Vec4
v = Vec4
u Vec4 -> Float -> Vec4
^* Float
alpha forall a. Num a => a -> a -> a
+ Vec4
v Vec4 -> Float -> Vec4
^* (Float
1 forall a. Num a => a -> a -> a
- Float
alpha)

-- TODO: SIMD
{-# INLINE dot #-}
dot :: Vec4 -> Vec4 -> Float
dot :: Vec4 -> Vec4 -> Float
dot Vec4
a Vec4
b =
  forall r. Vec4 -> (Float -> Float -> Float -> Float -> r) -> r
withVec4 Vec4
a \Float
a1 Float
a2 Float
a3 Float
a4 ->
    forall r. Vec4 -> (Float -> Float -> Float -> Float -> r) -> r
withVec4 Vec4
b \Float
b1 Float
b2 Float
b3 Float
b4 ->
      Float
a1 forall a. Num a => a -> a -> a
* Float
b1 forall a. Num a => a -> a -> a
+
      Float
a2 forall a. Num a => a -> a -> a
* Float
b2 forall a. Num a => a -> a -> a
+
      Float
a3 forall a. Num a => a -> a -> a
* Float
b3 forall a. Num a => a -> a -> a
+
      Float
a4 forall a. Num a => a -> a -> a
* Float
b4

{-# INLINE normalize #-}
normalize :: Vec4 -> Vec4
normalize :: Vec4 -> Vec4
normalize Vec4
v =
  if forall {a}. (Ord a, Fractional a) => a -> Bool
nearZero Float
q Bool -> Bool -> Bool
|| forall {a}. (Ord a, Fractional a) => a -> Bool
nearZero (Float
1forall a. Num a => a -> a -> a
-Float
q) then
    Vec4
v
  else
    Vec4
v Vec4 -> Float -> Vec4
^/ Float
l

  where
    q :: Float
q = Vec4 -> Vec4 -> Float
dot Vec4
v Vec4
v
    l :: Float
l = forall a. Floating a => a -> a
sqrt Float
q

    nearZero :: a -> Bool
nearZero a
a = forall a. Num a => a -> a
abs a
a forall a. Ord a => a -> a -> Bool
<= a
1e-6

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

instance GlNearest Vec4

instance GlModf Vec4 Vec4 where
  glModf :: Vec4 -> (Vec4, Vec4)
glModf Vec4
v =
    forall r. Vec4 -> (Float -> Float -> Float -> Float -> r) -> r
withVec4 Vec4
v \Float
vx Float
vy Float
vz Float
vw ->
      let
        (Integer
xi, Float
xf) = forall i f. GlModf i f => f -> (i, f)
glModf Float
vx
        (Integer
yi, Float
yf) = forall i f. GlModf i f => f -> (i, f)
glModf Float
vy
        (Integer
zi, Float
zf) = forall i f. GlModf i f => f -> (i, f)
glModf Float
vz
        (Integer
wi, Float
wf) = forall i f. GlModf i f => f -> (i, f)
glModf Float
vw
      in
        ( Float -> Float -> Float -> Float -> Vec4
vec4 (forall a. Num a => Integer -> a
fromInteger Integer
xi) (forall a. Num a => Integer -> a
fromInteger Integer
yi) (forall a. Num a => Integer -> a
fromInteger Integer
zi) (forall a. Num a => Integer -> a
fromInteger Integer
wi)
        , Float -> Float -> Float -> Float -> Vec4
vec4 Float
xf Float
yf Float
zf Float
wf
        )