Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added documentation for DefaultCameraController #52

Merged
merged 2 commits into from
Sep 22, 2019
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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