Set the camera of the current view: eye, center and up in the view
frame's coordinates (OpenFrames' trackball setTransformation), or in its
root frame's if in_root (as the frames are now). With duration (s),
fly there from the camera shown. Before the view is shown, it is its
camera when it is (set_camera).
Common views of a planet of radius re, shown by a View of its frame (so in
its coordinates: z is the north pole). up must not point along the view.
d = 3.0_wp * re ! the camera's distance
center = [0.0_wp, 0.0_wp, 0.0_wp] ! looking at the planet's center
! from the side, over the equator (as the default view: looking along +y)
call window%set_camera([0.0_wp, -d, 0.0_wp], center, [0.0_wp, 0.0_wp, 1.0_wp])
! from above the north pole (+y up on the screen); from below the south pole
call window%set_camera([0.0_wp, 0.0_wp, d], center, [0.0_wp, 1.0_wp, 0.0_wp])
call window%set_camera([0.0_wp, 0.0_wp, -d], center, [0.0_wp, 1.0_wp, 0.0_wp])
! over a latitude and longitude, flying there in 2 s
lat = 30.0_wp * pi / 180.0_wp
lon = 45.0_wp * pi / 180.0_wp
call window%set_camera(d * [cos(lat) * cos(lon), cos(lat) * sin(lon), sin(lat)], center, &
[0.0_wp, 0.0_wp, 1.0_wp], duration=2.0_wp)
! zoom in: half the distance, the same direction
call window%get_camera(eye, center, up)
call window%set_camera(center + 0.5_wp * (eye - center), center, up)
! in the root frame's coordinates, whatever frame the view follows
call window%set_camera([0.0_wp, 0.0_wp, 4.0_wp * re], [0.0_wp, 0.0_wp, 0.0_wp], &
[1.0_wp, 0.0_wp, 0.0_wp], in_root=.true.)
A chase camera, in a View of a spacecraft's frame (its body axes): behind it (along -x) and a little above, looking at it.
call window%set_camera([-1000.0_wp, 0.0_wp, 300.0_wp], [0.0_wp, 0.0_wp, 0.0_wp], &
[0.0_wp, 0.0_wp, 1.0_wp])
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(WindowProxy), | intent(inout), | target | :: | self | ||
| real(kind=wp), | intent(in) | :: | eye(3) |
view frame's coordinates (or root's) |
||
| real(kind=wp), | intent(in) | :: | center(3) |
view frame's coordinates (or root's) |
||
| real(kind=wp), | intent(in) | :: | up(3) |
view frame's coordinates (or root's) |
||
| real(kind=wp), | intent(in), | optional | :: | duration |
s (default: at once) |
|
| logical, | intent(in), | optional | :: | in_root |
true: eye, center and up are in the root frame's coordinates |
subroutine set_camera(self, eye, center, up, duration, in_root) class(WindowProxy), intent(inout), target :: self real(wp), intent(in) :: eye(3), center(3), up(3) !! view frame's coordinates (or root's) real(wp), intent(in), optional :: duration !! s (default: at once) logical, intent(in), optional :: in_root !! true: eye, center and up are in the root frame's coordinates type(View), pointer :: v real(wp) :: cam(3,3), now(3,3) logical :: root v => self%current_view() cam = reshape([eye, center, up], [3, 3]) root = .false. if (present(in_root)) root = in_root if (root) cam = transform_camera(v%world_to_view(), cam) if (.not. self%is_open() .or. .not. associated(self%shown, v)) then call v%set_camera(cam(:, 1), cam(:, 2), cam(:, 3)) return end if if (present(duration)) then if (duration > 0.0_wp .and. vkf_viewer_get_look_at(self%viewer_, now(:, 1), now(:, 2), now(:, 3)) == 0) then call start_flight(self, v, now, v, cam, duration) return end if end if self%flight%active = .false. call put_camera(self, cam) end subroutine set_camera