{-# LANGUAGE BlockArguments #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE PatternSynonyms #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE ViewPatterns #-}

-- | Specialized and inlined @V2 Float@.

module Geomancy.Vec2
  ( Vec2
  , vec2
  , withVec2
  , pattern WithVec2
  , fromTuple

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

  , dot
  , normalize
  ) where

import Control.DeepSeq (NFData(rnf))
import Data.MonoTraversable (Element, MonoFunctor(..), MonoPointed(..))
import Data.VectorSpace (VectorSpace)
import Foreign (Storable(..))
import qualified Data.VectorSpace as VectorSpace

import Geomancy.Elementwise (Elementwise(..))
import Geomancy.Gl.Funs (GlModf(..), GlNearest)

data Vec2 = Vec2
  {-# UNPACK #-} !Float
  {-# UNPACK #-} !Float
  deriving (Vec2 -> Vec2 -> Bool
(Vec2 -> Vec2 -> Bool) -> (Vec2 -> Vec2 -> Bool) -> Eq Vec2
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Vec2 -> Vec2 -> Bool
$c/= :: Vec2 -> Vec2 -> Bool
== :: Vec2 -> Vec2 -> Bool
$c== :: Vec2 -> Vec2 -> Bool
Eq, Eq Vec2
Eq Vec2
-> (Vec2 -> Vec2 -> Ordering)
-> (Vec2 -> Vec2 -> Bool)
-> (Vec2 -> Vec2 -> Bool)
-> (Vec2 -> Vec2 -> Bool)
-> (Vec2 -> Vec2 -> Bool)
-> (Vec2 -> Vec2 -> Vec2)
-> (Vec2 -> Vec2 -> Vec2)
-> Ord Vec2
Vec2 -> Vec2 -> Bool
Vec2 -> Vec2 -> Ordering
Vec2 -> Vec2 -> Vec2
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: Vec2 -> Vec2 -> Vec2
$cmin :: Vec2 -> Vec2 -> Vec2
max :: Vec2 -> Vec2 -> Vec2
$cmax :: Vec2 -> Vec2 -> Vec2
>= :: Vec2 -> Vec2 -> Bool
$c>= :: Vec2 -> Vec2 -> Bool
> :: Vec2 -> Vec2 -> Bool
$c> :: Vec2 -> Vec2 -> Bool
<= :: Vec2 -> Vec2 -> Bool
$c<= :: Vec2 -> Vec2 -> Bool
< :: Vec2 -> Vec2 -> Bool
$c< :: Vec2 -> Vec2 -> Bool
compare :: Vec2 -> Vec2 -> Ordering
$ccompare :: Vec2 -> Vec2 -> Ordering
$cp1Ord :: Eq Vec2
Ord, Int -> Vec2 -> ShowS
[Vec2] -> ShowS
Vec2 -> String
(Int -> Vec2 -> ShowS)
-> (Vec2 -> String) -> ([Vec2] -> ShowS) -> Show Vec2
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Vec2] -> ShowS
$cshowList :: [Vec2] -> ShowS
show :: Vec2 -> String
$cshow :: Vec2 -> String
showsPrec :: Int -> Vec2 -> ShowS
$cshowsPrec :: Int -> Vec2 -> ShowS
Show)

{-# INLINE vec2 #-}
vec2 :: Float -> Float -> Vec2
vec2 :: Float -> Float -> Vec2
vec2 = Float -> Float -> Vec2
Vec2

{-# INLINE withVec2 #-}
withVec2
  :: Vec2
  -> (Float -> Float -> r)
  -> r
withVec2 :: Vec2 -> (Float -> Float -> r) -> r
withVec2 (Vec2 Float
a Float
b) Float -> Float -> r
f = Float -> Float -> r
f Float
a Float
b

pattern WithVec2 :: Float -> Float -> Vec2
pattern $mWithVec2 :: forall r. Vec2 -> (Float -> Float -> r) -> (Void# -> r) -> r
WithVec2 a b <- ((`withVec2` (,)) -> (a, b))
{-# COMPLETE WithVec2 #-}

{-# INLINE fromTuple #-}
fromTuple :: (Float, Float) -> Vec2
fromTuple :: (Float, Float) -> Vec2
fromTuple (Float
x, Float
y) = Float -> Float -> Vec2
vec2 Float
x Float
y

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

type instance Element Vec2 = Float

instance MonoFunctor Vec2 where
  {-# INLINE omap #-}
  omap :: (Element Vec2 -> Element Vec2) -> Vec2 -> Vec2
omap Element Vec2 -> Element Vec2
f Vec2
v =
    Vec2 -> (Float -> Float -> Vec2) -> Vec2
forall r. Vec2 -> (Float -> Float -> r) -> r
withVec2 Vec2
v \Float
x Float
y ->
      Float -> Float -> Vec2
vec2 (Element Vec2 -> Element Vec2
f Float
Element Vec2
x) (Element Vec2 -> Element Vec2
f Float
Element Vec2
y)

instance MonoPointed Vec2 where
  opoint :: Element Vec2 -> Vec2
opoint Element Vec2
x = Float -> Float -> Vec2
vec2 Float
Element Vec2
x Float
Element Vec2
x

instance Elementwise Vec2 where
  {-# INLINE emap2 #-}
  emap2 :: (Element Vec2 -> Element Vec2 -> Element Vec2)
-> Vec2 -> Vec2 -> Vec2
emap2 Element Vec2 -> Element Vec2 -> Element Vec2
f Vec2
p0 Vec2
p1 =
    Vec2 -> (Float -> Float -> Vec2) -> Vec2
forall r. Vec2 -> (Float -> Float -> r) -> r
withVec2 Vec2
p0 \Float
x0 Float
y0 ->
    Vec2 -> (Float -> Float -> Vec2) -> Vec2
forall r. Vec2 -> (Float -> Float -> r) -> r
withVec2 Vec2
p1 \Float
x1 Float
y1 ->
      Float -> Float -> Vec2
vec2
        (Element Vec2 -> Element Vec2 -> Element Vec2
f Float
Element Vec2
x0 Float
Element Vec2
x1)
        (Element Vec2 -> Element Vec2 -> Element Vec2
f Float
Element Vec2
y0 Float
Element Vec2
y1)

  {-# INLINE emap3 #-}
  emap3 :: (Element Vec2 -> Element Vec2 -> Element Vec2 -> Element Vec2)
-> Vec2 -> Vec2 -> Vec2 -> Vec2
emap3 Element Vec2 -> Element Vec2 -> Element Vec2 -> Element Vec2
f Vec2
p0 Vec2
p1 Vec2
p2 =
    Vec2 -> (Float -> Float -> Vec2) -> Vec2
forall r. Vec2 -> (Float -> Float -> r) -> r
withVec2 Vec2
p0 \Float
x0 Float
y0 ->
    Vec2 -> (Float -> Float -> Vec2) -> Vec2
forall r. Vec2 -> (Float -> Float -> r) -> r
withVec2 Vec2
p1 \Float
x1 Float
y1 ->
    Vec2 -> (Float -> Float -> Vec2) -> Vec2
forall r. Vec2 -> (Float -> Float -> r) -> r
withVec2 Vec2
p2 \Float
x2 Float
y2 ->
      Float -> Float -> Vec2
vec2
        (Element Vec2 -> Element Vec2 -> Element Vec2 -> Element Vec2
f Float
Element Vec2
x0 Float
Element Vec2
x1 Float
Element Vec2
x2)
        (Element Vec2 -> Element Vec2 -> Element Vec2 -> Element Vec2
f Float
Element Vec2
y0 Float
Element Vec2
y1 Float
Element Vec2
y2)

  {-# INLINE emap4 #-}
  emap4 :: (Element Vec2
 -> Element Vec2 -> Element Vec2 -> Element Vec2 -> Element Vec2)
-> Vec2 -> Vec2 -> Vec2 -> Vec2 -> Vec2
emap4 Element Vec2
-> Element Vec2 -> Element Vec2 -> Element Vec2 -> Element Vec2
f Vec2
p0 Vec2
p1 Vec2
p2 Vec2
p3 =
    Vec2 -> (Float -> Float -> Vec2) -> Vec2
forall r. Vec2 -> (Float -> Float -> r) -> r
withVec2 Vec2
p0 \Float
x0 Float
y0 ->
    Vec2 -> (Float -> Float -> Vec2) -> Vec2
forall r. Vec2 -> (Float -> Float -> r) -> r
withVec2 Vec2
p1 \Float
x1 Float
y1 ->
    Vec2 -> (Float -> Float -> Vec2) -> Vec2
forall r. Vec2 -> (Float -> Float -> r) -> r
withVec2 Vec2
p2 \Float
x2 Float
y2 ->
    Vec2 -> (Float -> Float -> Vec2) -> Vec2
forall r. Vec2 -> (Float -> Float -> r) -> r
withVec2 Vec2
p3 \Float
x3 Float
y3 ->
      Float -> Float -> Vec2
vec2
        (Element Vec2
-> Element Vec2 -> Element Vec2 -> Element Vec2 -> Element Vec2
f Float
Element Vec2
x0 Float
Element Vec2
x1 Float
Element Vec2
x2 Float
Element Vec2
x3)
        (Element Vec2
-> Element Vec2 -> Element Vec2 -> Element Vec2 -> Element Vec2
f Float
Element Vec2
y0 Float
Element Vec2
y1 Float
Element Vec2
y2 Float
Element Vec2
y3)

  {-# INLINE emap5 #-}
  emap5 :: (Element Vec2
 -> Element Vec2
 -> Element Vec2
 -> Element Vec2
 -> Element Vec2
 -> Element Vec2)
-> Vec2 -> Vec2 -> Vec2 -> Vec2 -> Vec2 -> Vec2
emap5 Element Vec2
-> Element Vec2
-> Element Vec2
-> Element Vec2
-> Element Vec2
-> Element Vec2
f Vec2
p0 Vec2
p1 Vec2
p2 Vec2
p3 Vec2
p4 =
    Vec2 -> (Float -> Float -> Vec2) -> Vec2
forall r. Vec2 -> (Float -> Float -> r) -> r
withVec2 Vec2
p0 \Float
x0 Float
y0 ->
    Vec2 -> (Float -> Float -> Vec2) -> Vec2
forall r. Vec2 -> (Float -> Float -> r) -> r
withVec2 Vec2
p1 \Float
x1 Float
y1 ->
    Vec2 -> (Float -> Float -> Vec2) -> Vec2
forall r. Vec2 -> (Float -> Float -> r) -> r
withVec2 Vec2
p2 \Float
x2 Float
y2 ->
    Vec2 -> (Float -> Float -> Vec2) -> Vec2
forall r. Vec2 -> (Float -> Float -> r) -> r
withVec2 Vec2
p3 \Float
x3 Float
y3 ->
    Vec2 -> (Float -> Float -> Vec2) -> Vec2
forall r. Vec2 -> (Float -> Float -> r) -> r
withVec2 Vec2
p4 \Float
x4 Float
y4 ->
      Float -> Float -> Vec2
vec2
        (Element Vec2
-> Element Vec2
-> Element Vec2
-> Element Vec2
-> Element Vec2
-> Element Vec2
f Float
Element Vec2
x0 Float
Element Vec2
x1 Float
Element Vec2
x2 Float
Element Vec2
x3 Float
Element Vec2
x4)
        (Element Vec2
-> Element Vec2
-> Element Vec2
-> Element Vec2
-> Element Vec2
-> Element Vec2
f Float
Element Vec2
y0 Float
Element Vec2
y1 Float
Element Vec2
y2 Float
Element Vec2
y3 Float
Element Vec2
y4)

instance Num Vec2 where
  {-# INLINE (+) #-}
  Vec2 Float
l1 Float
l2 + :: Vec2 -> Vec2 -> Vec2
+ Vec2 Float
r1 Float
r2 =
    Float -> Float -> Vec2
Vec2
      (Float
l1 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
r1)
      (Float
l2 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
r2)

  {-# INLINE (-) #-}
  Vec2 Float
l1 Float
l2 - :: Vec2 -> Vec2 -> Vec2
- Vec2 Float
r1 Float
r2 =
    Float -> Float -> Vec2
Vec2
      (Float
l1 Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
r1)
      (Float
l2 Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
r2)

  {-# INLINE (*) #-}
  Vec2 Float
l1 Float
l2 * :: Vec2 -> Vec2 -> Vec2
* Vec2 Float
r1 Float
r2 =
    Float -> Float -> Vec2
Vec2
      (Float
l1 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
r1)
      (Float
l2 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
r2)

  {-# INLINE abs #-}
  abs :: Vec2 -> Vec2
abs (Vec2 Float
a Float
b) =
    Float -> Float -> Vec2
Vec2 (Float -> Float
forall a. Num a => a -> a
abs Float
a) (Float -> Float
forall a. Num a => a -> a
abs Float
b)

  {-# INLINE signum #-}
  signum :: Vec2 -> Vec2
signum (Vec2 Float
a Float
b) =
    Float -> Float -> Vec2
Vec2 (Float -> Float
forall a. Num a => a -> a
signum Float
a) (Float -> Float
forall a. Num a => a -> a
signum Float
b)

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

instance Fractional Vec2 where
  {-# INLINE (/) #-}
  Vec2 Float
l1 Float
l2 / :: Vec2 -> Vec2 -> Vec2
/ Vec2 Float
r1 Float
r2 =
    Float -> Float -> Vec2
Vec2 (Float
l1 Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/ Float
r1) (Float
l2 Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/ Float
r2)

  {-# INLINE recip #-}
  recip :: Vec2 -> Vec2
recip (Vec2 Float
a Float
b) =
    Float -> Float -> Vec2
Vec2 (Float -> Float
forall a. Fractional a => a -> a
recip Float
a) (Float -> Float
forall a. Fractional a => a -> a
recip Float
b)

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

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

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

  ** :: Vec2 -> Vec2 -> Vec2
(**) = (Element Vec2 -> Element Vec2 -> Element Vec2)
-> Vec2 -> Vec2 -> Vec2
forall a.
Elementwise a =>
(Element a -> Element a -> Element a) -> a -> a -> a
emap2 Element Vec2 -> Element Vec2 -> Element Vec2
forall a. Floating a => a -> a -> a
(**)

{-# INLINE (^*) #-}
(^*) :: Vec2 -> Float -> Vec2
Vec2 Float
a Float
b ^* :: Vec2 -> Float -> Vec2
^* Float
x =
  Float -> Float -> Vec2
Vec2
    (Float
a Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
x)
    (Float
b Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
x)

{-# INLINE (^/) #-}
(^/) :: Vec2 -> Float -> Vec2
Vec2 Float
a Float
b ^/ :: Vec2 -> Float -> Vec2
^/ Float
x =
  Float -> Float -> Vec2
Vec2
    (Float
a Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/ Float
x)
    (Float
b Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/ Float
x)

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

{-# INLINE dot #-}
dot :: Vec2 -> Vec2 -> Float
dot :: Vec2 -> Vec2 -> Float
dot (Vec2 Float
l1 Float
l2) (Vec2 Float
r1 Float
r2) =
  Float
l1 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
r1 Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
l2 Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
r2

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

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

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

instance Storable Vec2 where
  {-# INLINE sizeOf #-}
  sizeOf :: Vec2 -> Int
sizeOf Vec2
_ = Int
8

  {-# INLINE alignment #-}
  alignment :: Vec2 -> Int
alignment Vec2
_ = Int
8

  {-# INLINE poke #-}
  poke :: Ptr Vec2 -> Vec2 -> IO ()
poke Ptr Vec2
ptr Vec2
v4 =
    Vec2 -> (Float -> Float -> IO ()) -> IO ()
forall r. Vec2 -> (Float -> Float -> r) -> r
withVec2 Vec2
v4 \Float
a Float
b -> do
      Ptr Vec2 -> Int -> Float -> IO ()
forall a b. Storable a => Ptr b -> Int -> a -> IO ()
pokeByteOff Ptr Vec2
ptr Int
0 Float
a
      Ptr Vec2 -> Int -> Float -> IO ()
forall a b. Storable a => Ptr b -> Int -> a -> IO ()
pokeByteOff Ptr Vec2
ptr Int
4 Float
b

  {-# INLINE peek #-}
  peek :: Ptr Vec2 -> IO Vec2
peek Ptr Vec2
ptr = Float -> Float -> Vec2
vec2
    (Float -> Float -> Vec2) -> IO Float -> IO (Float -> Vec2)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Ptr Vec2 -> Int -> IO Float
forall a b. Storable a => Ptr b -> Int -> IO a
peekByteOff Ptr Vec2
ptr Int
0
    IO (Float -> Vec2) -> IO Float -> IO Vec2
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Ptr Vec2 -> Int -> IO Float
forall a b. Storable a => Ptr b -> Int -> IO a
peekByteOff Ptr Vec2
ptr Int
4

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

  {-# INLINE (*^) #-}
  Float
a *^ :: Float -> Vec2 -> Vec2
*^ Vec2
v = Vec2
v Vec2 -> Float -> Vec2
Geomancy.Vec2.^* Float
a

  {-# INLINE (^/) #-}
  Vec2
v ^/ :: Vec2 -> Float -> Vec2
^/ Float
a = Vec2
v Vec2 -> Float -> Vec2
Geomancy.Vec2.^/ Float
a

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

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

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

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

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

instance GlNearest Vec2

instance GlModf Vec2 Vec2 where
  glModf :: Vec2 -> (Vec2, Vec2)
glModf Vec2
v =
    Vec2 -> (Float -> Float -> (Vec2, Vec2)) -> (Vec2, Vec2)
forall r. Vec2 -> (Float -> Float -> r) -> r
withVec2 Vec2
v \Float
vx Float
vy ->
      let
        (Integer
xi, Float
xf) = Float -> (Integer, Float)
forall i f. GlModf i f => f -> (i, f)
glModf Float
vx
        (Integer
yi, Float
yf) = Float -> (Integer, Float)
forall i f. GlModf i f => f -> (i, f)
glModf Float
vy
      in
        ( Float -> Float -> Vec2
vec2 (Integer -> Float
forall a. Num a => Integer -> a
fromInteger Integer
xi) (Integer -> Float
forall a. Num a => Integer -> a
fromInteger Integer
yi)
        , Float -> Float -> Vec2
vec2 Float
xf Float
yf
        )