summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoe Crayne <joe@jerkface.net>2019-04-29 21:31:50 -0400
committerJoe Crayne <joe@jerkface.net>2019-04-29 21:31:50 -0400
commit051f60000748548b04084aca77bc30b11d7bf2db (patch)
treeda1f75558526ed60a17d4d537b024f97e95a6528
parent4c98ccde118f4dd0503226154876001bfc2770f7 (diff)
Camera object.
-rw-r--r--MeshSketch.hs61
1 files changed, 58 insertions, 3 deletions
diff --git a/MeshSketch.hs b/MeshSketch.hs
index 9c6c457..675c388 100644
--- a/MeshSketch.hs
+++ b/MeshSketch.hs
@@ -43,8 +43,46 @@ import Matrix
43data State = State 43data State = State
44 { stTimeKeeper :: TimeKeeper 44 { stTimeKeeper :: TimeKeeper
45 , stTickCallback :: TickCallbackHandle 45 , stTickCallback :: TickCallbackHandle
46 , stCamera :: IORef Camera
46 } 47 }
47 48
49data Camera = Camera
50 { camHeightAngle :: Float
51 , camTarget :: Vector Float
52 , camDirection :: Vector Float
53 , camDistance :: Float
54 , camWidth :: Float
55 , camHeight :: Float
56 , camUp :: Vector Float
57 , camWorldToScreen :: Maybe (Matrix Float)
58 , camScreenToWorld :: Maybe (Matrix Float)
59 }
60
61initCamera :: Camera
62initCamera = Camera
63 { camHeightAngle = pi/6
64 , camTarget = fromList [0,0,0]
65 , camDirection = scale (1/d) $ fromList [-2,-2,-10]
66 , camDistance = d
67 , camWidth = 700
68 , camHeight = 700
69 , camUp = fromList [0,1,0]
70 , camWorldToScreen = Nothing
71 , camScreenToWorld = Nothing
72 }
73 where d = realToFrac $ norm_2 $ fromList [2::Float,2,10]
74
75viewProjection :: Camera -> (Camera,(Matrix Float,Vector Float))
76viewProjection c
77 | Just m <- camWorldToScreen c = (c,(m,pos))
78 | otherwise = (c { camWorldToScreen = Just m' }, (m',pos))
79 where
80 m' = proj <> cam
81 cam = lookat pos (camTarget c) (camUp c)
82 pos = camTarget c - scale (camDistance c) (camDirection c)
83 proj = perspective 0.1 100 (camHeightAngle c) (camWidth c / camHeight c)
84
85
48addOBJToObjectArray :: GLStorage -> String -> [(GPUMesh, Maybe Text)] -> Map Text (ObjMaterial,TextureData) -> IO [LC.Object] 86addOBJToObjectArray :: GLStorage -> String -> [(GPUMesh, Maybe Text)] -> Map Text (ObjMaterial,TextureData) -> IO [LC.Object]
49addOBJToObjectArray storage slotName objMesh mtlLib = forM objMesh $ \(mesh,mat) -> do 87addOBJToObjectArray storage slotName objMesh mtlLib = forM objMesh $ \(mesh,mat) -> do
50 obj <- LC.addMeshToObjectArray storage slotName ["diffuseTexture","diffuseColor"] mesh 88 obj <- LC.addMeshToObjectArray storage slotName ["diffuseTexture","diffuseColor"] mesh
@@ -70,11 +108,13 @@ uploadState obj glarea storage = do
70 108
71 -- setup FrameClock 109 -- setup FrameClock
72 tm <- newTimeKeeper 110 tm <- newTimeKeeper
111 cam <- newIORef initCamera
73 tickcb <- widgetAddTickCallback glarea (tick tm) 112 tickcb <- widgetAddTickCallback glarea (tick tm)
74 113
75 return State 114 return State
76 { stTimeKeeper = tm 115 { stTimeKeeper = tm
77 , stTickCallback = tickcb 116 , stTickCallback = tickcb
117 , stCamera = cam
78 } 118 }
79 119
80destroyState :: GLArea -> State -> IO () 120destroyState :: GLArea -> State -> IO ()
@@ -89,12 +129,23 @@ setUniforms gl storage st = do
89 t <- (/ 10.0) <$> getSeconds (stTimeKeeper st) 129 t <- (/ 10.0) <$> getSeconds (stTimeKeeper st)
90 let tf = realToFrac t :: Float 130 let tf = realToFrac t :: Float
91 rot = rotMatrixZ (-tf) <> rotMatrixX (-tf) 131 rot = rotMatrixZ (-tf) <> rotMatrixX (-tf)
92 pos = rot #> fromList [2,2,10] 132 modifyIORef (stCamera st) $ \cam -> cam
133 { camUp = rot #> fromList [0,1,0]
134 , camDirection = (scale (1/camDistance cam) $ fromList [-2,-2,-10]) <# rot
135 , camWorldToScreen = Nothing
136 , camScreenToWorld = Nothing
137 }
138
139 (mvp,pos) <- atomicModifyIORef' (stCamera st) viewProjection
140
141 {-
142 let pos = rot #> fromList [2,2,10]
93 up = rot #> fromList [0,1,0] 143 up = rot #> fromList [0,1,0]
94 cam = lookat pos 0 up 144 view = lookat pos 0 up
95 aspect = 1 145 aspect = 1
96 proj = perspective 0.1 100 deg30 aspect 146 proj = perspective 0.1 100 deg30 aspect
97 mvp = proj <> cam 147 mvp = proj <> view
148 -}
98 149
99 LC.updateUniforms storage $ do 150 LC.updateUniforms storage $ do
100 "CameraPosition" @= return (pos :: Vector Float) 151 "CameraPosition" @= return (pos :: Vector Float)
@@ -187,4 +238,8 @@ onResize glarea realized w h = do
187 (wd,ht) <- do wd <- windowGetWidth win 238 (wd,ht) <- do wd <- windowGetWidth win
188 ht <- windowGetHeight win 239 ht <- windowGetHeight win
189 return (fromIntegral wd,fromIntegral ht) 240 return (fromIntegral wd,fromIntegral ht)
241 modifyIORef' (stCamera $ stState realized)
242 $ \c -> c { camWidth = fromIntegral wd
243 , camHeight = fromIntegral ht
244 }
190 LC.setScreenSize (stStorage realized) wd ht) 245 LC.setScreenSize (stStorage realized) wd ht)