{-# OPTIONS_GHC -Wall #-} module Vis.Camera ( Camera0(..) , Camera(..) , makeCamera , setCamera , cameraMotion , cameraKeyboardMouse ) where import Graphics.UI.GLUT ( GLdouble, GLint , Vector3(..), Vertex3(..) , Position(..), MouseButton(..), Key(..), KeyState(..) ) import qualified Graphics.UI.GLUT as GLUT import SpatialMath ( V3(..) ) data Camera0 = Camera0 { Camera0 -> GLdouble phi0 :: GLdouble , Camera0 -> GLdouble theta0 :: GLdouble , Camera0 -> GLdouble rho0 :: GLdouble } deriving Int -> Camera0 -> ShowS [Camera0] -> ShowS Camera0 -> String forall a. (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a showList :: [Camera0] -> ShowS $cshowList :: [Camera0] -> ShowS show :: Camera0 -> String $cshow :: Camera0 -> String showsPrec :: Int -> Camera0 -> ShowS $cshowsPrec :: Int -> Camera0 -> ShowS Show data Camera = Camera { Camera -> GLdouble phi :: GLdouble , Camera -> GLdouble theta :: GLdouble , Camera -> GLdouble rho :: GLdouble , Camera -> V3 GLdouble pos :: V3 GLdouble , Camera -> GLint ballX :: GLint , Camera -> GLint ballY :: GLint , Camera -> GLint leftButton :: GLint , Camera -> GLint rightButton :: GLint , Camera -> GLint middleButton :: GLint } makeCamera :: Camera0 -> Camera makeCamera :: Camera0 -> Camera makeCamera Camera0 camera0 = Camera { phi :: GLdouble phi = Camera0 -> GLdouble phi0 Camera0 camera0 , theta :: GLdouble theta = Camera0 -> GLdouble theta0 Camera0 camera0 , rho :: GLdouble rho = Camera0 -> GLdouble rho0 Camera0 camera0 , pos :: V3 GLdouble pos = forall a. a -> a -> a -> V3 a V3 GLdouble 0 GLdouble 0 GLdouble 0 , ballX :: GLint ballX = (-GLint 1) , ballY :: GLint ballY = (-GLint 1) , leftButton :: GLint leftButton = GLint 0 , rightButton :: GLint rightButton = GLint 0 , middleButton :: GLint middleButton = GLint 0 } setCamera :: Camera -> IO () setCamera :: Camera -> IO () setCamera Camera camera = Vertex3 GLdouble -> Vertex3 GLdouble -> Vector3 GLdouble -> IO () GLUT.lookAt (forall a. a -> a -> a -> Vertex3 a Vertex3 GLdouble xc GLdouble yc GLdouble zc) (forall a. a -> a -> a -> Vertex3 a Vertex3 GLdouble x0 GLdouble y0 GLdouble z0) (forall a. a -> a -> a -> Vector3 a Vector3 GLdouble 0 GLdouble 0 (-GLdouble 1)) where V3 GLdouble x0 GLdouble y0 GLdouble z0 = Camera -> V3 GLdouble pos Camera camera phi' :: GLdouble phi' = Camera -> GLdouble phi Camera camera theta' :: GLdouble theta' = Camera -> GLdouble theta Camera camera rho' :: GLdouble rho' = Camera -> GLdouble rho Camera camera xc :: GLdouble xc = GLdouble x0 forall a. Num a => a -> a -> a + GLdouble rho'forall a. Num a => a -> a -> a *forall a. Floating a => a -> a cos(GLdouble phi'forall a. Num a => a -> a -> a *forall a. Floating a => a piforall a. Fractional a => a -> a -> a /GLdouble 180)forall a. Num a => a -> a -> a *forall a. Floating a => a -> a cos(GLdouble theta'forall a. Num a => a -> a -> a *forall a. Floating a => a piforall a. Fractional a => a -> a -> a /GLdouble 180) yc :: GLdouble yc = GLdouble y0 forall a. Num a => a -> a -> a + GLdouble rho'forall a. Num a => a -> a -> a *forall a. Floating a => a -> a sin(GLdouble phi'forall a. Num a => a -> a -> a *forall a. Floating a => a piforall a. Fractional a => a -> a -> a /GLdouble 180)forall a. Num a => a -> a -> a *forall a. Floating a => a -> a cos(GLdouble theta'forall a. Num a => a -> a -> a *forall a. Floating a => a piforall a. Fractional a => a -> a -> a /GLdouble 180) zc :: GLdouble zc = GLdouble z0 forall a. Num a => a -> a -> a - GLdouble rho'forall a. Num a => a -> a -> a *forall a. Floating a => a -> a sin(GLdouble theta'forall a. Num a => a -> a -> a *forall a. Floating a => a piforall a. Fractional a => a -> a -> a /GLdouble 180) cameraMotion :: Camera -> Position -> Camera cameraMotion :: Camera -> Position -> Camera cameraMotion (Camera GLdouble phi0' GLdouble theta0' GLdouble rho0' (V3 GLdouble x0 GLdouble y0 GLdouble z0) GLint bx GLint by GLint lb GLint rb GLint mb) (Position GLint x GLint y) = GLdouble -> GLdouble -> GLdouble -> V3 GLdouble -> GLint -> GLint -> GLint -> GLint -> GLint -> Camera Camera GLdouble nextPhi GLdouble nextTheta GLdouble rho0' V3 GLdouble nextPos GLint nextBallX GLint nextBallY GLint lb GLint rb GLint mb where deltaX :: GLdouble deltaX | GLint bx forall a. Eq a => a -> a -> Bool == -GLint 1 = GLdouble 0 | Bool otherwise = forall a b. (Integral a, Num b) => a -> b fromIntegral (GLint x forall a. Num a => a -> a -> a - GLint bx) deltaY :: GLdouble deltaY | GLint by forall a. Eq a => a -> a -> Bool == -GLint 1 = GLdouble 0 | Bool otherwise = forall a b. (Integral a, Num b) => a -> b fromIntegral (GLint y forall a. Num a => a -> a -> a - GLint by) deltaZ :: GLdouble deltaZ | GLint by forall a. Eq a => a -> a -> Bool == -GLint 1 = GLdouble 0 | Bool otherwise = forall a b. (Integral a, Num b) => a -> b fromIntegral (GLint y forall a. Num a => a -> a -> a - GLint by) nextTheta' :: GLdouble nextTheta' | GLdouble deltaY forall a. Num a => a -> a -> a + GLdouble theta0' forall a. Ord a => a -> a -> Bool > GLdouble 80 = GLdouble 80 | GLdouble deltaY forall a. Num a => a -> a -> a + GLdouble theta0' forall a. Ord a => a -> a -> Bool < -GLdouble 80 = -GLdouble 80 | Bool otherwise = GLdouble deltaY forall a. Num a => a -> a -> a + GLdouble theta0' nextX :: GLdouble nextX = GLdouble x0 forall a. Num a => a -> a -> a + GLdouble 0.003forall a. Num a => a -> a -> a *GLdouble rho0'forall a. Num a => a -> a -> a *( -forall a. Floating a => a -> a sin(GLdouble phi0'forall a. Num a => a -> a -> a *forall a. Floating a => a piforall a. Fractional a => a -> a -> a /GLdouble 180)forall a. Num a => a -> a -> a *GLdouble deltaX forall a. Num a => a -> a -> a - forall a. Floating a => a -> a cos(GLdouble phi0'forall a. Num a => a -> a -> a *forall a. Floating a => a piforall a. Fractional a => a -> a -> a /GLdouble 180)forall a. Num a => a -> a -> a *GLdouble deltaY) nextY :: GLdouble nextY = GLdouble y0 forall a. Num a => a -> a -> a + GLdouble 0.003forall a. Num a => a -> a -> a *GLdouble rho0'forall a. Num a => a -> a -> a *( forall a. Floating a => a -> a cos(GLdouble phi0'forall a. Num a => a -> a -> a *forall a. Floating a => a piforall a. Fractional a => a -> a -> a /GLdouble 180)forall a. Num a => a -> a -> a *GLdouble deltaX forall a. Num a => a -> a -> a - forall a. Floating a => a -> a sin(GLdouble phi0'forall a. Num a => a -> a -> a *forall a. Floating a => a piforall a. Fractional a => a -> a -> a /GLdouble 180)forall a. Num a => a -> a -> a *GLdouble deltaY) nextZ :: GLdouble nextZ = GLdouble z0 forall a. Num a => a -> a -> a - GLdouble 0.001forall a. Num a => a -> a -> a *GLdouble rho0'forall a. Num a => a -> a -> a *GLdouble deltaZ (GLdouble nextPhi, GLdouble nextTheta) = if GLint lb forall a. Eq a => a -> a -> Bool == GLint 1 then (GLdouble phi0' forall a. Num a => a -> a -> a + GLdouble deltaX, GLdouble nextTheta') else (GLdouble phi0', GLdouble theta0') nextPos :: V3 GLdouble nextPos | GLint rb forall a. Eq a => a -> a -> Bool == GLint 1 = forall a. a -> a -> a -> V3 a V3 GLdouble nextX GLdouble nextY GLdouble z0 | GLint mb forall a. Eq a => a -> a -> Bool == GLint 1 = forall a. a -> a -> a -> V3 a V3 GLdouble x0 GLdouble y0 GLdouble nextZ | Bool otherwise = forall a. a -> a -> a -> V3 a V3 GLdouble x0 GLdouble y0 GLdouble z0 nextBallX :: GLint nextBallX = GLint x nextBallY :: GLint nextBallY = GLint y cameraKeyboardMouse :: Camera -> Key -> KeyState -> Camera cameraKeyboardMouse :: Camera -> Key -> KeyState -> Camera cameraKeyboardMouse Camera camera Key key KeyState keyState = Camera camera {rho :: GLdouble rho = GLdouble newRho, leftButton :: GLint leftButton = GLint lb, rightButton :: GLint rightButton = GLint rb, middleButton :: GLint middleButton = GLint mb, ballX :: GLint ballX = GLint bx, ballY :: GLint ballY = GLint by} where (GLint lb, Bool reset0) = case (Key key, KeyState keyState) of (MouseButton MouseButton LeftButton, KeyState Down) -> (GLint 1, Bool True) (MouseButton MouseButton LeftButton, KeyState Up) -> (GLint 0, Bool False) (Key, KeyState) _ -> (Camera -> GLint leftButton Camera camera, Bool False) (GLint rb, Bool reset1) = case (Key key, KeyState keyState) of (MouseButton MouseButton RightButton, KeyState Down) -> (GLint 1, Bool True) (MouseButton MouseButton RightButton, KeyState Up) -> (GLint 0, Bool False) (Key, KeyState) _ -> (Camera -> GLint rightButton Camera camera, Bool False) (GLint mb, Bool reset2) = case (Key key, KeyState keyState) of (MouseButton MouseButton MiddleButton, KeyState Down) -> (GLint 1, Bool True) (MouseButton MouseButton MiddleButton, KeyState Up) -> (GLint 0, Bool False) (Key, KeyState) _ -> (Camera -> GLint middleButton Camera camera, Bool False) (GLint bx,GLint by) = if Bool reset0 Bool -> Bool -> Bool || Bool reset1 Bool -> Bool -> Bool || Bool reset2 then (-GLint 1,-GLint 1) else (Camera -> GLint ballX Camera camera, Camera -> GLint ballY Camera camera) newRho :: GLdouble newRho = case (Key key, KeyState keyState) of (MouseButton MouseButton WheelUp, KeyState Down) -> GLdouble 0.9 forall a. Num a => a -> a -> a * (Camera -> GLdouble rho Camera camera) (MouseButton MouseButton WheelDown, KeyState Down) -> GLdouble 1.1 forall a. Num a => a -> a -> a * (Camera -> GLdouble rho Camera camera) (Char Char 'e', KeyState Down) -> GLdouble 0.9 forall a. Num a => a -> a -> a * (Camera -> GLdouble rho Camera camera) (Char Char 'q', KeyState Down) -> GLdouble 1.1 forall a. Num a => a -> a -> a * (Camera -> GLdouble rho Camera camera) (Key, KeyState) _ -> Camera -> GLdouble rho Camera camera