vkf_shadow Module

Shadow cones: the regions of a celestial body's shadow in the light of another (e.g. the Earth's or the Moon's shadow in sunlight), drawn as transparent cones:

  • the umbra (total eclipse: the light hidden), converging behind the body to its apex, at d R / (Rs - R) from the body's center;
  • the antumbra (annular eclipse: the light seen around the body), from the umbra's apex outward, widening at the umbra's angle;
  • the penumbra (partial eclipse), widening behind the body.

(R and Rs: the body's and the light's radii; d: the distance between their centers. The edges are the lines tangent to both spheres: the outer tangents for the umbra and antumbra, half-angle asin((Rs - R) / d), the inner ones for the penumbra, asin((Rs + R) / d).) A body larger than its light has no apex: its umbra widens (or is a cylinder), with no antumbra.

A ShadowCones is a frame of its own, made a child of the body (add_child) for one body's shadow, and shown or hidden with show_contents: a scene without one does no shadow work at all. It refers to the body and the light frames (they must stay alive while set); each scene update, after the whole tree has moved (late_update), it moves itself to the body's center and turns its +z axis away from the light (its own position and attitude are set there, whatever its parent), and reshapes the cones for the distance between them: the cones' vertices are rewritten in place and uploaded only when the shape changed (not as the body only turns). Hidden, it does nothing (and is placed again when shown).

The radii: given (set_body_radius, set_light_radius), or the frames' own: a Sphere's equatorial radius, a TerrainBody's (a light that is a plain ReferenceFrame needs its radius given: none, no shadow). The shadow is drawn to set_length behind the body's center (default: twice the umbra's length; a hundred body radii without an apex); the umbra stops there if shorter. Each region has a color ([r, g, b, a]; the surfaces are unlit, transparent, seen from both sides, as the cones of vkf_shapes) and can be drawn or not (set_regions).

Bodies in a shadow are not darkened (that needs shadows in the lighting).


Uses

  • module~~vkf_shadow~~UsesGraph module~vkf_shadow vkf_shadow iso_c_binding iso_c_binding module~vkf_shadow->iso_c_binding module~vkf_frames vkf_frames module~vkf_shadow->module~vkf_frames module~vkf_layer vkf_layer module~vkf_shadow->module~vkf_layer module~vkf_math vkf_math module~vkf_shadow->module~vkf_math module~vkf_sphere vkf_sphere module~vkf_shadow->module~vkf_sphere module~vkf_terrain vkf_terrain module~vkf_shadow->module~vkf_terrain module~vkf_frames->iso_c_binding module~vkf_frames->module~vkf_layer module~vkf_frames->module~vkf_math module~vkf_follower vkf_follower module~vkf_frames->module~vkf_follower module~vkf_geometry vkf_geometry module~vkf_frames->module~vkf_geometry module~vkf_pick vkf_pick module~vkf_frames->module~vkf_pick module~vkf_text vkf_text module~vkf_frames->module~vkf_text module~vkf_trajectory vkf_trajectory module~vkf_frames->module~vkf_trajectory module~vkf_layer->iso_c_binding iso_fortran_env iso_fortran_env module~vkf_math->iso_fortran_env module~vkf_sphere->iso_c_binding module~vkf_sphere->module~vkf_frames module~vkf_sphere->module~vkf_layer module~vkf_sphere->module~vkf_math module~vkf_files vkf_files module~vkf_sphere->module~vkf_files module~vkf_sphere->module~vkf_geometry module~vkf_sphere->module~vkf_pick module~vkf_terrain->iso_c_binding module~vkf_terrain->module~vkf_frames module~vkf_terrain->module~vkf_layer module~vkf_terrain->module~vkf_math module~vkf_terrain->module~vkf_files module~vkf_terrain->module~vkf_pick module~vkf_follower->module~vkf_math module~vkf_follower->module~vkf_trajectory module~vkf_geometry->iso_c_binding module~vkf_geometry->module~vkf_layer module~vkf_geometry->module~vkf_math module~vkf_pick->module~vkf_math module~vkf_text->iso_c_binding module~vkf_text->module~vkf_layer module~vkf_text->module~vkf_math module~vkf_text->module~vkf_files module~vkf_trajectory->iso_c_binding module~vkf_trajectory->module~vkf_math module~vkf_trajectory->iso_fortran_env

Used by

  • module~~vkf_shadow~~UsedByGraph module~vkf_shadow vkf_shadow module~vkframes vkframes module~vkframes->module~vkf_shadow

Variables

Type Visibility Attributes Name Initial
integer, public, parameter :: SHADOW_ALL = 7

SHADOW_UMBRA + SHADOW_PENUMBRA + SHADOW_ANTUMBRA

integer, public, parameter :: SHADOW_ANTUMBRA = 4

The regions (combine with ior).

integer, public, parameter :: SHADOW_PENUMBRA = 2

The regions (combine with ior).

integer, public, parameter :: SHADOW_UMBRA = 1

The regions (combine with ior).

integer, private, parameter :: antumbra = 3

region indices

integer, private, parameter :: n_around = 128

segments around each cone

integer, private, parameter :: n_regions = 3

umbra, penumbra and antumbra

integer, private, parameter :: penumbra = 2

region indices

integer, private, parameter :: umbra = 1

region indices


Interfaces

public interface ShadowCones

The ShadowCones constructor: ShadowCones(...) makes one (see new_shadow_cones for its arguments).

  • private function new_shadow_cones(name, body, light, body_radius, light_radius) result(s)

    The shadow named name of body in the light of light (frames of the same tree; optional here, set later with set_body and set_light), with their radii if given (else the frames': see the module documentation). Its axes and name label are hidden.

    Arguments

    Type IntentOptional Attributes Name
    character(len=*), intent(in) :: name

    the frame's name

    class(ReferenceFrame), intent(in), optional, target :: body

    the body casting the shadow, the light (not owned)

    class(ReferenceFrame), intent(in), optional, target :: light

    the body casting the shadow, the light (not owned)

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

    scene units (default: the frames' own)

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

    scene units (default: the frames' own)

    Return Value type(ShadowCones)


Derived Types

type, public, extends(ReferenceFrame) ::  ShadowCones

A body's shadow cones (see the module documentation).

Components

Type Visibility Attributes Name Initial
class(ReferenceFrame), private, pointer :: body_ => null()

the body casting the shadow (not owned)

real(kind=wp), private :: body_radius_ = 0.0_wp

(0: the frames' own)

real(kind=wp), private :: distance_ = 0.0_wp

body to light at the last update (scene units)

real(kind=wp), private :: drawn_length_ = 0.0_wp

the length drawn at the last update (scene units)

real(kind=wp), private :: length_ = 0.0_wp

(0: automatic)

class(ReferenceFrame), private, pointer :: light_ => null()

the light (not owned)

real(kind=wp), private :: light_radius_ = 0.0_wp

(0: the frames' own)

type(ShadowRegion), private :: region(n_regions)

umbra, penumbra and antumbra

integer, private :: regions_ = SHADOW_ALL

an ior of SHADOW_UMBRA, SHADOW_PENUMBRA, SHADOW_ANTUMBRA

real(kind=wp), private :: shaped(4) = -1.0_wp

R, Rs, d and length the cones have now

Constructor

The ShadowCones constructor: ShadowCones(...) makes one (see new_shadow_cones for its arguments).

private function new_shadow_cones (name, body, light, body_radius, light_radius)

The shadow named name of body in the light of light (frames of the same tree; optional here, set later with set_body and set_light), with their radii if given (else the frames': see the module documentation). Its axes and name label are hidden.

Type-Bound Procedures

procedure, public :: add_child
procedure, public :: attitude
procedure, public :: axes_labels_shown
procedure, public :: axes_shown
procedure, public :: axis_label
procedure, public :: body
procedure, public :: body_radius
procedure, public :: bound => shadow_bound
procedure, public :: build_contents => shadow_build_contents
procedure, public :: child
procedure, public :: child_index
procedure, public :: color
procedure, public :: contents_shown
procedure, public :: detach
procedure, public :: distance
procedure, public :: drawn_length
procedure, public :: follow
procedure, public :: follow_frame
procedure, public :: follower
procedure, public :: frame_info => shadow_frame_info
procedure, public :: frame_string
procedure, public :: has_light_source
procedure, public :: is_following
procedure, public :: label_alignment
procedure, public :: label_font
procedure, public :: label_size
procedure, public :: late_update => shadow_late_update
procedure, public :: length
procedure, public :: light
procedure, public :: light_ambient
procedure, public :: light_diffuse
procedure, public :: light_radius
procedure, public :: light_source_enabled
procedure, public :: light_specular
procedure, public :: local_matrix
procedure, public :: local_matrix_at
procedure, public :: motion_key
procedure, public :: move_x_axis
procedure, public :: move_y_axis
procedure, public :: move_z_axis
procedure, public :: name
procedure, public :: name_label_on_top
procedure, public :: name_label_shown
procedure, public :: node
procedure, public :: num_children
procedure, public :: num_parents
procedure, public :: parent
procedure, public :: parent_index
procedure, public :: pick
procedure, public :: pickable
procedure, public :: position
procedure, public :: position_of
procedure, public :: realize
procedure, public :: region_color
procedure, public :: region_extent
procedure, public :: regions
procedure, public :: remove_child
procedure, public :: reposition_axes
procedure, public :: set_attitude
procedure, public :: set_body
procedure, public :: set_body_radius
procedure, public :: set_color
procedure, public :: set_label_alignment
procedure, public :: set_label_font
procedure, public :: set_label_size
procedure, public :: set_length
procedure, public :: set_light
procedure, public :: set_light_ambient
procedure, public :: set_light_diffuse
procedure, public :: set_light_radius
procedure, public :: set_light_source_enabled
procedure, public :: set_light_specular
procedure, public :: set_name
procedure, public :: set_name_label_on_top
procedure, public :: set_pickable
procedure, public :: set_position
procedure, public :: set_region_color
procedure, public :: set_regions
procedure, public :: set_x_label
procedure, public :: set_y_label
procedure, public :: set_z_label
procedure, public :: show_axes
procedure, public :: show_axes_labels
procedure, public :: show_contents
procedure, public :: show_decorations
procedure, public :: show_name_label
procedure, public :: sync
procedure, public :: umbra_length
procedure, public :: unfollow
procedure, public :: update
procedure, public :: world_matrix
procedure, public :: world_matrix_at

type, private ::  ShadowRegion

A shadow region's surface: a frustum along z from z0 (radius r0) to z1 (radius r1), in the shadow frame's coordinates.

Components

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

[r, g, b, a] (0 to 1)

logical, public :: drawn = .false.

has a surface (and is to be drawn)

type(c_ptr), public :: mesh = c_null_ptr

the surface: rings of vertices at z0 and z1

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

radius at z0 (scene units)

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

radius at z1 (scene units)

type(c_ptr), public :: switch = c_null_ptr

shows or hides the mesh (null until built)

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

start along z (scene units)

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

end along z (scene units)


Functions

private function body(self) result(p)

The body casting the shadow (null if not set).

Arguments

Type IntentOptional Attributes Name
class(ShadowCones), intent(in) :: self

Return Value class(ReferenceFrame), pointer

private function body_radius(self)

The body's radius used (0: none known).

Arguments

Type IntentOptional Attributes Name
class(ShadowCones), intent(in) :: self

Return Value real(kind=wp)

private pure function distance(self)

The distance between the body and the light at the last update.

Arguments

Type IntentOptional Attributes Name
class(ShadowCones), intent(in) :: self

Return Value real(kind=wp)

private pure function drawn_length(self)

The length drawn at the last update.

Arguments

Type IntentOptional Attributes Name
class(ShadowCones), intent(in) :: self

Return Value real(kind=wp)

private function frame_radius(frame) result(r)

A body's own radius: a Sphere's equatorial one, a TerrainBody's; else 0.

Arguments

Type IntentOptional Attributes Name
class(ReferenceFrame), intent(in) :: frame

the body or the light

Return Value real(kind=wp)

private pure function length(self)

The length set (0: automatic).

Arguments

Type IntentOptional Attributes Name
class(ShadowCones), intent(in) :: self

Return Value real(kind=wp)

private function light(self) result(p)

The light (null if not set).

Arguments

Type IntentOptional Attributes Name
class(ShadowCones), intent(in) :: self

Return Value class(ReferenceFrame), pointer

private function light_radius(self)

The light's radius used (0: none known).

Arguments

Type IntentOptional Attributes Name
class(ShadowCones), intent(in) :: self

Return Value real(kind=wp)

private function new_shadow_cones(name, body, light, body_radius, light_radius) result(s)

The shadow named name of body in the light of light (frames of the same tree; optional here, set later with set_body and set_light), with their radii if given (else the frames': see the module documentation). Its axes and name label are hidden.

Arguments

Type IntentOptional Attributes Name
character(len=*), intent(in) :: name

the frame's name

class(ReferenceFrame), intent(in), optional, target :: body

the body casting the shadow, the light (not owned)

class(ReferenceFrame), intent(in), optional, target :: light

the body casting the shadow, the light (not owned)

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

scene units (default: the frames' own)

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

scene units (default: the frames' own)

Return Value type(ShadowCones)

private function region_color(self, region) result(c)

A region's color [r, g, b, a] (0 for an unknown region).

Arguments

Type IntentOptional Attributes Name
class(ShadowCones), intent(in) :: self
integer, intent(in) :: region

SHADOW_UMBRA, SHADOW_PENUMBRA or SHADOW_ANTUMBRA

Return Value real(kind=wp), (4)

private pure function region_index(region) result(k)

The index in self%region of SHADOW_UMBRA, SHADOW_PENUMBRA or SHADOW_ANTUMBRA (0 for anything else).

Arguments

Type IntentOptional Attributes Name
integer, intent(in) :: region

SHADOW_UMBRA, SHADOW_PENUMBRA or SHADOW_ANTUMBRA

Return Value integer

private pure function regions(self)

The regions drawn: an ior of SHADOW_UMBRA, SHADOW_PENUMBRA and SHADOW_ANTUMBRA.

Arguments

Type IntentOptional Attributes Name
class(ShadowCones), intent(in) :: self

Return Value integer

private function shadow_frame_info(self) result(info)

What kind of frame this is: 'ShadowCones'.

Arguments

Type IntentOptional Attributes Name
class(ShadowCones), intent(in) :: self

Return Value character(len=:), allocatable

private pure function umbra_length(self)

The distance from the body's center to the umbra's apex at the last update (huge() for a body no smaller than its light; 0 before).

Arguments

Type IntentOptional Attributes Name
class(ShadowCones), intent(in) :: self

Return Value real(kind=wp)


Subroutines

private subroutine apply_color(g)

A region's color, through its mesh's material (the unlit shader multiplies the vertex color, white, by the diffuse color).

Arguments

Type IntentOptional Attributes Name
type(ShadowRegion), intent(in) :: g

the region (umbra, penumbra or antumbra)

private subroutine place(self)

Move the shadow to the body's center (in the parent's coordinates) with its +z axis away from the light, and reshape the cones if the radii, the distance or the length set changed.

Arguments

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

private subroutine region_extent(self, region, drawn, z0, r0, z1, r1)

A region's surface at the last update, along the frame's +z axis (away from the light; the body's center at the origin): drawn, from z0 (radius r0) to z1 (radius r1).

Arguments

Type IntentOptional Attributes Name
class(ShadowCones), intent(in) :: self
integer, intent(in) :: region

SHADOW_UMBRA, SHADOW_PENUMBRA or SHADOW_ANTUMBRA

logical, intent(out) :: drawn

it has a surface and is drawn

real(kind=wp), intent(out), optional :: z0

scene units

real(kind=wp), intent(out), optional :: r0

scene units

real(kind=wp), intent(out), optional :: z1

scene units

real(kind=wp), intent(out), optional :: r1

scene units

private subroutine set_body(self, body, radius)

The body casting the shadow (it must stay alive while set), and its radius (optional: see set_body_radius).

Arguments

Type IntentOptional Attributes Name
class(ShadowCones), intent(inout) :: self
class(ReferenceFrame), intent(in), target :: body

the body casting the shadow (not owned)

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

scene units (see set_body_radius)

private subroutine set_body_radius(self, radius)

The body's radius (scene units; 0: the body's own, a Sphere's equatorial radius or a TerrainBody's).

Arguments

Type IntentOptional Attributes Name
class(ShadowCones), intent(inout) :: self
real(kind=wp), intent(in) :: radius

scene units (0: the body's own)

private subroutine set_length(self, length)

How far behind the body's center the shadow is drawn (scene units; 0: automatic, twice the umbra's length).

Arguments

Type IntentOptional Attributes Name
class(ShadowCones), intent(inout) :: self
real(kind=wp), intent(in) :: length

scene units (0: automatic)

private subroutine set_light(self, light, radius)

The light (e.g. the Sun; it must stay alive while set), and its radius (optional: see set_light_radius).

Arguments

Type IntentOptional Attributes Name
class(ShadowCones), intent(inout) :: self
class(ReferenceFrame), intent(in), target :: light

the light, e.g. the Sun (not owned)

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

scene units (see set_light_radius)

private subroutine set_light_radius(self, radius)

The light's radius (scene units; 0: the light's own, if a Sphere).

Arguments

Type IntentOptional Attributes Name
class(ShadowCones), intent(inout) :: self
real(kind=wp), intent(in) :: radius

scene units (0: the light's own)

private subroutine set_region_color(self, region, color)

A region's color (region: one of SHADOW_UMBRA, SHADOW_PENUMBRA, SHADOW_ANTUMBRA; [r, g, b], alpha unchanged, or [r, g, b, a]).

Arguments

Type IntentOptional Attributes Name
class(ShadowCones), intent(inout) :: self
integer, intent(in) :: region

SHADOW_UMBRA, SHADOW_PENUMBRA or SHADOW_ANTUMBRA

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

[r, g, b] (alpha unchanged) or [r, g, b, a], 0 to 1

private subroutine set_regions(self, regions)

The regions to draw: an ior of SHADOW_UMBRA, SHADOW_PENUMBRA and SHADOW_ANTUMBRA (default SHADOW_ALL).

Arguments

Type IntentOptional Attributes Name
class(ShadowCones), intent(inout) :: self
integer, intent(in) :: regions

an ior of SHADOW_UMBRA, SHADOW_PENUMBRA, SHADOW_ANTUMBRA

private subroutine shadow_bound(self, center, radius)

The drawn regions' bounding sphere (frame coordinates).

Arguments

Type IntentOptional Attributes Name
class(ShadowCones), intent(in) :: self
real(kind=wp), intent(out) :: center(3)

the bounding sphere, frame coordinates (scene units)

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

the bounding sphere, frame coordinates (scene units)

private subroutine shadow_build_contents(self, viewer, group)

A switch with a mesh for each region (vertices written at each change of shape), under group.

Arguments

Type IntentOptional Attributes Name
class(ShadowCones), intent(inout) :: self
type(c_ptr), intent(in) :: viewer

a window's viewer (null: headless)

type(c_ptr), intent(in) :: group

the frame's contents group

private recursive subroutine shadow_late_update(self, t)

After the tree's update for time t: the shadow moved to the body, turned away from the light, and reshaped if the distance or a setting changed.

Arguments

Type IntentOptional Attributes Name
class(ShadowCones), intent(inout) :: self
real(kind=wp), intent(in) :: t

the scene time

private subroutine shape_regions(self, r, rs, d)

The regions' frustums for body radius r, light radius rs and distance d (see the module documentation), written to their meshes.

Arguments

Type IntentOptional Attributes Name
type(ShadowCones), intent(inout) :: self
real(kind=wp), intent(in) :: r

scene units

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

scene units

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

scene units

private subroutine write_region(g)

A region's frustum into its mesh (uploaded), and shown or hidden.

Arguments

Type IntentOptional Attributes Name
type(ShadowRegion), intent(in) :: g

the region (umbra, penumbra or antumbra)