Street-name style text laid flat on the ground, following a line. More...
| Import Statement: | import Clayground.Canvas3D |
PathLabel3D writes text along a line of a LineBatch3D, the way a map paints a street name onto a road. It splits the text into words and places each word as a flat, unlit quad tangent to the path, so the label bends with the curve. The quads carry the words as 2x-oversampled textures, which stay crisp under the top-down/tactical cameras these labels are made for.
Placement rides the line's own geometry via pathLength() and positionAt(): the label centers on the path distance at (or the middle of the path when at is negative), and repeatEvery stamps the same name at a fixed spacing along a long road. To keep the name from ever appearing upside-down, PathLabel3D makes a single flip-to-read decision per placement from the placement's dominant direction and applies it to every word of that placement.
The placement is computed on demand - once, whenever an input changes - and then stays put. There is no per-frame tick: the quads are static geometry until lines, lineId, at, text or a sizing property changes.
By default PathLabel3D places one texture quad per word (cheap, bends at word boundaries). Set glyphPlacement to true for per-glyph text-on-curve (maplibre's model): the text is shaped once and each glyph is placed and rotated individually so the baseline hugs tight bends, rendered through an internal LabelBatch3D that is created lazily so word-mode labels pay for no SDF atlas.
Example usage:
import QtQuick3D import Clayground.Canvas3D View3D { LineBatch3D { id: roads } PathLabel3D { lines: roads lineId: 0 text: "CLAY STREET" worldHeight: 30 repeatEvery: 900 } }
See also LineBatch3D, Label3D, and LabelBatch3D.
at : real |
Path distance (world units) the label centers on.
A negative value (the default) auto-centers the label on the middle of the path. With repeatEvery set, this is the distance of the first placement.
glyphBatchActive : bool |
Whether the lazy internal glyph batch currently exists (read-only).
false whenever glyphPlacement is false - proof that word-mode labels allocate no glyph batch or atlas (the pay-per-use guarantee).
glyphPlacement : bool |
Selects per-glyph text-on-curve placement instead of per-word quads.
false (default): each whitespace-separated word is drawn as one flat 2x-oversampled texture quad tangent to the path - the classic, cheap street-name look. Bends happen at word boundaries only.true: the text is shaped once into glyphs and each glyph is placed and rotated individually along the curve (maplibre's model), so the baseline hugs tight bends smoothly. Rendering routes through an internal LabelBatch3D created lazily on first use - with glyphPlacement false no glyph batch or SDF atlas is ever allocated (pay-per-use).The two modes share at, repeatEvery and auto-centering semantics exactly. worldHeight, groundOffset and the labelStyle text color and halo carry across; a background pill (labelStyle.background) is not supported in glyph mode v1.
Note: Magnification differs by carrier: word mode packs each word into a 2x-oversampled raster texture, crisp down to roughly that oversample; glyph mode bakes an SDF atlas once and stays crisp at any zoom, at the cost of one atlas plus a per-glyph instance.
groundOffset : real |
Height in world units the quads sit above y=0 to avoid z-fighting.
labelStyle : QtObject |
Grouped ground-paint styling: color, halo, optional background, font.
| Sub-property | Meaning |
|---|---|
textColor | Text color (white default). |
halo | Whether the text gets an outline halo (on by default). |
haloColor | Halo color (dark default). |
background | Whether a filled pill sits behind the text (off by default - ground paint rarely wants one). |
backgroundColor | Background fill color when background is on. |
fontFamily | Text font family. |
fontSize | Source font pixel size (before oversample); drives texel density and aspect. |
bold | Whether the text is bold. |
paddingH | Horizontal padding in source pixels. |
paddingV | Vertical padding in source pixels. |
Note: Layout-affecting changes (fontSize, paddingH, paddingV, bold, fontFamily) alter word aspect, so set them before the label completes or call rebuild() afterwards.
lineId : int |
Index of the line inside lines to run the text along.
lines : QtObject |
The LineBatch3D whose geometry the label follows.
The label reads lines.pathLength(lineId) and lines.positionAt(lineId, d) to place its words; it never modifies the batch.
oversample : real |
Texture oversample factor for crispness (2 renders at 2x texels).
readingDirection : vector2d |
Reference reading direction in the ground (X, Z) plane.
A placement whose dominant direction points into the opposite half-plane (a negative dot with this vector) is flipped 180 degrees about the quad normal so the text reads the right way up. The default favours the +X/+Z half-plane.
repeatEvery : real |
Spacing in world units between repeated placements (0 = single).
When positive, the same name is stamped every repeatEvery units along the path, each placement deciding its own flip-to-read orientation - the street-name-repeated-along-a-road look.
skippedPlacements : int |
Number of placements skipped by the curvature guard (read-only).
In glyphPlacement mode a placement whose baseline would wrap too sharp an arc (a hairpin tighter than the label can follow) is dropped rather than drawn mirrored or overlapping; this counts how many were skipped on the last rebuild.
text : string |
The label text; split on whitespace into per-word quads.
uniqueTextureCount : int |
Number of distinct word textures currently in use (read-only).
One oversampled texture is shared by every placement of the same word, so a repeated "CLAY STREET" costs two textures, not two per repeat.
Note: Only meaningful in the default per-word texture mode; it is 0 in glyphPlacement mode, which draws no word textures.
wordSpacing : real |
Gap in world units between consecutive words. Negative auto-derives it from worldHeight.
worldHeight : real |
Text height in world units; the quad width follows the text aspect.
void rebuild() |
Recomputes word placement now. Called automatically on input change.