diff options
author | Joe Crayne <joe@jerkface.net> | 2019-05-18 03:04:20 -0400 |
---|---|---|
committer | Joe Crayne <joe@jerkface.net> | 2019-05-18 03:04:20 -0400 |
commit | a590439eef76c5fe1e8ec7fce28a3b194bfd6e8e (patch) | |
tree | e4112135a37e3fe0fcce3baa5468f304309b6d89 | |
parent | 1f1e8adb543a3338e85313b005b3213471600541 (diff) |
Allow alternate plane positions.
-rw-r--r-- | MeshSketch.hs | 82 | ||||
-rw-r--r-- | hello_obj2.lc | 9 |
2 files changed, 66 insertions, 25 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) | |||
17 | import Data.Map.Strict (Map) | 17 | import Data.Map.Strict (Map) |
18 | import qualified Data.Map.Strict as Map | 18 | import qualified Data.Map.Strict as Map |
19 | import qualified Data.Vector as V | 19 | import qualified Data.Vector as V |
20 | import qualified Data.Vector.Generic as G (init) | 20 | import qualified Data.Vector.Generic as G (init,(//)) |
21 | import Foreign.Marshal.Array | 21 | import Foreign.Marshal.Array |
22 | import Foreign.Storable | 22 | import Foreign.Storable |
23 | import GI.Gdk | 23 | import 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 | ||
89 | data Camera = Camera | 90 | data 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 | |||
231 | deg30 :: Float | 234 | deg30 :: Float |
232 | deg30 = pi/6 | 235 | deg30 = pi/6 |
233 | 236 | ||
237 | ĵ :: Vector Float | ||
238 | ĵ = fromList [0,1,0] | ||
239 | |||
240 | computePlaneModel :: Vector Float -> Matrix Float | ||
241 | computePlaneModel 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 | |||
234 | whirlingCamera :: State -> Animation | 250 | whirlingCamera :: State -> Animation |
235 | whirlingCamera st = Animation $ \_ t -> do | 251 | whirlingCamera 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 | |||
246 | setUniforms :: glctx -> GLStorage -> State -> IO () | 262 | setUniforms :: glctx -> GLStorage -> State -> IO () |
247 | setUniforms gl storage st = do | 263 | setUniforms 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 | ||
254 | data MeshSketch = MeshSketch | 273 | data 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 | ||
436 | rotate4 :: ( Floating a | ||
437 | , Math.Container Vector a | ||
438 | , Indexable (Vector a) a | ||
439 | , Normed (Vector a) | ||
440 | ) => a -> Vector a -> Matrix a | ||
441 | rotate4 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 | |||
458 | translate4 :: (Storable a, Num a, Indexable c a) => c -> Matrix a | ||
459 | translate4 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 | |||
416 | updateCameraRotation :: IsWidget a => a -> State -> Double -> Double -> IO () | 466 | updateCameraRotation :: IsWidget a => a -> State -> Double -> Double -> IO () |
417 | updateCameraRotation w st h k = do | 467 | updateCameraRotation 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 | ||
502 | pushRing :: IsWidget w => w -> State -> Double -> Double -> IO (Vector Float) | 552 | pushRing :: IsWidget w => w -> State -> Double -> Double -> IO (Vector Float) |
503 | pushRing w st h k = do | 553 | pushRing 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 |
diff --git a/hello_obj2.lc b/hello_obj2.lc index 629bf59..fdf08d6 100644 --- a/hello_obj2.lc +++ b/hello_obj2.lc | |||
@@ -20,6 +20,7 @@ makeFrame (cubemap :: TextureCube) | |||
20 | (prims :: PrimitiveStream Triangle (Vec 4 Float, Vec 3 Float, Vec 3 Float)) | 20 | (prims :: PrimitiveStream Triangle (Vec 4 Float, Vec 3 Float, Vec 3 Float)) |
21 | (plane :: PrimitiveStream Triangle ((Vec 4 Float))) | 21 | (plane :: PrimitiveStream Triangle ((Vec 4 Float))) |
22 | (points :: PrimitiveStream Point ((Vec 3 Float))) | 22 | (points :: PrimitiveStream Point ((Vec 3 Float))) |
23 | (plane_mat :: Mat 4 4 Float) | ||
23 | 24 | ||
24 | = imageFrame (emptyDepthImage 1, emptyColorImage (V4 0 0 0.4 1)) | 25 | = imageFrame (emptyDepthImage 1, emptyColorImage (V4 0 0 0.4 1)) |
25 | `overlay` | 26 | `overlay` |
@@ -38,7 +39,7 @@ makeFrame (cubemap :: TextureCube) | |||
38 | & accumulateWith (DepthOp Less True, ColorOp NoBlending (V4 True True True True)) | 39 | & accumulateWith (DepthOp Less True, ColorOp NoBlending (V4 True True True True)) |
39 | `overlay` | 40 | `overlay` |
40 | plane | 41 | plane |
41 | & mapPrimitives (\((p)) -> let p' = coordmap cam p in (p', p%xz)) | 42 | & mapPrimitives (\((p)) -> let p' = coordmap cam $ plane_mat *. p in (p', p%xz)) |
42 | & rasterizePrimitives (TriangleCtx CullNone PolygonFill NoOffset LastVertex) ((Smooth)) | 43 | & rasterizePrimitives (TriangleCtx CullNone PolygonFill NoOffset LastVertex) ((Smooth)) |
43 | & mapFragments (\((uv)) -> let c = mixB zero one (fract uv >= (one *! (0.95::Float))) | 44 | & mapFragments (\((uv)) -> let c = mixB zero one (fract uv >= (one *! (0.95::Float))) |
44 | r = V4 1 1 1 0 *! (max c%x c%y) | 45 | r = V4 1 1 1 0 *! (max c%x c%y) |
@@ -62,11 +63,9 @@ renderPoints cam points = | |||
62 | & mapFragments (\((c)) -> ((c))) | 63 | & mapFragments (\((c)) -> ((c))) |
63 | & accumulateWith (DepthOp Always False, ColorOp NoBlending (V4 True True True True)) | 64 | & accumulateWith (DepthOp Always False, ColorOp NoBlending (V4 True True True True)) |
64 | 65 | ||
65 | textureCubeSlot s = TextureCubeSlot s | ||
66 | |||
67 | main :: Output | 66 | main :: Output |
68 | main = renderFrame $ | 67 | main = renderFrame $ |
69 | makeFrame (textureCubeSlot "CubeMap") | 68 | makeFrame (TextureCubeSlot "CubeMap") |
70 | (fetch "SkyCube" ((Attribute "position"))) | 69 | (fetch "SkyCube" ((Attribute "position"))) |
71 | (Uniform "CameraPosition") | 70 | (Uniform "CameraPosition") |
72 | (Uniform "ViewProjection") | 71 | (Uniform "ViewProjection") |
@@ -75,4 +74,4 @@ main = renderFrame $ | |||
75 | (fetch "objects" (Attribute "position", Attribute "normal", Attribute "uvw")) | 74 | (fetch "objects" (Attribute "position", Attribute "normal", Attribute "uvw")) |
76 | (fetch "plane" ((Attribute "position"))) | 75 | (fetch "plane" ((Attribute "position"))) |
77 | (fetch "Points" ((Attribute "position"))) | 76 | (fetch "Points" ((Attribute "position"))) |
78 | 77 | (Uniform "PlaneModel") | |