packages feed

not-gloss 0.1.0 → 0.2.0

raw patch · 6 files changed

+534/−422 lines, 6 filesdep +glossPVP ok

version bump matches the API change (PVP)

Dependencies added: gloss

API changes (from Hackage documentation)

- Vis: Rgb :: GLfloat -> GLfloat -> GLfloat -> VisColor
- Vis: Rgba :: GLfloat -> GLfloat -> GLfloat -> GLfloat -> VisColor
- Vis: data VisColor
- Vis: instance Functor VisObject
+ Vis: Fixed8By13 :: BitmapFont
+ Vis: Fixed9By15 :: BitmapFont
+ Vis: Helvetica10 :: BitmapFont
+ Vis: Helvetica12 :: BitmapFont
+ Vis: Helvetica18 :: BitmapFont
+ Vis: KeyBegin :: SpecialKey
+ Vis: KeyDelete :: SpecialKey
+ Vis: KeyDown :: SpecialKey
+ Vis: KeyEnd :: SpecialKey
+ Vis: KeyF1 :: SpecialKey
+ Vis: KeyF10 :: SpecialKey
+ Vis: KeyF11 :: SpecialKey
+ Vis: KeyF12 :: SpecialKey
+ Vis: KeyF2 :: SpecialKey
+ Vis: KeyF3 :: SpecialKey
+ Vis: KeyF4 :: SpecialKey
+ Vis: KeyF5 :: SpecialKey
+ Vis: KeyF6 :: SpecialKey
+ Vis: KeyF7 :: SpecialKey
+ Vis: KeyF8 :: SpecialKey
+ Vis: KeyF9 :: SpecialKey
+ Vis: KeyHome :: SpecialKey
+ Vis: KeyInsert :: SpecialKey
+ Vis: KeyLeft :: SpecialKey
+ Vis: KeyNumLock :: SpecialKey
+ Vis: KeyPageDown :: SpecialKey
+ Vis: KeyPageUp :: SpecialKey
+ Vis: KeyRight :: SpecialKey
+ Vis: KeyUnknown :: Int -> SpecialKey
+ Vis: KeyUp :: SpecialKey
+ Vis: Solid :: Flavour
+ Vis: TimesRoman10 :: BitmapFont
+ Vis: TimesRoman24 :: BitmapFont
+ Vis: Vis2dText :: String -> (a, a) -> BitmapFont -> Color -> VisObject a
+ Vis: Vis3dText :: String -> (Xyz a) -> BitmapFont -> Color -> VisObject a
+ Vis: VisCustom :: (IO ()) -> VisObject a
+ Vis: VisEllipsoid :: (a, a, a) -> (Xyz a) -> (Quat a) -> Flavour -> Color -> VisObject a
+ Vis: VisSphere :: a -> (Xyz a) -> Flavour -> Color -> VisObject a
+ Vis: Wireframe :: Flavour
+ Vis: data BitmapFont :: *
+ Vis: data Flavour :: *
+ Vis: data SpecialKey :: *
+ Vis.Camera: Camera :: IORef GLdouble -> IORef GLdouble -> IORef GLdouble -> IORef GLdouble -> IORef GLdouble -> IORef GLdouble -> IORef GLint -> IORef GLint -> IORef GLint -> IORef GLint -> Camera
+ Vis.Camera: Camera0 :: GLdouble -> GLdouble -> GLdouble -> Camera0
+ Vis.Camera: ballX :: Camera -> IORef GLint
+ Vis.Camera: ballY :: Camera -> IORef GLint
+ Vis.Camera: data Camera
+ Vis.Camera: data Camera0
+ Vis.Camera: leftButton :: Camera -> IORef GLint
+ Vis.Camera: makeCamera :: Camera0 -> IO Camera
+ Vis.Camera: phi :: Camera -> IORef GLdouble
+ Vis.Camera: phi0 :: Camera0 -> GLdouble
+ Vis.Camera: rho :: Camera -> IORef GLdouble
+ Vis.Camera: rho0 :: Camera0 -> GLdouble
+ Vis.Camera: rightButton :: Camera -> IORef GLint
+ Vis.Camera: theta :: Camera -> IORef GLdouble
+ Vis.Camera: theta0 :: Camera0 -> GLdouble
+ Vis.Camera: x0c :: Camera -> IORef GLdouble
+ Vis.Camera: y0c :: Camera -> IORef GLdouble
+ Vis.Camera: z0c :: Camera -> IORef GLdouble
+ Vis.Interface: vis :: Real b => Camera0 -> (Maybe SpecialKey -> a -> IO a) -> (Maybe SpecialKey -> a -> [VisObject b]) -> a -> Double -> IO ()
+ Vis.VisObject: Vis2dText :: String -> (a, a) -> BitmapFont -> Color -> VisObject a
+ Vis.VisObject: Vis3dText :: String -> (Xyz a) -> BitmapFont -> Color -> VisObject a
+ Vis.VisObject: VisArrow :: (a, a) -> (Xyz a) -> (Xyz a) -> Color -> VisObject a
+ Vis.VisObject: VisAxes :: (a, a) -> (Xyz a) -> (Quat a) -> VisObject a
+ Vis.VisObject: VisBox :: (a, a, a) -> (Xyz a) -> (Quat a) -> Flavour -> Color -> VisObject a
+ Vis.VisObject: VisCustom :: (IO ()) -> VisObject a
+ Vis.VisObject: VisCylinder :: (a, a) -> (Xyz a) -> (Quat a) -> Color -> VisObject a
+ Vis.VisObject: VisEllipsoid :: (a, a, a) -> (Xyz a) -> (Quat a) -> Flavour -> Color -> VisObject a
+ Vis.VisObject: VisLine :: [Xyz a] -> Color -> VisObject a
+ Vis.VisObject: VisPlane :: (Xyz a) -> a -> Color -> Color -> VisObject a
+ Vis.VisObject: VisQuad :: (Xyz a) -> (Xyz a) -> (Xyz a) -> (Xyz a) -> Color -> VisObject a
+ Vis.VisObject: VisSphere :: a -> (Xyz a) -> Flavour -> Color -> VisObject a
+ Vis.VisObject: VisTriangle :: (Xyz a) -> (Xyz a) -> (Xyz a) -> Color -> VisObject a
+ Vis.VisObject: data VisObject a
+ Vis.VisObject: drawObjects :: [VisObject GLdouble] -> IO ()
+ Vis.VisObject: instance Functor VisObject
+ Vis.VisObject: setPerspectiveMode :: IO ()
- Vis: VisArrow :: (a, a) -> (Xyz a) -> (Xyz a) -> VisColor -> VisObject a
+ Vis: VisArrow :: (a, a) -> (Xyz a) -> (Xyz a) -> Color -> VisObject a
- Vis: VisBox :: (a, a, a) -> (Xyz a) -> (Quat a) -> VisColor -> VisObject a
+ Vis: VisBox :: (a, a, a) -> (Xyz a) -> (Quat a) -> Flavour -> Color -> VisObject a
- Vis: VisCylinder :: (a, a) -> (Xyz a) -> (Quat a) -> VisColor -> VisObject a
+ Vis: VisCylinder :: (a, a) -> (Xyz a) -> (Quat a) -> Color -> VisObject a
- Vis: VisLine :: [Xyz a] -> VisColor -> VisObject a
+ Vis: VisLine :: [Xyz a] -> Color -> VisObject a
- Vis: VisPlane :: (Xyz a) -> a -> VisColor -> VisColor -> VisObject a
+ Vis: VisPlane :: (Xyz a) -> a -> Color -> Color -> VisObject a
- Vis: VisQuad :: (Xyz a) -> (Xyz a) -> (Xyz a) -> (Xyz a) -> VisColor -> VisObject a
+ Vis: VisQuad :: (Xyz a) -> (Xyz a) -> (Xyz a) -> (Xyz a) -> Color -> VisObject a
- Vis: VisTriangle :: (Xyz a) -> (Xyz a) -> (Xyz a) -> VisColor -> VisObject a
+ Vis: VisTriangle :: (Xyz a) -> (Xyz a) -> (Xyz a) -> Color -> VisObject a

Files

Example.hs view
@@ -2,9 +2,9 @@  module Main where -import Graphics.UI.GLUT( SpecialKey(..) ) import SpatialMath import qualified Quat+ import Vis  ts :: Double@@ -18,14 +18,26 @@     dq = Quat 1 (x*ts) (v*ts) (x*v*ts)  drawFun :: Maybe SpecialKey -> State Double -> [VisObject Double]-drawFun key (State (x,_) quat) = [axes,box,plane]+drawFun key (State (x,_) quat) = [axes,box,ellipsoid,sphere] ++ (map text [-5..5]) ++ [boxText, plane]    where     axes = VisAxes (0.5, 15) (Xyz 0 0 0) (Quat 1 0 0 0)-    box = VisBox (0.2, 0.2, 0.2) (Xyz 0 0 x) quat col+    sphere = VisSphere 0.15 (Xyz 0 x (-1)) Wireframe col       where-        col = case key of Nothing -> Rgb 0 1 1-                          _       -> Rgb 1 1 0-    plane = VisPlane (Xyz 0 0 1) 0 (Rgb 1 1 1) (Rgba 0.4 0.6 0.65 0.4)+        col = case key of Nothing -> makeColor 0.2 0.3 0.8 1+                          _       -> makeColor 0.2 0.3 0.8 0.4+    ellipsoid = VisEllipsoid (0.2, 0.3, 0.4) (Xyz x 0 (-1)) quat Solid col+      where+        col = case key of Nothing -> makeColor 1 0.3 0.5 1+                          _       -> makeColor 1 0.3 0.5 0.3+    box = VisBox (0.2, 0.2, 0.2) (Xyz 0 0 x) quat Wireframe col+      where+        col = case key of Nothing -> makeColor 0 1 1 1+                          _       -> makeColor 0 1 1 0.2+    plane = VisPlane (Xyz 0 0 1) 0 (makeColor 1 1 1 1) (makeColor 0.4 0.6 0.65 0.4)+    text k = Vis2dText "OLOLOLOLOLO" (100,500 - k*100*x) TimesRoman24 (makeColor 0 (0.5 + x'/2) (0.5 - x'/2) 1)+      where+        x' = realToFrac $ (x + 1)/0.4*k/5+    boxText = Vis3dText "trololololo" (Xyz 0 0 (x-0.2)) TimesRoman24 (makeColor 1 0 0 1)  main :: IO () main = do
Vis.hs view
@@ -1,419 +1,16 @@--- Vis.hs- {-# OPTIONS_GHC -Wall #-}  module Vis ( vis            , VisObject(..)-           , VisColor(..)            , Camera0(..)+           , SpecialKey(..)+           , BitmapFont(..)+           , Flavour(..)+           , module Graphics.Gloss.Data.Color            ) where -import Data.IORef ( newIORef )-import System.Exit ( exitSuccess )-import Graphics.UI.GLUT-import Data.Time.Clock-import Control.Concurrent-import Control.Monad-import Graphics.Rendering.OpenGL.Raw( glBegin, glEnd, gl_QUADS, gl_QUAD_STRIP, gl_TRIANGLES, glVertex3f, glVertex3d, glNormal3d, gl_TRIANGLE_FAN )--import SpatialMath import Vis.Camera--data VisColor = Rgb GLfloat GLfloat GLfloat-              | Rgba GLfloat GLfloat GLfloat GLfloat--setColor :: VisColor -> IO ()-setColor (Rgb r g b)    = color (Color3 r g b)-setColor (Rgba r g b a) = color (Color4 r g b a)--setMaterialDiffuse :: VisColor -> GLfloat -> IO ()-setMaterialDiffuse (Rgb r g b) a = materialDiffuse Front $= Color4 r g b a-setMaterialDiffuse (Rgba r g b a) _ = materialDiffuse Front $= Color4 r g b a--data VisObject a = VisCylinder (a,a) (Xyz a) (Quat a) VisColor-                 | VisBox (a,a,a) (Xyz a) (Quat a) VisColor-                 | VisLine [Xyz a] VisColor-                 | VisArrow (a,a) (Xyz a) (Xyz a) VisColor-                 | VisAxes (a,a) (Xyz a) (Quat a)-                 | VisPlane (Xyz a) a VisColor VisColor-                 | VisTriangle (Xyz a) (Xyz a) (Xyz a) VisColor-                 | VisQuad (Xyz a) (Xyz a) (Xyz a) (Xyz a) VisColor--instance Functor VisObject where-  fmap f (VisCylinder (x,y) xyz quat col) = VisCylinder (f x, f y) (fmap f xyz) (fmap f quat) col-  fmap f (VisBox (x,y,z) xyz quat col) = VisBox (f x, f y, f z) (fmap f xyz) (fmap f quat) col-  fmap f (VisLine xyzs col) = VisLine (map (fmap f) xyzs) col-  fmap f (VisArrow (x,y) xyz0 xyz1 col) = VisArrow (f x, f y) (fmap f xyz0) (fmap f xyz1) col-  fmap f (VisAxes (x,y) xyz quat) = VisAxes (f x, f y) (fmap f xyz) (fmap f quat)-  fmap f (VisPlane xyz x col0 col1) = VisPlane (fmap f xyz) (f x) col0 col1-  fmap f (VisTriangle x0 x1 x2 col) = VisTriangle (fmap f x0) (fmap f x1) (fmap f x2) col-  fmap f (VisQuad x0 x1 x2 x3 col) = VisQuad (fmap f x0) (fmap f x1) (fmap f x2) (fmap f x3) col--myGlInit :: String -> IO ()-myGlInit progName = do-  initialDisplayMode $= [ DoubleBuffered, RGBMode, WithDepthBuffer ]-  Size x y <- get screenSize-  putStrLn $ "screen resolution " ++ show x ++ "x" ++ show y-  let intScale d i = round $ d*(realToFrac i :: Double)-      x0 = intScale 0.3 x-      xf = intScale 0.95 x-      y0 = intScale 0.05 y-      yf = intScale 0.95 y-  initialWindowSize $= Size (xf - x0) (yf - y0)-  initialWindowPosition $= Position (fromIntegral x0) (fromIntegral y0)-  _ <- createWindow progName--  clearColor $= Color4 0 0 0 0-  shadeModel $= Smooth-  depthFunc $= Just Less-  lighting $= Enabled-  light (Light 0) $= Enabled-  ambient (Light 0) $= Color4 1 1 1 1-   -  materialDiffuse Front $= Color4 0.5 0.5 0.5 1-  materialSpecular Front $= Color4 1 1 1 1-  materialShininess Front $= 25-  colorMaterial $= Just (Front, Diffuse)---drawObjects :: [VisObject GLdouble] -> IO ()-drawObjects = mapM_ drawObject-  where-    drawObject :: VisObject GLdouble -> IO ()--    -- triangle-    drawObject (VisTriangle (Xyz x0 y0 z0) (Xyz x1 y1 z1) (Xyz x2 y2 z2) col) =-      preservingMatrix $ do-        setMaterialDiffuse col 1-        setColor col-        glBegin gl_TRIANGLES-        glVertex3d x0 y0 z0-        glVertex3d x1 y1 z1-        glVertex3d x2 y2 z2-        glEnd-       -    -- quad-    drawObject (VisQuad (Xyz x0 y0 z0) (Xyz x1 y1 z1) (Xyz x2 y2 z2) (Xyz x3 y3 z3) col) =-      preservingMatrix $ do-        setMaterialDiffuse col 1-        setColor col-        glBegin gl_QUADS-        glVertex3d x0 y0 z0-        glVertex3d x1 y1 z1-        glVertex3d x2 y2 z2-        glVertex3d x3 y3 z3-        glEnd-    -    -- cylinder-    drawObject (VisCylinder (height,radius) (Xyz x y z) (Quat q0 q1 q2 q3) col) =-      preservingMatrix $ do-        setMaterialDiffuse col 1-        setColor col-        -        translate (Vector3 x y z :: Vector3 GLdouble)-        rotate (2 * acos q0 *180/pi :: GLdouble) (Vector3 q1 q2 q3)-----        translate (Vector3 0 0 (-height/2) :: Vector3 GLdouble)--        let nslices = 10 :: Int-            nstacks = 10 :: Int--            -- Pre-computed circle-            sinCosTable = map (\q -> (sin q, cos q)) angles-              where-                angle = 2*pi/(fromIntegral nslices)-                angles = reverse $ map ((angle*) . fromIntegral) [0..(nslices+1)]-                -        -- Cover the base and top-        glBegin gl_TRIANGLE_FAN-        glNormal3d 0 0 (-1)-        glVertex3d 0 0 0-        mapM_ (\(s,c) -> glVertex3d (c*radius) (s*radius) 0) sinCosTable-        glEnd--        glBegin gl_TRIANGLE_FAN-        glNormal3d 0 0 1-        glVertex3d 0 0 height-        mapM_ (\(s,c) -> glVertex3d (c*radius) (s*radius) height) (reverse sinCosTable)-        glEnd--        let -- Do the stacks-            -- Step in z and radius as stacks are drawn.-            zSteps = map (\k -> (fromIntegral k)*height/(fromIntegral nstacks)) [0..nstacks]-            drawSlice z0 z1 (s,c) = do-              glNormal3d  c          s         0-              glVertex3d (c*radius) (s*radius) z0-              glVertex3d (c*radius) (s*radius) z1--            drawSlices (z0,z1) = do-              glBegin gl_QUAD_STRIP-              mapM_ (drawSlice z0 z1) sinCosTable-              glEnd--        mapM_ drawSlices $ zip (init zSteps) (tail zSteps)--    -- box-    drawObject (VisBox (dx,dy,dz) (Xyz x y z) (Quat q0 q1 q2 q3) col) =-      preservingMatrix $ do-        setMaterialDiffuse col 0.1-        setColor col-        translate (Vector3 x y z :: Vector3 GLdouble)-        rotate (2 * acos q0 *180/pi :: GLdouble) (Vector3 q1 q2 q3)-        normalize $= Enabled-        scale dx dy dz-        renderObject Solid (Cube 1)-        normalize $= Disabled--    -- line-    drawObject (VisLine path col) =-      preservingMatrix $ do-        lighting $= Disabled-        setColor col-        renderPrimitive LineStrip $ mapM_ (\(Xyz x' y' z') -> vertex$Vertex3 x' y' z') path-        lighting $= Enabled--    -- plane-    drawObject (VisPlane (Xyz x y z) offset col1 col2) =-      preservingMatrix $ do-        let norm = 1/(sqrt $ x*x + y*y + z*z)-            x' = x*norm-            y' = y*norm-            z' = z*norm-            r  = 10-            n  = 5-            eps = 0.01-        translate (Vector3 (offset*x') (offset*y') (offset*z') :: Vector3 GLdouble)-        rotate ((acos z')*180/pi :: GLdouble) (Vector3 (-y') x' 0)-        mapM_ drawObject $ concat [[ VisLine [Xyz (-r) y0 eps, Xyz r y0 eps] col1-                                   , VisLine [Xyz x0 (-r) eps, Xyz x0 r eps] col1-                                   ] | x0 <- [-r,-r+r/n..r], y0 <- [-r,-r+r/n..r]]-        mapM_ drawObject $ concat [[ VisLine [Xyz (-r) y0 (-eps), Xyz r y0 (-eps)] col1-                                   , VisLine [Xyz x0 (-r) (-eps), Xyz x0 r (-eps)] col1-                                   ] | x0 <- [-r,-r+r/n..r], y0 <- [-r,-r+r/n..r]]-        glBegin gl_QUADS-        setColor col2-        let r' = realToFrac r-        glVertex3f   r'    r'  0-        glVertex3f (-r')   r'  0-        glVertex3f (-r')  (-r')  0-        glVertex3f   r'   (-r')  0-        glEnd--    -- arrow-    drawObject (VisArrow (size, aspectRatio) (Xyz x0 y0 z0) (Xyz x y z) col) =-      preservingMatrix $ do-        let numSlices = 8-            numStacks = 15-            cylinderRadius = 0.5*size/aspectRatio-            cylinderHeight = size-            coneRadius = 2*cylinderRadius-            coneHeight = 2*coneRadius--            rotAngle = acos(z/(sqrt(x*x + y*y + z*z) + 1e-15))*180/pi :: GLdouble-            rotAxis = Vector3 (-y) x 0-        -        translate (Vector3 x0 y0 z0 :: Vector3 GLdouble)-        rotate rotAngle rotAxis-        -        -- cylinder-        drawObject $ VisCylinder (cylinderHeight, cylinderRadius) (Xyz 0 0 0) (Quat 1 0 0 0) col-        -- cone-        setMaterialDiffuse col 1-        setColor col-        translate (Vector3 0 0 cylinderHeight :: Vector3 GLdouble)-        renderObject Solid (Cone coneRadius coneHeight numSlices numStacks)--    drawObject (VisAxes (size, aspectRatio) (Xyz x0 y0 z0) (Quat q0 q1 q2 q3)) = preservingMatrix $ do-      translate (Vector3 x0 y0 z0 :: Vector3 GLdouble)-      rotate (2 * acos q0 *180/pi :: GLdouble) (Vector3 q1 q2 q3)-        -      let xAxis = VisArrow (size, aspectRatio) (Xyz 0 0 0) (Xyz 1 0 0) (Rgb 1 0 0)-          yAxis = VisArrow (size, aspectRatio) (Xyz 0 0 0) (Xyz 0 1 0) (Rgb 0 1 0)-          zAxis = VisArrow (size, aspectRatio) (Xyz 0 0 0) (Xyz 0 0 1) (Rgb 0 0 1)-      drawObjects [xAxis, yAxis, zAxis]--display :: MVar a -> MVar (Maybe SpecialKey) -> MVar Bool -> Camera -> (Maybe SpecialKey -> a -> IO ()) -> DisplayCallback-display stateMVar keyRef visReadyMVar camera userDrawFun = do-   clear [ ColorBuffer, DepthBuffer ]-   -   -- draw the scene-   preservingMatrix $ do-     -- setup the camera-     x0     <- get (x0c    camera)-     y0     <- get (y0c    camera)-     z0     <- get (z0c    camera)-     phi'   <- get (phi   camera)-     theta' <- get (theta camera)-     rho'   <- get (rho   camera)-     let-       xc = x0 + rho'*cos(phi'*pi/180)*cos(theta'*pi/180)-       yc = y0 + rho'*sin(phi'*pi/180)*cos(theta'*pi/180)-       zc = z0 - rho'*sin(theta'*pi/180)-     lookAt (Vertex3 xc yc zc) (Vertex3 x0 y0 z0) (Vector3 0 0 (-1))-     -     -- call user function-     state <- readMVar stateMVar-     latestKey <- readMVar keyRef-     userDrawFun latestKey state--     ---- draw the torus-     --color (Color3 0 1 1 :: Color3 GLfloat)-     --renderObject Solid (Torus 0.275 1.85 8 15)-   -   flush-   swapBuffers-   _ <- swapMVar visReadyMVar True-   postRedisplay Nothing-   return ()---reshape :: ReshapeCallback-reshape size@(Size w h) = do-   viewport $= (Position 0 0, size)-   matrixMode $= Projection-   loadIdentity-   perspective 40 (fromIntegral w / fromIntegral h) 0.1 100-   matrixMode $= Modelview 0-   loadIdentity-   postRedisplay Nothing--keyboardMouse :: Camera -> MVar (Maybe SpecialKey) -> KeyboardMouseCallback-keyboardMouse camera keyRef key keyState _ _ =-  case (key, keyState) of-    -- kill sim thread when main loop finishes-    (Char '\27', Down) -> exitSuccess--    -- set keyRef-    (SpecialKey k, Down)   -> do-      _ <- swapMVar keyRef (Just k)-      return ()-    (SpecialKey _, Up)   -> do-      _ <- swapMVar keyRef Nothing-      return ()--    -- adjust camera-    (MouseButton LeftButton, Down) -> do -      resetMotion-      leftButton camera $= 1-    (MouseButton LeftButton, Up) -> leftButton camera $= 0-    (MouseButton RightButton, Down) -> do -      resetMotion-      rightButton camera $= 1-    (MouseButton RightButton, Up) -> rightButton camera $= 0-      -    (MouseButton WheelUp, Down) -> zoom 0.9-    (MouseButton WheelDown, Down) -> zoom 1.1-    -    _ -> return ()-    where resetMotion = do-            ballX camera $= -1-            ballY camera $= -1--          zoom factor = do-            rho camera $~ (* factor)-            postRedisplay Nothing-            --motion :: Camera -> MotionCallback-motion camera (Position x y) = do-   x0  <- get (x0c camera)-   y0  <- get (y0c camera)-   bx  <- get (ballX camera)-   by  <- get (ballY camera)-   phi' <- get (phi camera)-   theta' <- get (theta camera)-   rho' <- get (rho camera)-   lb <- get (leftButton camera)-   rb <- get (rightButton camera)-   let deltaX-         | bx == -1  = 0-         | otherwise = fromIntegral (x - bx)-       deltaY-         | by == -1  = 0-         | otherwise = fromIntegral (y - by)-       nextTheta -         | deltaY + theta' >  80 =  80-         | deltaY + theta' < -80 = -80-         | otherwise             = deltaY + theta'-       nextX0 = x0 + 0.003*rho'*( -sin(phi'*pi/180)*deltaX - cos(phi'*pi/180)*deltaY)-       nextY0 = y0 + 0.003*rho'*(  cos(phi'*pi/180)*deltaX - sin(phi'*pi/180)*deltaY)-       -   when (lb == 1) $ do-     phi   camera $~ (+ deltaX)-     theta camera $= nextTheta-   -   when (rb == 1) $ do-     x0c camera $= nextX0-     y0c camera $= nextY0-   -   ballX camera $= x-   ballY camera $= y-   -   postRedisplay Nothing---vis :: Real b => Camera0 -> (Maybe SpecialKey -> a -> IO a) -> (Maybe SpecialKey -> a -> [VisObject b]) -> a -> Double -> IO ()-vis camera0 userSimFun userDrawFun x0 ts = do-  -- init glut/scene-  (progName, _args) <- getArgsAndInitialize-  myGlInit progName-   -  -- create internal state-  stateMVar <- newMVar x0-  camera <- makeCamera camera0-  visReadyMVar <- newMVar False-  latestKey <- newMVar Nothing--  -- start sim thread-  _ <- forkIO $ simThread stateMVar visReadyMVar userSimFun ts latestKey-  -  -- setup callbacks-  displayCallback $= display stateMVar latestKey visReadyMVar camera (\x y -> drawObjects $ map (fmap realToFrac) (userDrawFun x y))-  reshapeCallback $= Just reshape-  keyboardMouseCallback $= Just (keyboardMouse camera  latestKey)-  motionCallback $= Just (motion camera)--  -- start main loop-  mainLoop---simThread :: MVar a -> MVar Bool -> (Maybe SpecialKey -> a -> IO a) -> Double -> MVar (Maybe SpecialKey) -> IO ()-simThread stateMVar visReadyMVar userSimFun ts keyRef = do-  let waitUntilDisplayIsReady :: IO ()-      waitUntilDisplayIsReady = do -        visReady <- readMVar visReadyMVar-        unless visReady $ do-          threadDelay 10000-          waitUntilDisplayIsReady-  -  waitUntilDisplayIsReady-  -  t0 <- getCurrentTime-  lastTimeRef <- newIORef t0--  forever $ do-    -- calculate how much longer to sleep before taking a timestep-    currentTime <- getCurrentTime-    lastTime <- get lastTimeRef-    let usRemaining :: Int-        usRemaining = round $ 1e6*(ts - realToFrac (diffUTCTime currentTime lastTime))--    if usRemaining <= 0-      -- slept for long enough, do a sim iteration-      then do-        lastTimeRef $= addUTCTime (realToFrac ts) lastTime--        let getNextState = do-              state <- readMVar stateMVar-              latestKey <- readMVar keyRef-              userSimFun latestKey state--        let putState = swapMVar stateMVar--        nextState <- getNextState-        _ <- nextState `seq` putState nextState--        postRedisplay Nothing-       -      -- need to sleep longer-      else threadDelay usRemaining-           +import Vis.Interface+import Vis.VisObject+import Graphics.Gloss.Data.Color+import Graphics.UI.GLUT
Vis/Camera.hs view
@@ -48,4 +48,3 @@                 , leftButton = leftButton'                 , rightButton = rightButton'                 }-
+ Vis/Interface.hs view
@@ -0,0 +1,228 @@+{-# OPTIONS_GHC -Wall #-}++module Vis.Interface ( vis+                     ) where++import Data.IORef ( newIORef )+import System.Exit ( exitSuccess )+import Data.Time.Clock ( getCurrentTime, diffUTCTime, addUTCTime )+import Control.Concurrent ( MVar, readMVar, swapMVar, newMVar, forkIO, threadDelay )+import Control.Monad ( when, unless, forever )+import Graphics.UI.GLUT+import Graphics.Rendering.OpenGL.Raw+                                       +import Vis.Camera ( Camera(..) , makeCamera, Camera0(..) )+import Vis.VisObject ( VisObject(..), drawObjects, setPerspectiveMode )++myGlInit :: String -> IO ()+myGlInit progName = do+  initialDisplayMode $= [ DoubleBuffered, RGBAMode, WithDepthBuffer ]+  Size x y <- get screenSize+  putStrLn $ "screen resolution " ++ show x ++ "x" ++ show y+  let intScale d i = round $ d*(realToFrac i :: Double)+      x0 = intScale 0.3 x+      xf = intScale 0.95 x+      y0 = intScale 0.05 y+      yf = intScale 0.95 y+  initialWindowSize $= Size (xf - x0) (yf - y0)+  initialWindowPosition $= Position (fromIntegral x0) (fromIntegral y0)+  _ <- createWindow progName++  clearColor $= Color4 0 0 0 0+  shadeModel $= Smooth+  depthFunc $= Just Less+  lighting $= Enabled+  light (Light 0) $= Enabled+  ambient (Light 0) $= Color4 1 1 1 1+   +  materialDiffuse Front $= Color4 0.5 0.5 0.5 1+  materialSpecular Front $= Color4 1 1 1 1+  materialShininess Front $= 100+  colorMaterial $= Just (Front, Diffuse)++  glEnable gl_BLEND+  glBlendFunc gl_SRC_ALPHA gl_ONE_MINUS_SRC_ALPHA++display :: MVar a -> MVar (Maybe SpecialKey) -> MVar Bool -> Camera -> (Maybe SpecialKey -> a -> IO ()) -> DisplayCallback+display stateMVar keyRef visReadyMVar camera userDrawFun = do+   clear [ ColorBuffer, DepthBuffer ]+   +   -- draw the scene+   preservingMatrix $ do+     -- setup the camera+     x0     <- get (x0c    camera)+     y0     <- get (y0c    camera)+     z0     <- get (z0c    camera)+     phi'   <- get (phi   camera)+     theta' <- get (theta camera)+     rho'   <- get (rho   camera)+     let+       xc = x0 + rho'*cos(phi'*pi/180)*cos(theta'*pi/180)+       yc = y0 + rho'*sin(phi'*pi/180)*cos(theta'*pi/180)+       zc = z0 - rho'*sin(theta'*pi/180)+     lookAt (Vertex3 xc yc zc) (Vertex3 x0 y0 z0) (Vector3 0 0 (-1))+     +     -- call user function+     state <- readMVar stateMVar+     latestKey <- readMVar keyRef+     userDrawFun latestKey state++     ---- draw the torus+     --color (Color3 0 1 1 :: Color3 GLfloat)+     --renderObject Solid (Torus 0.275 1.85 8 15)+   +   flush+   swapBuffers+   _ <- swapMVar visReadyMVar True+   postRedisplay Nothing+   return ()+++reshape :: ReshapeCallback+reshape size@(Size _ _) = do+   viewport $= (Position 0 0, size)+   setPerspectiveMode+   loadIdentity+   postRedisplay Nothing++keyboardMouse :: Camera -> MVar (Maybe SpecialKey) -> KeyboardMouseCallback+keyboardMouse camera keyRef key keyState _ _ =+  case (key, keyState) of+    -- kill sim thread when main loop finishes+    (Char '\27', Down) -> exitSuccess++    -- set keyRef+    (SpecialKey k, Down)   -> do+      _ <- swapMVar keyRef (Just k)+      return ()+    (SpecialKey _, Up)   -> do+      _ <- swapMVar keyRef Nothing+      return ()++    -- adjust camera+    (MouseButton LeftButton, Down) -> do +      resetMotion+      leftButton camera $= 1+    (MouseButton LeftButton, Up) -> leftButton camera $= 0+    (MouseButton RightButton, Down) -> do +      resetMotion+      rightButton camera $= 1+    (MouseButton RightButton, Up) -> rightButton camera $= 0+      +    (MouseButton WheelUp, Down) -> zoom 0.9+    (MouseButton WheelDown, Down) -> zoom 1.1+    +    _ -> return ()+    where resetMotion = do+            ballX camera $= -1+            ballY camera $= -1++          zoom factor = do+            rho camera $~ (* factor)+            postRedisplay Nothing+            ++motion :: Camera -> MotionCallback+motion camera (Position x y) = do+   x0  <- get (x0c camera)+   y0  <- get (y0c camera)+   bx  <- get (ballX camera)+   by  <- get (ballY camera)+   phi' <- get (phi camera)+   theta' <- get (theta camera)+   rho' <- get (rho camera)+   lb <- get (leftButton camera)+   rb <- get (rightButton camera)+   let deltaX+         | bx == -1  = 0+         | otherwise = fromIntegral (x - bx)+       deltaY+         | by == -1  = 0+         | otherwise = fromIntegral (y - by)+       nextTheta +         | deltaY + theta' >  80 =  80+         | deltaY + theta' < -80 = -80+         | otherwise             = deltaY + theta'+       nextX0 = x0 + 0.003*rho'*( -sin(phi'*pi/180)*deltaX - cos(phi'*pi/180)*deltaY)+       nextY0 = y0 + 0.003*rho'*(  cos(phi'*pi/180)*deltaX - sin(phi'*pi/180)*deltaY)+       +   when (lb == 1) $ do+     phi   camera $~ (+ deltaX)+     theta camera $= nextTheta+   +   when (rb == 1) $ do+     x0c camera $= nextX0+     y0c camera $= nextY0+   +   ballX camera $= x+   ballY camera $= y+   +   postRedisplay Nothing+++vis :: Real b => Camera0 -> (Maybe SpecialKey -> a -> IO a) -> (Maybe SpecialKey -> a -> [VisObject b]) -> a -> Double -> IO ()+vis camera0 userSimFun userDrawFun x0 ts = do+  -- init glut/scene+  (progName, _args) <- getArgsAndInitialize+  myGlInit progName+   +  -- create internal state+  stateMVar <- newMVar x0+  camera <- makeCamera camera0+  visReadyMVar <- newMVar False+  latestKey <- newMVar Nothing++  -- start sim thread+  _ <- forkIO $ simThread stateMVar visReadyMVar userSimFun ts latestKey+  +  -- setup callbacks+  displayCallback $= display stateMVar latestKey visReadyMVar camera (\x y -> drawObjects $ map (fmap realToFrac) (userDrawFun x y))+  reshapeCallback $= Just reshape+  keyboardMouseCallback $= Just (keyboardMouse camera  latestKey)+  motionCallback $= Just (motion camera)++  -- start main loop+  mainLoop+++simThread :: MVar a -> MVar Bool -> (Maybe SpecialKey -> a -> IO a) -> Double -> MVar (Maybe SpecialKey) -> IO ()+simThread stateMVar visReadyMVar userSimFun ts keyRef = do+  let waitUntilDisplayIsReady :: IO ()+      waitUntilDisplayIsReady = do +        visReady <- readMVar visReadyMVar+        unless visReady $ do+          threadDelay 10000+          waitUntilDisplayIsReady+  +  waitUntilDisplayIsReady+  +  t0 <- getCurrentTime+  lastTimeRef <- newIORef t0++  forever $ do+    -- calculate how much longer to sleep before taking a timestep+    currentTime <- getCurrentTime+    lastTime <- get lastTimeRef+    let usRemaining :: Int+        usRemaining = round $ 1e6*(ts - realToFrac (diffUTCTime currentTime lastTime))++    if usRemaining <= 0+      -- slept for long enough, do a sim iteration+      then do+        lastTimeRef $= addUTCTime (realToFrac ts) lastTime++        let getNextState = do+              state <- readMVar stateMVar+              latestKey <- readMVar keyRef+              userSimFun latestKey state++        let putState = swapMVar stateMVar++        nextState <- getNextState+        _ <- nextState `seq` putState nextState++        postRedisplay Nothing+       +      -- need to sleep longer+      else threadDelay usRemaining+           
+ Vis/VisObject.hs view
@@ -0,0 +1,263 @@+{-# OPTIONS_GHC -Wall #-}++module Vis.VisObject ( VisObject(..)+                     , drawObjects+                     , setPerspectiveMode+                     ) where++import Graphics.Rendering.OpenGL.Raw+import qualified Graphics.Gloss.Data.Color as Gloss+import Graphics.UI.GLUT++import SpatialMath++glColorOfColor :: Gloss.Color -> Color4 GLfloat+glColorOfColor = (\(r,g,b,a) -> fmap realToFrac (Color4 r g b a)) . Gloss.rgbaOfColor++setColor :: Gloss.Color -> IO ()+setColor = color . glColorOfColor++setMaterialDiffuse :: Gloss.Color -> IO ()+setMaterialDiffuse col = materialDiffuse Front $= (glColorOfColor col)++data VisObject a = VisCylinder (a,a) (Xyz a) (Quat a) Gloss.Color+                 | VisBox (a,a,a) (Xyz a) (Quat a) Flavour Gloss.Color+                 | VisEllipsoid (a,a,a) (Xyz a) (Quat a) Flavour Gloss.Color+                 | VisSphere a (Xyz a) Flavour Gloss.Color+                 | VisLine [Xyz a] Gloss.Color+                 | VisArrow (a,a) (Xyz a) (Xyz a) Gloss.Color+                 | VisAxes (a,a) (Xyz a) (Quat a)+                 | VisPlane (Xyz a) a Gloss.Color Gloss.Color+                 | VisTriangle (Xyz a) (Xyz a) (Xyz a) Gloss.Color+                 | VisQuad (Xyz a) (Xyz a) (Xyz a) (Xyz a) Gloss.Color+                 | VisCustom (IO ())+                 | Vis3dText String (Xyz a) BitmapFont Gloss.Color+                 | Vis2dText String (a,a) BitmapFont Gloss.Color++instance Functor VisObject where+  fmap f (VisCylinder (x,y) xyz quat col) = VisCylinder (f x, f y) (fmap f xyz) (fmap f quat) col+  fmap f (VisBox (x,y,z) xyz quat flav col) = VisBox (f x, f y, f z) (fmap f xyz) (fmap f quat) flav col+  fmap f (VisSphere s xyz flav col) = VisSphere (f s) (fmap f xyz) flav col+  fmap f (VisEllipsoid (sx,sy,sz) xyz quat flav col) = VisEllipsoid (f sx, f sy, f sz) (fmap f xyz) (fmap f quat) flav col+  fmap f (VisLine xyzs col) = VisLine (map (fmap f) xyzs) col+  fmap f (VisArrow (x,y) xyz0 xyz1 col) = VisArrow (f x, f y) (fmap f xyz0) (fmap f xyz1) col+  fmap f (VisAxes (x,y) xyz quat) = VisAxes (f x, f y) (fmap f xyz) (fmap f quat)+  fmap f (VisPlane xyz x col0 col1) = VisPlane (fmap f xyz) (f x) col0 col1+  fmap f (VisTriangle x0 x1 x2 col) = VisTriangle (fmap f x0) (fmap f x1) (fmap f x2) col+  fmap f (VisQuad x0 x1 x2 x3 col) = VisQuad (fmap f x0) (fmap f x1) (fmap f x2) (fmap f x3) col+  fmap f (Vis3dText t xyz bmf col) = Vis3dText t (fmap f xyz) bmf col+  fmap f (Vis2dText t (x,y) bmf col) = Vis2dText t (f x, f y) bmf col+  fmap _ (VisCustom f) = VisCustom f++setPerspectiveMode :: IO ()+setPerspectiveMode = do+  (_, Size w h) <- get viewport+  matrixMode $= Projection+  loadIdentity+  perspective 40 (fromIntegral w / fromIntegral h) 0.1 100+  matrixMode $= Modelview 0+++drawObjects :: [VisObject GLdouble] -> IO ()+drawObjects objects = do+  setPerspectiveMode+  mapM_ drawObject objects++drawObject :: VisObject GLdouble -> IO ()+-- triangle+drawObject (VisTriangle (Xyz x0 y0 z0) (Xyz x1 y1 z1) (Xyz x2 y2 z2) col) =+  preservingMatrix $ do+    setMaterialDiffuse col+    setColor col+    glBegin gl_TRIANGLES+    glVertex3d x0 y0 z0+    glVertex3d x1 y1 z1+    glVertex3d x2 y2 z2+    glEnd+   +-- quad+drawObject (VisQuad (Xyz x0 y0 z0) (Xyz x1 y1 z1) (Xyz x2 y2 z2) (Xyz x3 y3 z3) col) =+  preservingMatrix $ do+    setMaterialDiffuse col+    setColor col+    glBegin gl_QUADS+    glVertex3d x0 y0 z0+    glVertex3d x1 y1 z1+    glVertex3d x2 y2 z2+    glVertex3d x3 y3 z3+    glEnd++-- cylinder+drawObject (VisCylinder (height,radius) (Xyz x y z) (Quat q0 q1 q2 q3) col) =+  preservingMatrix $ do+    setMaterialDiffuse col+    setColor col+    +    translate (Vector3 x y z :: Vector3 GLdouble)+    rotate (2 * acos q0 *180/pi :: GLdouble) (Vector3 q1 q2 q3)+    -- translate (Vector3 0 0 (-height/2) :: Vector3 GLdouble)++    let nslices = 10 :: Int+        nstacks = 10 :: Int++        -- Pre-computed circle+        sinCosTable = map (\q -> (sin q, cos q)) angles+          where+            angle = 2*pi/(fromIntegral nslices)+            angles = reverse $ map ((angle*) . fromIntegral) [0..(nslices+1)]+            +    -- Cover the base and top+    glBegin gl_TRIANGLE_FAN+    glNormal3d 0 0 (-1)+    glVertex3d 0 0 0+    mapM_ (\(s,c) -> glVertex3d (c*radius) (s*radius) 0) sinCosTable+    glEnd++    glBegin gl_TRIANGLE_FAN+    glNormal3d 0 0 1+    glVertex3d 0 0 height+    mapM_ (\(s,c) -> glVertex3d (c*radius) (s*radius) height) (reverse sinCosTable)+    glEnd++    let -- Do the stacks+        -- Step in z and radius as stacks are drawn.+        zSteps = map (\k -> (fromIntegral k)*height/(fromIntegral nstacks)) [0..nstacks]+        drawSlice z0 z1 (s,c) = do+          glNormal3d  c          s         0+          glVertex3d (c*radius) (s*radius) z0+          glVertex3d (c*radius) (s*radius) z1++        drawSlices (z0,z1) = do+          glBegin gl_QUAD_STRIP+          mapM_ (drawSlice z0 z1) sinCosTable+          glEnd++    mapM_ drawSlices $ zip (init zSteps) (tail zSteps)++-- sphere+drawObject (VisSphere s xyz flav col) = drawObject $ VisEllipsoid (s,s,s) xyz (Quat 1 0 0 0) flav col++-- ellipsoid+drawObject (VisEllipsoid (sx,sy,sz) (Xyz x y z) (Quat q0 q1 q2 q3) flav col) =+  preservingMatrix $ do+    setMaterialDiffuse col+    setColor col+    translate (Vector3 x y z :: Vector3 GLdouble)+    rotate (2 * acos q0 *180/pi :: GLdouble) (Vector3 q1 q2 q3)+    normalize $= Enabled+    scale sx sy sz+    renderObject flav (Sphere' 1 20 20)+    normalize $= Disabled++-- box+drawObject (VisBox (dx,dy,dz) (Xyz x y z) (Quat q0 q1 q2 q3) flav col) =+  preservingMatrix $ do+    setMaterialDiffuse col+    setColor col+    translate (Vector3 x y z :: Vector3 GLdouble)+    rotate (2 * acos q0 *180/pi :: GLdouble) (Vector3 q1 q2 q3)+    normalize $= Enabled+    scale dx dy dz+    renderObject flav (Cube 1)+    normalize $= Disabled++-- line+drawObject (VisLine path col) =+  preservingMatrix $ do+    lighting $= Disabled+    setColor col+    renderPrimitive LineStrip $ mapM_ (\(Xyz x' y' z') -> vertex$Vertex3 x' y' z') path+    lighting $= Enabled++-- plane+drawObject (VisPlane (Xyz x y z) offset col1 col2) =+  preservingMatrix $ do+    let norm = 1/(sqrt $ x*x + y*y + z*z)+        x' = x*norm+        y' = y*norm+        z' = z*norm+        r  = 10+        n  = 5+        eps = 0.01+    translate (Vector3 (offset*x') (offset*y') (offset*z') :: Vector3 GLdouble)+    rotate ((acos z')*180/pi :: GLdouble) (Vector3 (-y') x' 0)++    glBegin gl_QUADS+    setColor col2++    let r' = realToFrac r+    glVertex3f   r'    r'  0+    glVertex3f (-r')   r'  0+    glVertex3f (-r')  (-r')  0+    glVertex3f   r'   (-r')  0+    glEnd++    glDisable gl_BLEND+    mapM_ drawObject $ concat [[ VisLine [Xyz (-r) y0 eps, Xyz r y0 eps] col1+                               , VisLine [Xyz x0 (-r) eps, Xyz x0 r eps] col1+                               ] | x0 <- [-r,-r+r/n..r], y0 <- [-r,-r+r/n..r]]+    mapM_ drawObject $ concat [[ VisLine [Xyz (-r) y0 (-eps), Xyz r y0 (-eps)] col1+                               , VisLine [Xyz x0 (-r) (-eps), Xyz x0 r (-eps)] col1+                               ] | x0 <- [-r,-r+r/n..r], y0 <- [-r,-r+r/n..r]]+    glEnable gl_BLEND+++-- arrow+drawObject (VisArrow (size, aspectRatio) (Xyz x0 y0 z0) (Xyz x y z) col) =+  preservingMatrix $ do+    let numSlices = 8+        numStacks = 15+        cylinderRadius = 0.5*size/aspectRatio+        cylinderHeight = size+        coneRadius = 2*cylinderRadius+        coneHeight = 2*coneRadius++        rotAngle = acos(z/(sqrt(x*x + y*y + z*z) + 1e-15))*180/pi :: GLdouble+        rotAxis = Vector3 (-y) x 0+    +    translate (Vector3 x0 y0 z0 :: Vector3 GLdouble)+    rotate rotAngle rotAxis+    +    -- cylinder+    drawObject $ VisCylinder (cylinderHeight, cylinderRadius) (Xyz 0 0 0) (Quat 1 0 0 0) col+    -- cone+    setMaterialDiffuse col+    setColor col+    translate (Vector3 0 0 cylinderHeight :: Vector3 GLdouble)+    renderObject Solid (Cone coneRadius coneHeight numSlices numStacks)++drawObject (VisAxes (size, aspectRatio) (Xyz x0 y0 z0) (Quat q0 q1 q2 q3)) = preservingMatrix $ do+  translate (Vector3 x0 y0 z0 :: Vector3 GLdouble)+  rotate (2 * acos q0 *180/pi :: GLdouble) (Vector3 q1 q2 q3)+  +  let xAxis = VisArrow (size, aspectRatio) (Xyz 0 0 0) (Xyz 1 0 0) (Gloss.makeColor 1 0 0 1)+      yAxis = VisArrow (size, aspectRatio) (Xyz 0 0 0) (Xyz 0 1 0) (Gloss.makeColor 0 1 0 1)+      zAxis = VisArrow (size, aspectRatio) (Xyz 0 0 0) (Xyz 0 0 1) (Gloss.makeColor 0 0 1 1)+  drawObjects [xAxis, yAxis, zAxis]++drawObject (VisCustom f) = preservingMatrix f++drawObject (Vis3dText string (Xyz x y z) font col) = preservingMatrix $ do+  lighting $= Disabled+  setColor col+  glRasterPos3d x y z+  renderString font string+  lighting $= Enabled++drawObject (Vis2dText string (x,y) font col) = preservingMatrix $ do+  lighting $= Disabled+  setColor col++  matrixMode $= Projection+  loadIdentity++  (_, Size w h) <- get viewport+  ortho2D 0 (fromIntegral w) 0 (fromIntegral h)+  matrixMode $= Modelview 0+  loadIdentity++  glRasterPos2d x y+  renderString font string++  setPerspectiveMode+  lighting $= Enabled
not-gloss.cabal view
@@ -1,7 +1,15 @@ name:                not-gloss-version:             0.1.0+version:             0.2.0+stability:           Experimental synopsis:            Painless 3D graphics, no affiliation with gloss--- description:         +description:{+This package intends to make it relatively easy to do simple 3d graphics using high-level primitives.+It is inspired by gloss and attempts to emulate it.+This is an early release and the api will certainly change.+Note that transparency can be controlled by the alpha value: "makeColor r g b alpha" but that you must draw objects from back to front for transparency to properly work (just put clear things last).+Also, transparent ellipsoids and cylinders have ugly artifacts, sorry.+Look at the example `Example.hs` to get started.+} license:             BSD3 license-file:        LICENSE author:              Greg Horn@@ -13,14 +21,18 @@  library   exposed-modules:     Vis+                       Vis.Camera+                       Vis.Interface+                       Vis.VisObject -  other-modules:       Vis.Camera+  other-modules:           build-depends:       base == 4.5.*,                        GLUT == 2.3.*,                        time == 1.4.*,                        OpenGLRaw == 1.2.*,-                       spatial-math >= 0.1.2 && < 0.2+                       spatial-math >= 0.1.2 && < 0.2,+                       gloss >= 1.7.4 && < 1.7.5    ghc-options: @@ -31,6 +43,7 @@                        spatial-math >= 0.1.2 && < 0.2,                        OpenGLRaw == 1.2.*,                        time == 1.4.*,+                       gloss >= 1.7.4 && < 1.7.5,                        not-gloss   ghc-options:         -threaded