Skip to content

Commit

Permalink
Merge pull request #52 from dallinbeutler/master
Browse files Browse the repository at this point in the history
Added documentation for DefaultCameraController
  • Loading branch information
krauthaufen authored Sep 22, 2019
2 parents 7d81835 + c1b5836 commit 14e8b68
Showing 1 changed file with 141 additions and 50 deletions.
191 changes: 141 additions & 50 deletions src/Application/Aardvark.Application/DefaultCameraController.fs
Original file line number Diff line number Diff line change
Expand Up @@ -6,46 +6,70 @@ open Aardvark.Base.Rendering
open Aardvark.Base.Incremental

module DefaultCameraController =

let controlWSAD (k : IKeyboard) (time : IMod<DateTime>) =
let w = k.IsDown Keys.W
let s = k.IsDown Keys.S
let a = k.IsDown Keys.A
let d = k.IsDown Keys.D

/// <summary>Move the camera forward, back, left, or right.
/// WASD controls the functionality.</summary>
/// <param name="keyboard"> the keyboard inputs (this is often pulled from the parent window)</param>
/// <param name="time"> incremental input representing the current time. (this is often pulled from the parent window) </param>
/// <returns>An incremental function that takes a CameraView</returns>
let controlWSAD (keyboard : IKeyboard) (time : IMod<DateTime>) =

//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
elif b && not f then -V2i.OI
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)
/// <summary> Gives a camera look controls.
/// Left mouse button controls the functionality </summary>
/// <param name="mouse"> the mouse inputs (this is often pulled from the parent window)</param>
/// <returns>An incremental function that takes a CameraView</returns>
let controlLookAround (mouse : IMouse) =
let down = mouse.IsDown(MouseButtons.Left)
let location = mouse.Position |> Mod.map (fun pp -> pp.Position)

adaptive {
let! d = down
Expand All @@ -64,10 +88,13 @@ module DefaultCameraController =
return AdaptiveFunc.Identity
}


let controlOrbitAround (m : IMouse) (center : IMod<V3d>) =
let down = m.IsDown(MouseButtons.Left)
let location = m.Position |> Mod.map (fun pp -> pp.Position)
/// <summary> Gives a camera look controls, orbiting around a point.
/// Left mouse button controls the functionality.</summary>
/// <param name="mouse"> the mouse inputs (this is often pulled from the parent window)</param>
/// <returns>An incremental function that takes a CameraView</returns>
let controlOrbitAround (mouse : IMouse) (center : IMod<V3d>) =
let down = mouse.IsDown(MouseButtons.Left)
let location = mouse.Position |> Mod.map (fun pp -> pp.Position)

adaptive {
let! d = down
Expand All @@ -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)
/// <summary> Gives a camera an option to move around laterally from
/// the direction of the camera.
/// A middle mouse button controls the functionality.</summary>
/// <param name="mouse"> the mouse inputs (this is often pulled from the parent window)</param>
/// <returns>An incremental function that takes a CameraView</returns>
let controlPan (mouse : IMouse) =
let down = mouse.IsDown(MouseButtons.Middle)
let location = mouse.Position |> Mod.map (fun pp -> pp.Position)

adaptive {
let! d = down
Expand All @@ -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)
/// <summary> 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.</summary>
/// <param name="mouse"> the mouse inputs (this is often pulled from the parent window)</param>
/// <returns>An incremental function that takes a CameraView</returns>
let controlZoom (mouse : IMouse) =
let down = mouse.IsDown(MouseButtons.Right)
let location = mouse.Position |> Mod.map (fun pp -> pp.Position)

adaptive {
let! d = down
Expand All @@ -125,11 +161,16 @@ module DefaultCameraController =
return AdaptiveFunc.Identity
}

let controllScroll (m : IMouse) (time : IMod<DateTime>) =
/// <summary> Gives a camera an option to move towards or away from the facing direction.
/// middle mouse wheel controls the functionality.</summary>
/// <param name="mouse"> the mouse inputs (this is often pulled from the parent window)</param>
/// <param name="time"> the time to use as reference (this is often pulled from the parent window)</param>
/// <returns>An incremental function that takes a CameraView</returns>
let controllScroll (mouse : IMouse) (time : IMod<DateTime>) =
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)
Expand All @@ -153,23 +194,35 @@ module DefaultCameraController =
)
else
return AdaptiveFunc.Identity
}

let control (mouse : IMouse) (keyboard : IKeyboard) (time : IMod<DateTime>) (cam : CameraView) : IMod<CameraView> =
Mod.integrate cam time [
}

/// <summary> Implement common control functions for movement, looking, panning, and zooming
/// for a given camera.</summary>
/// <param name="mouse"> the mouse inputs (this is often pulled from the parent window)</param>
/// <param name="keyboard"> the keyboard inputs (this is often pulled from the parent window)</param>
/// <param name="time"> the relative time (this is often pulled from the parent window)</param>
/// <param name="camera"> the initial state of the camera</param>
/// <returns>An incremental function that takes a CameraView</returns>
let control (mouse : IMouse) (keyboard : IKeyboard) (time : IMod<DateTime>) (camera : CameraView) : IMod<CameraView> =
Mod.integrate camera time [
controlWSAD keyboard time
controlLookAround mouse
controlPan mouse
controlZoom mouse
controllScroll mouse time
]


let controlWSADwithSpeed (speed : ModRef<float>) (k : IKeyboard) (time : IMod<DateTime>) =
let w = k.IsDown Keys.W
let s = k.IsDown Keys.S
let a = k.IsDown Keys.A
let d = k.IsDown Keys.D
/// <summary>Move the camera forward, back, left, or right.
/// WASD controls the functionality.</summary>
/// <param name="speed"> the camera movement speed</param>
/// <param name="keyboard"> the keyboard inputs (this is often pulled from the parent window)</param>
/// <param name="time"> incremental input representing the current time. (this is often pulled from the parent window) </param>
/// <returns>An incremental function that takes a CameraView</returns>
let controlWSADwithSpeed (speed : ModRef<float>) (keyboard : IKeyboard) (time : IMod<DateTime>) =
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 ->
Expand Down Expand Up @@ -201,9 +254,15 @@ module DefaultCameraController =
return AdaptiveFunc.Identity
} |> Mod.onPush

let controlPanWithSpeed (speed : ModRef<float>) (m : IMouse) =
let down = m.IsDown(MouseButtons.Middle)
let location = m.Position |> Mod.map (fun pp -> pp.Position)
/// <summary> Gives a camera an option to move around laterally from
/// the direction of the camera.
/// A middle mouse button controls the functionality.</summary>
/// <param name="speed"> the rate at which the panning movement occurs</param>
/// <param name="mouse"> the mouse inputs (this is often pulled from the parent window)</param>
/// <returns>An incremental function that takes a CameraView</returns>
let controlPanWithSpeed (speed : ModRef<float>) (mouse : IMouse) =
let down = mouse.IsDown(MouseButtons.Middle)
let location = mouse.Position |> Mod.map (fun pp -> pp.Position)

adaptive {
let! d = down
Expand All @@ -220,20 +279,30 @@ module DefaultCameraController =
return AdaptiveFunc.Identity
}

let controlReset (initial : CameraView) (k : IKeyboard) =
/// <summary> Gives a camera the ability to reset to it's initial state.
/// F9 is the default button for resetting.</summary>
/// <param name="keyboard"> the keyboard inputs (this is often pulled from the parent window)</param>
/// <returns>An incremental function that takes a CameraView</returns>
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<float>) (m : IMouse) (time : IMod<DateTime>) =

/// <summary> Gives a camera an option to move towards or away from the facing direction.
/// middle mouse wheel controls the functionality.</summary>
/// <param name="moveSpeed"> the rate at which the zooming occurs</param>
/// <param name="mouse"> the mouse inputs (this is often pulled from the parent window)</param>
/// <param name="time"> the time to use as reference (this is often pulled from the parent window)</param>
/// <returns>An incremental function that takes a CameraView</returns>
let controllScrollWithSpeed (moveSpeed : ModRef<float>) (mouse : IMouse) (time : IMod<DateTime>) =
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)
Expand All @@ -258,25 +327,38 @@ module DefaultCameraController =
else
return AdaptiveFunc.Identity
}

let controlZoomWithSpeed (speed : ModRef<float>) (m : IMouse) =
let down = m.IsDown(MouseButtons.Right)
let location = m.Position |> Mod.map (fun pp -> pp.Position)

/// <summary> 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.</summary>
/// <param name="moveSpeed"> the rate at which the zooming occurs</param>
/// <param name="mouse"> the mouse inputs (this is often pulled from the parent window)</param>
/// <returns>An incremental function that takes a CameraView</returns>
let controlZoomWithSpeed (moveSpeed : ModRef<float>) (mouse : IMouse) =
let down = mouse.IsDown(MouseButtons.Right)
let location = mouse.Position |> Mod.map (fun pp -> pp.Position)

adaptive {
let! d = down

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
}

}

/// <summary> Implement common control functions for movement, looking, panning, and zooming
/// for a given camera.</summary>
/// <param name="moveSpeed"> the rate at which all movement occurs</param>
/// <param name="mouse"> the mouse inputs (this is often pulled from the parent window)</param>
/// <param name="keyboard"> the keyboard inputs (this is often pulled from the parent window)</param>
/// <param name="time"> the relative time (this is often pulled from the parent window)</param>
/// <param name="camera"> the initial state of the camera</param>
/// <returns>An incremental function that takes a CameraView</returns>
let controlWithSpeed (speed : ModRef<float>) (mouse : IMouse) (keyboard : IKeyboard) (time : IMod<DateTime>) (cam : CameraView) : IMod<CameraView> =
Mod.integrate cam time [
controlWSADwithSpeed speed keyboard time
Expand All @@ -286,6 +368,15 @@ module DefaultCameraController =
controllScrollWithSpeed speed mouse time
]

/// <summary> 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.</summary>
/// <param name="initialSpeed"> the initial rate at which all movement occurs</param>
/// <param name="mouse"> the mouse inputs (this is often pulled from the parent window)</param>
/// <param name="keyboard"> the keyboard inputs (this is often pulled from the parent window)</param>
/// <param name="time"> the relative time (this is often pulled from the parent window)</param>
/// <param name="camera"> the initial state of the camera</param>
/// <returns>An incremental function that takes a CameraView</returns>
let controlExt (initialSpeed : float ) (mouse : IMouse) (keyboard : IKeyboard) (time : IMod<DateTime>) (cam : CameraView) : IMod<CameraView> =
let speed = Mod.init initialSpeed

Expand Down

0 comments on commit 14e8b68

Please sign in to comment.