Advertisement
jckuri

KeyboardAndMouse3DAnimation.hs

Jun 17th, 2013
322
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. -- KeyboardAndMouse3DAnimation.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 Polygon $ 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. cubeFrame w = renderPrimitive Lines $ vertify3 $
  24.  [( w,-w, w), ( w, w, w),  ( w, w, w), (-w, w, w),
  25.   (-w, w, w), (-w,-w, w),  (-w,-w, w), ( w,-w, w),
  26.   ( w,-w, w), ( w,-w,-w),  ( w, w, w), ( w, w,-w),
  27.   (-w, w, w), (-w, w,-w),  (-w,-w, w), (-w,-w,-w),
  28.   ( w,-w,-w), ( w, w,-w),  ( w, w,-w), (-w, w,-w),
  29.   (-w, w,-w), (-w,-w,-w),  (-w,-w,-w), ( w,-w,-w) ]
  30.        
  31. points :: GLfloat -> [(GLfloat,GLfloat,GLfloat)]
  32. points n = map (\k -> (sin(2*pi*k/n),cos(2*pi*k/n),0.0)) [1..n]
  33.  
  34. cube3d :: GLfloat -> Color3 GLfloat -> Color3 GLfloat -> IO ()
  35. cube3d size backgroundColor lineColor =
  36.  color backgroundColor >>
  37.  cube size >>
  38.  color lineColor >>
  39.  cubeFrame size
  40.  
  41. display angle location =
  42.  clear [ColorBuffer,DepthBuffer] >>
  43.  loadIdentity >>
  44.  color (Color3 (1.0::GLfloat) 1.0 1.0) >>
  45.  cube (0.3::GLfloat) >>
  46.  get location >>= \(x,y) ->
  47.  translate (Vector3 x y 0) >>
  48.  get angle >>= \a ->
  49.  rotate a (Vector3 0 0.1 (1::GLfloat)) >>
  50.  preservingMatrix drawPoints >>
  51.  cube3d (0.2::GLfloat) (Color3 (1.0::GLfloat) 0.0 0.0) (Color3 (0.0::GLfloat) 0.0 0.0) >>
  52.  swapBuffers
  53.  where
  54.   drawPoint (x,y,z) =
  55.    translate (Vector3 x y z) >>
  56.    cube3d (0.2::GLfloat) (Color3 ((x+1.0)/2.0) ((y+1.0)/2.0) ((z+1.0)/2.0)) (Color3 (0.0::GLfloat) 0.0 0.0)
  57.   drawPoints =
  58.    mapM_ (\p@(x,y,z) -> preservingMatrix $ drawPoint p) (points 24)
  59.  
  60. getIncrement :: Bool -> Bool -> GLfloat -> GLfloat
  61. getIncrement negativeKey positiveKey increment =
  62.  (if negativeKey then (-increment) else 0.0) + (if positiveKey then increment else 0.0)
  63.  
  64. limit x x0 x1 =
  65.  if x < x0 then x0 else
  66.   if x > x1 then x1 else x
  67.  
  68. limitPoint point =
  69.  get point >>= \(x,y) ->
  70.  point $= (limit x (-1.0) 1.0, limit y (-1.0) 1.0)
  71.  
  72. idle upKey downKey leftKey rightKey angle delta location =
  73.  get location >>= \(x,y) ->
  74.  get leftKey >>= \left ->
  75.  get rightKey >>= \right ->
  76.  get upKey >>= \up ->
  77.  get downKey >>= \down ->
  78.  location $= (x+(getIncrement left right 0.01),y+(getIncrement down up 0.01)) >>
  79.  limitPoint location >>
  80.  get angle >>= \a ->
  81.  get delta >>= \d ->
  82.  angle $=! (a+d) >>
  83.  postRedisplay Nothing
  84.  
  85. reshape s@(Size w h) =
  86.  viewport $= (Position 0 0, s)
  87.  
  88. fromGLintToGLfloat i = (fromIntegral i)::GLfloat
  89.  
  90. getCanvasSize =
  91.  get viewport >>= \(Position x y,Size width height) ->
  92.  return (fromGLintToGLfloat width,fromGLintToGLfloat height)
  93.  
  94. fromMousePointToCanvasPoint mp@(mx,my) =
  95.  getCanvasSize >>= \(width,height) ->
  96.  return (2.0*(fromGLintToGLfloat mx)/width-1.0,(-2.0)*(fromGLintToGLfloat my)/height+1.0)
  97.  
  98. keyboardMouse :: IORef (GLfloat, GLfloat) -> IORef Bool -> IORef Bool ->
  99.  IORef Bool -> IORef Bool -> IORef GLfloat -> Key -> KeyState -> Modifiers ->
  100.  Position-> IO ()
  101. keyboardMouse point upKey downKey leftKey rightKey delta key keyState modifiers position@(Position x y) =
  102.  case key of
  103.   MouseButton LeftButton ->
  104.    fromMousePointToCanvasPoint (x,y) >>= \(nx,ny) ->
  105.    point $= (nx,ny)
  106.   SpecialKey KeyLeft ->
  107.    leftKey $= keyState == Down
  108.   SpecialKey KeyRight ->
  109.    rightKey $= keyState == Down
  110.   SpecialKey KeyUp ->
  111.    upKey $= keyState == Down
  112.   SpecialKey KeyDown ->
  113.    downKey $= keyState == Down
  114.   Char ' ' ->
  115.    get delta >>= \d ->
  116.    if keyState == Down then delta $= -d else return ()
  117.   _ -> return ()
  118.  
  119. mouseMotion point position@(Position x y) =
  120.  fromMousePointToCanvasPoint (x,y) >>= \(nx,ny) ->
  121.   point $= (nx,ny)
  122.  
  123. main =
  124.  getArgsAndInitialize >>= \(programName,_) ->
  125.  initialDisplayMode $= [WithDepthBuffer,DoubleBuffered] >>
  126.  createWindow "Robotic Arm" >>
  127.  reshapeCallback $= Just reshape >>
  128.  newIORef (0.0::GLfloat) >>= \angle ->
  129.  newIORef (0.1::GLfloat) >>= \delta ->
  130.  newIORef (0::GLfloat,0::GLfloat) >>= \point ->
  131.  newIORef (False) >>= \upKey ->
  132.  newIORef (False) >>= \downKey ->
  133.  newIORef (False) >>= \leftKey ->
  134.  newIORef (False) >>= \rightKey ->
  135.  keyboardMouseCallback $= Just (keyboardMouse point upKey downKey leftKey rightKey delta) >>
  136.  motionCallback $= Just (mouseMotion point) >>
  137.  idleCallback $= Just (idle upKey downKey leftKey rightKey angle delta point) >>
  138.  displayCallback $= (display angle point) >>
  139.  mainLoop
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement