place_camera Subroutine

private subroutine place_camera(self)

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.

Arguments

Type IntentOptional Attributes Name
type(WindowProxy), intent(inout), target :: self

Calls

proc~~place_camera~~CallsGraph proc~place_camera place_camera interface~vkf_viewer_get_look_at vkf_viewer_get_look_at proc~place_camera->interface~vkf_viewer_get_look_at interface~vkf_viewer_orthographic vkf_viewer_orthographic proc~place_camera->interface~vkf_viewer_orthographic interface~vkf_viewer_perspective vkf_viewer_perspective proc~place_camera->interface~vkf_viewer_perspective interface~vkf_viewer_set_view_transform vkf_viewer_set_view_transform proc~place_camera->interface~vkf_viewer_set_view_transform proc~aspect_ratio aspect_ratio proc~place_camera->proc~aspect_ratio proc~current_view WindowProxy%current_view proc~place_camera->proc~current_view proc~field_of_view View%field_of_view proc~place_camera->proc~field_of_view proc~fly fly proc~place_camera->proc~fly proc~fm_frame FrameManager%fm_frame proc~place_camera->proc~fm_frame proc~home View%home proc~place_camera->proc~home proc~is_valid~2 View%is_valid proc~place_camera->proc~is_valid~2 proc~orthographic_bounds View%orthographic_bounds proc~place_camera->proc~orthographic_bounds proc~projection_type View%projection_type proc~place_camera->proc~projection_type proc~put_camera put_camera proc~place_camera->proc~put_camera proc~reset_view View%reset_view proc~place_camera->proc~reset_view proc~save_state View%save_state proc~place_camera->proc~save_state proc~saved_state View%saved_state proc~place_camera->proc~saved_state proc~set_view_frame View%set_view_frame proc~place_camera->proc~set_view_frame proc~start_flight start_flight proc~place_camera->proc~start_flight proc~take_camera View%take_camera proc~place_camera->proc~take_camera proc~take_reset View%take_reset proc~place_camera->proc~take_reset proc~world_to_view View%world_to_view proc~place_camera->proc~world_to_view interface~vkf_viewer_size vkf_viewer_size proc~aspect_ratio->interface~vkf_viewer_size proc~fly->proc~put_camera proc~fly->proc~world_to_view proc~camera_between camera_between proc~fly->proc~camera_between proc~rigid_inverse rigid_inverse proc~fly->proc~rigid_inverse proc~transform_camera transform_camera proc~fly->proc~transform_camera proc~window_wall window_wall proc~fly->proc~window_wall proc~home->proc~world_to_view proc~bound ReferenceFrame%bound proc~home->proc~bound proc~frame_to_root frame_to_root proc~home->proc~frame_to_root interface~vkf_viewer_look_at vkf_viewer_look_at proc~put_camera->interface~vkf_viewer_look_at proc~start_flight->proc~window_wall proc~world_to_view->proc~frame_to_root proc~identity_matrix identity_matrix proc~world_to_view->proc~identity_matrix proc~quat_from_vectors quat_from_vectors proc~world_to_view->proc~quat_from_vectors proc~quat_to_matrix quat_to_matrix proc~world_to_view->proc~quat_to_matrix proc~world_to_view->proc~rigid_inverse proc~rotated rotated proc~world_to_view->proc~rotated proc~translation_matrix translation_matrix proc~world_to_view->proc~translation_matrix proc~camera_between->proc~quat_to_matrix proc~camera_orientation camera_orientation proc~camera_between->proc~camera_orientation proc~quat_normalize quat_normalize proc~camera_between->proc~quat_normalize proc~quat_slerp quat_slerp proc~camera_between->proc~quat_slerp proc~frame_to_root->proc~rigid_inverse proc~world_matrix ReferenceFrame%world_matrix proc~frame_to_root->proc~world_matrix proc~cross cross proc~quat_from_vectors->proc~cross proc~quat_from_vectors->proc~quat_normalize proc~translation_matrix->proc~identity_matrix proc~wall_time wall_time proc~window_wall->proc~wall_time proc~camera_orientation->proc~cross proc~quat_from_matrix quat_from_matrix proc~camera_orientation->proc~quat_from_matrix proc~world_matrix->proc~world_matrix proc~local_matrix ReferenceFrame%local_matrix proc~world_matrix->proc~local_matrix proc~frame_matrix frame_matrix proc~local_matrix->proc~frame_matrix proc~frame_matrix->proc~quat_to_matrix

Called by

proc~~place_camera~~CalledByGraph proc~place_camera place_camera proc~frame WindowProxy%frame proc~frame->proc~place_camera proc~resize WindowProxy%resize proc~resize->proc~frame proc~run WindowProxy%run proc~run->proc~frame

Source Code

    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