{- Obj3d.hs - Objects Objects are the basic unit of 3d. -} module Obj3d where import Vec3d import Mat3d import Tri3d import qualified GraphicsUtils as G type Obj3 a = [Tri3 a] type Obj2 a = [Tri2 a] {- Partition function used for the qsort -} partition pvt (h:t) lt ge = if (averageZ h) < (averageZ pvt) then partition pvt t lt (h:ge) else partition pvt t (h:lt) ge partition pvt [] lt ge = (lt,ge) strObj3 :: Obj3 a -> IO () strObj3 (h:t) = do print ((show x) ++ ", " ++ (show y) ++ ", " ++ (show z)) strObj3 t where (x,y,z,_) = h strObj3 [] = return () strObj2 :: Obj2 a -> IO () strObj2 (h:t) = do print ((show x) ++ ", " ++ (show y) ++ ", " ++ (show z)) strObj2 t where (x,y,z,_) = h strObj2 [] = return () {- qsort the tri's in the object. -} zSortObj :: Obj3 a -> Obj3 a zSortObj (h:t) = (zSortObj front) ++ mid ++ (zSortObj back) where (front, back) = partition h t [] [] mid = [h] zSortObj [] = [] {- Transform objects -} rotObjX :: Obj3 a -> Float -> Obj3 a rotObjX objs theta = map (\x->x `rotTriX` theta) objs rotObjY :: Obj3 a -> Float -> Obj3 a rotObjY objs theta = map (\x->x `rotTriY` theta) objs rotObjZ :: Obj3 a -> Float -> Obj3 a rotObjZ objs theta = map (\x->x `rotTriZ` theta) objs flattenObj :: Obj3 a -> (Vector3 -> Vector2) -> Obj2 a flattenObj objs f = map (\x-> x `flatten` f) objs backFaceCull :: Obj2 a -> Obj2 a backFaceCull (h:t) = if not (zSign h) then h : (backFaceCull t) else (backFaceCull t) backFaceCull [] = [] drawObj2 :: G.Window -> Obj2 a -> (Tri2 a -> G.Graphic) -> IO () drawObj2 w (h:t) f = do G.drawInWindow w (f h) drawObj2 w t f drawObj2 w [] f = return () drawObj3 :: G.Window -> Obj3 a -> (Tri2 a -> G.Graphic) -> IO () drawObj3 w objs f = drawObj2 w (prepObj objs) f prepObj :: Obj3 a -> Obj2 a prepObj objs = obj2 where objs' = zSortObj objs obj2 = flattenObj objs' (deriveVec3To2 20.0) -- obj2' = backFaceCull obj2 rotObj :: Obj3 a -> Float -> Float -> Float -> Obj3 a rotObj obj x y z = obj''' where obj' = obj `rotObjX` x obj'' = obj' `rotObjY` y obj''' = obj'' `rotObjZ` z