summaryrefslogtreecommitdiff
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
parent1f1e8adb543a3338e85313b005b3213471600541 (diff)
Allow alternate plane positions.
-rw-r--r--MeshSketch.hs82
-rw-r--r--hello_obj2.lc9
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)
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
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
65textureCubeSlot s = TextureCubeSlot s
66
67main :: Output 66main :: Output
68main = renderFrame $ 67main = 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")