Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
Visitlab
Chromatin
chromoskein
Commits
8bccaed5
Commit
8bccaed5
authored
Mar 14, 2022
by
David Kouřil
Browse files
refactor smooth camera
should also fix the rotation
parent
7a42fb37
Changes
1
Hide whitespace changes
Inline
Side-by-side
libs/graphics/src/cameras/smooth.ts
View file @
8bccaed5
...
...
@@ -11,6 +11,30 @@ function deg_to_rad(degrees: number): number {
function
easeOutExp
(
t
:
number
):
number
{
return
-
Math
.
pow
(
2
,
-
10
*
t
)
+
1
;
}
//~ LOL, these definitions are useless actually...
type
OrbitingParams
=
{
currentLerpTime
:
number
;
lastFrameAngleX
:
number
;
lastFrameAngleY
:
number
;
endAngleY
:
number
;
endAngleX
:
number
;
pivot
:
vec3
;
}
type
ZoomingParams
=
{
currentLerpTime
:
number
;
endAmount
:
number
;
lastFrameZoomAmount
:
number
;
}
type
PanningParams
=
{
currentLerpTime
:
number
;
startPosition
:
vec3
;
endPosition
:
vec3
;
lastFramePosition
:
vec3
;
}
export
class
SmoothCamera
extends
Camera
{
private
currentMousePos
=
{
x
:
0
,
y
:
0
};
private
lastMousePos
=
{
x
:
0
,
y
:
0
};
...
...
@@ -22,32 +46,39 @@ export class SmoothCamera extends Camera {
//~ general
animTime
=
1000.0
;
zoomToCursor
=
false
;
//~ orbiting
orbitCurrentLerpTime
=
0
;
orbitLastFrameAngleX
=
0
;
orbitLastFrameAngleY
=
0
;
orbitEndAngleY
=
0
;
orbitEndAngleX
=
0
;
orbitingSpeed
=
0.5
;
orbitingPivot
=
vec3
.
fromValues
(
0
,
0
,
0
);
//~ zooming
zoomCurrentLerpTime
=
0.0
;
zoomEndAmount
=
0.0
;
lastFrameZoomAmount
=
0.0
;
scrollingSpeed
=
0.0015
;
//~ panning
panStartPosition
=
vec3
.
fromValues
(
0
,
0
,
0
);
lastFramePosition
=
vec3
.
fromValues
(
0
,
0
,
0
);
panEndPosition
=
vec3
.
fromValues
(
0
,
0
,
0
);
panCurrentLerpTime
=
0.0
;
zoomingSpeed
=
0.0015
;
panningSpeed
=
0.005
;
//~ orbiting params
orbiting
:
OrbitingParams
=
{
currentLerpTime
:
0
,
lastFrameAngleX
:
0
,
lastFrameAngleY
:
0
,
endAngleY
:
0
,
endAngleX
:
0
,
pivot
:
vec3
.
fromValues
(
0
,
0
,
0
)
}
//~ zooming params
zooming
:
ZoomingParams
=
{
currentLerpTime
:
0.0
,
endAmount
:
0.0
,
lastFrameZoomAmount
:
0.0
,
}
//~ panning params
panning
:
PanningParams
=
{
currentLerpTime
:
0.0
,
startPosition
:
vec3
.
fromValues
(
0
,
0
,
0
),
endPosition
:
vec3
.
fromValues
(
0
,
0
,
0
),
lastFramePosition
:
vec3
.
fromValues
(
0
,
0
,
0
),
}
constructor
(
device
:
GPUDevice
,
width
:
number
,
height
:
number
,
near
=
0.01
,
fieldOfView
=
45.0
)
{
super
(
device
,
width
,
height
,
near
,
fieldOfView
);
this
.
updateCPU
(
0
);
}
...
...
@@ -58,20 +89,20 @@ export class SmoothCamera extends Camera {
this
.
updateOrbiting
(
dt
);
this
.
updatePanning
(
dt
);
const
mvm
=
this
.
computeModelViewMatrix
(
this
.
position
,
this
.
orbiting
P
ivot
);
const
mvm
=
this
.
computeModelViewMatrix
(
this
.
position
,
this
.
orbiting
.
p
ivot
);
mat4
.
copy
(
this
.
_viewMatrix
,
mvm
);
super
.
updateCPU
(
dt
);
}
protected
updateZooming
(
dt
:
number
):
void
{
this
.
zoom
C
urrentLerpTime
+=
dt
;
if
(
this
.
zoom
C
urrentLerpTime
>
this
.
animTime
)
this
.
zoom
C
urrentLerpTime
=
this
.
animTime
;
const
perc
=
this
.
zoom
C
urrentLerpTime
/
this
.
animTime
;
this
.
zoom
ing
.
c
urrentLerpTime
+=
dt
;
if
(
this
.
zoom
ing
.
c
urrentLerpTime
>
this
.
animTime
)
this
.
zoom
ing
.
c
urrentLerpTime
=
this
.
animTime
;
const
perc
=
this
.
zoom
ing
.
c
urrentLerpTime
/
this
.
animTime
;
const
currentZoom
=
this
.
lerpNumber
(
0.0
,
this
.
zoom
E
ndAmount
,
easeOutExp
(
perc
));
const
change
=
currentZoom
-
this
.
lastFrameZoomAmount
;
this
.
lastFrameZoomAmount
=
currentZoom
;
const
currentZoom
=
this
.
lerpNumber
(
0.0
,
this
.
zoom
ing
.
e
ndAmount
,
easeOutExp
(
perc
));
const
change
=
currentZoom
-
this
.
zooming
.
lastFrameZoomAmount
;
this
.
zooming
.
lastFrameZoomAmount
=
currentZoom
;
if
(
!
this
.
zoomToCursor
)
{
//~ zoom in => move the camera by the current frame change
...
...
@@ -115,35 +146,37 @@ export class SmoothCamera extends Camera {
//~ move camera by offset
vec3
.
sub
(
this
.
position
,
this
.
position
,
offset
);
vec3
.
sub
(
this
.
orbiting
P
ivot
,
this
.
orbiting
P
ivot
,
offset
);
vec3
.
sub
(
this
.
orbiting
.
p
ivot
,
this
.
orbiting
.
p
ivot
,
offset
);
}
protected
updateOrbiting
(
dt
:
number
):
void
{
this
.
orbit
C
urrentLerpTime
+=
dt
;
if
(
this
.
orbit
C
urrentLerpTime
>
this
.
animTime
)
this
.
orbit
C
urrentLerpTime
=
this
.
animTime
;
const
perc
=
this
.
orbit
C
urrentLerpTime
/
this
.
animTime
;
this
.
orbit
ing
.
c
urrentLerpTime
+=
dt
;
if
(
this
.
orbit
ing
.
c
urrentLerpTime
>
this
.
animTime
)
this
.
orbit
ing
.
c
urrentLerpTime
=
this
.
animTime
;
const
perc
=
this
.
orbit
ing
.
c
urrentLerpTime
/
this
.
animTime
;
const
currentAngleX
=
this
.
lerpNumber
(
0.0
,
this
.
orbit
E
ndAngleX
,
easeOutExp
(
perc
));
const
currentAngleY
=
this
.
lerpNumber
(
0.0
,
this
.
orbit
E
ndAngleY
,
easeOutExp
(
perc
));
const
currentAngleX
=
this
.
lerpNumber
(
0.0
,
this
.
orbit
ing
.
e
ndAngleX
,
easeOutExp
(
perc
));
const
currentAngleY
=
this
.
lerpNumber
(
0.0
,
this
.
orbit
ing
.
e
ndAngleY
,
easeOutExp
(
perc
));
const
rotIncrementX
=
currentAngleX
-
this
.
orbit
L
astFrameAngleX
;
const
rotIncrementY
=
currentAngleY
-
this
.
orbit
L
astFrameAngleY
;
this
.
orbit
L
astFrameAngleX
=
currentAngleX
;
this
.
orbit
L
astFrameAngleY
=
currentAngleY
;
const
rotIncrementX
=
currentAngleX
-
this
.
orbit
ing
.
l
astFrameAngleX
;
const
rotIncrementY
=
currentAngleY
-
this
.
orbit
ing
.
l
astFrameAngleY
;
this
.
orbit
ing
.
l
astFrameAngleX
=
currentAngleX
;
this
.
orbit
ing
.
l
astFrameAngleY
=
currentAngleY
;
const
horizRot
=
quat
.
create
();
quat
.
setAxisAngle
(
horizRot
,
this
.
up
(),
deg_to_rad
(
-
rotIncrementY
));
// quat.setAxisAngle(horizRot, this.up(), deg_to_rad(-rotIncrementY));
quat
.
setAxisAngle
(
horizRot
,
vec3
.
fromValues
(
0
,
1
,
0
),
deg_to_rad
(
-
rotIncrementY
));
const
vertRot
=
quat
.
create
();
quat
.
setAxisAngle
(
vertRot
,
this
.
right
(),
deg_to_rad
(
rotIncrementX
));
// quat.setAxisAngle(vertRot, this.right(), deg_to_rad(rotIncrementX));
quat
.
setAxisAngle
(
vertRot
,
vec3
.
fromValues
(
1
,
0
,
0
),
deg_to_rad
(
rotIncrementX
));
const
newRot
=
quat
.
create
();
quat
.
mul
(
newRot
,
horizRot
,
vertRot
);
const
v
=
vec3
.
create
();
vec3
.
sub
(
v
,
this
.
position
,
this
.
orbiting
P
ivot
);
vec3
.
sub
(
v
,
this
.
position
,
this
.
orbiting
.
p
ivot
);
const
newPos
=
vec3
.
create
();
const
shift
=
vec3
.
create
();
vec3
.
transformQuat
(
shift
,
v
,
newRot
);
vec3
.
add
(
newPos
,
this
.
orbiting
P
ivot
,
shift
);
vec3
.
add
(
newPos
,
this
.
orbiting
.
p
ivot
,
shift
);
vec3
.
copy
(
this
.
position
,
newPos
);
quat
.
mul
(
this
.
rotation
,
newRot
,
this
.
rotation
);
...
...
@@ -153,19 +186,19 @@ export class SmoothCamera extends Camera {
}
protected
updatePanning
(
dt
:
number
):
void
{
this
.
pan
C
urrentLerpTime
+=
dt
;
if
(
this
.
pan
C
urrentLerpTime
>
this
.
animTime
)
this
.
pan
C
urrentLerpTime
=
this
.
animTime
;
const
perc
=
this
.
pan
C
urrentLerpTime
/
this
.
animTime
;
this
.
pan
ning
.
c
urrentLerpTime
+=
dt
;
if
(
this
.
pan
ning
.
c
urrentLerpTime
>
this
.
animTime
)
this
.
pan
ning
.
c
urrentLerpTime
=
this
.
animTime
;
const
perc
=
this
.
pan
ning
.
c
urrentLerpTime
/
this
.
animTime
;
const
currentFramePosition
=
vec3
.
create
();
vec3
.
lerp
(
currentFramePosition
,
this
.
pan
S
tartPosition
,
this
.
pan
E
ndPosition
,
easeOutExp
(
perc
));
vec3
.
lerp
(
currentFramePosition
,
this
.
pan
ning
.
s
tartPosition
,
this
.
pan
ning
.
e
ndPosition
,
easeOutExp
(
perc
));
const
frameOffset
=
vec3
.
create
();
vec3
.
sub
(
frameOffset
,
currentFramePosition
,
this
.
lastFramePosition
);
vec3
.
copy
(
this
.
lastFramePosition
,
currentFramePosition
);
vec3
.
sub
(
frameOffset
,
currentFramePosition
,
this
.
panning
.
lastFramePosition
);
vec3
.
copy
(
this
.
panning
.
lastFramePosition
,
currentFramePosition
);
vec3
.
add
(
this
.
position
,
this
.
position
,
frameOffset
);
//~ Seems like I should also add this, otherwise orbiting will be weird...
vec3
.
add
(
this
.
orbiting
P
ivot
,
this
.
orbiting
P
ivot
,
frameOffset
);
vec3
.
add
(
this
.
orbiting
.
p
ivot
,
this
.
orbiting
.
p
ivot
,
frameOffset
);
this
.
isMoving
=
this
.
isMoving
||
(
perc
<
1.0
);
...
...
@@ -178,7 +211,7 @@ export class SmoothCamera extends Camera {
type
:
CameraConfigurationType
.
Smooth
,
position
:
{
x
:
this
.
position
[
0
],
y
:
this
.
position
[
1
],
z
:
this
.
position
[
2
]
},
lookAtPosition
:
{
x
:
this
.
orbiting
P
ivot
[
0
],
y
:
this
.
orbiting
P
ivot
[
1
],
z
:
this
.
orbiting
P
ivot
[
2
]
},
lookAtPosition
:
{
x
:
this
.
orbiting
.
p
ivot
[
0
],
y
:
this
.
orbiting
.
p
ivot
[
1
],
z
:
this
.
orbiting
.
p
ivot
[
2
]
},
rotationQuat
:
{
x
:
this
.
rotation
[
0
],
y
:
this
.
rotation
[
1
],
z
:
this
.
rotation
[
2
],
w
:
this
.
rotation
[
3
]
}
};
}
...
...
@@ -198,6 +231,14 @@ export class SmoothCamera extends Camera {
public
get
rotation
():
quat
{
return
this
.
_rotation
;
}
public
get
orbitingPivot
():
vec3
{
return
this
.
orbiting
.
pivot
;
}
public
set
orbitingPivot
(
pivot
:
vec3
)
{
this
.
orbiting
.
pivot
=
pivot
;
}
//#endregion
protected
computeModelViewMatrix
(
camPosition
:
vec3
,
lookAtPosition
:
vec3
):
mat4
{
...
...
@@ -209,7 +250,7 @@ export class SmoothCamera extends Camera {
protected
getModelViewMatrix
():
mat4
{
let
mvm
=
mat4
.
create
();
mvm
=
this
.
computeModelViewMatrix
(
this
.
position
,
this
.
orbiting
P
ivot
);
mvm
=
this
.
computeModelViewMatrix
(
this
.
position
,
this
.
orbiting
.
p
ivot
);
return
mvm
;
}
...
...
@@ -255,11 +296,11 @@ export class SmoothCamera extends Camera {
this
.
dragging
=
true
;
}
this
.
orbit
C
urrentLerpTime
=
0.0
;
this
.
orbit
L
astFrameAngleX
=
0.0
;
this
.
orbit
L
astFrameAngleY
=
0.0
;
this
.
orbit
E
ndAngleY
=
delta
.
x
*
this
.
orbitingSpeed
;
this
.
orbit
E
ndAngleX
=
delta
.
y
*
this
.
orbitingSpeed
;
this
.
orbit
ing
.
c
urrentLerpTime
=
0.0
;
this
.
orbit
ing
.
l
astFrameAngleX
=
0.0
;
this
.
orbit
ing
.
l
astFrameAngleY
=
0.0
;
this
.
orbit
ing
.
e
ndAngleY
=
delta
.
x
*
this
.
orbitingSpeed
;
this
.
orbit
ing
.
e
ndAngleX
=
delta
.
y
*
this
.
orbitingSpeed
;
this
.
lastMousePos
=
{
x
:
event
.
screenX
,
y
:
event
.
screenY
};
}
...
...
@@ -267,17 +308,17 @@ export class SmoothCamera extends Camera {
{
const
delta
=
{
x
:
event
.
screenX
-
this
.
lastMousePos
.
x
,
y
:
event
.
screenY
-
this
.
lastMousePos
.
y
};
vec3
.
copy
(
this
.
pan
S
tartPosition
,
this
.
position
);
vec3
.
copy
(
this
.
lastFramePosition
,
this
.
position
);
vec3
.
copy
(
this
.
pan
ning
.
s
tartPosition
,
this
.
position
);
vec3
.
copy
(
this
.
panning
.
lastFramePosition
,
this
.
position
);
vec3
.
copy
(
this
.
pan
E
ndPosition
,
this
.
position
);
vec3
.
copy
(
this
.
pan
ning
.
e
ndPosition
,
this
.
position
);
const
incrVec
=
vec3
.
create
();
vec3
.
scale
(
incrVec
,
this
.
up
(),
delta
.
y
*
this
.
panningSpeed
);
vec3
.
add
(
this
.
pan
E
ndPosition
,
this
.
pan
E
ndPosition
,
incrVec
);
vec3
.
add
(
this
.
pan
ning
.
e
ndPosition
,
this
.
pan
ning
.
e
ndPosition
,
incrVec
);
vec3
.
scale
(
incrVec
,
this
.
right
(),
delta
.
x
*
this
.
panningSpeed
);
vec3
.
add
(
this
.
pan
E
ndPosition
,
this
.
pan
E
ndPosition
,
incrVec
);
vec3
.
add
(
this
.
pan
ning
.
e
ndPosition
,
this
.
pan
ning
.
e
ndPosition
,
incrVec
);
this
.
pan
C
urrentLerpTime
=
0.0
;
this
.
pan
ning
.
c
urrentLerpTime
=
0.0
;
this
.
lastMousePos
=
{
x
:
event
.
screenX
,
y
:
event
.
screenY
};
}
...
...
@@ -308,11 +349,11 @@ export class SmoothCamera extends Camera {
if
(
this
.
ignoreEvents
)
return
;
const
speed
=
this
.
scroll
ingSpeed
;
const
speed
=
this
.
zoom
ingSpeed
;
this
.
zoom
E
ndAmount
=
event
.
deltaY
*
speed
;
this
.
lastFrameZoomAmount
=
0.0
;
this
.
zoom
C
urrentLerpTime
=
0.0
;
this
.
zoom
ing
.
e
ndAmount
=
event
.
deltaY
*
speed
;
this
.
zooming
.
lastFrameZoomAmount
=
0.0
;
this
.
zoom
ing
.
c
urrentLerpTime
=
0.0
;
this
.
currentMousePos
=
{
x
:
event
.
offsetX
,
y
:
event
.
offsetY
};
}
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment