diff options
Diffstat (limited to 'MeshSketch.hs')
-rw-r--r-- | MeshSketch.hs | 64 |
1 files changed, 47 insertions, 17 deletions
diff --git a/MeshSketch.hs b/MeshSketch.hs index 7ab0d7a..f31c7cf 100644 --- a/MeshSketch.hs +++ b/MeshSketch.hs | |||
@@ -66,11 +66,12 @@ import Matrix | |||
66 | import qualified GPURing as GPU | 66 | import qualified GPURing as GPU |
67 | import qualified VectorRing as Vector | 67 | import qualified VectorRing as Vector |
68 | import RingBuffer | 68 | import RingBuffer |
69 | import MaskableStream (AttributeKey,(@<-)) | 69 | import MaskableStream (AttributeKey,(@<-),updateCommands) |
70 | import SmallRing | 70 | import SmallRing |
71 | import Camera | 71 | import Camera |
72 | import FitCurves | 72 | import FitCurves |
73 | import Bezier | 73 | import Bezier |
74 | import Mask | ||
74 | 75 | ||
75 | prettyDebug :: GL.DebugMessage -> String | 76 | prettyDebug :: GL.DebugMessage -> String |
76 | prettyDebug (GL.DebugMessage src typ (GL.DebugMessageID mid) severity msg) = unwords ws | 77 | prettyDebug (GL.DebugMessage src typ (GL.DebugMessageID mid) severity msg) = unwords ws |
@@ -113,6 +114,8 @@ data State = State | |||
113 | , stDragPlane :: IORef (Maybe (Vector Float,Plane)) | 114 | , stDragPlane :: IORef (Maybe (Vector Float,Plane)) |
114 | , stRecentPts :: IORef (Giver (Vector Double)) | 115 | , stRecentPts :: IORef (Giver (Vector Double)) |
115 | , stAngle :: IORef Int | 116 | , stAngle :: IORef Int |
117 | , stObjects :: IORef [MaskableObject] | ||
118 | , stMasks :: IORef [Mask] | ||
116 | } | 119 | } |
117 | 120 | ||
118 | initCamera :: Camera | 121 | initCamera :: Camera |
@@ -138,9 +141,14 @@ realToFracVector v = Math.fromList $ map realToFrac $ Math.toList v | |||
138 | 141 | ||
139 | data MaskableObject = MaskableObject | 142 | data MaskableObject = MaskableObject |
140 | { maskableObject :: LC.Object | 143 | { maskableObject :: LC.Object |
141 | , groupMasks :: Map Text [(Int32,Int32)] | 144 | , groupMasks :: Map Text Mask |
142 | } | 145 | } |
143 | 146 | ||
147 | objSpan :: LC.Object -> Mask | ||
148 | objSpan obj = case Map.elems (objAttributes obj) of | ||
149 | Stream { streamLength = x }:_ -> Mask [(0,fromIntegral x)] | ||
150 | _ -> Mask [(0,1)] | ||
151 | |||
144 | addOBJToObjectArray :: GLStorage -> String -> [(GPUMesh, Maybe Text)] -> Map Text (ObjMaterial,TextureData) | 152 | addOBJToObjectArray :: GLStorage -> String -> [(GPUMesh, Maybe Text)] -> Map Text (ObjMaterial,TextureData) |
145 | -> IO [MaskableObject] | 153 | -> IO [MaskableObject] |
146 | addOBJToObjectArray storage slotName objMesh mtlLib = forM objMesh $ \(mesh,mat) -> do | 154 | addOBJToObjectArray storage slotName objMesh mtlLib = forM objMesh $ \(mesh,mat) -> do |
@@ -151,10 +159,7 @@ addOBJToObjectArray storage slotName objMesh mtlLib = forM objMesh $ \(mesh,mat) | |||
151 | Just (ObjMaterial{..},t) -> LC.updateObjectUniforms obj $ do | 159 | Just (ObjMaterial{..},t) -> LC.updateObjectUniforms obj $ do |
152 | "diffuseTexture" @= return t -- set model's diffuse texture | 160 | "diffuseTexture" @= return t -- set model's diffuse texture |
153 | "diffuseColor" @= let (r,g,b) = mtl_Kd in return (V4 r g b mtl_Tr) | 161 | "diffuseColor" @= let (r,g,b) = mtl_Kd in return (V4 r g b mtl_Tr) |
154 | let len = case Map.elems (objAttributes obj) of | 162 | return $ MaskableObject obj $ maybe Map.empty (`Map.singleton` objSpan obj) mat |
155 | Stream { streamLength = x }:_ -> x | ||
156 | _ -> 1 | ||
157 | return $ MaskableObject obj $ maybe Map.empty (`Map.singleton` [(0,1)]) mat | ||
158 | 163 | ||
159 | mkFullscreenToggle :: IsWindow a => a -> IO (IO ()) | 164 | mkFullscreenToggle :: IsWindow a => a -> IO (IO ()) |
160 | mkFullscreenToggle w = do | 165 | mkFullscreenToggle w = do |
@@ -182,6 +187,8 @@ uploadState obj mm storage = do | |||
182 | let gs = Map.keys $ foldr (\a ms -> Map.union (groupMasks a) ms) Map.empty bufs | 187 | let gs = Map.keys $ foldr (\a ms -> Map.union (groupMasks a) ms) Map.empty bufs |
183 | forM_ gs $ \groupname -> do | 188 | forM_ gs $ \groupname -> do |
184 | addToGroupsPane (mmListStore mm) True groupname | 189 | addToGroupsPane (mmListStore mm) True groupname |
190 | objsRef <- newIORef bufs | ||
191 | masksRef <- newIORef $ map (objSpan . maskableObject) bufs | ||
185 | 192 | ||
186 | -- grid plane | 193 | -- grid plane |
187 | uploadMeshToGPU xzplane >>= addMeshToObjectArray storage "plane" [] | 194 | uploadMeshToGPU xzplane >>= addMeshToObjectArray storage "plane" [] |
@@ -239,6 +246,8 @@ uploadState obj mm storage = do | |||
239 | , stDragPlane = dragPlane | 246 | , stDragPlane = dragPlane |
240 | , stRecentPts = recentPts | 247 | , stRecentPts = recentPts |
241 | , stAngle = angle | 248 | , stAngle = angle |
249 | , stObjects = objsRef | ||
250 | , stMasks = masksRef | ||
242 | } | 251 | } |
243 | -- _ <- addAnimation tm (whirlingCamera st) | 252 | -- _ <- addAnimation tm (whirlingCamera st) |
244 | 253 | ||
@@ -336,17 +345,15 @@ new = do | |||
336 | either (\e _ -> hPutStrLn stderr e >> throwIO (userError e)) (&) m $ \(obj,pipeline) -> do | 345 | either (\e _ -> hPutStrLn stderr e >> throwIO (userError e)) (&) m $ \(obj,pipeline) -> do |
337 | mapM_ (putStrLn . ppShow) (targets $ dynamicPipeline pipeline) | 346 | mapM_ (putStrLn . ppShow) (targets $ dynamicPipeline pipeline) |
338 | ref <- newIORef Nothing | 347 | ref <- newIORef Nothing |
339 | (groups,liststore) <- newGroupsListWidget | 348 | g <- gLAreaNew |
349 | (groups,liststore) <- newGroupsListWidget (\store itr b -> onMaskedGroup g ref store itr b) | ||
340 | panes <- panedNew OrientationHorizontal | 350 | panes <- panedNew OrientationHorizontal |
341 | g <- do | 351 | let mm = MeshSketch g panes groups liststore ref |
342 | g <- gLAreaNew | 352 | gLAreaSetHasDepthBuffer g True |
343 | let mm = MeshSketch g panes groups liststore ref | 353 | st <- return g |
344 | gLAreaSetHasDepthBuffer g True | 354 | _ <- on g #realize $ withCurrentGL g (onRealize obj (dynamicPipeline pipeline) (dynamicSchema pipeline) mm) |
345 | st <- return g | 355 | _ <- on g #unrealize $ onUnrealize mm |
346 | _ <- on g #realize $ withCurrentGL g (onRealize obj (dynamicPipeline pipeline) (dynamicSchema pipeline) mm) | 356 | _ <- on g #createContext $ nullableContext (onCreateContext g) |
347 | _ <- on g #unrealize $ onUnrealize mm | ||
348 | _ <- on g #createContext $ nullableContext (onCreateContext g) | ||
349 | return g | ||
350 | panedPack1 panes g True True | 357 | panedPack1 panes g True True |
351 | return panes | 358 | return panes |
352 | 359 | ||
@@ -357,7 +364,7 @@ addToGroupsPane liststore isEnabled groupName = do | |||
357 | iter <- listStoreAppend liststore | 364 | iter <- listStoreAppend liststore |
358 | listStoreSet liststore iter [0,1] [gtrue,gvalue] | 365 | listStoreSet liststore iter [0,1] [gtrue,gvalue] |
359 | 366 | ||
360 | newGroupsListWidget = do | 367 | newGroupsListWidget changedListStore = do |
361 | liststore <- listStoreNew [gtypeBoolean,gtypeString] | 368 | liststore <- listStoreNew [gtypeBoolean,gtypeString] |
362 | treeView <- treeViewNewWithModel liststore | 369 | treeView <- treeViewNewWithModel liststore |
363 | treeViewSetHeadersVisible treeView False | 370 | treeViewSetHeadersVisible treeView False |
@@ -379,6 +386,7 @@ newGroupsListWidget = do | |||
379 | b <- fromGValue gval | 386 | b <- fromGValue gval |
380 | notb <- toGValue (not b) | 387 | notb <- toGValue (not b) |
381 | listStoreSetValue liststore itr 0 notb | 388 | listStoreSetValue liststore itr 0 notb |
389 | changedListStore liststore itr (not b) | ||
382 | return togc | 390 | return togc |
383 | groupc <- do | 391 | groupc <- do |
384 | groupr <- cellRendererTextNew | 392 | groupr <- cellRendererTextNew |
@@ -876,3 +884,25 @@ onCreateContext w = do | |||
876 | putStrLn "onCreateContext!" | 884 | putStrLn "onCreateContext!" |
877 | mwin <- widgetGetWindow w | 885 | mwin <- widgetGetWindow w |
878 | forM mwin $ \win -> windowCreateGlContext win | 886 | forM mwin $ \win -> windowCreateGlContext win |
887 | |||
888 | onMaskedGroup g ref store itr b = do | ||
889 | gval <- treeModelGetValue store itr 1 | ||
890 | mtxt <- fromGValue gval | ||
891 | let _ = mtxt :: Maybe Text | ||
892 | putStrLn $ "Mask changed " ++ show (mtxt,b) | ||
893 | mr <- readIORef ref | ||
894 | forM_ ((,) <$> mr <*> mtxt) $ \(r,txt) -> do | ||
895 | let st = stState r | ||
896 | os <- readIORef (stObjects st) -- stObjects :: IORef [MaskableObject] | ||
897 | ms <- readIORef (stMasks st) -- stMasks :: IORef [Mask] | ||
898 | ms' <- forM (zip os ms) $ \(o,m) -> do | ||
899 | let mmask = Map.lookup txt (groupMasks o) | ||
900 | op = maybe id (flip $ bool maskSubtract maskPlus b) mmask | ||
901 | m' = op m | ||
902 | unmask (Mask is) = is | ||
903 | updateCommands (stStorage r) (maskableObject o) (const $ unmask m') | ||
904 | return m' | ||
905 | writeIORef (stMasks st) ms' | ||
906 | mwin <- widgetGetWindow g | ||
907 | forM_ mwin $ \win -> windowInvalidateRect win Nothing False | ||
908 | return () | ||