diff --git a/src/Application/Aardvark.Application/DefaultCameraController.fs b/src/Application/Aardvark.Application/DefaultCameraController.fs index b0aca3e93..7fa9be5d8 100644 --- a/src/Application/Aardvark.Application/DefaultCameraController.fs +++ b/src/Application/Aardvark.Application/DefaultCameraController.fs @@ -6,20 +6,27 @@ open Aardvark.Base.Rendering open Aardvark.Base.Incremental module DefaultCameraController = - - let controlWSAD (k : IKeyboard) (time : IMod) = - let w = k.IsDown Keys.W - let s = k.IsDown Keys.S - let a = k.IsDown Keys.A - let d = k.IsDown Keys.D - + /// Move the camera forward, back, left, or right. + /// WASD controls the functionality. + /// the keyboard inputs (this is often pulled from the parent window) + /// incremental input representing the current time. (this is often pulled from the parent window) + /// An incremental function that takes a CameraView + let controlWSAD (keyboard : IKeyboard) (time : IMod) = + + //Each keypress is represented by an incremental variable, or IMod. + let w = keyboard.IsDown Keys.W + let s = keyboard.IsDown Keys.S + let a = keyboard.IsDown Keys.A + let d = keyboard.IsDown Keys.D + + // left and rignt are mapped to a single axis let moveX = Mod.map2 (fun l r -> if l && not r then -V2i.IO elif r && not l then V2i.IO else V2i.Zero ) a d - + // same for up and down let moveY = Mod.map2 (fun f b -> if f && not b then V2i.OI @@ -27,25 +34,42 @@ module DefaultCameraController = else V2i.Zero ) w s + //we combine the separate axes into one variable, a (normalized) movement vector let move = Mod.map2 (+) moveX moveY + //an adaptive computation expression is created to make working in the incremental 'realm' easier adaptive { + + //let! unwraps an IMod so we can work with the underlying value. let! m = move + + //If a key has been pressed if m <> V2i.Zero then - return time |> Mod.stepTime (fun t dt (cam : CameraView) -> - //printfn "%Ams" dt.TotalMilliseconds + // map the current time to a delta time, then apply it to a function + return time + |> Mod.stepTime (fun t dt (cam : CameraView) -> + + //apply our movement vector relative to the direction the camera is facing let direction = float m.X * cam.Right + float m.Y * cam.Forward + + // 1.2 is the default speed let delta = 1.2 * dt.TotalSeconds * direction + //update camera location cam.WithLocation(cam.Location + delta) ) + // else do nothing else return AdaptiveFunc.Identity } - let controlLookAround (m : IMouse) = - let down = m.IsDown(MouseButtons.Left) - let location = m.Position |> Mod.map (fun pp -> pp.Position) + /// Gives a camera look controls. + /// Left mouse button controls the functionality + /// the mouse inputs (this is often pulled from the parent window) + /// An incremental function that takes a CameraView + let controlLookAround (mouse : IMouse) = + let down = mouse.IsDown(MouseButtons.Left) + let location = mouse.Position |> Mod.map (fun pp -> pp.Position) adaptive { let! d = down @@ -64,10 +88,13 @@ module DefaultCameraController = return AdaptiveFunc.Identity } - - let controlOrbitAround (m : IMouse) (center : IMod) = - let down = m.IsDown(MouseButtons.Left) - let location = m.Position |> Mod.map (fun pp -> pp.Position) + /// Gives a camera look controls, orbiting around a point. + /// Left mouse button controls the functionality. + /// the mouse inputs (this is often pulled from the parent window) + /// An incremental function that takes a CameraView + let controlOrbitAround (mouse : IMouse) (center : IMod) = + let down = mouse.IsDown(MouseButtons.Left) + let location = mouse.Position |> Mod.map (fun pp -> pp.Position) adaptive { let! d = down @@ -88,9 +115,14 @@ module DefaultCameraController = return AdaptiveFunc.Identity } - let controlPan (m : IMouse) = - let down = m.IsDown(MouseButtons.Middle) - let location = m.Position |> Mod.map (fun pp -> pp.Position) + /// Gives a camera an option to move around laterally from + /// the direction of the camera. + /// A middle mouse button controls the functionality. + /// the mouse inputs (this is often pulled from the parent window) + /// An incremental function that takes a CameraView + let controlPan (mouse : IMouse) = + let down = mouse.IsDown(MouseButtons.Middle) + let location = mouse.Position |> Mod.map (fun pp -> pp.Position) adaptive { let! d = down @@ -107,9 +139,13 @@ module DefaultCameraController = return AdaptiveFunc.Identity } - let controlZoom (m : IMouse) = - let down = m.IsDown(MouseButtons.Right) - let location = m.Position |> Mod.map (fun pp -> pp.Position) + /// Gives a camera an option to move towards or away from the facing direction. + /// right mouse button with mouse y axis movement controls the functionality. + /// the mouse inputs (this is often pulled from the parent window) + /// An incremental function that takes a CameraView + let controlZoom (mouse : IMouse) = + let down = mouse.IsDown(MouseButtons.Right) + let location = mouse.Position |> Mod.map (fun pp -> pp.Position) adaptive { let! d = down @@ -125,11 +161,16 @@ module DefaultCameraController = return AdaptiveFunc.Identity } - let controllScroll (m : IMouse) (time : IMod) = + /// Gives a camera an option to move towards or away from the facing direction. + /// middle mouse wheel controls the functionality. + /// the mouse inputs (this is often pulled from the parent window) + /// the time to use as reference (this is often pulled from the parent window) + /// An incremental function that takes a CameraView + let controllScroll (mouse : IMouse) (time : IMod) = let active = Mod.init false let speed = ref 0.0 - let s = m.Scroll.Values.Subscribe(fun d -> + let s = mouse.Scroll.Values.Subscribe(fun d -> speed := !speed + d if not <| active.GetValue() then transact (fun () -> Mod.change active true) @@ -153,10 +194,17 @@ module DefaultCameraController = ) else return AdaptiveFunc.Identity - } - - let control (mouse : IMouse) (keyboard : IKeyboard) (time : IMod) (cam : CameraView) : IMod = - Mod.integrate cam time [ + } + + /// Implement common control functions for movement, looking, panning, and zooming + /// for a given camera. + /// the mouse inputs (this is often pulled from the parent window) + /// the keyboard inputs (this is often pulled from the parent window) + /// the relative time (this is often pulled from the parent window) + /// the initial state of the camera + /// An incremental function that takes a CameraView + let control (mouse : IMouse) (keyboard : IKeyboard) (time : IMod) (camera : CameraView) : IMod = + Mod.integrate camera time [ controlWSAD keyboard time controlLookAround mouse controlPan mouse @@ -164,12 +212,17 @@ module DefaultCameraController = controllScroll mouse time ] - - let controlWSADwithSpeed (speed : ModRef) (k : IKeyboard) (time : IMod) = - let w = k.IsDown Keys.W - let s = k.IsDown Keys.S - let a = k.IsDown Keys.A - let d = k.IsDown Keys.D + /// Move the camera forward, back, left, or right. + /// WASD controls the functionality. + /// the camera movement speed + /// the keyboard inputs (this is often pulled from the parent window) + /// incremental input representing the current time. (this is often pulled from the parent window) + /// An incremental function that takes a CameraView + let controlWSADwithSpeed (speed : ModRef) (keyboard : IKeyboard) (time : IMod) = + let w = keyboard.IsDown Keys.W + let s = keyboard.IsDown Keys.S + let a = keyboard.IsDown Keys.A + let d = keyboard.IsDown Keys.D let moveX = Mod.map2 (fun l r -> @@ -201,9 +254,15 @@ module DefaultCameraController = return AdaptiveFunc.Identity } |> Mod.onPush - let controlPanWithSpeed (speed : ModRef) (m : IMouse) = - let down = m.IsDown(MouseButtons.Middle) - let location = m.Position |> Mod.map (fun pp -> pp.Position) + /// Gives a camera an option to move around laterally from + /// the direction of the camera. + /// A middle mouse button controls the functionality. + /// the rate at which the panning movement occurs + /// the mouse inputs (this is often pulled from the parent window) + /// An incremental function that takes a CameraView + let controlPanWithSpeed (speed : ModRef) (mouse : IMouse) = + let down = mouse.IsDown(MouseButtons.Middle) + let location = mouse.Position |> Mod.map (fun pp -> pp.Position) adaptive { let! d = down @@ -220,20 +279,30 @@ module DefaultCameraController = return AdaptiveFunc.Identity } - let controlReset (initial : CameraView) (k : IKeyboard) = + /// Gives a camera the ability to reset to it's initial state. + /// F9 is the default button for resetting. + /// the keyboard inputs (this is often pulled from the parent window) + /// An incremental function that takes a CameraView + let controlReset (initial : CameraView) (keyboard : IKeyboard) = adaptive { - let! t = k.IsDown Keys.F9 + let! t = keyboard.IsDown Keys.F9 if t then return Mod.constant 0 |> Mod.step (fun _ _ _ -> initial ) else return AdaptiveFunc.Identity } - - let controllScrollWithSpeed (moveSpeed : ModRef) (m : IMouse) (time : IMod) = + + /// Gives a camera an option to move towards or away from the facing direction. + /// middle mouse wheel controls the functionality. + /// the rate at which the zooming occurs + /// the mouse inputs (this is often pulled from the parent window) + /// the time to use as reference (this is often pulled from the parent window) + /// An incremental function that takes a CameraView + let controllScrollWithSpeed (moveSpeed : ModRef) (mouse : IMouse) (time : IMod) = let active = Mod.init false let speed = ref 0.0 - let s = m.Scroll.Values.Subscribe(fun d -> + let s = mouse.Scroll.Values.Subscribe(fun d -> speed := !speed + d if not <| active.GetValue() then transact (fun () -> Mod.change active true) @@ -258,10 +327,15 @@ module DefaultCameraController = else return AdaptiveFunc.Identity } - - let controlZoomWithSpeed (speed : ModRef) (m : IMouse) = - let down = m.IsDown(MouseButtons.Right) - let location = m.Position |> Mod.map (fun pp -> pp.Position) + + /// Gives a camera an option to move towards or away from the facing direction. + /// right mouse button with mouse y axis movement controls the functionality. + /// the rate at which the zooming occurs + /// the mouse inputs (this is often pulled from the parent window) + /// An incremental function that takes a CameraView + let controlZoomWithSpeed (moveSpeed : ModRef) (mouse : IMouse) = + let down = mouse.IsDown(MouseButtons.Right) + let location = mouse.Position |> Mod.map (fun pp -> pp.Position) adaptive { let! d = down @@ -269,14 +343,22 @@ module DefaultCameraController = if d then return location |> Mod.step (fun p delta (cam : CameraView) -> - let step = -0.006 * speed.Value * (cam.Forward * float delta.Y) + let step = -0.006 * moveSpeed.Value * (cam.Forward * float delta.Y) cam.WithLocation(cam.Location + step) ) else return AdaptiveFunc.Identity - } - + } + + /// Implement common control functions for movement, looking, panning, and zooming + /// for a given camera. + /// the rate at which all movement occurs + /// the mouse inputs (this is often pulled from the parent window) + /// the keyboard inputs (this is often pulled from the parent window) + /// the relative time (this is often pulled from the parent window) + /// the initial state of the camera + /// An incremental function that takes a CameraView let controlWithSpeed (speed : ModRef) (mouse : IMouse) (keyboard : IKeyboard) (time : IMod) (cam : CameraView) : IMod = Mod.integrate cam time [ controlWSADwithSpeed speed keyboard time @@ -286,6 +368,15 @@ module DefaultCameraController = controllScrollWithSpeed speed mouse time ] + /// Implement common control functions for movement, looking, panning, and zooming + /// for a given camera. also adds the ability to adjust movement speed. + /// Default controls use PageUp and PageDown. + /// the initial rate at which all movement occurs + /// the mouse inputs (this is often pulled from the parent window) + /// the keyboard inputs (this is often pulled from the parent window) + /// the relative time (this is often pulled from the parent window) + /// the initial state of the camera + /// An incremental function that takes a CameraView let controlExt (initialSpeed : float ) (mouse : IMouse) (keyboard : IKeyboard) (time : IMod) (cam : CameraView) : IMod = let speed = Mod.init initialSpeed