{- Raybox.hs; Mun Hon Cheong (mhch295@cse.unsw.edu.au) 2005 This module performs collision tests between AABBs, spheres and rays. -} module Raybox where import Matrix -- tests if a ray intersects a box rayBox :: (Double,Double,Double) -> (Double,Double,Double) -> (Double,Double,Double) -> (Double,Double,Double) -> Bool rayBox (rayOx,rayOy,rayOz) (rayDx,rayDy,rayDz) (minx,miny,minz)(maxx,maxy,maxz) | (rayOx,rayOy,rayOz) == (rayDx,rayDy,rayDz) = False | otherwise = case ((txmin > tymax) || (tymin > txmax)) of True -> False _ -> intersectz where (txmin,txmax) = getT rayOx rayDx minx maxx (tymin,tymax) = getT rayOy rayDy miny maxy (tzmin,tzmax) = getT rayOz rayDz minz maxz intersectz = not (((max txmin tymin) > tzmax) || (tzmin > (min txmax tymax))) getT :: Double -> Double -> Double -> Double -> (Double, Double) getT rayO rayD mn mx | dd >= 0 = ((mn-rayO)*dd, (mx-rayO)*dd) | otherwise = ((mx-rayO)*dd, (mn-rayO)*dd) where dd = (1/(rayO-rayD)) -- tests if 2 AABBs intersect boxBox :: Vec3 -> Vec3 -> Vec3 -> Vec3 -> Bool boxBox (x1,y1,z1) (w1,h1,d1) (x2,y2,z2) (w2,h2,d2) | abs (x1 - x2) <= w1+w2 = True | abs (y1 - y2) <= h1+h2 = True | abs (z1 - z2) <= d1+d2 = True | otherwise = False -- tests if an AABB intersects a sphere boxSphere :: Vec3 -> Vec3 -> Vec3 -> Double -> Bool boxSphere (x1,y1,z1) (w1,h1,d1) (x2,y2,z2) rad | (abs (x1 - x2)) <= (w1+rad) = True | (abs (y1 - y2)) <= (h1+rad) = True | (abs (z1 - z2)) <= (d1+rad) = True | otherwise = False -- test if two spheres intersect sphereSphere :: Vec3 -> Vec3 -> Double -> Double -> Bool sphereSphere (x1,y1,z1) (x2,y2,z2) rad1 rad2 = (sqrt ((x1-x2)*(x1-x2))+((y1-y2)*(y1-y2))+((z1-z2)*(z1-z2))) <= (rad1+rad2) -- tests if a point lies within a sphere spherePoint :: Vec3 -> Vec3 -> Double -> Bool spherePoint (x1,y1,z1) (x2,y2,z2) rad = (sqrt $ ((x1-x2)*(x1-x2)) + ((y1-y2)*(y1-y2)) + ((z1-z2)*(z1-z2))) <= rad -- test if a point lies in an AABB pointBox :: Vec3 -> Vec3 -> Vec3 -> Bool pointBox (x1,y1,z1) (x2,y2,z2) (w,h,d) | abs (x1 - x2) <= w && abs (y1 - y2) <= h && abs (z1 - z2) <= d = True | otherwise = False