grab Function

private function grab(self, origin, dir) result(ok)

Grab the handle with the cursor's ray (origin, unit dir; root frame): its constraint is taken as it is now, and the point's offset from where the ray meets it. False if it isn't draggable.

Type Bound

DragHandle

Arguments

Type IntentOptional Attributes Name
class(DragHandle), intent(inout) :: self
real(kind=wp), intent(in) :: origin(3)

the cursor's ray (root frame)

real(kind=wp), intent(in) :: dir(3)

the cursor's ray (root frame)

Return Value logical


Calls

proc~~grab~~CallsGraph proc~grab DragHandle%grab handle_point handle_point proc~grab->handle_point proc~constrained constrained proc~grab->proc~constrained proc~ray_sphere ray_sphere proc~grab->proc~ray_sphere proc~world_matrix ReferenceFrame%world_matrix proc~grab->proc~world_matrix show_state show_state proc~grab->show_state proc~constrained->proc~ray_sphere proc~ray_line ray_line proc~constrained->proc~ray_line proc~ray_plane ray_plane proc~constrained->proc~ray_plane 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~quat_to_matrix quat_to_matrix proc~frame_matrix->proc~quat_to_matrix

Called by

proc~~grab~~CalledByGraph proc~grab DragHandle%grab proc~grab_handle grab_handle proc~grab_handle->proc~grab proc~dispatch_event dispatch_event proc~dispatch_event->proc~grab_handle proc~dispatch_events dispatch_events proc~dispatch_events->proc~dispatch_event proc~frame WindowProxy%frame proc~frame->proc~dispatch_events proc~resize WindowProxy%resize proc~resize->proc~frame proc~run WindowProxy%run proc~run->proc~frame

Source Code

    logical function grab(self, origin, dir) result(ok)
        class(DragHandle), intent(inout) :: self
        real(wp), intent(in) :: origin(3), dir(3)           !! the cursor's ray (root frame)
        real(wp) :: m(4,4), p(3), h(3), near, far, c(3)
        ok = .false.
        if (.not. self%draggable_) return
        m = self%world_matrix()
        p = self%handle_point()
        self%ref_point = p
        self%ref_axis = self%axis_
        select case (self%constraint_)
        case (HANDLE_FREE)
            self%ref_axis = matmul(transpose(m(1:3, 1:3)), -dir)  ! (facing the camera, now)
        case (HANDLE_RADIAL)
            if (norm2(p) > 0.0_wp) self%ref_axis = p / norm2(p)
        case (HANDLE_SPHERE)
            self%radius = norm2(p)
            self%far_side = .false.
            c = m(1:3, 4)
            if (ray_sphere(origin, dir, c, self%radius, near, far)) &   ! (the side nearer the point)
                self%far_side = norm2(origin + far * dir - (matmul(m(1:3, 1:3), p) + c)) < &
                                norm2(origin + near * dir - (matmul(m(1:3, 1:3), p) + c))
        end select
        self%offset = 0.0_wp
        if (constrained(self, origin, dir, m, h)) self%offset = p - h
        self%dragged_ = .true.
        call self%show_state()
        ok = .true.
    end function grab