summaryrefslogtreecommitdiff
path: root/MeshSketch.hs
diff options
context:
space:
mode:
authorJoe Crayne <joe@jerkface.net>2019-05-18 03:04:20 -0400
committerJoe Crayne <joe@jerkface.net>2019-05-18 03:04:20 -0400
commita590439eef76c5fe1e8ec7fce28a3b194bfd6e8e (patch)
treee4112135a37e3fe0fcce3baa5468f304309b6d89 /MeshSketch.hs
parent1f1e8adb543a3338e85313b005b3213471600541 (diff)
Allow alternate plane positions.
Diffstat (limited to 'MeshSketch.hs')
-rw-r--r--MeshSketch.hs82
1 files changed, 62 insertions, 20 deletions
diff --git a/MeshSketch.hs b/MeshSketch.hs
index 95c79af..14039e9 100644
--- a/MeshSketch.hs
+++ b/MeshSketch.hs
@@ -17,7 +17,7 @@ import Data.Text (Text)
17import Data.Map.Strict (Map) 17import Data.Map.Strict (Map)
18import qualified Data.Map.Strict as Map 18import qualified Data.Map.Strict as Map
19import qualified Data.Vector as V 19import qualified Data.Vector as V
20import qualified Data.Vector.Generic as G (init) 20import qualified Data.Vector.Generic as G (init,(//))
21import Foreign.Marshal.Array 21import Foreign.Marshal.Array
22import Foreign.Storable 22import Foreign.Storable
23import GI.Gdk 23import GI.Gdk
@@ -84,6 +84,7 @@ data State = State
84 , stDragFrom :: IORef (Maybe (Vector Float,Camera)) 84 , stDragFrom :: IORef (Maybe (Vector Float,Camera))
85 , stRingBuffer :: Ring 85 , stRingBuffer :: Ring
86 , stPenDown :: IORef Bool 86 , stPenDown :: IORef Bool
87 , stPlane :: IORef (Maybe (Vector Float))
87 } 88 }
88 89
89data Camera = Camera 90data Camera = Camera
@@ -206,6 +207,7 @@ uploadState obj glarea storage = do
206 207
207 drag <- newIORef Nothing 208 drag <- newIORef Nothing
208 pendown <- newIORef False 209 pendown <- newIORef False
210 plane <- newIORef $ Just (xzPlaneVector G.// [(3,-1)])
209 211
210 let st = State 212 let st = State
211 { stAnimator = tm 213 { stAnimator = tm
@@ -217,6 +219,7 @@ uploadState obj glarea storage = do
217 , stDragFrom = drag 219 , stDragFrom = drag
218 , stRingBuffer = ring 220 , stRingBuffer = ring
219 , stPenDown = pendown 221 , stPenDown = pendown
222 , stPlane = plane
220 } 223 }
221 -- _ <- addAnimation tm (whirlingCamera st) 224 -- _ <- addAnimation tm (whirlingCamera st)
222 225
@@ -231,6 +234,19 @@ destroyState glarea st = do
231deg30 :: Float 234deg30 :: Float
232deg30 = pi/6 235deg30 = pi/6
233 236
237ĵ :: Vector Float
238ĵ = fromList [0,1,0]
239
240computePlaneModel :: Vector Float -> Matrix Float
241computePlaneModel plane = if n̂ == ĵ then translate4 p
242 else translate4 p <> rotate4 cosθ axis
243 where
244 n̂ = G.init plane
245 c = plane!3
246 p = scale c n̂
247 cosθ = dot n̂ ĵ
248 axis = ĵ `cross` n̂
249
234whirlingCamera :: State -> Animation 250whirlingCamera :: State -> Animation
235whirlingCamera st = Animation $ \_ t -> do 251whirlingCamera st = Animation $ \_ t -> do
236 let tf = realToFrac t :: Float 252 let tf = realToFrac t :: Float
@@ -246,9 +262,12 @@ whirlingCamera st = Animation $ \_ t -> do
246setUniforms :: glctx -> GLStorage -> State -> IO () 262setUniforms :: glctx -> GLStorage -> State -> IO ()
247setUniforms gl storage st = do 263setUniforms gl storage st = do
248 (mvp,pos) <- atomicModifyIORef' (stCamera st) viewProjection 264 (mvp,pos) <- atomicModifyIORef' (stCamera st) viewProjection
265 mplane <- readIORef (stPlane st)
266 let planeModel = maybe (ident 4) computePlaneModel mplane
249 LC.updateUniforms storage $ do 267 LC.updateUniforms storage $ do
250 "CameraPosition" @= return (pos :: Vector Float) 268 "CameraPosition" @= return (pos :: Vector Float)
251 "ViewProjection" @= return (mvp :: Matrix Float) 269 "ViewProjection" @= return (mvp :: Matrix Float)
270 "PlaneModel" @= return planeModel
252 updateRingUniforms storage (stRingBuffer st) 271 updateRingUniforms storage (stRingBuffer st)
253 272
254data MeshSketch = MeshSketch 273data MeshSketch = MeshSketch
@@ -284,6 +303,7 @@ new = do
284 "CubeMap" @: FTextureCube 303 "CubeMap" @: FTextureCube
285 "CameraPosition" @: V3F 304 "CameraPosition" @: V3F
286 "ViewProjection" @: M44F 305 "ViewProjection" @: M44F
306 "PlaneModel" @: M44F
287 "PointsMax" @: Int 307 "PointsMax" @: Int
288 "PointsStart" @: Int 308 "PointsStart" @: Int
289 "diffuseTexture" @: FTexture2D 309 "diffuseTexture" @: FTexture2D
@@ -413,6 +433,36 @@ rotate cosθ u = (3><3)
413 uy² = uy . uy 433 uy² = uy . uy
414 uz² = uz . uz 434 uz² = uz . uz
415 435
436rotate4 :: ( Floating a
437 , Math.Container Vector a
438 , Indexable (Vector a) a
439 , Normed (Vector a)
440 ) => a -> Vector a -> Matrix a
441rotate4 cosθ u = (4><4)
442 [ cosθ + ux² mcosθ , (uy.uy)mcosθ - uz sinθ , (ux.uz)mcosθ + uy sinθ , 0
443 , (uy.ux)mcosθ + uz sinθ , cosθ + uy² mcosθ , (uy.uz)mcosθ - ux sinθ , 0
444 , (uz.ux)mcosθ - uy sinθ , (uz.uy)mcosθ + ux sinθ , cosθ + uz² mcosθ , 0
445 , 0 , 0 , 0 , 1
446 ]
447 where
448 sinθ = sqrt (1 - cosθ * cosθ)
449 mcosθ = 1 - cosθ
450 û = scale (1/realToFrac (norm_2 u)) u
451 ux a = (û!0) * a
452 uy a = (û!1) * a
453 uz a = (û!2) * a
454 ux² = ux . ux
455 uy² = uy . uy
456 uz² = uz . uz
457
458translate4 :: (Storable a, Num a, Indexable c a) => c -> Matrix a
459translate4 p = (4><4)
460 [ 1 , 0 , 0 , p!0
461 , 0 , 1 , 0 , p!1
462 , 0 , 0 , 1 , p!2
463 , 0 , 0 , 0 , 1
464 ]
465
416updateCameraRotation :: IsWidget a => a -> State -> Double -> Double -> IO () 466updateCameraRotation :: IsWidget a => a -> State -> Double -> Double -> IO ()
417updateCameraRotation w st h k = do 467updateCameraRotation w st h k = do
418 m <- readIORef (stDragFrom st) 468 m <- readIORef (stDragFrom st)
@@ -501,7 +551,8 @@ worldCoordinates st h k mplane = do
501 551
502pushRing :: IsWidget w => w -> State -> Double -> Double -> IO (Vector Float) 552pushRing :: IsWidget w => w -> State -> Double -> Double -> IO (Vector Float)
503pushRing w st h k = do 553pushRing w st h k = do
504 d <- worldCoordinates st h k (Just xzPlaneVector) 554 plane <- readIORef (stPlane st)
555 d <- worldCoordinates st h k plane
505 Just win <- getWidgetWindow w 556 Just win <- getWidgetWindow w
506 pushBack (stRingBuffer st) (d!0) (d!1) (d!2) 557 pushBack (stRingBuffer st) (d!0) (d!1) (d!2)
507 windowInvalidateRect win Nothing False 558 windowInvalidateRect win Nothing False
@@ -521,38 +572,32 @@ onEvent w realized ev = do
521 case etype of 572 case etype of
522 573
523 EventTypeMotionNotify -> do 574 EventTypeMotionNotify -> do
575 mev <- get ev #motion
576 h <- get mev #x
577 k <- get mev #y
524 case inputSource of 578 case inputSource of
525 Just InputSourcePen -> do 579 Just InputSourcePen -> do
526 isDown <- readIORef (stPenDown st) 580 isDown <- readIORef (stPenDown st)
527 when isDown $ do 581 when isDown $ do
528 mev <- get ev #motion
529 h <- get mev #x
530 k <- get mev #y
531 d <- pushRing w st h k 582 d <- pushRing w st h k
532 put (etype,(h,k),d) 583 put (etype,(h,k),d)
533 _ -> do 584 _ -> do
534 mev <- get ev #motion
535 h <- get mev #x
536 k <- get mev #y
537 put (h,k) 585 put (h,k)
538 updateCameraRotation w st h k 586 updateCameraRotation w st h k
539 return () 587 return ()
540 588
541 EventTypeButtonPress -> do 589 EventTypeButtonPress -> do
590 bev <- get ev #button
591 h <- get bev #x
592 k <- get bev #y
542 case inputSource of 593 case inputSource of
543 Just InputSourcePen -> do 594 Just InputSourcePen -> do
544 writeIORef (stPenDown st) True 595 writeIORef (stPenDown st) True
545 bev <- get ev #button
546 h <- get bev #x
547 k <- get bev #y
548 d <- pushRing w st h k 596 d <- pushRing w st h k
549 Just win <- getWidgetWindow w 597 Just win <- getWidgetWindow w
550 windowInvalidateRect win Nothing False 598 windowInvalidateRect win Nothing False
551 put (etype,(h,k),d) 599 put (etype,(h,k),d)
552 _ -> do 600 _ -> do
553 bev <- get ev #button
554 h <- get bev #x
555 k <- get bev #y
556 _ {- d -} <- worldCoordinates st h k Nothing 601 _ {- d -} <- worldCoordinates st h k Nothing
557 cam <- readIORef (stCamera st) 602 cam <- readIORef (stCamera st)
558 let d = computeDirection cam h k 603 let d = computeDirection cam h k
@@ -561,19 +606,16 @@ onEvent w realized ev = do
561 return () 606 return ()
562 607
563 EventTypeButtonRelease -> do 608 EventTypeButtonRelease -> do
609 bev <- get ev #button
610 h <- get bev #x
611 k <- get bev #y
564 case inputSource of 612 case inputSource of
565 Just InputSourcePen -> do 613 Just InputSourcePen -> do
566 writeIORef (stPenDown st) False 614 writeIORef (stPenDown st) False
567 bev <- get ev #button
568 h <- get bev #x
569 k <- get bev #y
570 d <- pushRing w st h k 615 d <- pushRing w st h k
571 Just win <- getWidgetWindow w 616 Just win <- getWidgetWindow w
572 windowInvalidateRect win Nothing False 617 windowInvalidateRect win Nothing False
573 _ -> do 618 _ -> do
574 bev <- get ev #button
575 h <- get bev #x
576 k <- get bev #y
577 updateCameraRotation w st h k 619 updateCameraRotation w st h k
578 sanitizeCamera st 620 sanitizeCamera st
579 writeIORef (stDragFrom st) Nothing 621 writeIORef (stDragFrom st) Nothing