constrained Function

private function constrained(self, origin, dir, m, h) result(ok)

Where the ray (origin, unit dir; root frame) meets the constraint taken at the grab, the frame at transform m to the root: h, in the frame's coordinates. False if it doesn't.

Arguments

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

the cursor's ray: its origin (root frame)

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

its direction (a unit vector)

real(kind=wp), intent(in) :: m(4,4)

the frame's transform to the root

real(kind=wp), intent(out) :: h(3)

where it meets the constraint (frame coordinates)

Return Value logical


Calls

proc~~constrained~~CallsGraph proc~constrained constrained proc~ray_line ray_line proc~constrained->proc~ray_line proc~ray_plane ray_plane proc~constrained->proc~ray_plane proc~ray_sphere ray_sphere proc~constrained->proc~ray_sphere

Called by

proc~~constrained~~CalledByGraph proc~constrained constrained proc~drag DragHandle%drag proc~drag->proc~constrained proc~grab DragHandle%grab proc~grab->proc~constrained proc~drag_handle drag_handle proc~drag_handle->proc~drag proc~grab_handle grab_handle proc~grab_handle->proc~grab proc~dispatch_event dispatch_event proc~dispatch_event->proc~drag_handle 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 constrained(self, origin, dir, m, h) result(ok)
        class(DragHandle), intent(in) :: self
        real(wp), intent(in) :: origin(3)                   !! the cursor's ray: its origin (root frame)
        real(wp), intent(in) :: dir(3)                      !! its direction (a unit vector)
        real(wp), intent(in) :: m(4,4)                      !! the frame's transform to the root
        real(wp), intent(out) :: h(3)                       !! where it meets the constraint (frame coordinates)
        real(wp) :: p(3), a(3), c(3), w(3), q(3), t, near, far
        c = m(1:3, 4)
        p = matmul(m(1:3, 1:3), self%ref_point) + c
        a = matmul(m(1:3, 1:3), self%ref_axis)
        h = self%ref_point
        select case (self%constraint_)
        case (HANDLE_FREE, HANDLE_PLANE)
            ok = ray_plane(origin, dir, p, a, t, w)
        case (HANDLE_LINE, HANDLE_RADIAL)
            ok = ray_line(origin, dir, p, a, t, w)
        case (HANDLE_SPHERE)
            ok = self%radius > 0.0_wp
            if (.not. ok) return
            if (ray_sphere(origin, dir, c, self%radius, near, far)) then
                t = near
                if (self%far_side .or. near < 0.0_wp) t = far
                w = origin + t * dir
            else                                            ! (missed: the edge nearest the ray)
                q = origin + max(0.0_wp, dot_product(c - origin, dir)) * dir
                ok = norm2(q - c) > 0.0_wp
                if (.not. ok) return
                w = c + self%radius * (q - c) / norm2(q - c)
            end if
        case default
            ok = .false.
        end select
        if (ok) h = matmul(transpose(m(1:3, 1:3)), w - c)
    end function constrained