module Geometry.Intersect
( Hit
, ray'plane
) where
import RIO
import Geomancy.Vec3 (dot, (^*))
import Geometry.Hit (Hit(..))
import Geometry.Plane (Plane)
import Geometry.Plane qualified as Plane
import Geometry.Ray (Ray)
import Geometry.Ray qualified as Ray
ray'plane
:: Ray
-> Plane
-> Maybe Hit
ray'plane :: Ray -> Plane -> Maybe Hit
ray'plane Ray
ray Plane
plane =
if (forall a. Num a => a -> a
abs Float
denom forall a. Ord a => a -> a -> Bool
> Float
eps) then
forall a. a -> Maybe a
Just Hit
{ $sel:distance:Hit :: Float
distance = Float
t
, $sel:cosine:Hit :: Float
cosine = Float
denom
, $sel:position:Hit :: Vec3
position = Vec3
hit
}
else
forall a. Maybe a
Nothing
where
eps :: Float
eps = Float
1forall a. Fractional a => a -> a -> a
/Float
32
denom :: Float
denom =
Plane -> Vec3
Plane.normal Plane
plane Vec3 -> Vec3 -> Float
`dot` Ray -> Vec3
Ray.direction Ray
ray
t :: Float
t =
forall a. Num a => a -> a
negate ((Plane -> Vec3
Plane.normal Plane
plane Vec3 -> Vec3 -> Float
`dot` Ray -> Vec3
Ray.origin Ray
ray) forall a. Num a => a -> a -> a
+ Plane -> Float
Plane.depth Plane
plane) forall a. Fractional a => a -> a -> a
/ Float
denom
hit :: Vec3
hit =
Ray -> Vec3
Ray.origin Ray
ray forall a. Num a => a -> a -> a
+ Ray -> Vec3
Ray.direction Ray
ray Vec3 -> Float -> Vec3
^* Float
t