bbIntersection (BoundingBox l u) p v = foldr (<>) AllT (liftI4 l u p v)
  where
   -- The near coordinate is the first intersection from coming from
   -- -Infinity *^ v. The far intersection is the first intersection
   -- coming from +Infinity *^ v. The the direcion is negative, the
   -- means the near and far coordinates are flipped.
   -- We return the time where the near and far intersections occur.
   --
   -- a - lower point of bounding box
   -- b - upper point of bounding box
   -- s - trace starting point
   -- d - direction of trace
   f a b s d
     | d == 0    = if s >= a && s <= b then AllT else None
     | otherwise = two ((a-s)/d) ((b-s)/d)

   -- utilities
   liftI4 (P a) (P b) (P c) = liftI2 id (liftI2 id (liftI2 f a b) c)
   {-# INLINE liftI4 #-}

   two :: Ord a => a -> a -> Intersect a
   two a b = if a < b then Two a b else Two b a
   {-# INLINE two #-}
bbIntersection (BoundingBox l u) p v = foldr (<>) AllT (liftI4 l u p v)
  where
   -- The near coordinate is the first intersection from coming from
   -- -Infinity *^ v. The far intersection is the first intersection
   -- coming from +Infinity *^ v. The the direcion is negative, the
   -- means the near and far coordinates are flipped.
   -- We return the time where the near and far intersections occur.
   --
   -- a - lower point of bounding box
   -- b - upper point of bounding box
   -- s - trace starting point
   -- d - direction of trace
   f a b s d
     | d == 0    = if s >= a && s <= b then AllT else None
     | otherwise = two ((a-s)/d) ((b-s)/d)

   -- utilities
   liftI4 (P a) (P b) (P c) = liftI2 id (liftI2 id (liftI2 f a b) c)
   {-# INLINE liftI4 #-}

   two :: Ord a => a -> a -> Intersect a
   two a b = if a < b then Two a b else Two b a
   {-# INLINE two #-}
bbIntersection (BoundingBox l u) p v = foldr (<>) AllT (liftI4 l u p v)
  where
   -- The near coordinate is the first intersection from coming from
   -- -Infinity *^ v. The far intersection is the first intersection
   -- coming from +Infinity *^ v. The the direcion is negative, the
   -- means the near and far coordinates are flipped.
   -- We return the time where the near and far intersections occur.
   --
   -- a - lower point of bounding box
   -- b - upper point of bounding box
   -- s - trace starting point
   -- d - direction of trace
   f a b s d
     | d == 0    = if s >= a && s <= b then AllT else None
     | otherwise = two ((a-s)/d) ((b-s)/d)

   -- utilities
   liftI4 (P a) (P b) (P c) = liftI2 id (liftI2 id (liftI2 f a b) c)
   {-# INLINE liftI4 #-}

   two :: Ord a => a -> a -> Intersect a
   two a b = if a < b then Two a b else Two b a
   {-# INLINE two #-}