Advertisement
jckuri

KeyboardAndMouseAnimation.hs

Jun 6th, 2013
177
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. -- KeyboardAndMouseAnimation.hs
  2. -- Inspired by:
  3. -- http://cvs.haskell.org/Hugs/pages/libraries/GLUT/Graphics-UI-GLUT-Callbacks-Window.html
  4. -- http://www.haskell.org/haskellwiki/OpenGLTutorial2
  5.  
  6. module Main(main) where
  7.  
  8. import Graphics.Rendering.OpenGL
  9. import Graphics.UI.GLUT
  10. import Data.IORef
  11.  
  12. vertify3 :: [(GLfloat,GLfloat,GLfloat)] -> IO ()
  13. vertify3 verts = sequence_ $ map (\(a,b,c) -> vertex $ Vertex3 a b c) verts
  14.  
  15. cube w = renderPrimitive Quads $ vertify3
  16.  [( w, w, w), ( w, w,-w), ( w,-w,-w), ( w,-w, w),
  17.   ( w, w, w), ( w, w,-w), (-w, w,-w), (-w, w, w),
  18.   ( w, w, w), ( w,-w, w), (-w,-w, w), (-w, w, w),
  19.   (-w, w, w), (-w, w,-w), (-w,-w,-w), (-w,-w, w),
  20.   ( w,-w, w), ( w,-w,-w), (-w,-w,-w), (-w,-w, w),
  21.   ( w, w,-w), ( w,-w,-w), (-w,-w,-w), (-w, w,-w)]
  22.        
  23. points :: GLfloat -> [(GLfloat,GLfloat,GLfloat)]
  24. points n = map (\k -> (sin(2*pi*k/n),cos(2*pi*k/n),0.0)) [1..n]
  25.  
  26. display angle location =
  27.  clear [ColorBuffer] >>
  28.  loadIdentity >>
  29.  get location >>= \(x,y) ->
  30.  translate (Vector3 x y 0) >>
  31.  preservingMatrix aux1 >>
  32.  swapBuffers
  33.  where
  34.   aux0 (x,y,z) =
  35.    color (Color3 ((x+1.0)/2.0) ((y+1.0)/2.0) ((z+1.0)/2.0)) >>
  36.    translate (Vector3 x y z) >>
  37.    cube (0.1::GLfloat)  
  38.   aux1 =
  39.    get angle >>= \a ->
  40.    rotate a (Vector3 0 0 (1::GLfloat)) >>
  41.    scale 0.7 0.7 (0.7::GLfloat) >>
  42.    mapM_ (\p@(x,y,z) -> preservingMatrix $ aux0 p) (points 24)
  43.  
  44. getIncrement :: Bool -> Bool -> GLfloat -> GLfloat
  45. getIncrement negativeKey positiveKey increment =
  46.  (if negativeKey then (-increment) else 0.0) + (if positiveKey then increment else 0.0)
  47.  
  48. limit x x0 x1 =
  49.  if x < x0 then x0 else
  50.   if x > x1 then x1 else x
  51.  
  52. limitPoint point =
  53.  get point >>= \(x,y) ->
  54.  point $= (limit x (-1.0) 1.0, limit y (-1.0) 1.0)
  55.  
  56. idle upKey downKey leftKey rightKey angle delta location =
  57.  get location >>= \(x,y) ->
  58.  get leftKey >>= \left ->
  59.  get rightKey >>= \right ->
  60.  get upKey >>= \up ->
  61.  get downKey >>= \down ->
  62.  location $= (x+(getIncrement left right 0.001),y+(getIncrement down up 0.001)) >>
  63.  limitPoint location >>
  64.  get angle >>= \a ->
  65.  get delta >>= \d ->
  66.  angle $=! (a+d) >>
  67.  postRedisplay Nothing
  68.  
  69. reshape s@(Size w h) =
  70.  viewport $= (Position 0 0, s)
  71.  
  72. fromGLintToGLfloat i = (fromIntegral i)::GLfloat
  73.  
  74. getCanvasSize =
  75.  get viewport >>= \(Position x y,Size width height) ->
  76.  return (fromGLintToGLfloat width,fromGLintToGLfloat height)
  77.  
  78. fromMousePointToCanvasPoint mp@(mx,my) =
  79.  getCanvasSize >>= \(width,height) ->
  80.  return (2.0*(fromGLintToGLfloat mx)/width-1.0,(-2.0)*(fromGLintToGLfloat my)/height+1.0)
  81.  
  82. keyboardMouse :: IORef (GLfloat, GLfloat) -> IORef Bool -> IORef Bool -> IORef Bool -> IORef Bool -> Key -> KeyState -> Modifiers -> Position-> IO ()
  83. keyboardMouse point upKey downKey leftKey rightKey key keyState modifiers position@(Position x y) =
  84.  case key of
  85.   MouseButton LeftButton ->
  86.    fromMousePointToCanvasPoint (x,y) >>= \(nx,ny) ->
  87.    point $= (nx,ny)
  88.   SpecialKey KeyLeft ->
  89.    leftKey $= keyState == Down
  90.   SpecialKey KeyRight ->
  91.    rightKey $= keyState == Down
  92.   SpecialKey KeyUp ->
  93.    upKey $= keyState == Down
  94.   SpecialKey KeyDown ->
  95.    downKey $= keyState == Down
  96.   _ -> return ()
  97.  
  98. mouseMotion point position@(Position x y) =
  99.  fromMousePointToCanvasPoint (x,y) >>= \(nx,ny) ->
  100.   point $= (nx,ny)
  101.  
  102. main =
  103.  getArgsAndInitialize >>= \(programName,_) ->
  104.  initialDisplayMode $= [DoubleBuffered] >>
  105.  createWindow "Robotic Arm" >>
  106.  reshapeCallback $= Just reshape >>
  107.  newIORef (0.0::GLfloat) >>= \angle ->
  108.  newIORef (0.1::GLfloat) >>= \delta ->
  109.  newIORef (0::GLfloat,0::GLfloat) >>= \point ->
  110.  newIORef (False) >>= \upKey ->
  111.  newIORef (False) >>= \downKey ->
  112.  newIORef (False) >>= \leftKey ->
  113.  newIORef (False) >>= \rightKey ->
  114.  keyboardMouseCallback $= Just (keyboardMouse point upKey downKey leftKey rightKey) >>
  115.  motionCallback $= Just (mouseMotion point) >>
  116.  idleCallback $= Just (idle upKey downKey leftKey rightKey angle delta point) >>
  117.  displayCallback $= (display angle point) >>
  118.  mainLoop
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement