summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoe Crayne <joe@jerkface.net>2019-05-18 16:14:09 -0400
committerJoe Crayne <joe@jerkface.net>2019-05-18 16:14:09 -0400
commit7b366a9d7e80ff7d9847eafb7a47fba06faac40e (patch)
treeabdcd558be20c4fa656367d538e8bf11d59b2cc4
parenta590439eef76c5fe1e8ec7fce28a3b194bfd6e8e (diff)
Control to move draw-plane up and down.
-rw-r--r--MeshSketch.hs81
1 files changed, 62 insertions, 19 deletions
diff --git a/MeshSketch.hs b/MeshSketch.hs
index 14039e9..5ada40e 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
21import Foreign.Marshal.Array 21import Foreign.Marshal.Array
22import Foreign.Storable 22import Foreign.Storable
23import GI.Gdk 23import GI.Gdk
@@ -72,6 +72,7 @@ setupGLDebugging = do
72 GL.debugMessageControl (GL.MessageGroup Nothing Nothing Nothing) GL.$= GL.Enabled 72 GL.debugMessageControl (GL.MessageGroup Nothing Nothing Nothing) GL.$= GL.Enabled
73 GL.debugMessageCallback GL.$= Just pdebug 73 GL.debugMessageCallback GL.$= Just pdebug
74 74
75type Plane = Vector Float
75 76
76-- State created by uploadState. 77-- State created by uploadState.
77data State = State 78data State = State
@@ -84,7 +85,8 @@ data State = State
84 , stDragFrom :: IORef (Maybe (Vector Float,Camera)) 85 , stDragFrom :: IORef (Maybe (Vector Float,Camera))
85 , stRingBuffer :: Ring 86 , stRingBuffer :: Ring
86 , stPenDown :: IORef Bool 87 , stPenDown :: IORef Bool
87 , stPlane :: IORef (Maybe (Vector Float)) 88 , stPlane :: IORef (Maybe Plane)
89 , stDragPlane :: IORef (Maybe (Vector Float,Plane))
88 } 90 }
89 91
90data Camera = Camera 92data Camera = Camera
@@ -206,6 +208,7 @@ uploadState obj glarea storage = do
206 LC.addMeshToObjectArray storage "SkyCube" [] mi 208 LC.addMeshToObjectArray storage "SkyCube" [] mi
207 209
208 drag <- newIORef Nothing 210 drag <- newIORef Nothing
211 dragPlane <- newIORef Nothing
209 pendown <- newIORef False 212 pendown <- newIORef False
210 plane <- newIORef $ Just (xzPlaneVector G.// [(3,-1)]) 213 plane <- newIORef $ Just (xzPlaneVector G.// [(3,-1)])
211 214
@@ -220,6 +223,7 @@ uploadState obj glarea storage = do
220 , stRingBuffer = ring 223 , stRingBuffer = ring
221 , stPenDown = pendown 224 , stPenDown = pendown
222 , stPlane = plane 225 , stPlane = plane
226 , stDragPlane = dragPlane
223 } 227 }
224 -- _ <- addAnimation tm (whirlingCamera st) 228 -- _ <- addAnimation tm (whirlingCamera st)
225 229
@@ -388,6 +392,9 @@ onResize glarea realized w h = do
388 } 392 }
389 LC.setScreenSize (stStorage realized) wd ht 393 LC.setScreenSize (stStorage realized) wd ht
390 394
395unit :: (Linear t c, Fractional t, Normed (c t)) => c t -> c t
396unit v = scale (1/realToFrac (norm_2 v)) v
397
391-- This computes a point in world coordinates on the view screen if 398-- This computes a point in world coordinates on the view screen if
392-- we assume the camera is located at the origin. 399-- we assume the camera is located at the origin.
393computeDirection :: Camera -> Double -> Double -> Vector Float 400computeDirection :: Camera -> Double -> Double -> Vector Float
@@ -399,9 +406,11 @@ computeDirection cam h k | Just pv <- camScreenToWorld cam =
399 ] :: Vector Float 406 ] :: Vector Float
400 d1 = pv #> d0 407 d1 = pv #> d0
401 d2 = scale (1 /(d1!3)) $ G.init d1 408 d2 = scale (1 /(d1!3)) $ G.init d1
409 {-
402 p = camPos cam 410 p = camPos cam
403 d3 = d2 - p 411 d3 = d2 - p
404 d4 = scale (1/realToFrac (norm_2 d3)) d3 412 d4 = unit d3
413 -}
405 in d2 414 in d2
406computeDirection cam h k = 415computeDirection cam h k =
407 let d̂ = camDirection cam -- forward 416 let d̂ = camDirection cam -- forward
@@ -425,7 +434,7 @@ rotate cosθ u = (3><3)
425 where 434 where
426 sinθ = sqrt (1 - cosθ * cosθ) 435 sinθ = sqrt (1 - cosθ * cosθ)
427 mcosθ = 1 - cosθ 436 mcosθ = 1 - cosθ
428 û = scale (1/realToFrac (norm_2 u)) u 437 û = unit u
429 ux a = (û!0) * a 438 ux a = (û!0) * a
430 uy a = (û!1) * a 439 uy a = (û!1) * a
431 uz a = (û!2) * a 440 uz a = (û!2) * a
@@ -447,7 +456,7 @@ rotate4 cosθ u = (4><4)
447 where 456 where
448 sinθ = sqrt (1 - cosθ * cosθ) 457 sinθ = sqrt (1 - cosθ * cosθ)
449 mcosθ = 1 - cosθ 458 mcosθ = 1 - cosθ
450 û = scale (1/realToFrac (norm_2 u)) u 459 û = unit u
451 ux a = (û!0) * a 460 ux a = (û!0) * a
452 uy a = (û!1) * a 461 uy a = (û!1) * a
453 uz a = (û!2) * a 462 uz a = (û!2) * a
@@ -507,16 +516,12 @@ sanitizeCamera st = do
507 modifyIORef (stCamera st) $ \cam -> 516 modifyIORef (stCamera st) $ \cam ->
508 let d = camDirection cam 517 let d = camDirection cam
509 u = camUp cam 518 u = camUp cam
510 dd = norm_2 d 519 d̂ = case unit d of
511 uu = norm_2 u 520 dd | any isNaN (toList dd) -> fromList [0,0,-1]
512 e = scale (realToFrac $ 1/dd) d 521 | otherwise -> dd
513 d̂ = if any isNaN (toList e) 522 û = case unit u of
514 then fromList [0,0,-1] 523 uu | any isNaN (toList uu) -> fromList [0,1,0]
515 else e 524 | otherwise -> uu
516 f = scale (realToFrac $ 1/uu) u
517 û = if any isNaN (toList f)
518 then fromList [0,1,0]
519 else f
520 in cam 525 in cam
521 { camDirection = d̂ 526 { camDirection = d̂
522 , camUp = û 527 , camUp = û
@@ -538,7 +543,7 @@ worldCoordinates st h k mplane = do
538 q2 = scale (1 /(q1!3)) $ G.init q1 543 q2 = scale (1 /(q1!3)) $ G.init q1
539 p = camPos cam 544 p = camPos cam
540 d = q2 - p 545 d = q2 - p
541 d̂ = scale (1/realToFrac (norm_2 d)) d 546 d̂ = unit d
542 return $ case mplane of 547 return $ case mplane of
543 -- Write on the plane. 548 -- Write on the plane.
544 Just plane -> let n̂ = G.init plane 549 Just plane -> let n̂ = G.init plane
@@ -575,7 +580,9 @@ onEvent w realized ev = do
575 mev <- get ev #motion 580 mev <- get ev #motion
576 h <- get mev #x 581 h <- get mev #x
577 k <- get mev #y 582 k <- get mev #y
578 case inputSource of 583 pd <- readIORef (stDragPlane st)
584 case pd of
585 Nothing -> case inputSource of
579 Just InputSourcePen -> do 586 Just InputSourcePen -> do
580 isDown <- readIORef (stPenDown st) 587 isDown <- readIORef (stPenDown st)
581 when isDown $ do 588 when isDown $ do
@@ -585,12 +592,26 @@ onEvent w realized ev = do
585 put (h,k) 592 put (h,k)
586 updateCameraRotation w st h k 593 updateCameraRotation w st h k
587 return () 594 return ()
595 Just (from,plane) -> do
596 -- doDragPlane
597 pos <- camPos <$> readIORef (stCamera st)
598 n <- subtract pos <$> worldCoordinates st h k Nothing
599 let n̂ = unit n
600 p <- worldCoordinates st h k (Just $ n̂ `G.snoc` (from `dot` n̂))
601 let δ = dot (p - from) (G.init plane)
602 writeIORef (stPlane st) $ Just $ plane G.// [(3,δ + plane!3)]
603 mwin <- widgetGetWindow w
604 forM_ mwin $ \win -> windowInvalidateRect win Nothing False
605 putStrLn ("drag-plane " ++ show (δ,p))
606 -- end doDragPlane
588 607
589 EventTypeButtonPress -> do 608 EventTypeButtonPress -> do
590 bev <- get ev #button 609 bev <- get ev #button
591 h <- get bev #x 610 h <- get bev #x
592 k <- get bev #y 611 k <- get bev #y
593 case inputSource of 612 cam <- readIORef (stCamera st)
613 if h < realToFrac (camWidth cam) * 0.9 then
614 case inputSource of
594 Just InputSourcePen -> do 615 Just InputSourcePen -> do
595 writeIORef (stPenDown st) True 616 writeIORef (stPenDown st) True
596 d <- pushRing w st h k 617 d <- pushRing w st h k
@@ -604,12 +625,20 @@ onEvent w realized ev = do
604 writeIORef (stDragFrom st) $ Just (d,cam) 625 writeIORef (stDragFrom st) $ Just (d,cam)
605 put (etype,(h,k),d) 626 put (etype,(h,k),d)
606 return () 627 return ()
628 else do
629 mplane <- readIORef (stPlane st)
630 forM_ mplane $ \plane -> do
631 p <- worldCoordinates st h k mplane
632 writeIORef (stDragPlane st) $ Just (p,plane)
633 putStrLn $ "Start plane drag: " ++ show p
607 634
608 EventTypeButtonRelease -> do 635 EventTypeButtonRelease -> do
609 bev <- get ev #button 636 bev <- get ev #button
610 h <- get bev #x 637 h <- get bev #x
611 k <- get bev #y 638 k <- get bev #y
612 case inputSource of 639 pd <- readIORef (stDragPlane st)
640 case pd of
641 Nothing -> case inputSource of
613 Just InputSourcePen -> do 642 Just InputSourcePen -> do
614 writeIORef (stPenDown st) False 643 writeIORef (stPenDown st) False
615 d <- pushRing w st h k 644 d <- pushRing w st h k
@@ -619,6 +648,20 @@ onEvent w realized ev = do
619 updateCameraRotation w st h k 648 updateCameraRotation w st h k
620 sanitizeCamera st 649 sanitizeCamera st
621 writeIORef (stDragFrom st) Nothing 650 writeIORef (stDragFrom st) Nothing
651 Just (from,plane) -> do
652 writeIORef (stDragPlane st) Nothing
653 -- doDragPlane
654 pos <- camPos <$> readIORef (stCamera st)
655 n <- subtract pos <$> worldCoordinates st h k Nothing
656 let n̂ = unit n
657 p <- worldCoordinates st h k (Just $ n̂ `G.snoc` (from `dot` n̂))
658 let δ = dot (p - from) (G.init plane)
659 writeIORef (stPlane st) $ Just $ plane G.// [(3,δ + plane!3)]
660 mwin <- widgetGetWindow w
661 forM_ mwin $ \win -> windowInvalidateRect win Nothing False
662 putStrLn ("drag-plane " ++ show (δ,p))
663 -- end doDragPlane
664
622 665
623 EventTypeScroll -> do 666 EventTypeScroll -> do
624 sev <- get ev #scroll 667 sev <- get ev #scroll