module Bound (bound_object) where import Vec import Solid -- Bounding objects: we can use any object as a bounding -- object for any other object; if a ray misses the -- bounding object, we can assume it missed the bounded -- object as well. Unlike bih, setting up bounds is a manual -- process. It is important that the bounded object is -- completely inside the bounding object. -- The bounding object should have a cheaper intersection test than -- the bounded object for this to be useful. -- The first SolidItem is the bounding object, the second -- is the bounded object. data Bound = Bound SolidItem SolidItem deriving Show bound_object :: SolidItem -> SolidItem -> SolidItem bound_object a b = SolidItem $ Bound a b rayint_bound :: Bound -> Ray -> Flt -> Texture -> Rayint rayint_bound (Bound sa sb) r d t = let (Ray orig _) = r in if inside sa orig || shadow sa r d then rayint sb r d t else RayMiss shadow_bound :: Bound -> Ray -> Flt -> Bool shadow_bound (Bound sa sb) r d = let (Ray orig _ ) = r in if inside sa orig || shadow sa r d then shadow sb r d else False inside_bound :: Bound -> Vec -> Bool inside_bound (Bound sa sb) pt = inside sa pt && inside sb pt -- if this is too slow, we could just take the bounding box for sa bound_bound :: Bound -> Bbox bound_bound (Bound sa sb) = bboverlap (bound sa) (bound sb) -- remove bounding objects when we flatten transformations -- (this is so that the accelleration structure can -- build an automatic bounding hierarchy rather than -- a manual one) flatten_transform_bound :: Bound -> SolidItem flatten_transform_bound (Bound sa sb) = flatten_transform sb instance Solid Bound where rayint = rayint_bound shadow = shadow_bound inside = inside_bound bound = bound_bound flatten_transform = flatten_transform_bound