vkf_pick Module

Picking geometry: what is under a point of a window (pick).

A PickCamera is the camera and the cursor of a pick, in the scene's root frame: the eye and its axes (right, up, forward), the projection, the viewport's size and the cursor's position (-1 to 1, y up, as the window's events). Frames test their contents against it (pick and its extensions): * points and line segments on the screen, within a tolerance in pixels (point_pick, segment_pick: the closest point of a segment, its fraction along the segment in the scene, perspective-correct, and its depth), for trajectories, markers and frames' origins; * a ray from the eye through the cursor against an ellipsoid (ray, ray_ellipsoid), for bodies; * the ray against a plane, a sphere and a line (ray_plane, ray_sphere, ray_line), for dragging (cursor_ray, and vkf_handles' constraints); * bounding spheres on the screen (sphere_near), to skip whole chunks of a long trajectory. Depths are distances along the view direction (perspective) or from the eye's plane (orthographic); points closer than near are behind the eye.


Uses

  • module~~vkf_pick~~UsesGraph module~vkf_pick vkf_pick module~vkf_math vkf_math module~vkf_pick->module~vkf_math iso_fortran_env iso_fortran_env module~vkf_math->iso_fortran_env

Used by

  • module~~vkf_pick~~UsedByGraph module~vkf_pick vkf_pick module~vkf_artists vkf_artists module~vkf_artists->module~vkf_pick module~vkf_frames vkf_frames module~vkf_artists->module~vkf_frames module~vkf_frames->module~vkf_pick module~vkf_handles vkf_handles module~vkf_handles->module~vkf_pick module~vkf_handles->module~vkf_artists module~vkf_handles->module~vkf_frames module~vkf_model vkf_model module~vkf_model->module~vkf_pick module~vkf_model->module~vkf_frames module~vkf_sphere vkf_sphere module~vkf_sphere->module~vkf_pick module~vkf_sphere->module~vkf_frames module~vkf_terrain vkf_terrain module~vkf_terrain->module~vkf_pick module~vkf_terrain->module~vkf_frames module~vkf_window vkf_window module~vkf_window->module~vkf_pick module~vkf_window->module~vkf_frames module~vkf_window->module~vkf_handles module~vkf_hud vkf_hud module~vkf_window->module~vkf_hud module~vkf_view vkf_view module~vkf_window->module~vkf_view module~vkframes vkframes module~vkframes->module~vkf_pick module~vkframes->module~vkf_artists module~vkframes->module~vkf_frames module~vkframes->module~vkf_handles module~vkframes->module~vkf_model module~vkframes->module~vkf_sphere module~vkframes->module~vkf_terrain module~vkframes->module~vkf_window module~vkframes->module~vkf_hud module~vkf_line_segments vkf_line_segments module~vkframes->module~vkf_line_segments module~vkf_shadow vkf_shadow module~vkframes->module~vkf_shadow module~vkf_shapes vkf_shapes module~vkframes->module~vkf_shapes module~vkframes->module~vkf_view module~vkf_hud->module~vkf_frames module~vkf_line_segments->module~vkf_frames module~vkf_shadow->module~vkf_frames module~vkf_shadow->module~vkf_sphere module~vkf_shadow->module~vkf_terrain module~vkf_shapes->module~vkf_artists module~vkf_shapes->module~vkf_frames module~vkf_view->module~vkf_frames

Derived Types

type, public ::  PickCamera

The camera and cursor of a pick (see the module documentation).

Components

Type Visibility Attributes Name Initial
real(kind=wp), public :: aspect = 1.0_wp

width / height

real(kind=wp), public :: eye(3) = 0.0_wp

the eye (root frame)

real(kind=wp), public :: forward(3) = [0.0_wp, 1.0_wp, 0.0_wp]

the view direction (unit vector, root frame)

real(kind=wp), public :: half_h = 1.0_wp

half the viewport (framebuffer pixels)

real(kind=wp), public :: half_w = 1.0_wp

half the viewport (framebuffer pixels)

integer, public :: kinds = -1

the kinds of hits wanted: bit k for kind k (all)

real(kind=wp), public :: max_depth = huge(1.0_wp)

hits deeper than this aren't wanted (nearest only)

real(kind=wp), public :: near = 0.0_wp

the smallest depth in front of the eye

real(kind=wp), public :: ortho(4) = [-1.0_wp, 1.0_wp, -1.0_wp, 1.0_wp]

(orthographic: left, right, bottom, top)

logical, public :: perspective = .true.

(true: perspective; false: orthographic)

real(kind=wp), public :: pixel_ratio = 1.0_wp

framebuffer pixels per window unit (for line widths, marker sizes)

real(kind=wp), public :: right(3) = [1.0_wp, 0.0_wp, 0.0_wp]

the camera's right axis (unit vector, root frame)

real(kind=wp), public :: tan_y = 0.0_wp

tan(vertical field of view / 2)

real(kind=wp), public :: tolerance = 6.0_wp

framebuffer pixels

real(kind=wp), public :: up(3) = [0.0_wp, 0.0_wp, 1.0_wp]

the camera's up axis (unit vector, root frame)

real(kind=wp), public :: x = 0.0_wp

the cursor (-1 to 1, y up)

real(kind=wp), public :: y = 0.0_wp

the cursor (-1 to 1, y up)


Functions

public pure function pick_camera(eye, center, up, perspective, fovy, aspect, ortho, width, height, x, y, tolerance) result(cam)

The camera of a pick: eye, center and up (root frame), a perspective projection (fovy, degrees, and aspect) or an orthographic one (ortho: left, right, bottom, top), a viewport of width x height framebuffer pixels, the cursor (x, y: -1 to 1, y up) and the tolerance (framebuffer pixels).

Arguments

Type IntentOptional Attributes Name
real(kind=wp), intent(in) :: eye(3)

the camera (root frame)

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

the camera (root frame)

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

the camera (root frame)

logical, intent(in) :: perspective

(true: perspective; false: orthographic)

real(kind=wp), intent(in) :: fovy

vertical field of view (degrees; perspective)

real(kind=wp), intent(in) :: aspect

width / height (perspective)

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

left, right, bottom, top (orthographic)

integer, intent(in) :: width

the viewport (framebuffer pixels)

integer, intent(in) :: height

the viewport (framebuffer pixels)

real(kind=wp), intent(in) :: x

the cursor (-1 to 1, y up)

real(kind=wp), intent(in) :: y

the cursor (-1 to 1, y up)

real(kind=wp), intent(in) :: tolerance

(framebuffer pixels)

Return Value type(PickCamera)

public function point_pick(cam, p, pixels, depth, extra) result(hit)

Point p (root frame) is within the tolerance (plus extra pixels, e.g. half a marker's size) of the cursor: its distance from it (pixels) and its depth.

Arguments

Type IntentOptional Attributes Name
type(PickCamera), intent(in) :: cam

the camera and cursor of the pick

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

the point (root frame)

real(kind=wp), intent(out) :: pixels

distance from the cursor (framebuffer pixels)

real(kind=wp), intent(out) :: depth

(scene units)

real(kind=wp), intent(in), optional :: extra

added to the tolerance (framebuffer pixels)

Return Value logical

public function project(cam, p, sx, sy, depth) result(visible)

The screen offset (framebuffer pixels) of point p (root frame) from the cursor, and its depth; false if it is behind the eye.

Arguments

Type IntentOptional Attributes Name
type(PickCamera), intent(in) :: cam

the camera and cursor of the pick

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

the point (root frame)

real(kind=wp), intent(out) :: sx

offset from the cursor (framebuffer pixels, y up)

real(kind=wp), intent(out) :: sy

offset from the cursor (framebuffer pixels, y up)

real(kind=wp), intent(out) :: depth

(scene units)

Return Value logical

public function ray_ellipsoid(origin, dir, center, axes, radii, distance, point, local) result(hit)

Where the ray (origin, unit dir) first meets the ellipsoid centered at center with semi-axes radii along the columns of axes (unit vectors): the distance along the ray, the point, and the point in the ellipsoid's axes (from its center). False if it misses (or the ellipsoid is behind).

Arguments

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

the ray (dir: a unit vector)

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

the ray (dir: a unit vector)

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

the ellipsoid's center

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

its axes (columns: unit vectors)

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

its semi-axes along them

real(kind=wp), intent(out) :: distance

along the ray (huge() if missed)

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

the point met

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

the point in the ellipsoid's axes, from its center

Return Value logical

public function ray_line(origin, dir, point, axis, s, line_point) result(hit)

The point of the line through point along axis closest to the ray (origin, unit dir): its parameter s (the point is point + s * axis, axis normalized) and the point. False if the ray and the line are parallel (within 1e-6 of it, as a sine squared), or the closest point of the ray is behind its origin.

Arguments

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

the ray (dir: a unit vector)

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

the ray (dir: a unit vector)

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

the line (axis: any length but 0)

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

the line (axis: any length but 0)

real(kind=wp), intent(out) :: s

along the line (scene units, from point)

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

the point of the line

Return Value logical

public function ray_plane(origin, dir, point, normal, distance, hit_point) result(hit)

Where the ray (origin, unit dir) meets the plane through point with normal normal: the distance along the ray and the point. False if the ray is parallel to the plane (within 1e-6 of it, as a cosine) or the plane is behind.

Arguments

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

the ray (dir: a unit vector)

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

the ray (dir: a unit vector)

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

the plane (normal: any length but 0)

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

the plane (normal: any length but 0)

real(kind=wp), intent(out) :: distance

along the ray (huge() if missed)

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

the point met

Return Value logical

public function ray_sphere(origin, dir, center, radius, near, far) result(hit)

Where the ray (origin, unit dir) meets the sphere of center and radius: the distances along the ray of where it enters and leaves (near <= far; near < 0 if the origin is inside). False if it misses, or the sphere is behind.

Arguments

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

the ray (dir: a unit vector)

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

the ray (dir: a unit vector)

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

the sphere's center

real(kind=wp), intent(in) :: radius

its radius (> 0)

real(kind=wp), intent(out) :: near

distances along the ray (huge() if missed)

real(kind=wp), intent(out) :: far

distances along the ray (huge() if missed)

Return Value logical

public function segment_pick(cam, a, b, pixels, s, depth, extra) result(hit)

Segment a-b (root frame) passes within the tolerance (plus extra pixels, e.g. half the line's width) of the cursor: the distance (pixels) of its closest point, the fraction s of the way from a to b of that point in the scene (perspective-correct), and its depth. The part behind the eye is cut off.

Arguments

Type IntentOptional Attributes Name
type(PickCamera), intent(in) :: cam

the camera and cursor of the pick

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

the segment's ends (root frame)

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

the segment's ends (root frame)

real(kind=wp), intent(out) :: pixels

distance from the cursor (framebuffer pixels)

real(kind=wp), intent(out) :: s

fraction of the way from a to b (0 to 1)

real(kind=wp), intent(out) :: depth

(scene units)

real(kind=wp), intent(in), optional :: extra

added to the tolerance (framebuffer pixels)

Return Value logical

public function sphere_near(cam, c, r, extra) result(near)

A sphere (root frame: center c, radius r) might be within the tolerance (plus extra pixels) of the cursor on the screen (false only if it surely isn't: to skip what it bounds).

Arguments

Type IntentOptional Attributes Name
type(PickCamera), intent(in) :: cam

the camera and cursor of the pick

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

the sphere's center (root frame) and radius (scene units)

real(kind=wp), intent(in) :: r

the sphere's center (root frame) and radius (scene units)

real(kind=wp), intent(in), optional :: extra

added to the tolerance (framebuffer pixels)

Return Value logical

public pure function wants(cam, kind)

Hits of kind (vkf_frames' PICK_*) are wanted.

Arguments

Type IntentOptional Attributes Name
type(PickCamera), intent(in) :: cam

the camera and cursor of the pick

integer, intent(in) :: kind

a PICK_* constant of vkf_frames

Return Value logical


Subroutines

public pure subroutine ray(cam, origin, dir)

The ray from the eye through the cursor (root frame; dir a unit vector).

Arguments

Type IntentOptional Attributes Name
type(PickCamera), intent(in) :: cam

the camera and cursor of the pick

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

the ray (root frame; dir: a unit vector)

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

the ray (root frame; dir: a unit vector)