-
Notifications
You must be signed in to change notification settings - Fork 1
/
Fly.hs
98 lines (73 loc) · 2.78 KB
/
Fly.hs
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
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
{-# LANGUAGE OverloadedStrings #-}
module Fly (
newFlyingActor
) where
import HGamer3D
import Control.Monad
import Control.Concurrent
import Control.Monad.Trans.Reader
import Control.Monad.Trans.State
import Control.Monad.Trans.Class
import Control.Monad.IO.Class
import Data
import Actor
-- FLYING CONTROL ACTOR
-- --------------------
type FaR = Entity
type FaS = (Var Speed, Var (Position, Orientation))
newFlyingActor :: Entity -> IO Actor
newFlyingActor cam = do
speed' <- makeVar (Speed 0)
ori <- readC cam ctOrientation
pos <- readC cam ctPosition
campos' <- makeVar (pos, ori)
let loop = do
(Speed s) <- readVar speed'
if s /= 0 then forward cam ((fromIntegral s)/30.0) else return ()
sleepFor (msecT 30)
loop
forkIO $ forever $ loop
actor <- newActor
runActor actor flyingActorF cam (speed', campos')
return actor
flyingActorF :: Actor -> Message -> ReaderStateIO FaR FaS ()
flyingActorF flyA msg = do
let f = 0.01
cam <- lift ask
(speed, campos) <- get
case msg of
YawRight -> liftIO (yaw' cam (f)) >> return ()
YawLeft -> liftIO (yaw' cam (-f)) >> return ()
RollRight -> liftIO (roll' cam (-f)) >> return ()
RollLeft -> liftIO (roll' cam f) >> return ()
PitchUp -> liftIO (pitch' cam (0.3 *f)) >> return ()
PitchDown -> liftIO (pitch' cam (0.3 * (-f))) >> return ()
MoreSpeed -> liftIO (updateVar speed (\(Speed i) -> (Speed (i + 1), ()))) >> return ()
LessSpeed -> liftIO (updateVar speed (\(Speed i) -> (Speed (i - 1), ()))) >> return ()
ZeroSpeed -> liftIO (writeVar speed (Speed 0)) >> return ()
SaveCamPosition -> do
ori <- liftIO $ readC cam ctOrientation
pos <- liftIO $ readC cam ctPosition
liftIO $ writeVar campos (pos, ori)
liftIO $ print $ "cam position: " ++ (show pos) ++ " ori: " ++ (show ori)
return ()
RestoreCamPosition -> do
(pos, ori) <- liftIO $ readVar campos
liftIO $ setC cam ctOrientation ori
liftIO $ setC cam ctPosition pos
return ()
ResetCamPosition -> do
liftIO $ setC cam ctOrientation unitU
liftIO $ setC cam ctPosition (Vec3 1 1 (-30.0))
return ()
yaw' e val = updateC e ctOrientation (\ori -> yaw ori (Rad val))
roll' e val = updateC e ctOrientation (\ori -> roll ori (Rad val))
pitch' e val = updateC e ctOrientation (\ori -> pitch ori (Rad val))
-- function, to move into direction of flight
forward :: Entity -> Float -> IO ()
forward e val = do
qob <- readC e ctOrientation
-- this points towards nose
let vdir = actU qob vec3Z
updateC e ctPosition (\pos -> pos &+ (val *& vdir))
return ()