A growing set of points drawn from a chain of GPU buffers ("chunks"), for the trajectory artists: a line strip, separate segments (pairs of points), markers (one per point) or a ribbon (a translucent surface through pairs of points: a quad between each pair and the next). Points are written in place, as (high, low) float pairs for double precision (see src/vsg/vkf_layer.cpp: EyeRelative), with a strip's distance along it (for dash patterns, see shaders/line.vert; measured from the trajectory's points), and only the chunks written to are uploaded again. A full chain gets new chunks, each as large as the chain so far or as what is needed at once, but at least min_chunk and at most max_chunk points, so nothing is ever copied or reallocated, and changing a point uploads at most max_chunk points again. In a strip, consecutive chunks share their end point so that the line is continuous; in a ribbon, their end pair.
Level of detail (strips): seen from far away, a dense trajectory is mostly segments shorter than a pixel. For each chunk, the chain keeps the bounding sphere of its points and, for strides 2, 4, ... 2^lod_levels, a bound on how far the points skipped can be from the segments drawn (every stride-th point and the last), and gives them to the renderer (vkf_line_set_lod), which picks the stride per view (src/vsg/vkf_layer.cpp: EyeRelative). The bounds are built level by level: a segment at stride 2s is within the larger of its two halves' bounds, plus its middle point's distance from it, of the points it skips (the halves' segments lie within that distance of it). They are updated only for the segments the points written change.
Writing points i1 .. i2 (indices along the whole chain):
call chain%reserve(i2)
do j = 1, chain%num_chunks()
call chain%slice(j, i1, i2, lo, hi, p) ! p: points lo .. hi of chunk j
if (.not. associated(p)) cycle
... fill p(1:3, :, 1:hi-lo+1) (e.g. with split_points) ...
end do
call chain%written(i1, i2) ! measure (strips) and upload
call chain%draw(i2)
| Type | Visibility | Attributes | Name | Initial | |||
|---|---|---|---|---|---|---|---|
| integer, | public, | parameter | :: | CHAIN_MARKERS | = | 2 |
a marker per point |
| integer, | public, | parameter | :: | CHAIN_RIBBON | = | 3 |
a ribbon (a quad between each pair of points and the next) |
| integer, | public, | parameter | :: | CHAIN_SEGMENTS | = | 1 |
separate segments (pairs of points) |
| integer, | public, | parameter | :: | CHAIN_STRIP | = | 0 |
what a chain draws a line strip |
| integer, | private, | parameter | :: | lod_levels | = | 12 |
strides up to 2^12 = 4096 (strips) |
| integer, | public, | parameter | :: | max_chunk | = | 65536 |
points in a chunk made for appending (1.5 MB) |
| integer, | private, | parameter | :: | min_chunk | = | 64 |
points in the smallest chunk |
A chain of point buffers (see the module documentation).
| Type | Visibility | Attributes | Name | Initial | |||
|---|---|---|---|---|---|---|---|
| type(LineChunk), | private, | allocatable | :: | chunks(:) |
(capacity): the chunks, in chain order |
||
| real(kind=c_float), | private | :: | color(4) | = | 1.0_c_float |
[r, g, b, a] (0 to 1) |
|
| logical, | private | :: | colored | = | .false. |
(lines, markers: a color per point (color_slice)) |
|
| logical, | private | :: | compile_new | = | .false. |
chunks made from now on are compiled (the group is shown) |
|
| real(kind=wp), | private | :: | dash_length | = | 0.0_wp |
(2: the pattern's length, scene units; 0 from the first view) |
|
| integer, | private | :: | dash_mode | = | 0 |
(lines: 0 anchored, 1 screen-locked, 2 fixed length) |
|
| type(c_ptr), | private | :: | group | = | c_null_ptr |
the group node the chunks are under (null: not built) |
|
| real(kind=c_float), | private | :: | highlight(12) | = | [1.0_c_float, 1.0_c_float, 1.0_c_float, 1.0_c_float, 0.0_c_float, 40.0_c_float, 50.0_c_float, 12.0_c_float, 1.5_c_float, 0.0_c_float, 0.0_c_float, 0.0_c_float] |
(lines: highlight, see vkf_line_set_highlight) |
|
| type(c_ptr), | private | :: | image | = | c_null_ptr |
(markers: the image (shape 10)) |
|
| integer, | private | :: | kind | = | CHAIN_STRIP |
what is drawn: a CHAIN_* constant |
|
| logical, | private | :: | lod | = | .true. |
(strips: level of detail (else every point drawn)) |
|
| integer, | private | :: | n_chunks | = | 0 |
number of chunks |
|
| integer, | private | :: | pattern | = | int(z'FFFF') |
(lines: 16-bit dash pattern (z'FFFF': solid)) |
|
| integer, | private | :: | pattern_factor | = | 1 |
(lines: dash pattern (see line_set_pattern)) |
|
| real(kind=c_float), | private | :: | radius | = | 0.0_c_float |
(markers: attenuation radius) |
|
| integer, | private | :: | shape | = | 0 |
markers |
|
| real(kind=c_float), | private | :: | trail(20) | = | 0.0_c_float |
(strips: the trail, see vkf_line_set_trail; z = 0: none) |
|
| real(kind=c_float), | private | :: | width | = | 1.0_c_float |
line width, or marker size |
| procedure, public :: chunk_bounds | |
| procedure, public :: color_slice | |
| procedure, public :: dash_mode_of | |
| procedure, public :: detach | |
| procedure, public :: distance | |
| procedure, public :: draw | |
| procedure, public :: draw_range | |
| procedure, public :: init | |
| procedure, public :: is_built | |
| procedure, public :: is_colored | |
| procedure, public :: lod_error | |
| procedure, public :: num_chunks | |
| procedure, public :: point | |
| procedure, public :: point_color | |
| procedure, public :: release | |
| procedure, public :: reserve | |
| procedure, public :: set_compile | |
| procedure, public :: set_dash_mode | |
| procedure, public :: set_highlight | |
| procedure, public :: set_lod | |
| procedure, public :: set_marker_style | |
| procedure, public :: set_pattern | |
| procedure, public :: set_style | |
| procedure, public :: set_trail | |
| procedure, public :: slice | |
| procedure, public :: style_node | |
| procedure, public :: written |
A buffer holding points first .. first+capacity-1 of the chain.
| Type | Visibility | Attributes | Name | Initial | |||
|---|---|---|---|---|---|---|---|
| real(kind=wp), | public | :: | box_hi(3) | = | 0.0_wp |
bounding box of the points written: upper corner |
|
| real(kind=wp), | public | :: | box_lo(3) | = | 0.0_wp |
bounding box of the points written: lower corner |
|
| integer, | public | :: | capacity | = | 0 |
number of points it holds |
|
| integer, | public | :: | first | = | 1 |
the chain index of its first point |
|
| type(c_ptr), | public | :: | line | = | c_null_ptr |
the line, marker or ribbon node |
|
| type(LodLevel), | public | :: | lod(lod_levels) |
error bounds at strides 2, 4, ... 2^lod_levels |
|||
| integer, | public | :: | n_written | = | 0 |
points written (the bounds are for them) |
Error bounds of a strip's segments at one stride (level of detail).
| Type | Visibility | Attributes | Name | Initial | |||
|---|---|---|---|---|---|---|---|
| real(kind=c_float), | public, | allocatable | :: | bound(:) |
(0 : segments - 1) |
The dashes' layout (set_dash_mode).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(LineChain), | intent(in) | :: | self |
A strip's distance along it at point i, as written.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(LineChain), | intent(in) | :: | self | |||
| integer, | intent(in) | :: | i |
chain index |
For lines and markers, whether each point has its own color (init's colored).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(LineChain), | intent(in) | :: | self |
Chunk j's error bounds: how far the points skipped can be from the segments drawn at stride 2^k (k = 1 .. lod_levels; 0 where not known).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(LineChain), | intent(in) | :: | self | |||
| integer, | intent(in) | :: | j |
the chunk (outside 1 to the chunks: zeros) |
Number of chunks.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(LineChain), | intent(in) | :: | self |
Point i as written: read back from the buffers (zero if not held).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(LineChain), | intent(in) | :: | self | |||
| integer, | intent(in) | :: | i |
chain index |
The color of point i of a colored chain, as stored (rgba; white if not colored).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(LineChain), | intent(in) | :: | self | |||
| integer, | intent(in) | :: | i |
chain index |
Distance from point v to the segment from a to b.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| real(kind=wp), | intent(in) | :: | v(3) |
the point, and the segment's ends |
||
| real(kind=wp), | intent(in) | :: | a(3) |
the point, and the segment's ends |
||
| real(kind=wp), | intent(in) | :: | b(3) |
the point, and the segment's ends |
Give the chain's style (color, width or size, pattern, highlight, marker shape) to the node line.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(LineChain), | intent(in) | :: | self | |||
| type(c_ptr), | intent(in) | :: | line |
line or marker node |
Chunk j's points (strips: first .. first + n - 1 of the chain) and the bounding box of them (n = 0 if none are measured yet), e.g. to skip a chunk when picking.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(LineChain), | intent(in) | :: | self | |||
| integer, | intent(in) | :: | j |
the chunk |
||
| integer, | intent(out) | :: | first |
its first point (chain index), and points written (0: none) |
||
| integer, | intent(out) | :: | n |
its first point (chain index), and points written (0: none) |
||
| real(kind=wp), | intent(out) | :: | lo(3) |
the bounding box's corners |
||
| real(kind=wp), | intent(out) | :: | hi(3) |
the bounding box's corners |
As slice, for the colors of a colored chain: c(rgba, point) of points lo .. hi of chunk j (null if not colored or nothing there).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(LineChain), | intent(in) | :: | self | |||
| integer, | intent(in) | :: | j |
the chunk, and points i1 .. i2 (chain indices) |
||
| integer, | intent(in) | :: | i1 |
the chunk, and points i1 .. i2 (chain indices) |
||
| integer, | intent(in) | :: | i2 |
the chunk, and points i1 .. i2 (chain indices) |
||
| integer, | intent(out) | :: | lo |
chain indices (lo > hi: none) |
||
| integer, | intent(out) | :: | hi |
chain indices (lo > hi: none) |
||
| real(kind=c_float), | intent(out), | dimension(:,:), pointer | :: | c |
(4, hi-lo+1): [r, g, b, a] |
Remove the chunks from the group (also while running), and release them.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(LineChain), | intent(inout) | :: | self |
Draw points 1 .. k (no upload).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(LineChain), | intent(in) | :: | self | |||
| integer, | intent(in) | :: | k |
last point drawn (chain index) |
Draw points i1 .. i2 only (chain indices; none if i2 < i1): e.g. a trace of decreasing times, its last points.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(LineChain), | intent(in) | :: | self | |||
| integer, | intent(in) | :: | i1 |
first and last points drawn (chain indices) |
||
| integer, | intent(in) | :: | i2 |
first and last points drawn (chain indices) |
Draw under group (a CHAIN_* kind; markers with image, a
vkf_image_read handle, for the image shape). Chunks made later are
compiled once set_compile says so.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(LineChain), | intent(inout) | :: | self | |||
| type(c_ptr), | intent(in) | :: | group |
the group node to draw under |
||
| integer, | intent(in) | :: | kind |
a CHAIN_* constant |
||
| type(c_ptr), | intent(in), | optional | :: | image |
(markers: a vkf_image_read handle) |
|
| logical, | intent(in), | optional | :: | colored |
(lines, markers: a color per point (color_slice)) |
The point buffer of a line or marker node: (xyz and distance, high/low, point).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(c_ptr), | intent(in) | :: | line |
line or marker node |
||
| real(kind=c_float), | intent(out), | dimension(:,:,:), pointer | :: | p |
(4, 2, capacity); null if none |
The distances along the strip of points lo .. hi of chunk j: from the
previous point (in this chunk; the first point of a chunk after the
first is the previous chunk's last, measured before), or 0 at point 1.
From x (as in written) if given, else from the floats written.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(LineChain), | intent(in) | :: | self | |||
| integer, | intent(in) | :: | j |
the chunk, and its points lo .. hi (chain indices) |
||
| integer, | intent(in) | :: | lo |
the chunk, and its points lo .. hi (chain indices) |
||
| integer, | intent(in) | :: | hi |
the chunk, and its points lo .. hi (chain indices) |
||
| real(kind=wp), | intent(in), | optional | :: | x(:,:) |
(3, chain points): the points, as in written |
Forget the chunks (after their group was removed from the scene): init starts again.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(LineChain), | intent(inout) | :: | self |
Chunks for at least n points (at least one chunk). Separate segments and ribbons: chunks hold whole pairs (n should be even).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(LineChain), | intent(inout) | :: | self | |||
| integer, | intent(in) | :: | n |
number of points to hold |
Give chunk j's level of detail to the renderer (none if switched off).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(LineChain), | intent(in) | :: | self | |||
| integer, | intent(in) | :: | j |
the chunk |
Compile chunks made from now on (for the windows running): once the group is shown (not while building, when they are compiled with it).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(LineChain), | intent(inout) | :: | self | |||
| logical, | intent(in) | :: | compile |
true: compile new chunks (once the group is shown) |
For lines, how the dashes are laid out: 0 anchored to the line (the
default), 1 screen-locked (a constant length in pixels, following the
line on screen), 2 a fixed length of the line (strips): length scene
units for the pattern, or if 0 its length on screen when first drawn.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(LineChain), | intent(inout) | :: | self | |||
| integer, | intent(in) | :: | mode |
0 anchored, 1 screen-locked, 2 fixed length |
||
| real(kind=wp), | intent(in) | :: | length |
(2) the pattern's length (scene units; 0: from the first view) |
For lines, the highlight (see shaders/line.vert): flags (1 pulse, 2
arrows; 0 none), its color (rgba), the arrows' spacing and speed (window
units, and per second), the band's width (window units) and the pulse's
period (s).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(LineChain), | intent(inout) | :: | self | |||
| integer, | intent(in) | :: | flags |
1 pulse + 2 arrows (0: none) |
||
| real(kind=wp), | intent(in) | :: | color(4) |
[r, g, b, a] (0 to 1) |
||
| real(kind=wp), | intent(in) | :: | spacing |
between arrows (window units) |
||
| real(kind=wp), | intent(in) | :: | speed |
of the arrows (window units per second) |
||
| real(kind=wp), | intent(in) | :: | band |
width of the band the arrows are drawn in (window units) |
||
| real(kind=wp), | intent(in) | :: | period |
of the pulse (s) |
Level of detail on (the default: seen from far away, a strip is drawn from fewer points, within half a pixel of all of them) or off (every point drawn).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(LineChain), | intent(inout) | :: | self | |||
| logical, | intent(in) | :: | enabled |
level of detail on (false: every point drawn) |
For markers, the color (rgba), size (window units), shape (shaders/marker.frag) and attenuation radius (scene units, 0 for none).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(LineChain), | intent(inout) | :: | self | |||
| real(kind=wp), | intent(in) | :: | color(4) |
[r, g, b, a] (0 to 1) |
||
| real(kind=wp), | intent(in) | :: | size |
(window units) |
||
| integer, | intent(in) | :: | shape |
marker shape (shaders/marker.frag) |
||
| real(kind=wp), | intent(in) | :: | radius |
attenuation radius (scene units; 0: none) |
For lines, a dash pattern (see line_set_pattern; z'FFFF' solid).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(LineChain), | intent(inout) | :: | self | |||
| integer, | intent(in) | :: | factor |
repeat count of each bit of the pattern |
||
| integer, | intent(in) | :: | pattern |
16-bit dash pattern (z'FFFF': solid) |
Color (rgba) and width (window units) of the whole chain.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(LineChain), | intent(inout) | :: | self | |||
| real(kind=wp), | intent(in) | :: | color(4) |
[r, g, b, a] (0 to 1) |
||
| real(kind=wp), | intent(in) | :: | width |
(window units) |
For strips, the trail (see vkf_line_set_trail: 20 values; the third 0: none), given to every chunk (changed every frame the time does: a few floats per chunk uploaded).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(LineChain), | intent(inout) | :: | self | |||
| real(kind=c_float), | intent(in) | :: | values(20) |
the trail (see vkf_line_set_trail) |
The part lo .. hi of points i1 .. i2 that chunk j holds, and its buffer p(xyz and distance, high/low, lo:hi) (null if none).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(LineChain), | intent(in) | :: | self | |||
| integer, | intent(in) | :: | j |
the chunk, and points i1 .. i2 (chain indices) |
||
| integer, | intent(in) | :: | i1 |
the chunk, and points i1 .. i2 (chain indices) |
||
| integer, | intent(in) | :: | i2 |
the chunk, and points i1 .. i2 (chain indices) |
||
| integer, | intent(out) | :: | lo |
chain indices (lo > hi: none) |
||
| integer, | intent(out) | :: | hi |
chain indices (lo > hi: none) |
||
| real(kind=c_float), | intent(out), | dimension(:,:,:), pointer | :: | p |
(4, 2, hi-lo+1) |
Distances s(n) into d(high/low, n).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| real(kind=wp), | intent(in) | :: | s(:) |
(n) |
||
| real(kind=c_float), | intent(inout) | :: | d(:,:) |
(2, n) |
Points x(3, n) into p(xyz and distance, high/low, n): the floats nearest, and the rest (the distances are left as they are).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| real(kind=wp), | intent(in) | :: | x(:,:) |
(3, n) |
||
| real(kind=c_float), | intent(inout) | :: | p(:,:,:) |
(4, 2, n) |
Give the chain's style to line, a node not in the chain (e.g. a
curve's trace-mode tail, drawn as part of it).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(LineChain), | intent(in) | :: | self | |||
| type(c_ptr), | intent(in) | :: | line |
node to style (not in the chain) |
Points lo .. hi of chunk j (a strip's) were written, the last being hi:
update the bounding box and the error bounds of the segments they change
at each stride, and give them to the renderer. x as in written.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(LineChain), | intent(inout) | :: | self | |||
| integer, | intent(in) | :: | j |
the chunk, and its points lo .. hi (chain indices) |
||
| integer, | intent(in) | :: | lo |
the chunk, and its points lo .. hi (chain indices) |
||
| integer, | intent(in) | :: | hi |
the chunk, and its points lo .. hi (chain indices) |
||
| real(kind=wp), | intent(in), | optional | :: | x(:,:) |
(3, chain points): the points, as in written |
Points i1 .. i2 were written: measure a strip's distances along it (from
the distance at point i1-1), update its level of detail, and upload the
chunks holding them. x: the points in double precision, x(:, i) for
chain point i (at least i1-1 .. i2), to measure from; without it, from
the floats written. (i2 is the last point written in the chain.)
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(LineChain), | intent(inout) | :: | self | |||
| integer, | intent(in) | :: | i1 |
points written (chain indices) |
||
| integer, | intent(in) | :: | i2 |
points written (chain indices) |
||
| real(kind=wp), | intent(in), | optional | :: | x(:,:) |
(3, at least i1-1 .. i2): the points |