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:
(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).
| 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 |
The ShadowCones constructor: ShadowCones(...) makes one (see new_shadow_cones for its
arguments).
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 | Intent | Optional | 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) |
A body's shadow cones (see the module documentation).
| 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 |
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 |
| 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 |
A shadow region's surface: a frustum along z from z0 (radius r0) to z1 (radius r1), in the shadow frame's coordinates.
| 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) |
The body casting the shadow (null if not set).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(ShadowCones), | intent(in) | :: | self |
The body's radius used (0: none known).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(ShadowCones), | intent(in) | :: | self |
The distance between the body and the light at the last update.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(ShadowCones), | intent(in) | :: | self |
The length drawn at the last update.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(ShadowCones), | intent(in) | :: | self |
A body's own radius: a Sphere's equatorial one, a TerrainBody's; else 0.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(ReferenceFrame), | intent(in) | :: | frame |
the body or the light |
The length set (0: automatic).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(ShadowCones), | intent(in) | :: | self |
The light (null if not set).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(ShadowCones), | intent(in) | :: | self |
The light's radius used (0: none known).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(ShadowCones), | intent(in) | :: | self |
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 | Intent | Optional | 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) |
A region's color [r, g, b, a] (0 for an unknown region).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(ShadowCones), | intent(in) | :: | self | |||
| integer, | intent(in) | :: | region |
SHADOW_UMBRA, SHADOW_PENUMBRA or SHADOW_ANTUMBRA |
The index in self%region of SHADOW_UMBRA, SHADOW_PENUMBRA or SHADOW_ANTUMBRA (0 for anything else).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| integer, | intent(in) | :: | region |
SHADOW_UMBRA, SHADOW_PENUMBRA or SHADOW_ANTUMBRA |
The regions drawn: an ior of SHADOW_UMBRA, SHADOW_PENUMBRA and SHADOW_ANTUMBRA.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(ShadowCones), | intent(in) | :: | self |
What kind of frame this is: 'ShadowCones'.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(ShadowCones), | intent(in) | :: | 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).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(ShadowCones), | intent(in) | :: | self |
A region's color, through its mesh's material (the unlit shader multiplies the vertex color, white, by the diffuse color).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(ShadowRegion), | intent(in) | :: | g |
the region (umbra, penumbra or antumbra) |
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.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(ShadowCones), | intent(inout) | :: | self |
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).
| Type | Intent | Optional | 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 |
The body casting the shadow (it must stay alive while set), and its radius (optional: see set_body_radius).
| Type | Intent | Optional | 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) |
The body's radius (scene units; 0: the body's own, a Sphere's equatorial radius or a TerrainBody's).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(ShadowCones), | intent(inout) | :: | self | |||
| real(kind=wp), | intent(in) | :: | radius |
scene units (0: the body's own) |
How far behind the body's center the shadow is drawn (scene units; 0: automatic, twice the umbra's length).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(ShadowCones), | intent(inout) | :: | self | |||
| real(kind=wp), | intent(in) | :: | length |
scene units (0: automatic) |
The light (e.g. the Sun; it must stay alive while set), and its radius (optional: see set_light_radius).
| Type | Intent | Optional | 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) |
The light's radius (scene units; 0: the light's own, if a Sphere).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(ShadowCones), | intent(inout) | :: | self | |||
| real(kind=wp), | intent(in) | :: | radius |
scene units (0: the light's own) |
A region's color (region: one of SHADOW_UMBRA, SHADOW_PENUMBRA, SHADOW_ANTUMBRA; [r, g, b], alpha unchanged, or [r, g, b, a]).
| Type | Intent | Optional | 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 |
The regions to draw: an ior of SHADOW_UMBRA, SHADOW_PENUMBRA and SHADOW_ANTUMBRA (default SHADOW_ALL).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(ShadowCones), | intent(inout) | :: | self | |||
| integer, | intent(in) | :: | regions |
an ior of SHADOW_UMBRA, SHADOW_PENUMBRA, SHADOW_ANTUMBRA |
The drawn regions' bounding sphere (frame coordinates).
| Type | Intent | Optional | 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) |
A switch with a mesh for each region (vertices written at each change
of shape), under group.
| Type | Intent | Optional | 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 |
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.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(ShadowCones), | intent(inout) | :: | self | |||
| real(kind=wp), | intent(in) | :: | t |
the scene time |
The regions' frustums for body radius r, light radius rs and distance d (see the module documentation), written to their meshes.
| Type | Intent | Optional | 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 |
A region's frustum into its mesh (uploaded), and shown or hidden.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(ShadowRegion), | intent(in) | :: | g |
the region (umbra, penumbra or antumbra) |