added collision with planes

This commit is contained in:
Nicole Dresselhaus 2014-10-25 00:37:23 +02:00
parent df11c1aed0
commit 64dbcca6ef
3 changed files with 23 additions and 11 deletions

View File

@ -21,4 +21,4 @@ sphere -1.0 0.5 2.0 0.5 0.0 1.0 0.0 0.0 1.0 0.0 1.0 1.0 1.0 200.0 0.2
sphere 3.0 2.0 1.5 2.0 0.0 0.0 1.0 0.0 0.0 1.0 1.0 1.0 1.0 50.0 0.2 sphere 3.0 2.0 1.5 2.0 0.0 0.0 1.0 0.0 0.0 1.0 1.0 1.0 1.0 50.0 0.2
# planes: center, normal, material # planes: center, normal, material
#plane 0 0 0 0 1 0 0.2 0.2 0.2 0.2 0.2 0.2 0.0 0.0 0.0 100.0 0.1 plane 0 0 0 0 1 0 0.2 0.2 0.2 0.2 0.2 0.2 0.0 0.0 0.0 100.0 0.1

View File

@ -122,7 +122,7 @@ parsePlane = do
endOfLine endOfLine
return $ OpP Plane return $ OpP Plane
{ planeCenter = c { planeCenter = c
, planeNormal = n , planeNormal = normalize n
, planeMaterial = m , planeMaterial = m
} }

View File

@ -15,7 +15,7 @@ import Linear
import Scene.Parser import Scene.Parser
import Scene.Types import Scene.Types
import Debug.Trace import Debug.Trace as D
data Ray = Ray (V3 Float) (V3 Float) data Ray = Ray (V3 Float) (V3 Float)
@ -26,6 +26,9 @@ data Collision = Collision (V3 Float) (V3 Float) Float Collidable
instance Ord Collision where instance Ord Collision where
compare (Collision _ _ a _) (Collision _ _ b _) = compare a b compare (Collision _ _ a _) (Collision _ _ b _) = compare a b
epsilon :: Float
epsilon = 0.00001
render :: Int -> Int -> Scene -> Int -> PixelRGB8 render :: Int -> Int -> Scene -> Int -> PixelRGB8
render w h s index = PixelRGB8 (ci cr) (ci cg) (ci cb) render w h s index = PixelRGB8 (ci cr) (ci cg) (ci cb)
where where
@ -36,14 +39,14 @@ render w h s index = PixelRGB8 (ci cr) (ci cg) (ci cb)
-- ambient lighting -- ambient lighting
((ambColor . ambientLight $ s) * (materialAmbience . getMaterial $ obj)) ((ambColor . ambientLight $ s) * (materialAmbience . getMaterial $ obj))
-- + diffuse lighting -- + diffuse lighting
^+^ (foldl1 (^+^) $ (diffuse c s) <$> sceneLights s) + (foldl1 (+) $ (diffuse c s) <$> sceneLights s)
-- + reflections - TODO -- + reflections - TODO
ray = camRay x y (sceneCamera s) ray = camRay x y (sceneCamera s)
y = fromIntegral $ index `mod` w y = fromIntegral $ index `mod` w
x = fromIntegral $ index `div` w x = fromIntegral $ index `div` w
ci = floor . (clamp 0 255) . (*255) ci = floor . (clamp 0 255) . (*255)
--wrong format: --wrong format:
--Ray (eye cam) $ rotCam x y w h (center cam ^-^ eye cam) (up cam) (fovy cam) --Ray (eye cam) $ rotCam x y w h (center cam - eye cam) (up cam) (fovy cam)
--cam = sceneCamera s --cam = sceneCamera s
diffuse :: Collision -> Scene -> Light -> V3 Float diffuse :: Collision -> Scene -> Light -> V3 Float
@ -59,7 +62,7 @@ diffuse (Collision pos n _ obj) s (Light lpos color int) =
ill = i * dot n (normalize lightdir) *^ color * materialDiffuse mat ill = i * dot n (normalize lightdir) *^ color * materialDiffuse mat
mat = getMaterial obj mat = getMaterial obj
blocked = raytrace (Ray pos lightdir) s blocked = raytrace (Ray pos lightdir) s
lightdir = (lpos ^-^ pos) lightdir = (lpos - pos)
i = case int of i = case int of
Nothing -> 1 Nothing -> 1
Just a -> a Just a -> a
@ -79,7 +82,7 @@ raytrace r s = case possibleCollisions of
possibleCollisions = map fromJust $ filter isJust $ (intersect r) <$> (sceneObjects s) possibleCollisions = map fromJust $ filter isJust $ (intersect r) <$> (sceneObjects s)
camRay :: Float -> Float -> Camera -> Ray camRay :: Float -> Float -> Camera -> Ray
camRay x y c = Ray (eye c) (lowerLeft c ^+^ x *^ xDir c ^+^ y *^ yDir c ^-^ eye c) camRay x y c = Ray (eye c) (lowerLeft c + x *^ xDir c + y *^ yDir c - eye c)
rotateDegAx :: Float -> V3 Float -> V3 Float -> V3 Float rotateDegAx :: Float -> V3 Float -> V3 Float -> V3 Float
rotateDegAx phi axis = rotate q rotateDegAx phi axis = rotate q
@ -88,7 +91,7 @@ rotateDegAx phi axis = rotate q
intersect :: Ray -> Collidable -> Maybe Collision intersect :: Ray -> Collidable -> Maybe Collision
intersect (Ray ro rd) s@(S (Sphere sc sr _)) = if (d > 0 && int > 0) then intersect (Ray ro rd) s@(S (Sphere sc sr _)) = if (d > 0 && int > 0) then
Just (Collision pos (normalize $ pos ^-^ sc) int s) Just $ Collision pos (normalize $ pos - sc) int s
else else
Nothing Nothing
where where
@ -96,12 +99,21 @@ intersect (Ray ro rd) s@(S (Sphere sc sr _)) = if (d > 0 && int > 0) then
b = 2 * dot rd oc b = 2 * dot rd oc
c = dot oc oc - sr*sr c = dot oc oc - sr*sr
d = b * b - 4 * a * c d = b * b - 4 * a * c
oc = ro ^-^ sc oc = ro - sc
pos = ro ^+^ (rd ^* int) pos = ro + (rd ^* int)
int = case ints of int = case ints of
[] -> 0 [] -> 0
a -> foldl1 min a a -> foldl1 min a
ints = filter (uncurry (&&).(&&&) (>0.00001) (not.isNaN)) [(-b-(sqrt d))/(2*a),(-b+(sqrt d))/(2*a)] ints = filter (uncurry (&&).(&&&) (>epsilon) (not.isNaN)) [(-b-(sqrt d))/(2*a),(-b+(sqrt d))/(2*a)]
intersect (Ray ro rd) p@(P (Plane pc pn _)) = if det == 0 || t < epsilon
then Nothing
else Just -- $ D.trace (show (det, t, pos))
$ Collision pos pn t p
where
pos = ro + t *^ rd'
det = dot rd' pn
t = (dot (pc - ro) pn)/det
rd' = normalize rd
intersect _ _ = undefined intersect _ _ = undefined