Skip to content

Commit

Permalink
new camera controller cleanups
Browse files Browse the repository at this point in the history
  • Loading branch information
haraldsteinlechner committed Aug 21, 2018
1 parent 14aebf0 commit 6205c48
Show file tree
Hide file tree
Showing 26 changed files with 431 additions and 133 deletions.
10 changes: 5 additions & 5 deletions src/Aardvark.UI.Primitives/.domaincache
@@ -1,7 +1,7 @@
75E3501761A08C348BEC259E49201017
UI.Primitives.Models.fs|true|5248386907853845142|Xg+kHTuBGmrGI+VPs+fxxg==
UI.Primitives.fs|false|5248386911255020241|UFMna2zg1WyPK184737ovg==
UI.Primitives.Simple.fs|false|5248386911255010248|2Gbk4JHWHDJFZltVuI19Fg==
UI.Primitives.Simple.fs|false|5248390425986911176|SVEmF6FuthZhQWXGoa6B2g==
TrafoControls\TrafoModel.fs|true|5248386907853835154|bP/X3ZlGSRkCxOYHiZUdwg==
TrafoControls\TrafoController.fs|false|5248386907853835154|zdQPTYADImEgV0pQYBE1qQ==
TrafoControls\TranslationController.fs|false|5248386907853845142|pdX41+39G9VhY4ZiO8AdeA==
Expand All @@ -10,9 +10,9 @@ TrafoControls\ScaleController.fs|false|5248386907853825164|oGOtQHhHJwP3a9jCbnZk0
Animation\Model.fs|true|5248386907853785196|/DlehXwK9E7Sd6oSCdUp/w==
Animation\AnimationBase.fs|false|5248386907853775205|x4QuUzVnVgihIy+RGZMyAw==
IntegrationHelpers.fs|false|5248389812481980355|UqKLKqNZS2kEKhtWYbv4PA==
CameraModel.fs|true|5248389830275978180|HDuR0dljajvedQWO4/dXaQ==
FreeFlyController.fs|false|5248390352188003333|Zjm1x5fWV3278Q9KlexxzA==
ArcBallController.fs|false|5248389838880431248|BbxrJ4/y1nfHzEjQhRC1XQ==
LegacyCameraController.fs|false|5248390348764716654|nkSkwBXeTnkIM6pVfcVktw==
CameraModel.fs|true|5248390428855377681|ubzL2ea9VZH6S0oVakMeYg==
FreeFlyController.fs|false|5248390429112671103|hVHYalCnON9dZO+Jb1xPWQ==
ArcBallController.fs|false|5248390368153606147|vty5QTRvREJUZCqEfdOcfA==
LegacyCameraController.fs|false|5248390368805093220|TJ3wKlZusYK+il7fpOu0yQ==
Docking.fs|false|5248390348764576776|RoFRTVp6yIQM7o66oPwWOg==
OpenDialog.fs|false|5248386907853815291|J4330PV6MSGl8s15tzyikA==
3 changes: 3 additions & 0 deletions src/Aardvark.UI.Primitives/ArcBallController.fs
Expand Up @@ -59,6 +59,9 @@ module ArcBallController =
targetPan = V2d.Zero
targetDolly = 0.0
panSpeed = 0.0
targetZoom = 0.0

freeFlyConfig = FreeFlyConfig.initial
}

let sw = Diagnostics.Stopwatch()
Expand Down
51 changes: 49 additions & 2 deletions src/Aardvark.UI.Primitives/CameraModel.fs
Expand Up @@ -4,6 +4,50 @@ open Aardvark.Base
open Aardvark.Base.Incremental
open Aardvark.Application

[<DomainType>]
type FreeFlyConfig =
{
lookAtMouseSensitivity : float
lookAtConstant : float
lookAtDamping : float

panMouseSensitivity : float
panConstant : float
panDamping : float

dollyMouseSensitivity : float
dollyConstant : float
dollyDamping : float

zoomMouseWheelSensitivity : float
zoomConstant : float
zoomDamping : float

moveSensitivity : float
}

module FreeFlyConfig =
let initial = {
lookAtMouseSensitivity = 0.01
lookAtConstant = 0.1
lookAtDamping = 30.0

panMouseSensitivity = 0.05
panConstant = 0.01
panDamping = 3.0

dollyMouseSensitivity = 0.175
dollyConstant = 0.05
dollyDamping = 3.25

zoomMouseWheelSensitivity = 1.5
zoomConstant = 0.05
zoomDamping = 3.25

moveSensitivity = 1.0
}



[<DomainType>]
type CameraControllerState =
Expand All @@ -16,6 +60,8 @@ type CameraControllerState =
zoom : bool
pan : bool
dolly : bool
isWheel : bool
scrolling : bool

forward : bool
backward : bool
Expand All @@ -26,20 +72,21 @@ type CameraControllerState =
panSpeed : float
orbitCenter : Option<V3d>
lastTime : Option<float>
isWheel : bool

animating : bool

sensitivity : float
scrollSensitivity : float
scrolling : bool
zoomFactor : float
panFactor : float
rotationFactor : float

targetPhiTheta : V2d
targetPan : V2d
targetDolly : float
targetZoom : float

freeFlyConfig : FreeFlyConfig

[<TreatAsValue>]
stash : Option<CameraControllerState>
Expand Down
199 changes: 181 additions & 18 deletions src/Aardvark.UI.Primitives/CameraModel.g.fs

Large diffs are not rendered by default.

69 changes: 44 additions & 25 deletions src/Aardvark.UI.Primitives/FreeFlyController.fs
Expand Up @@ -16,8 +16,8 @@ open Aardvark.UI.Primitives
module FreeFlyController =
open Aardvark.Base.Incremental.Operators

type CameraMotion = { dPos : V3d; dRot : V3d; dMoveSpeed : float; dPanSpeed : float; dPan : V2d; dDolly : float } with
static member Zero = { dPos = V3d.Zero; dRot = V3d.Zero; dMoveSpeed = 0.0; dPanSpeed = 0.0; dPan = V2d.Zero; dDolly = 0.0 }
type CameraMotion = { dPos : V3d; dRot : V3d; dMoveSpeed : float; dZoom : float; dPan : V2d; dDolly : float } with
static member Zero = { dPos = V3d.Zero; dRot = V3d.Zero; dMoveSpeed = 0.0; dZoom = 0.0; dPan = V2d.Zero; dDolly = 0.0 }

static member (+) (cam : CameraView, motion : CameraMotion) =
let cam =
Expand All @@ -40,6 +40,12 @@ module FreeFlyController =
cam.Location +
motion.dDolly * cam.Forward
)

let cam =
cam.WithLocation(
cam.Location +
motion.dZoom * cam.Forward
)

let cam =
let trafo =
Expand All @@ -63,19 +69,19 @@ module FreeFlyController =
dPos = l.dPos + trafo.TransformDir r.dPos
dRot = l.dRot + r.dRot
dMoveSpeed = l.dMoveSpeed + r.dMoveSpeed
dPanSpeed = l.dPanSpeed + r.dPanSpeed
dZoom = l.dZoom + r.dZoom
dPan = l.dPan + r.dPan
dDolly = l.dDolly + r.dDolly
}

static member (*) (motion : CameraMotion, f : float) =
{ dPos = motion.dPos * f; dRot = motion.dRot * f; dMoveSpeed = motion.dMoveSpeed * f; dPanSpeed = motion.dPanSpeed * f; dPan = motion.dPan * f; dDolly = motion.dDolly * f}
{ dPos = motion.dPos * f; dRot = motion.dRot * f; dMoveSpeed = motion.dMoveSpeed * f; dZoom = motion.dZoom * f; dPan = motion.dPan * f; dDolly = motion.dDolly * f}

static member (*) (f : float, motion : CameraMotion) = motion * f


static member Move(dPos : V3d) = { dPos = dPos; dRot = V3d.Zero; dMoveSpeed = 0.0; dPanSpeed = 0.0; dPan = V2d.Zero; dDolly = 0.0 }
static member Rotate(dRot : V3d) = { dPos = V3d.Zero; dRot = dRot; dMoveSpeed = 0.0; dPanSpeed = 0.0; dPan = V2d.Zero; dDolly = 0.0 }
static member Move(dPos : V3d) = { dPos = dPos; dRot = V3d.Zero; dMoveSpeed = 0.0; dZoom = 0.0; dPan = V2d.Zero; dDolly = 0.0 }
static member Rotate(dRot : V3d) = { dPos = V3d.Zero; dRot = dRot; dMoveSpeed = 0.0; dZoom = 0.0; dPan = V2d.Zero; dDolly = 0.0 }


static member (+) (state : CameraControllerState, motion : CameraMotion) =
Expand All @@ -96,7 +102,7 @@ module FreeFlyController =
view = state.view + motion
moveSpeed = state.moveSpeed + motion.dMoveSpeed
targetPhiTheta = state.targetPhiTheta - V2d(motion.dRot.Y, motion.dRot.X)
panSpeed = state.panSpeed - motion.dPanSpeed
targetZoom = state.targetZoom - motion.dZoom
targetPan = state.targetPan - motion.dPan
targetDolly = state.targetDolly - motion.dDolly
}
Expand All @@ -106,10 +112,11 @@ module FreeFlyController =
| Up of button : MouseButtons
| Wheel of V2d
| Move of V2i
| StepTime
| KeyDown of key : Keys
| KeyUp of key : Keys
| Blur
| Interpolate
| Rendered

let initial =
{
Expand All @@ -134,7 +141,10 @@ module FreeFlyController =
scrollSensitivity = 0.8
scrolling = false

freeFlyConfig = FreeFlyConfig.initial

targetPhiTheta = V2d.Zero
targetZoom = 0.0
targetDolly = 0.0
animating = false
targetPan = V2d.Zero
Expand Down Expand Up @@ -176,6 +186,8 @@ module FreeFlyController =

let update (model : CameraControllerState) (message : Message) =
match message with
| Rendered ->
if model.animating then dummyChange model else model
| Blur ->
{ model with
lastTime = None
Expand All @@ -184,7 +196,7 @@ module FreeFlyController =
look = false; zoom = false; pan = false
forward = false; backward = false; left = false; right = false
}
| StepTime ->
| Interpolate ->
let now = sw.Elapsed.TotalSeconds

let clampAbs (maxAbs : float) (v : float) =
Expand All @@ -196,15 +208,15 @@ module FreeFlyController =
let move (state : CameraControllerState) =
if state.moveVec <> V3i.Zero then
{ CameraMotion.Zero with
dPos = V3d state.moveVec * exp state.sensitivity
dPos = V3d state.moveVec * exp state.freeFlyConfig.moveSensitivity
}
else
CameraMotion.Zero

let pan (state : CameraControllerState) =
if state.targetPan.Length > 0.05 then
let tt = (0.01 + abs state.targetPan.X * exp (state.sensitivity * 3.0)) * float (sign state.targetPan.X)
let tu = (0.01 + abs state.targetPan.Y * exp (state.sensitivity * 3.0)) * float (sign state.targetPan.Y)
let tt = (state.freeFlyConfig.panConstant + abs state.targetPan.X * exp (state.freeFlyConfig.panDamping )) * float (sign state.targetPan.X)
let tu = (state.freeFlyConfig.panConstant + abs state.targetPan.Y * exp (state.freeFlyConfig.panDamping )) * float (sign state.targetPan.Y)
{ CameraMotion.Zero with
dPan = V2d(tt,tu)
}
Expand All @@ -213,18 +225,27 @@ module FreeFlyController =

let dolly (state : CameraControllerState) =
if abs state.targetDolly > 0.05 then
let dd = (0.05 + abs state.targetDolly * exp (state.sensitivity * 3.25)) * float (sign state.targetDolly)
let dd = (state.freeFlyConfig.dollyConstant + abs state.targetDolly * exp (state.freeFlyConfig.dollyDamping )) * float (sign state.targetDolly)
{ CameraMotion.Zero with
dDolly = dd
}
else
CameraMotion.Zero

let zoom (state : CameraControllerState) =
if abs state.targetZoom > 0.05 then
let dd = (state.freeFlyConfig.zoomConstant + abs state.targetZoom * exp (state.freeFlyConfig.zoomDamping )) * float (sign state.targetZoom)
{ CameraMotion.Zero with
dZoom = dd
}
else
CameraMotion.Zero

let look (state : CameraControllerState) =
if state.targetPhiTheta <> V2d.Zero then

let rr = (0.1 + abs state.targetPhiTheta.Y * 30.0) * float (sign (state.targetPhiTheta.Y))
let ru = (0.1 + abs state.targetPhiTheta.X * 30.0) * float (sign (state.targetPhiTheta.X))
let rr = (state.freeFlyConfig.lookAtConstant + abs state.targetPhiTheta.Y * state.freeFlyConfig.lookAtDamping) * float (sign (state.targetPhiTheta.Y))
let ru = (state.freeFlyConfig.lookAtConstant + abs state.targetPhiTheta.X * state.freeFlyConfig.lookAtDamping) * float (sign (state.targetPhiTheta.X))

{ CameraMotion.Zero with
dRot = V3d(rr, ru, 0.0)
Expand All @@ -236,14 +257,14 @@ module FreeFlyController =
match model.lastTime with
| Some last ->
let dt = now - last
let step = Integrator.rungeKutta (fun t s -> move s + look s + pan s + dolly s)
let step = Integrator.rungeKutta (fun t s -> move s + look s + pan s + dolly s + zoom s)

Integrator.integrate 0.0166666 step model dt

| None ->
model

if model.moveVec = V3i.Zero && model.targetPhiTheta = V2d.Zero && (model.targetPan.Length <= 0.05) && (abs model.targetDolly <= 0.05) then
if model.moveVec = V3i.Zero && model.targetPhiTheta = V2d.Zero && (model.targetPan.Length <= 0.05) && (abs model.targetDolly <= 0.05) && (abs model.targetZoom <= 0.05) then
stopAnimation model
else
{ model with lastTime = Some now; }
Expand Down Expand Up @@ -275,7 +296,7 @@ module FreeFlyController =
| Wheel delta ->
startAnimation
{ model with
targetDolly = model.targetDolly + (float delta.Y) * 1.5
targetZoom = model.targetZoom + (float delta.Y) * model.freeFlyConfig.zoomMouseWheelSensitivity
}

| KeyDown Keys.A ->
Expand Down Expand Up @@ -322,14 +343,10 @@ module FreeFlyController =

| Move pos ->
let delta = pos - model.dragStart

//let trafo =
// M44d.Rotation(cam.Right, float delta.Y * -model.rotationFactor) *
// M44d.Rotation(cam.Sky, float delta.X * -model.rotationFactor)

let look model =
if model.look then
let deltaAngle = V2d(float delta.X * -model.rotationFactor, float delta.Y * -model.rotationFactor)
let deltaAngle = V2d(float delta.X * -model.freeFlyConfig.lookAtMouseSensitivity, float delta.Y * -model.freeFlyConfig.lookAtMouseSensitivity)

startAnimation
{ model with
Expand All @@ -342,7 +359,7 @@ module FreeFlyController =
if model.pan then
startAnimation
{ model with
targetPan = model.targetPan + (V2d(delta.X,-delta.Y)) * 0.05
targetPan = model.targetPan + (V2d(delta.X,-delta.Y)) * model.freeFlyConfig.panMouseSensitivity
dragStart = pos
}
else
Expand All @@ -352,7 +369,7 @@ module FreeFlyController =
if model.dolly then
startAnimation
{ model with
targetDolly = model.targetDolly + (float -delta.Y) * 0.0175
targetDolly = model.targetDolly + (float -delta.Y) * model.freeFlyConfig.dollyMouseSensitivity
dragStart = pos
}
else
Expand All @@ -377,6 +394,8 @@ module FreeFlyController =
always (onKeyUp (KeyUp >> f))
always (onWheel(fun x -> f (Wheel x)))
onlyWhen (state.look %|| state.pan %|| state.dolly %|| state.zoom) (onMouseMove (Move >> f))
always (onEvent "preRender" [] (fun _ -> f Interpolate))
onlyWhen state.animating (onEvent "onRendered" [] (fun _ -> f Rendered))
]

let extractAttributes (state : MCameraControllerState) (f : Message -> 'msg) =
Expand Down
3 changes: 2 additions & 1 deletion src/Aardvark.UI.Primitives/LegacyCameraController.fs
Expand Up @@ -56,6 +56,8 @@ module CameraController =
animating = false
targetPan = V2d.Zero
panSpeed = 0.0
targetZoom = 0.0
freeFlyConfig = FreeFlyConfig.initial
}

let initial' (dist:float) =
Expand Down Expand Up @@ -287,7 +289,6 @@ module CameraController =
]


[<Obsolete("CameraController module is deprecated. Use much smoother FreeFlyController instead.")>]
let threads (state : CameraControllerState) =
let pool = ThreadPool.empty

Expand Down

0 comments on commit 6205c48

Please sign in to comment.