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

-- | Specialized and inlined @V2 Float@.

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

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

  , dot
  , normalize
  ) where

import Control.DeepSeq (NFData(rnf))
import Data.Coerce (Coercible, coerce)
import Data.MonoTraversable (Element, MonoFunctor(..), MonoPointed(..))
import Data.VectorSpace (VectorSpace)
import Foreign (Storable(..))
import Foreign.Ptr.Diff (peekDiffOff, pokeDiffOff)
import qualified Data.VectorSpace as VectorSpace

import Geomancy.Elementwise (Elementwise(..))
import Graphics.Gl.Block (Block(..))
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
$c== :: Vec2 -> Vec2 -> Bool
== :: Vec2 -> Vec2 -> Bool
$c/= :: Vec2 -> Vec2 -> Bool
/= :: 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
$ccompare :: Vec2 -> Vec2 -> Ordering
compare :: Vec2 -> Vec2 -> Ordering
$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
>= :: Vec2 -> Vec2 -> Bool
$cmax :: Vec2 -> Vec2 -> Vec2
max :: Vec2 -> Vec2 -> Vec2
$cmin :: Vec2 -> Vec2 -> Vec2
min :: Vec2 -> Vec2 -> 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
$cshowsPrec :: Int -> Vec2 -> ShowS
showsPrec :: Int -> Vec2 -> ShowS
$cshow :: Vec2 -> String
show :: Vec2 -> String
$cshowList :: [Vec2] -> ShowS
showList :: [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 :: forall r. Vec2 -> (Float -> Float -> r) -> r
withVec2 (Vec2 Float
a Float
b) Float -> Float -> r
f = Float -> Float -> r
f Float
a Float
b

{-# INLINE convert #-}
convert :: Coercible v Vec2 => (Float -> a) -> (a -> a -> r) -> v -> r
convert :: forall v a r.
Coercible v Vec2 =>
(Float -> a) -> (a -> a -> r) -> v -> r
convert Float -> a
f a -> a -> r
t v
v =
  Vec2 -> (Float -> Float -> r) -> r
forall r. Vec2 -> (Float -> Float -> r) -> r
withVec2 (v -> Vec2
forall a b. Coercible a b => a -> b
coerce v
v) \Float
a Float
b ->
    a -> a -> r
t (Float -> a
f Float
a) (Float -> a
f Float
b)

pattern WithVec2 :: Float -> Float -> Vec2
pattern $mWithVec2 :: forall {r}. Vec2 -> (Float -> Float -> r) -> ((# #) -> 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 Float
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 Float -> Float
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 Float -> Float
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 Float -> Float
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 Float -> Float
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 Float -> Float
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 Float -> Float
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 Float -> Float
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 Float -> Float
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 Float -> Float
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 Float -> Float
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 Float -> Float
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 Float -> Float
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 Float -> Float
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 Float -> Float -> Float
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 b. Ptr b -> 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 b. Ptr b -> 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 b. Ptr b -> 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 a b. IO (a -> b) -> IO a -> IO b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Ptr Vec2 -> Int -> IO Float
forall b. Ptr b -> Int -> IO Float
forall a b. Storable a => Ptr b -> Int -> IO a
peekByteOff Ptr Vec2
ptr Int
4

instance Block Vec2 where
  type PackedSize Vec2 = 8
  alignment140 :: forall (proxy :: * -> *). proxy Vec2 -> Int
alignment140 proxy Vec2
_  = Int
8
  sizeOf140 :: forall (proxy :: * -> *). proxy Vec2 -> Int
sizeOf140 proxy Vec2
_     = Int
8
  alignment430 :: forall (proxy :: * -> *). proxy Vec2 -> Int
alignment430    = proxy Vec2 -> Int
forall b (proxy :: * -> *). Block b => proxy b -> Int
forall (proxy :: * -> *). proxy Vec2 -> Int
alignment140
  sizeOf430 :: forall (proxy :: * -> *). proxy Vec2 -> Int
sizeOf430       = proxy Vec2 -> Int
forall b (proxy :: * -> *). Block b => proxy b -> Int
forall (proxy :: * -> *). proxy Vec2 -> Int
sizeOf140
  isStruct :: forall (proxy :: * -> *). proxy Vec2 -> Bool
isStruct proxy Vec2
_      = Bool
False
  read140 :: forall (m :: * -> *) a. MonadIO m => Ptr a -> Diff a Vec2 -> m Vec2
read140     = Ptr a -> Diff a Vec2 -> m Vec2
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 Vec2 -> Vec2 -> m ()
write140    = Ptr a -> Diff a Vec2 -> Vec2 -> m ()
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 Vec2 -> m Vec2
read430     = Ptr a -> Diff a Vec2 -> m Vec2
forall b (m :: * -> *) a.
(Block b, MonadIO m) =>
Ptr a -> Diff a b -> m b
forall (m :: * -> *) a. MonadIO m => Ptr a -> Diff a Vec2 -> m Vec2
read140
  write430 :: forall (m :: * -> *) a.
MonadIO m =>
Ptr a -> Diff a Vec2 -> Vec2 -> m ()
write430    = Ptr a -> Diff a Vec2 -> Vec2 -> m ()
forall b (m :: * -> *) a.
(Block b, MonadIO m) =>
Ptr a -> Diff a b -> b -> m ()
forall (m :: * -> *) a.
MonadIO m =>
Ptr a -> Diff a Vec2 -> Vec2 -> m ()
write140
  readPacked :: forall (m :: * -> *) a. MonadIO m => Ptr a -> Diff a Vec2 -> m Vec2
readPacked  = Ptr a -> Diff a Vec2 -> m Vec2
forall b (m :: * -> *) a.
(Block b, MonadIO m) =>
Ptr a -> Diff a b -> m b
forall (m :: * -> *) a. MonadIO m => Ptr a -> Diff a Vec2 -> m Vec2
read140
  writePacked :: forall (m :: * -> *) a.
MonadIO m =>
Ptr a -> Diff a Vec2 -> Vec2 -> m ()
writePacked = Ptr a -> Diff a Vec2 -> Vec2 -> m ()
forall b (m :: * -> *) a.
(Block b, MonadIO m) =>
Ptr a -> Diff a b -> b -> m ()
forall (m :: * -> *) a.
MonadIO m =>
Ptr a -> Diff a Vec2 -> Vec2 -> 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 Vec2 Float where
  zeroVector :: Vec2
zeroVector = Element Vec2 -> Vec2
forall a. Elementwise a => Element a -> a
epoint Float
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 Float -> Float -> Float
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 Float -> Float
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
        )