diff options
author | Joe Crayne <joe@jerkface.net> | 2019-05-18 00:39:07 -0400 |
---|---|---|
committer | Joe Crayne <joe@jerkface.net> | 2019-05-18 00:39:07 -0400 |
commit | 1f1e8adb543a3338e85313b005b3213471600541 (patch) | |
tree | 7c92233f189b6b326ba7287a9bbbacc36c528e6e | |
parent | 9203f1f1cbcf18237751083e363218f3a87a7aa7 (diff) |
Draw on the xz plane.
-rw-r--r-- | MeshSketch.hs | 32 |
1 files changed, 22 insertions, 10 deletions
diff --git a/MeshSketch.hs b/MeshSketch.hs index 099f8d4..95c79af 100644 --- a/MeshSketch.hs +++ b/MeshSketch.hs | |||
@@ -164,6 +164,10 @@ mkFullscreenToggle w = do | |||
164 | else windowUnfullscreen w | 164 | else windowUnfullscreen w |
165 | 165 | ||
166 | 166 | ||
167 | xzPlaneVector :: Vector Float | ||
168 | xzPlaneVector = fromList [ 0,1,0 -- unit normal | ||
169 | , 0 ] -- distance from origin | ||
170 | |||
167 | uploadState :: IsWidget glarea => MeshData -> glarea -> GLStorage -> IO State | 171 | uploadState :: IsWidget glarea => MeshData -> glarea -> GLStorage -> IO State |
168 | uploadState obj glarea storage = do | 172 | uploadState obj glarea storage = do |
169 | -- load OBJ geometry and material descriptions | 173 | -- load OBJ geometry and material descriptions |
@@ -471,25 +475,33 @@ sanitizeCamera st = do | |||
471 | } | 475 | } |
472 | 476 | ||
473 | 477 | ||
474 | worldCoordinates :: State -> Double -> Double -> IO (Vector Float) | 478 | worldCoordinates :: State -> Double -> Double -> Maybe (Vector Float) -> IO (Vector Float) |
475 | worldCoordinates st h k = do | 479 | worldCoordinates st h k mplane = do |
476 | pv <- atomicModifyIORef' (stCamera st) projectionView | 480 | pv <- atomicModifyIORef' (stCamera st) projectionView |
477 | cam <- readIORef (stCamera st) | 481 | cam <- readIORef (stCamera st) |
478 | let d0 = fromList [ 2 * realToFrac h/camWidth cam - 1 | 482 | let q0 = fromList [ 2 * realToFrac h/camWidth cam - 1 |
479 | , 1 - 2 * realToFrac k/camHeight cam | 483 | , 1 - 2 * realToFrac k/camHeight cam |
480 | , 1 | 484 | , 1 |
481 | , 1 | 485 | , 1 |
482 | ] :: Vector Float | 486 | ] :: Vector Float |
483 | d1 = pv #> d0 | 487 | q1 = pv #> q0 |
484 | d2 = scale (1 /(d1!3)) $ G.init d1 | 488 | q2 = scale (1 /(q1!3)) $ G.init q1 |
485 | p = camPos cam | 489 | p = camPos cam |
486 | d3 = d2 - p | 490 | d = q2 - p |
487 | d4 = scale (camDistance cam/realToFrac (norm_2 d3)) d3 | 491 | d̂ = scale (1/realToFrac (norm_2 d)) d |
488 | return $ p + d4 | 492 | return $ case mplane of |
493 | -- Write on the plane. | ||
494 | Just plane -> let n̂ = G.init plane | ||
495 | c = plane!3 | ||
496 | a = (c - dot p n̂) / dot d̂ n̂ | ||
497 | in p + scale a d̂ | ||
498 | |||
499 | -- Write on the camDistance sphere. | ||
500 | Nothing -> p + scale (camDistance cam) d̂ | ||
489 | 501 | ||
490 | pushRing :: IsWidget w => w -> State -> Double -> Double -> IO (Vector Float) | 502 | pushRing :: IsWidget w => w -> State -> Double -> Double -> IO (Vector Float) |
491 | pushRing w st h k = do | 503 | pushRing w st h k = do |
492 | d <- worldCoordinates st h k | 504 | d <- worldCoordinates st h k (Just xzPlaneVector) |
493 | Just win <- getWidgetWindow w | 505 | Just win <- getWidgetWindow w |
494 | pushBack (stRingBuffer st) (d!0) (d!1) (d!2) | 506 | pushBack (stRingBuffer st) (d!0) (d!1) (d!2) |
495 | windowInvalidateRect win Nothing False | 507 | windowInvalidateRect win Nothing False |
@@ -541,7 +553,7 @@ onEvent w realized ev = do | |||
541 | bev <- get ev #button | 553 | bev <- get ev #button |
542 | h <- get bev #x | 554 | h <- get bev #x |
543 | k <- get bev #y | 555 | k <- get bev #y |
544 | _ {- d -} <- worldCoordinates st h k | 556 | _ {- d -} <- worldCoordinates st h k Nothing |
545 | cam <- readIORef (stCamera st) | 557 | cam <- readIORef (stCamera st) |
546 | let d = computeDirection cam h k | 558 | let d = computeDirection cam h k |
547 | writeIORef (stDragFrom st) $ Just (d,cam) | 559 | writeIORef (stDragFrom st) $ Just (d,cam) |