Set the renderer's camera for the current view: keep the previous view's trackball state and restore (or reset) the current one's when the view changes, then set its world-to-view transform and projection.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(WindowProxy), | intent(inout), | target | :: | self |
subroutine place_camera(self) type(WindowProxy), intent(inout), target :: self type(View), pointer :: v, from class(ReferenceFrame), pointer :: root real(wp) :: eye(3), center(3), up(3), dist, near, far, bounds(4), cam(3,3), from_cam(3,3), duration logical :: have_target v => self%current_view() if (associated(v, self%default_view) .and. associated(self%scene)) then root => self%scene%frame() if (associated(root) .and. .not. self%default_view%is_valid()) call self%default_view%set_view_frame(root, root) end if ! the camera shown (to fly from), and the new one: a view changed to (its ! camera set, kept, or reset), a camera set, or a reset from => null() if (associated(self%shown)) then if (vkf_viewer_get_look_at(self%viewer_, from_cam(:, 1), from_cam(:, 2), from_cam(:, 3)) == 0) & from => self%shown end if duration = self%transition_ have_target = .false. if (.not. associated(v, self%shown)) then if (associated(from)) call from%save_state(from_cam(:, 1), from_cam(:, 2), from_cam(:, 3)) if (self%switch_duration >= 0.0_wp) duration = self%switch_duration self%switch_duration = -1.0_wp if (v%take_camera(cam)) then have_target = .true. else if (v%saved_state(eye, center, up)) then cam = reshape([eye, center, up], [3, 3]) have_target = .true. else call v%reset_view() end if self%shown => v else if (v%take_camera(cam)) then have_target = .true. duration = 0.0_wp ! (View%set_camera: at once) end if if (v%take_reset()) then call v%home(aspect_ratio(self), eye, center, up) cam = reshape([eye, center, up], [3, 3]) have_target = .true. end if if (have_target) then if (associated(from) .and. duration > 0.0_wp) then call start_flight(self, from, from_cam, v, cam, duration) else self%flight%active = .false. call put_camera(self, cam) end if end if call fly(self, v) if (vkf_viewer_set_view_transform(self%viewer_, v%world_to_view()) /= 0) & write(*, '(a)') 'vkframes: could not set the view' ! near and far planes from the camera's distance to its center (reverse-Z ! float depth covers the wide ratio) if (vkf_viewer_get_look_at(self%viewer_, eye, center, up) /= 0) return dist = max(norm2(eye - center), tiny(1.0_wp)) near = 1.0e-6_wp * dist far = 1.0e9_wp * dist if (v%projection_type() == PERSPECTIVE) then if (vkf_viewer_perspective(self%viewer_, v%field_of_view(), near, far) /= 0) & write(*, '(a)') 'vkframes: could not set the projection' else bounds = v%orthographic_bounds() if (vkf_viewer_orthographic(self%viewer_, bounds(1), bounds(2), bounds(3), bounds(4), -far, far) /= 0) & write(*, '(a)') 'vkframes: could not set the projection' end if end subroutine place_camera