diff options
author | Joe Crayne <joe@jerkface.net> | 2019-06-03 20:16:38 -0400 |
---|---|---|
committer | Joe Crayne <joe@jerkface.net> | 2019-06-03 20:22:04 -0400 |
commit | 4beea73feaa37a0871d89365556c2e9ff4d9648c (patch) | |
tree | 581d6f932b0bfb1812e0c47f5ea219f233f22f09 | |
parent | f13eedc6482098581c359518e5db1dc7ec572eaf (diff) |
Started FitCurves module.
-rw-r--r-- | FitCurves.hs | 46 | ||||
-rw-r--r-- | MeshSketch.hs | 67 | ||||
-rw-r--r-- | lambda-gtk.cabal | 2 |
3 files changed, 74 insertions, 41 deletions
diff --git a/FitCurves.hs b/FitCurves.hs new file mode 100644 index 0000000..8c73cfb --- /dev/null +++ b/FitCurves.hs | |||
@@ -0,0 +1,46 @@ | |||
1 | {-# LANGUAGE RecordWildCards, DataKinds, DeriveDataTypeable #-} | ||
2 | module FitCurves where | ||
3 | |||
4 | import Control.Monad | ||
5 | import Data.Data | ||
6 | import Data.Int | ||
7 | import Data.IORef | ||
8 | import qualified Data.Vector.Storable.Mutable as MV | ||
9 | import Foreign.Ptr | ||
10 | import Foreign.Storable | ||
11 | import GHC.Exts (RealWorld) | ||
12 | import Numeric.LinearAlgebra as Math hiding ((<>)) | ||
13 | |||
14 | import Bezier | ||
15 | import Camera | ||
16 | import qualified GPURing as GPU | ||
17 | import LambdaCube.GL.Input.Type | ||
18 | import MaskableStream | ||
19 | import RingBuffer | ||
20 | import qualified VectorRing as Vector | ||
21 | ;import VectorRing (Point) | ||
22 | import LambdaCube.GL.HMatrix () | ||
23 | |||
24 | |||
25 | data RingPoint = RingPoint | ||
26 | { rpPosition :: AttributeKey (GLVector 3 Float) | ||
27 | , rpColor :: AttributeKey (GLVector 3 Float) | ||
28 | } | ||
29 | deriving Data | ||
30 | |||
31 | |||
32 | white,red,yellow,blue :: Vector Float | ||
33 | white = fromList [1,1,1] | ||
34 | yellow = fromList [1,1,0] | ||
35 | blue = fromList [0,0,1] | ||
36 | red = fromList [1,0,0] | ||
37 | |||
38 | fitCurve1 :: Camera | ||
39 | -> Maybe Plane | ||
40 | -> (Int32 -> [(Int32, Int32)]) | ||
41 | -> Int | ||
42 | -> TargetBuffer (GPU.Update RingPoint) | ||
43 | -> MV.MVector RealWorld Vector.Point | ||
44 | -> IO (Maybe Int) | ||
45 | fitCurve1 cam plane mask max_curve_pts buf dta = do | ||
46 | return Nothing -- TODO | ||
diff --git a/MeshSketch.hs b/MeshSketch.hs index 1019d72..14b3ebc 100644 --- a/MeshSketch.hs +++ b/MeshSketch.hs | |||
@@ -68,7 +68,8 @@ import RingBuffer | |||
68 | import MaskableStream (AttributeKey,(@<-)) | 68 | import MaskableStream (AttributeKey,(@<-)) |
69 | import SmallRing | 69 | import SmallRing |
70 | import Camera | 70 | import Camera |
71 | 71 | import FitCurves | |
72 | import Bezier | ||
72 | 73 | ||
73 | prettyDebug :: GL.DebugMessage -> String | 74 | prettyDebug :: GL.DebugMessage -> String |
74 | prettyDebug (GL.DebugMessage src typ (GL.DebugMessageID mid) severity msg) = unwords ws | 75 | prettyDebug (GL.DebugMessage src typ (GL.DebugMessageID mid) severity msg) = unwords ws |
@@ -89,13 +90,6 @@ setupGLDebugging = do | |||
89 | GL.debugMessageControl (GL.MessageGroup Nothing Nothing Nothing) GL.$= GL.Enabled | 90 | GL.debugMessageControl (GL.MessageGroup Nothing Nothing Nothing) GL.$= GL.Enabled |
90 | GL.debugMessageCallback GL.$= Just pdebug | 91 | GL.debugMessageCallback GL.$= Just pdebug |
91 | 92 | ||
92 | type Plane = Vector Float | ||
93 | |||
94 | data RingPoint = RingPoint | ||
95 | { rpPosition :: AttributeKey (GLVector 3 Float) | ||
96 | , rpColor :: AttributeKey (GLVector 3 Float) | ||
97 | } | ||
98 | deriving Data | ||
99 | 93 | ||
100 | ringPointAttr :: String -> String | 94 | ringPointAttr :: String -> String |
101 | ringPointAttr ('r':'p':c:cs) = toLower c : cs | 95 | ringPointAttr ('r':'p':c:cs) = toLower c : cs |
@@ -237,12 +231,6 @@ destroyState glarea st = do | |||
237 | -- widgetRemoveTickCallback glarea (stTickCallback st) | 231 | -- widgetRemoveTickCallback glarea (stTickCallback st) |
238 | return () | 232 | return () |
239 | 233 | ||
240 | deg30 :: Float | ||
241 | deg30 = pi/6 | ||
242 | |||
243 | ĵ :: Vector Float | ||
244 | ĵ = fromList [0,1,0] | ||
245 | |||
246 | computePlaneModel :: Vector Float -> Matrix Float | 234 | computePlaneModel :: Vector Float -> Matrix Float |
247 | computePlaneModel plane = if n̂ == ĵ then translate4 p | 235 | computePlaneModel plane = if n̂ == ĵ then translate4 p |
248 | else translate4 p <> rotate4 cosθ axis | 236 | else translate4 p <> rotate4 cosθ axis |
@@ -258,7 +246,7 @@ whirlingCamera st = Animation $ \_ t -> do | |||
258 | let tf = realToFrac t :: Float | 246 | let tf = realToFrac t :: Float |
259 | rot = rotMatrixZ (-tf/2) <> rotMatrixX (-tf/pi) | 247 | rot = rotMatrixZ (-tf/2) <> rotMatrixX (-tf/pi) |
260 | modifyIORef (stCamera st) $ \cam -> cam | 248 | modifyIORef (stCamera st) $ \cam -> cam |
261 | { camUp = fromList [0,1,0] <# rot | 249 | { camUp = ĵ <# rot |
262 | , camDirection = (scale (1/camDistance cam) $ fromList [-2,-2,-10]) <# rot | 250 | , camDirection = (scale (1/camDistance cam) $ fromList [-2,-2,-10]) <# rot |
263 | , camWorldToScreen = Nothing | 251 | , camWorldToScreen = Nothing |
264 | , camScreenToWorld = Nothing | 252 | , camScreenToWorld = Nothing |
@@ -571,25 +559,28 @@ worldCoordinates :: State -> Double -> Double -> Maybe (Vector Float) -> IO (Vec | |||
571 | worldCoordinates st h k mplane = do | 559 | worldCoordinates st h k mplane = do |
572 | pv <- atomicModifyIORef' (stCamera st) projectionView | 560 | pv <- atomicModifyIORef' (stCamera st) projectionView |
573 | cam <- readIORef (stCamera st) | 561 | cam <- readIORef (stCamera st) |
574 | let q0 = fromList [ 2 * realToFrac h/camWidth cam - 1 | 562 | return $ camWorldCoordinates cam h k mplane |
575 | , 1 - 2 * realToFrac k/camHeight cam | 563 | |
576 | , 1 | 564 | fitCurves :: State -> IO () |
577 | , 1 | 565 | fitCurves st = do |
578 | ] :: Vector Float | 566 | _ <- atomicModifyIORef' (stCamera st) projectionView |
579 | q1 = pv #> q0 | 567 | cam <- readIORef (stCamera st) |
580 | q2 = scale (1 /(q1!3)) $ G.init q1 | 568 | plane <- readIORef (stPlane st) |
581 | p = camPos cam | 569 | mask <- ringMask (stDataRing st) |
582 | d = q2 - p | 570 | let max_curve_pts = ringCapacity (stRingBuffer st) |
583 | d̂ = unit d | 571 | buf = rBuffer (stRingBuffer st) |
584 | return $ case mplane of | 572 | dta = stDataPoints st |
585 | -- Write on the plane. | 573 | -- dta_cnt <- readIORef (rSize $ stDataRing st) |
586 | Just plane -> let n̂ = G.init plane | 574 | -- when (dta_cnt > 4) $ do |
587 | c = plane!3 | 575 | -- when (idx > 0) $ |
588 | a = (c - dot p n̂) / dot d̂ n̂ | 576 | midx <- fitCurve1 cam plane mask max_curve_pts buf dta |
589 | in p + scale a d̂ | 577 | forM_ midx $ \idx -> do |
590 | 578 | putStrLn $ "idx = " ++ show idx | |
591 | -- Write on the camDistance sphere. | 579 | -- syncBuffer buf $ \cnt -> [(0,max cnt $ fromIntegral idx)] |
592 | Nothing -> p + scale (camDistance cam) d̂ | 580 | writeIORef (rBack $ stRingBuffer st) idx |
581 | writeIORef (rSize $ stRingBuffer st) idx | ||
582 | syncRing (stRingBuffer st) | ||
583 | |||
593 | 584 | ||
594 | pushRing :: IsWidget w => w -> State | 585 | pushRing :: IsWidget w => w -> State |
595 | -> Bool -- ^ True when press/release. | 586 | -> Bool -- ^ True when press/release. |
@@ -647,14 +638,9 @@ pushRing w st endpt h k c = do | |||
647 | else do | 638 | else do |
648 | fromMaybe withEndpt $ take3 withTriple g | 639 | fromMaybe withEndpt $ take3 withTriple g |
649 | windowInvalidateRect win Nothing False | 640 | windowInvalidateRect win Nothing False |
641 | fitCurves st | ||
650 | return d | 642 | return d |
651 | 643 | ||
652 | white,red,yellow,blue :: Vector Float | ||
653 | white = fromList [1,1,1] | ||
654 | yellow = fromList [1,1,0] | ||
655 | blue = fromList [0,0,1] | ||
656 | red = fromList [1,0,0] | ||
657 | |||
658 | onEvent :: IsWidget w => w -> Realized -> Event -> IO Bool | 644 | onEvent :: IsWidget w => w -> Realized -> Event -> IO Bool |
659 | onEvent w realized ev = do | 645 | onEvent w realized ev = do |
660 | msrc <- eventGetSourceDevice ev | 646 | msrc <- eventGetSourceDevice ev |
@@ -710,6 +696,7 @@ onEvent w realized ev = do | |||
710 | writeIORef (stAngle st) 0 | 696 | writeIORef (stAngle st) 0 |
711 | writeIORef (stRecentPts st) Give0 | 697 | writeIORef (stRecentPts st) Give0 |
712 | clearRing (stRingBuffer st) | 698 | clearRing (stRingBuffer st) |
699 | clearRing (stDataRing st) | ||
713 | d <- pushRing w st True h k red | 700 | d <- pushRing w st True h k red |
714 | Just win <- getWidgetWindow w | 701 | Just win <- getWidgetWindow w |
715 | windowInvalidateRect win Nothing False | 702 | windowInvalidateRect win Nothing False |
diff --git a/lambda-gtk.cabal b/lambda-gtk.cabal index a0c9fc3..86269e5 100644 --- a/lambda-gtk.cabal +++ b/lambda-gtk.cabal | |||
@@ -50,7 +50,7 @@ executable meshsketch | |||
50 | other-modules: InfinitePlane LambdaCubeWidget GLWidget LambdaCube.Gtk TimeKeeper | 50 | other-modules: InfinitePlane LambdaCubeWidget GLWidget LambdaCube.Gtk TimeKeeper |
51 | LoadMesh MtlParser Matrix LambdaCube.GL.HMatrix | 51 | LoadMesh MtlParser Matrix LambdaCube.GL.HMatrix |
52 | Animator MeshSketch CubeMap AttributeData GPURing MaskableStream | 52 | Animator MeshSketch CubeMap AttributeData GPURing MaskableStream |
53 | RingBuffer SmallRing VectorRing Camera | 53 | RingBuffer SmallRing VectorRing Camera Bezier FitCurves |
54 | extensions: NondecreasingIndentation | 54 | extensions: NondecreasingIndentation |
55 | other-extensions: OverloadedLabels, OverloadedLists, OverloadedStrings | 55 | other-extensions: OverloadedLabels, OverloadedLists, OverloadedStrings |
56 | build-depends: base, containers >=0.5 && <0.6, bytestring >=0.10 && <0.11, | 56 | build-depends: base, containers >=0.5 && <0.6, bytestring >=0.10 && <0.11, |