module Diagrams.ThreeD.Camera
( Camera
, PerspectiveLens(..), OrthoLens(..)
, horizontalFieldOfView, verticalFieldOfView
, orthoWidth, orthoHeight
, camLoc, camForward, camUp, camRight, camLens
, facing_ZCamera, mm50Camera
, mm50, mm50Wide, mm50Narrow
, aspect, camAspect
)
where
import Control.Lens (makeLenses)
import Data.Cross
import Data.Monoid
import Data.Typeable
import Diagrams.Angle
import Diagrams.Core
import Diagrams.ThreeD.Types
import Diagrams.ThreeD.Vector
data Camera l = Camera
{ camLoc :: P3
, forward :: R3
, up :: R3
, lens :: l
}
deriving Typeable
class Typeable l => CameraLens l where
aspect :: l -> Double
data PerspectiveLens = PerspectiveLens
{ _horizontalFieldOfView :: Angle
, _verticalFieldOfView :: Angle
}
deriving Typeable
makeLenses ''PerspectiveLens
instance CameraLens PerspectiveLens where
aspect (PerspectiveLens h v) = angleRatio h v
data OrthoLens = OrthoLens
{ _orthoWidth :: Double
, _orthoHeight :: Double
}
deriving Typeable
makeLenses ''OrthoLens
instance CameraLens OrthoLens where
aspect (OrthoLens h v) = h / v
type instance V (Camera l) = R3
instance Transformable (Camera l) where
transform t (Camera p f u l) =
Camera (transform t p)
(transform t f)
(transform t u)
l
instance Renderable (Camera l) NullBackend where
render _ _ = mempty
mm50Camera :: (Backend b R3, Renderable (Camera PerspectiveLens) b) => Diagram b R3
mm50Camera = facing_ZCamera mm50
facing_ZCamera :: (CameraLens l, Backend b R3, Renderable (Camera l) b) =>
l -> Diagram b R3
facing_ZCamera l = mkQD (Prim $ Camera origin unit_Z unitY l)
mempty mempty mempty (Query . const . Any $ False)
mm50, mm50Wide, mm50Narrow :: PerspectiveLens
mm50 = PerspectiveLens (40.5 @@ deg) (27 @@ deg)
mm50Wide = PerspectiveLens (43.2 @@ deg) (27 @@ deg)
mm50Narrow = PerspectiveLens (36 @@ deg) (27 @@ deg)
camForward :: Camera l -> Direction
camForward = direction . forward
camUp :: Camera l -> Direction
camUp = direction . up
camRight :: Camera l -> Direction
camRight c = direction right where
right = cross3 (forward c) (up c)
camLens :: Camera l -> l
camLens = lens
camAspect :: CameraLens l => Camera l -> Double
camAspect = aspect . camLens