{-# LANGUAGE BlockArguments #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE PatternSynonyms #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE ViewPatterns #-}
{-# LANGUAGE DerivingStrategies #-}

-- | Specialized and inlined @V3 Float@.

module Geomancy.Vec3
  ( Vec3
  , vec3
  , withVec3
  , pattern WithVec3
  , fromVec2
  , fromTuple

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

  , cross
  , dot
  , normalize

  , Packed(..)
  , packed

  , emap2
  , emap3
  , emap4
  ) where

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

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

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

{-# INLINE vec3 #-}
vec3 :: Float -> Float -> Float -> Vec3
vec3 :: Float -> Float -> Float -> Vec3
vec3 = Float -> Float -> Float -> Vec3
Vec3

{-# INLINE withVec3 #-}
withVec3
  :: Vec3
  -> (Float -> Float -> Float -> r)
  -> r
withVec3 :: Vec3 -> (Float -> Float -> Float -> r) -> r
withVec3 (Vec3 Float
a Float
b Float
c) Float -> Float -> Float -> r
f = Float -> Float -> Float -> r
f Float
a Float
b Float
c

pattern WithVec3 :: Float -> Float -> Float -> Vec3
pattern $mWithVec3 :: forall r.
Vec3 -> (Float -> Float -> Float -> r) -> (Void# -> r) -> r
WithVec3 a b c <- ((`withVec3` (,,)) -> (a, b, c))
{-# COMPLETE WithVec3 #-}

{-# INLINE fromVec2 #-}
fromVec2 :: Coercible Vec3 a => Vec2 -> Float -> a
fromVec2 :: Vec2 -> Float -> a
fromVec2 Vec2
xy Float
z =
  Vec2 -> (Float -> Float -> a) -> a
forall r. Vec2 -> (Float -> Float -> r) -> r
withVec2 Vec2
xy \Float
x Float
y ->
    Vec3 -> a
coerce (Float -> Float -> Float -> Vec3
vec3 Float
x Float
y Float
z)

{-# INLINE fromTuple #-}
fromTuple :: Coercible Vec3 a => (Float, Float, Float) -> a
fromTuple :: (Float, Float, Float) -> a
fromTuple (Float
x, Float
y, Float
z) = Vec3 -> a
coerce (Float -> Float -> Float -> Vec3
vec3 Float
x Float
y Float
z)

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

type instance Element Vec3 = Float

instance MonoFunctor Vec3 where
  {-# INLINE omap #-}
  omap :: (Element Vec3 -> Element Vec3) -> Vec3 -> Vec3
omap Element Vec3 -> Element Vec3
f Vec3
v =
    Vec3 -> (Float -> Float -> Float -> Vec3) -> Vec3
forall r. Vec3 -> (Float -> Float -> Float -> r) -> r
withVec3 Vec3
v \Float
x Float
y Float
z ->
      Float -> Float -> Float -> Vec3
vec3 (Element Vec3 -> Element Vec3
f Float
Element Vec3
x) (Element Vec3 -> Element Vec3
f Float
Element Vec3
y) (Element Vec3 -> Element Vec3
f Float
Element Vec3
z)

instance MonoPointed Vec3 where
  opoint :: Element Vec3 -> Vec3
opoint Element Vec3
x = Float -> Float -> Float -> Vec3
vec3 Float
Element Vec3
x Float
Element Vec3
x Float
Element Vec3
x

instance Elementwise Vec3 where
  {-# INLINE emap2 #-}
  emap2 :: (Element Vec3 -> Element Vec3 -> Element Vec3)
-> Vec3 -> Vec3 -> Vec3
emap2 Element Vec3 -> Element Vec3 -> Element Vec3
f Vec3
p0 Vec3
p1 =
    Vec3 -> (Float -> Float -> Float -> Vec3) -> Vec3
forall r. Vec3 -> (Float -> Float -> Float -> r) -> r
withVec3 Vec3
p0 \Float
x0 Float
y0 Float
z0 ->
    Vec3 -> (Float -> Float -> Float -> Vec3) -> Vec3
forall r. Vec3 -> (Float -> Float -> Float -> r) -> r
withVec3 Vec3
p1 \Float
x1 Float
y1 Float
z1 ->
      Float -> Float -> Float -> Vec3
vec3
        (Element Vec3 -> Element Vec3 -> Element Vec3
f Float
Element Vec3
x0 Float
Element Vec3
x1)
        (Element Vec3 -> Element Vec3 -> Element Vec3
f Float
Element Vec3
y0 Float
Element Vec3
y1)
        (Element Vec3 -> Element Vec3 -> Element Vec3
f Float
Element Vec3
z0 Float
Element Vec3
z1)

  {-# INLINE emap3 #-}
  emap3 :: (Element Vec3 -> Element Vec3 -> Element Vec3 -> Element Vec3)
-> Vec3 -> Vec3 -> Vec3 -> Vec3
emap3 Element Vec3 -> Element Vec3 -> Element Vec3 -> Element Vec3
f Vec3
p0 Vec3
p1 Vec3
p2 =
    Vec3 -> (Float -> Float -> Float -> Vec3) -> Vec3
forall r. Vec3 -> (Float -> Float -> Float -> r) -> r
withVec3 Vec3
p0 \Float
x0 Float
y0 Float
z0 ->
    Vec3 -> (Float -> Float -> Float -> Vec3) -> Vec3
forall r. Vec3 -> (Float -> Float -> Float -> r) -> r
withVec3 Vec3
p1 \Float
x1 Float
y1 Float
z1 ->
    Vec3 -> (Float -> Float -> Float -> Vec3) -> Vec3
forall r. Vec3 -> (Float -> Float -> Float -> r) -> r
withVec3 Vec3
p2 \Float
x2 Float
y2 Float
z2 ->
      Float -> Float -> Float -> Vec3
vec3
        (Element Vec3 -> Element Vec3 -> Element Vec3 -> Element Vec3
f Float
Element Vec3
x0 Float
Element Vec3
x1 Float
Element Vec3
x2)
        (Element Vec3 -> Element Vec3 -> Element Vec3 -> Element Vec3
f Float
Element Vec3
y0 Float
Element Vec3
y1 Float
Element Vec3
y2)
        (Element Vec3 -> Element Vec3 -> Element Vec3 -> Element Vec3
f Float
Element Vec3
z0 Float
Element Vec3
z1 Float
Element Vec3
z2)

  {-# INLINE emap4 #-}
  emap4 :: (Element Vec3
 -> Element Vec3 -> Element Vec3 -> Element Vec3 -> Element Vec3)
-> Vec3 -> Vec3 -> Vec3 -> Vec3 -> Vec3
emap4 Element Vec3
-> Element Vec3 -> Element Vec3 -> Element Vec3 -> Element Vec3
f Vec3
p0 Vec3
p1 Vec3
p2 Vec3
p3 =
    Vec3 -> (Float -> Float -> Float -> Vec3) -> Vec3
forall r. Vec3 -> (Float -> Float -> Float -> r) -> r
withVec3 Vec3
p0 \Float
x0 Float
y0 Float
z0 ->
    Vec3 -> (Float -> Float -> Float -> Vec3) -> Vec3
forall r. Vec3 -> (Float -> Float -> Float -> r) -> r
withVec3 Vec3
p1 \Float
x1 Float
y1 Float
z1 ->
    Vec3 -> (Float -> Float -> Float -> Vec3) -> Vec3
forall r. Vec3 -> (Float -> Float -> Float -> r) -> r
withVec3 Vec3
p2 \Float
x2 Float
y2 Float
z2 ->
    Vec3 -> (Float -> Float -> Float -> Vec3) -> Vec3
forall r. Vec3 -> (Float -> Float -> Float -> r) -> r
withVec3 Vec3
p3 \Float
x3 Float
y3 Float
z3 ->
      Float -> Float -> Float -> Vec3
vec3
        (Element Vec3
-> Element Vec3 -> Element Vec3 -> Element Vec3 -> Element Vec3
f Float
Element Vec3
x0 Float
Element Vec3
x1 Float
Element Vec3
x2 Float
Element Vec3
x3)
        (Element Vec3
-> Element Vec3 -> Element Vec3 -> Element Vec3 -> Element Vec3
f Float
Element Vec3
y0 Float
Element Vec3
y1 Float
Element Vec3
y2 Float
Element Vec3
y3)
        (Element Vec3
-> Element Vec3 -> Element Vec3 -> Element Vec3 -> Element Vec3
f Float
Element Vec3
z0 Float
Element Vec3
z1 Float
Element Vec3
z2 Float
Element Vec3
z3)

  {-# INLINE emap5 #-}
  emap5 :: (Element Vec3
 -> Element Vec3
 -> Element Vec3
 -> Element Vec3
 -> Element Vec3
 -> Element Vec3)
-> Vec3 -> Vec3 -> Vec3 -> Vec3 -> Vec3 -> Vec3
emap5 Element Vec3
-> Element Vec3
-> Element Vec3
-> Element Vec3
-> Element Vec3
-> Element Vec3
f Vec3
p0 Vec3
p1 Vec3
p2 Vec3
p3 Vec3
p4 =
    Vec3 -> (Float -> Float -> Float -> Vec3) -> Vec3
forall r. Vec3 -> (Float -> Float -> Float -> r) -> r
withVec3 Vec3
p0 \Float
x0 Float
y0 Float
z0 ->
    Vec3 -> (Float -> Float -> Float -> Vec3) -> Vec3
forall r. Vec3 -> (Float -> Float -> Float -> r) -> r
withVec3 Vec3
p1 \Float
x1 Float
y1 Float
z1 ->
    Vec3 -> (Float -> Float -> Float -> Vec3) -> Vec3
forall r. Vec3 -> (Float -> Float -> Float -> r) -> r
withVec3 Vec3
p2 \Float
x2 Float
y2 Float
z2 ->
    Vec3 -> (Float -> Float -> Float -> Vec3) -> Vec3
forall r. Vec3 -> (Float -> Float -> Float -> r) -> r
withVec3 Vec3
p3 \Float
x3 Float
y3 Float
z3 ->
    Vec3 -> (Float -> Float -> Float -> Vec3) -> Vec3
forall r. Vec3 -> (Float -> Float -> Float -> r) -> r
withVec3 Vec3
p4 \Float
x4 Float
y4 Float
z4 ->
      Float -> Float -> Float -> Vec3
vec3
        (Element Vec3
-> Element Vec3
-> Element Vec3
-> Element Vec3
-> Element Vec3
-> Element Vec3
f Float
Element Vec3
x0 Float
Element Vec3
x1 Float
Element Vec3
x2 Float
Element Vec3
x3 Float
Element Vec3
x4)
        (Element Vec3
-> Element Vec3
-> Element Vec3
-> Element Vec3
-> Element Vec3
-> Element Vec3
f Float
Element Vec3
y0 Float
Element Vec3
y1 Float
Element Vec3
y2 Float
Element Vec3
y3 Float
Element Vec3
y4)
        (Element Vec3
-> Element Vec3
-> Element Vec3
-> Element Vec3
-> Element Vec3
-> Element Vec3
f Float
Element Vec3
z0 Float
Element Vec3
z1 Float
Element Vec3
z2 Float
Element Vec3
z3 Float
Element Vec3
z4)

instance Num Vec3 where
  {-# INLINE (+) #-}
  Vec3 Float
a Float
b Float
c + :: Vec3 -> Vec3 -> Vec3
+ Vec3 Float
d Float
e Float
f =
    Float -> Float -> Float -> Vec3
Vec3
      (Float
a Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
d)
      (Float
b Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
e)
      (Float
c Float -> Float -> Float
forall a. Num a => a -> a -> a
+ Float
f)

  {-# INLINE (-) #-}
  Vec3 Float
a Float
b Float
c - :: Vec3 -> Vec3 -> Vec3
- Vec3 Float
d Float
e Float
f =
    Float -> Float -> Float -> Vec3
Vec3
      (Float
a Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
d)
      (Float
b Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
e)
      (Float
c Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
f)

  {-# INLINE (*) #-}
  Vec3 Float
a Float
b Float
c * :: Vec3 -> Vec3 -> Vec3
* Vec3 Float
d Float
e Float
f =
    Float -> Float -> Float -> Vec3
Vec3
      (Float
a Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
d)
      (Float
b Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
e)
      (Float
c Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
f)

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

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

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

instance Fractional Vec3 where
  {-# INLINE (/) #-}
  Vec3 Float
l1 Float
l2 Float
l3 / :: Vec3 -> Vec3 -> Vec3
/ Vec3 Float
r1 Float
r2 Float
r3 =
    Float -> Float -> Float -> Vec3
Vec3 (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) (Float
l3 Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/ Float
r3)

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

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

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

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

  Vec3
a ** :: Vec3 -> Vec3 -> Vec3
** Vec3
b =
    Vec3 -> (Float -> Float -> Float -> Vec3) -> Vec3
forall r. Vec3 -> (Float -> Float -> Float -> r) -> r
withVec3 Vec3
a \Float
ax Float
ay Float
az ->
    Vec3 -> (Float -> Float -> Float -> Vec3) -> Vec3
forall r. Vec3 -> (Float -> Float -> Float -> r) -> r
withVec3 Vec3
b \Float
bx Float
by Float
bz ->
      Float -> Float -> Float -> Vec3
vec3
        (Float
ax Float -> Float -> Float
forall a. Floating a => a -> a -> a
** Float
bx)
        (Float
ay Float -> Float -> Float
forall a. Floating a => a -> a -> a
** Float
by)
        (Float
az Float -> Float -> Float
forall a. Floating a => a -> a -> a
** Float
bz)

{-
  XXX: GPU layouts call for some padding.

  Maybe it would be worth it to flip the sizeOf-s.
-}
instance Storable Vec3 where
  {-# INLINE sizeOf #-}
  sizeOf :: Vec3 -> Int
sizeOf Vec3
_ = Int
16

  {-# INLINE alignment #-}
  alignment :: Vec3 -> Int
alignment Vec3
_ = Int
4

  {-# INLINE poke #-}
  poke :: Ptr Vec3 -> Vec3 -> IO ()
poke Ptr Vec3
ptr Vec3
v3 =
    Vec3 -> (Float -> Float -> Float -> IO ()) -> IO ()
forall r. Vec3 -> (Float -> Float -> Float -> r) -> r
withVec3 Vec3
v3 \Float
a Float
b Float
c -> do
      Ptr Float -> Float -> IO ()
forall a. Storable a => Ptr a -> a -> IO ()
poke Ptr Float
ptr' Float
a
      Ptr Float -> Int -> Float -> IO ()
forall a. Storable a => Ptr a -> Int -> a -> IO ()
pokeElemOff Ptr Float
ptr' Int
1 Float
b
      Ptr Float -> Int -> Float -> IO ()
forall a. Storable a => Ptr a -> Int -> a -> IO ()
pokeElemOff Ptr Float
ptr' Int
2 Float
c
      Ptr Float -> Int -> Float -> IO ()
forall a. Storable a => Ptr a -> Int -> a -> IO ()
pokeElemOff Ptr Float
ptr' Int
3 (Float
1.0 :: Float)
    where
      ptr' :: Ptr Float
ptr' = Ptr Vec3 -> Ptr Float
forall a b. Ptr a -> Ptr b
castPtr Ptr Vec3
ptr

  {-# INLINE peek #-}
  peek :: Ptr Vec3 -> IO Vec3
peek Ptr Vec3
ptr =
    Float -> Float -> Float -> Vec3
vec3 (Float -> Float -> Float -> Vec3)
-> IO Float -> IO (Float -> Float -> Vec3)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Ptr Float -> IO Float
forall a. Storable a => Ptr a -> IO a
peek Ptr Float
ptr' IO (Float -> Float -> Vec3) -> IO Float -> IO (Float -> Vec3)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Ptr Float -> Int -> IO Float
forall a. Storable a => Ptr a -> Int -> IO a
peekElemOff Ptr Float
ptr' Int
1 IO (Float -> Vec3) -> IO Float -> IO Vec3
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Ptr Float -> Int -> IO Float
forall a. Storable a => Ptr a -> Int -> IO a
peekElemOff Ptr Float
ptr' Int
2
    where
      ptr' :: Ptr Float
ptr' = Ptr Vec3 -> Ptr Float
forall a b. Ptr a -> Ptr b
castPtr Ptr Vec3
ptr

{-# INLINE (^*) #-}
(^*) :: Vec3 -> Float -> Vec3
Vec3 Float
a Float
b Float
c ^* :: Vec3 -> Float -> Vec3
^* Float
x =
  Float -> Float -> Float -> Vec3
Vec3
    (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)
    (Float
c Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
x)

{-# INLINE (^/) #-}
(^/) :: Vec3 -> Float -> Vec3
Vec3 Float
a Float
b Float
c ^/ :: Vec3 -> Float -> Vec3
^/ Float
x =
  Float -> Float -> Float -> Vec3
Vec3
    (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)
    (Float
c Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/ Float
x)

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

{-# INLINE cross #-}
cross :: Vec3 -> Vec3 -> Vec3
cross :: Vec3 -> Vec3 -> Vec3
cross (Vec3 Float
a Float
b Float
c) (Vec3 Float
d Float
e Float
f) =
  Float -> Float -> Float -> Vec3
Vec3
    (Float
b Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
f Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
c Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
e)
    (Float
c Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
d Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
a Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
f)
    (Float
a Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
e Float -> Float -> Float
forall a. Num a => a -> a -> a
- Float
b Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
d)

{-# INLINE dot #-}
dot :: Vec3 -> Vec3 -> Float
dot :: Vec3 -> Vec3 -> Float
dot (Vec3 Float
a Float
b Float
c) (Vec3 Float
d Float
e Float
f) =
  Float
a Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
d Float -> Float -> Float
forall a. Num a => a -> a -> a
+
  Float
b Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
e Float -> Float -> Float
forall a. Num a => a -> a -> a
+
  Float
c Float -> Float -> Float
forall a. Num a => a -> a -> a
* Float
f

{-# INLINE normalize #-}
normalize :: Vec3 -> Vec3
normalize :: Vec3 -> Vec3
normalize Vec3
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
1Float -> Float -> Float
forall a. Num a => a -> a -> a
-Float
q) then
    Vec3
v
  else
    let
      Vec3 Float
x Float
y Float
z = Vec3
v
    in
      Float -> Float -> Float -> Vec3
Vec3 (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) (Float
z Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/ Float
l)

  where
    q :: Float
q = Vec3 -> Vec3 -> Float
dot Vec3
v Vec3
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 VectorSpace Vec3 Float where
  zeroVector :: Vec3
zeroVector = Element Vec3 -> Vec3
forall a. Elementwise a => Element a -> a
epoint Element Vec3
0

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

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

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

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

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

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

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

-- * Unpadded

type instance Element Packed = Float

newtype Packed = Packed { Packed -> Vec3
unPacked :: Vec3 }
  deriving stock
    ( Packed -> Packed -> Bool
(Packed -> Packed -> Bool)
-> (Packed -> Packed -> Bool) -> Eq Packed
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Packed -> Packed -> Bool
$c/= :: Packed -> Packed -> Bool
== :: Packed -> Packed -> Bool
$c== :: Packed -> Packed -> Bool
Eq, Eq Packed
Eq Packed
-> (Packed -> Packed -> Ordering)
-> (Packed -> Packed -> Bool)
-> (Packed -> Packed -> Bool)
-> (Packed -> Packed -> Bool)
-> (Packed -> Packed -> Bool)
-> (Packed -> Packed -> Packed)
-> (Packed -> Packed -> Packed)
-> Ord Packed
Packed -> Packed -> Bool
Packed -> Packed -> Ordering
Packed -> Packed -> Packed
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 :: Packed -> Packed -> Packed
$cmin :: Packed -> Packed -> Packed
max :: Packed -> Packed -> Packed
$cmax :: Packed -> Packed -> Packed
>= :: Packed -> Packed -> Bool
$c>= :: Packed -> Packed -> Bool
> :: Packed -> Packed -> Bool
$c> :: Packed -> Packed -> Bool
<= :: Packed -> Packed -> Bool
$c<= :: Packed -> Packed -> Bool
< :: Packed -> Packed -> Bool
$c< :: Packed -> Packed -> Bool
compare :: Packed -> Packed -> Ordering
$ccompare :: Packed -> Packed -> Ordering
$cp1Ord :: Eq Packed
Ord, Int -> Packed -> ShowS
[Packed] -> ShowS
Packed -> String
(Int -> Packed -> ShowS)
-> (Packed -> String) -> ([Packed] -> ShowS) -> Show Packed
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Packed] -> ShowS
$cshowList :: [Packed] -> ShowS
show :: Packed -> String
$cshow :: Packed -> String
showsPrec :: Int -> Packed -> ShowS
$cshowsPrec :: Int -> Packed -> ShowS
Show
    )
  deriving newtype
    ( Packed -> ()
(Packed -> ()) -> NFData Packed
forall a. (a -> ()) -> NFData a
rnf :: Packed -> ()
$crnf :: Packed -> ()
NFData, Integer -> Packed
Packed -> Packed
Packed -> Packed -> Packed
(Packed -> Packed -> Packed)
-> (Packed -> Packed -> Packed)
-> (Packed -> Packed -> Packed)
-> (Packed -> Packed)
-> (Packed -> Packed)
-> (Packed -> Packed)
-> (Integer -> Packed)
-> Num Packed
forall a.
(a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (Integer -> a)
-> Num a
fromInteger :: Integer -> Packed
$cfromInteger :: Integer -> Packed
signum :: Packed -> Packed
$csignum :: Packed -> Packed
abs :: Packed -> Packed
$cabs :: Packed -> Packed
negate :: Packed -> Packed
$cnegate :: Packed -> Packed
* :: Packed -> Packed -> Packed
$c* :: Packed -> Packed -> Packed
- :: Packed -> Packed -> Packed
$c- :: Packed -> Packed -> Packed
+ :: Packed -> Packed -> Packed
$c+ :: Packed -> Packed -> Packed
Num, Num Packed
Num Packed
-> (Packed -> Packed -> Packed)
-> (Packed -> Packed)
-> (Rational -> Packed)
-> Fractional Packed
Rational -> Packed
Packed -> Packed
Packed -> Packed -> Packed
forall a.
Num a
-> (a -> a -> a) -> (a -> a) -> (Rational -> a) -> Fractional a
fromRational :: Rational -> Packed
$cfromRational :: Rational -> Packed
recip :: Packed -> Packed
$crecip :: Packed -> Packed
/ :: Packed -> Packed -> Packed
$c/ :: Packed -> Packed -> Packed
$cp1Fractional :: Num Packed
Fractional, Fractional Packed
Packed
Fractional Packed
-> Packed
-> (Packed -> Packed)
-> (Packed -> Packed)
-> (Packed -> Packed)
-> (Packed -> Packed -> Packed)
-> (Packed -> Packed -> Packed)
-> (Packed -> Packed)
-> (Packed -> Packed)
-> (Packed -> Packed)
-> (Packed -> Packed)
-> (Packed -> Packed)
-> (Packed -> Packed)
-> (Packed -> Packed)
-> (Packed -> Packed)
-> (Packed -> Packed)
-> (Packed -> Packed)
-> (Packed -> Packed)
-> (Packed -> Packed)
-> (Packed -> Packed)
-> (Packed -> Packed)
-> (Packed -> Packed)
-> (Packed -> Packed)
-> Floating Packed
Packed -> Packed
Packed -> Packed -> Packed
forall a.
Fractional a
-> a
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> Floating a
log1mexp :: Packed -> Packed
$clog1mexp :: Packed -> Packed
log1pexp :: Packed -> Packed
$clog1pexp :: Packed -> Packed
expm1 :: Packed -> Packed
$cexpm1 :: Packed -> Packed
log1p :: Packed -> Packed
$clog1p :: Packed -> Packed
atanh :: Packed -> Packed
$catanh :: Packed -> Packed
acosh :: Packed -> Packed
$cacosh :: Packed -> Packed
asinh :: Packed -> Packed
$casinh :: Packed -> Packed
tanh :: Packed -> Packed
$ctanh :: Packed -> Packed
cosh :: Packed -> Packed
$ccosh :: Packed -> Packed
sinh :: Packed -> Packed
$csinh :: Packed -> Packed
atan :: Packed -> Packed
$catan :: Packed -> Packed
acos :: Packed -> Packed
$cacos :: Packed -> Packed
asin :: Packed -> Packed
$casin :: Packed -> Packed
tan :: Packed -> Packed
$ctan :: Packed -> Packed
cos :: Packed -> Packed
$ccos :: Packed -> Packed
sin :: Packed -> Packed
$csin :: Packed -> Packed
logBase :: Packed -> Packed -> Packed
$clogBase :: Packed -> Packed -> Packed
** :: Packed -> Packed -> Packed
$c** :: Packed -> Packed -> Packed
sqrt :: Packed -> Packed
$csqrt :: Packed -> Packed
log :: Packed -> Packed
$clog :: Packed -> Packed
exp :: Packed -> Packed
$cexp :: Packed -> Packed
pi :: Packed
$cpi :: Packed
$cp1Floating :: Fractional Packed
Floating
    , (Element Packed -> Element Packed) -> Packed -> Packed
((Element Packed -> Element Packed) -> Packed -> Packed)
-> MonoFunctor Packed
forall mono.
((Element mono -> Element mono) -> mono -> mono)
-> MonoFunctor mono
omap :: (Element Packed -> Element Packed) -> Packed -> Packed
$comap :: (Element Packed -> Element Packed) -> Packed -> Packed
MonoFunctor, Element Packed -> Packed
(Element Packed -> Packed) -> MonoPointed Packed
forall mono. (Element mono -> mono) -> MonoPointed mono
opoint :: Element Packed -> Packed
$copoint :: Element Packed -> Packed
MonoPointed
    , Element Packed -> Packed
(Element Packed -> Element Packed) -> Packed -> Packed
(Element Packed -> Packed)
-> ((Element Packed -> Element Packed) -> Packed -> Packed)
-> ((Element Packed -> Element Packed -> Element Packed)
    -> Packed -> Packed -> Packed)
-> ((Element Packed
     -> Element Packed -> Element Packed -> Element Packed)
    -> Packed -> Packed -> Packed -> Packed)
-> ((Element Packed
     -> Element Packed
     -> Element Packed
     -> Element Packed
     -> Element Packed)
    -> Packed -> Packed -> Packed -> Packed -> Packed)
-> ((Element Packed
     -> Element Packed
     -> Element Packed
     -> Element Packed
     -> Element Packed
     -> Element Packed)
    -> Packed -> Packed -> Packed -> Packed -> Packed -> Packed)
-> Elementwise Packed
(Element Packed -> Element Packed -> Element Packed)
-> Packed -> Packed -> Packed
(Element Packed
 -> Element Packed -> Element Packed -> Element Packed)
-> Packed -> Packed -> Packed -> Packed
(Element Packed
 -> Element Packed
 -> Element Packed
 -> Element Packed
 -> Element Packed)
-> Packed -> Packed -> Packed -> Packed -> Packed
(Element Packed
 -> Element Packed
 -> Element Packed
 -> Element Packed
 -> Element Packed
 -> Element Packed)
-> Packed -> Packed -> Packed -> Packed -> Packed -> Packed
forall a.
(Element a -> a)
-> ((Element a -> Element a) -> a -> a)
-> ((Element a -> Element a -> Element a) -> a -> a -> a)
-> ((Element a -> Element a -> Element a -> Element a)
    -> a -> a -> a -> a)
-> ((Element a -> Element a -> Element a -> Element a -> Element a)
    -> a -> a -> a -> a -> a)
-> ((Element a
     -> Element a -> Element a -> Element a -> Element a -> Element a)
    -> a -> a -> a -> a -> a -> a)
-> Elementwise a
emap5 :: (Element Packed
 -> Element Packed
 -> Element Packed
 -> Element Packed
 -> Element Packed
 -> Element Packed)
-> Packed -> Packed -> Packed -> Packed -> Packed -> Packed
$cemap5 :: (Element Packed
 -> Element Packed
 -> Element Packed
 -> Element Packed
 -> Element Packed
 -> Element Packed)
-> Packed -> Packed -> Packed -> Packed -> Packed -> Packed
emap4 :: (Element Packed
 -> Element Packed
 -> Element Packed
 -> Element Packed
 -> Element Packed)
-> Packed -> Packed -> Packed -> Packed -> Packed
$cemap4 :: (Element Packed
 -> Element Packed
 -> Element Packed
 -> Element Packed
 -> Element Packed)
-> Packed -> Packed -> Packed -> Packed -> Packed
emap3 :: (Element Packed
 -> Element Packed -> Element Packed -> Element Packed)
-> Packed -> Packed -> Packed -> Packed
$cemap3 :: (Element Packed
 -> Element Packed -> Element Packed -> Element Packed)
-> Packed -> Packed -> Packed -> Packed
emap2 :: (Element Packed -> Element Packed -> Element Packed)
-> Packed -> Packed -> Packed
$cemap2 :: (Element Packed -> Element Packed -> Element Packed)
-> Packed -> Packed -> Packed
emap :: (Element Packed -> Element Packed) -> Packed -> Packed
$cemap :: (Element Packed -> Element Packed) -> Packed -> Packed
epoint :: Element Packed -> Packed
$cepoint :: Element Packed -> Packed
Elementwise
    )

{-# INLINE packed #-}
packed :: Float -> Float -> Float -> Packed
packed :: Float -> Float -> Float -> Packed
packed Float
x Float
y Float
z = Vec3 -> Packed
Packed (Float -> Float -> Float -> Vec3
vec3 Float
x Float
y Float
z)

instance Storable Packed where
  {-# INLINE sizeOf #-}
  sizeOf :: Packed -> Int
sizeOf Packed
_ = Int
12

  {-# INLINE alignment #-}
  alignment :: Packed -> Int
alignment Packed
_ = Int
4

  {-# INLINE poke #-}
  poke :: Ptr Packed -> Packed -> IO ()
poke Ptr Packed
ptr (Packed Vec3
v3) =
    Vec3 -> (Float -> Float -> Float -> IO ()) -> IO ()
forall r. Vec3 -> (Float -> Float -> Float -> r) -> r
withVec3 Vec3
v3 \Float
a Float
b Float
c -> do
      Ptr Float -> Float -> IO ()
forall a. Storable a => Ptr a -> a -> IO ()
poke Ptr Float
ptr' Float
a
      Ptr Float -> Int -> Float -> IO ()
forall a. Storable a => Ptr a -> Int -> a -> IO ()
pokeElemOff Ptr Float
ptr' Int
1 Float
b
      Ptr Float -> Int -> Float -> IO ()
forall a. Storable a => Ptr a -> Int -> a -> IO ()
pokeElemOff Ptr Float
ptr' Int
2 Float
c
    where
      ptr' :: Ptr Float
ptr' = Ptr Packed -> Ptr Float
forall a b. Ptr a -> Ptr b
castPtr Ptr Packed
ptr

  {-# INLINE peek #-}
  peek :: Ptr Packed -> IO Packed
peek Ptr Packed
ptr = Float -> Float -> Float -> Packed
packed
    (Float -> Float -> Float -> Packed)
-> IO Float -> IO (Float -> Float -> Packed)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Ptr Float -> IO Float
forall a. Storable a => Ptr a -> IO a
peek Ptr Float
ptr'
    IO (Float -> Float -> Packed) -> IO Float -> IO (Float -> Packed)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Ptr Float -> Int -> IO Float
forall a. Storable a => Ptr a -> Int -> IO a
peekElemOff Ptr Float
ptr' Int
1
    IO (Float -> Packed) -> IO Float -> IO Packed
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Ptr Float -> Int -> IO Float
forall a. Storable a => Ptr a -> Int -> IO a
peekElemOff Ptr Float
ptr' Int
2
    where
      ptr' :: Ptr Float
ptr' = Ptr Packed -> Ptr Float
forall a b. Ptr a -> Ptr b
castPtr Ptr Packed
ptr

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

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

  {-# INLINE (^/) #-}
  ^/ :: Packed -> Float -> Packed
(^/) = (Vec3 -> Float -> Vec3) -> Packed -> Float -> Packed
coerce Vec3 -> Float -> Vec3
(Geomancy.Vec3.^/)

  {-# INLINE (^+^) #-}
  Packed
v1 ^+^ :: Packed -> Packed -> Packed
^+^ Packed
v2 = Packed
v1 Packed -> Packed -> Packed
forall a. Num a => a -> a -> a
+ Packed
v2

  {-# INLINE (^-^) #-}
  Packed
v1 ^-^ :: Packed -> Packed -> Packed
^-^ Packed
v2 = Packed
v1 Packed -> Packed -> Packed
forall a. Num a => a -> a -> a
- Packed
v2

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

  {-# INLINE dot #-}
  dot :: Packed -> Packed -> Float
dot = (Vec3 -> Vec3 -> Float) -> Packed -> Packed -> Float
coerce Vec3 -> Vec3 -> Float
Geomancy.Vec3.dot

  {-# INLINE normalize #-}
  normalize :: Packed -> Packed
normalize = (Vec3 -> Vec3) -> Packed -> Packed
coerce Vec3 -> Vec3
Geomancy.Vec3.normalize

instance GlNearest Vec3

instance GlModf Vec3 Vec3 where
  glModf :: Vec3 -> (Vec3, Vec3)
glModf Vec3
v =
    Vec3 -> (Float -> Float -> Float -> (Vec3, Vec3)) -> (Vec3, Vec3)
forall r. Vec3 -> (Float -> Float -> Float -> r) -> r
withVec3 Vec3
v \Float
vx Float
vy Float
vz ->
      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
        (Integer
zi, Float
zf) = Float -> (Integer, Float)
forall i f. GlModf i f => f -> (i, f)
glModf Float
vz
      in
        ( Float -> Float -> Float -> Vec3
vec3 (Integer -> Float
forall a. Num a => Integer -> a
fromInteger Integer
xi) (Integer -> Float
forall a. Num a => Integer -> a
fromInteger Integer
yi) (Integer -> Float
forall a. Num a => Integer -> a
fromInteger Integer
zi)
        , Float -> Float -> Float -> Vec3
vec3 Float
xf Float
yf Float
zf
        )