-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathView.hs
More file actions
58 lines (51 loc) · 1.64 KB
/
View.hs
File metadata and controls
58 lines (51 loc) · 1.64 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE TypeOperators #-}
module Isometry.View
( View(..)
, withView
-- * Transforms
, transformToWindowSize
-- * Re-exports
, module Geometry.Transform
) where
import Control.Carrier.Reader
import Control.Effect.Lift
import Control.Lens ((&), (.~))
import Data.Functor.I
import GL.Shader.DSL (ClipUnits(..))
import Geometry.Transform
import Isometry.World
import Linear.Exts
import UI.Window as Window
import Unit.Algebra
import Unit.Length
newtype View = View
{ transform :: Transform V4 Float Distance ClipUnits
}
withView
:: ( Has (Lift IO) sig m
, Has (Reader Window.Window) sig m
)
=> I Double
-> ReaderC View m a
-> m a
withView !angle m = do
!size <- Window.size
let !zoom = 1 :: I Double
!focus = 0 :: V3 (Distance Double)
-- how many pixels to draw something / one semimetre across
!scale = Window.Coords 5 ./. Semi (Metres 1) :: (Window.Coords :/: Distance) Double
!transform
= tmap realToFrac
$ transformToWindowSize size
<<< mkScale (pure scale)
<<< mkTranslation (negated focus)
<<< mkRotation
( axisAngle (unit _y) angle)
<<< mkScale (pure zoom)
runReader View{ transform } m
transformToWindowSize :: V2 (Window.Coords Int) -> Transform V4 Double Window.Coords ClipUnits
transformToWindowSize size
-- NB: we *always* use 2/size, rather than ratio/size, because clip space always extends from -1...1, i.e. it always has diameter 2. this is true irrespective of the DPI ratio.
= mkScale (pure 1 & _xy .~ ClipUnits 2 ./^ (fmap fromIntegral <$> size) & _z .~ -1/10000)