Bases: Generic[PointT]
A Waypoint comprises an identifier, a position, and, optionally, bezier control point(s).
Positions are in the moving node's parent's frame. On the text plane a Coord is a cell, and means
Vec3(column, row, 0); a Vec3 can add a height toward the camera.
A waypoint (or a bezier control) can also be a node, such as another character or a body: a live target.
A path reads a live target's world position again every tick, so the mover heads for where it is now and
arrives on it exactly when the path finishes, however it moved.
A waypoint made by Path.walk is an amount instead: coord is Vec3(columns, rows, 0), and where the walk ends
is worked out from the previous waypoint when the path is activated.
Attributes:
| Name |
Type |
Description |
waypoint_id |
str
|
Unique identifier for the waypoint.
|
coord |
Coord | Vec3 | SpatialNode
|
Position of the waypoint as given, or the node it homes in on.
|
bezier_control |
tuple[Coord | Vec3 | SpatialNode, ...] | None
|
Optional bezier control point(s).
Defaults to None.
|
point |
Vec3
|
coord as a Vec3. For a live target, where it was last read, in the mover's frame. For a
walk, where it ended on the last activation.
|
Source code in terminaltexteffects/engine/motion.py
| @dataclass(frozen=True)
class Waypoint(typing.Generic[PointT]):
"""A Waypoint comprises an identifier, a position, and, optionally, bezier control point(s).
Positions are in the moving node's parent's frame. On the text plane a `Coord` is a cell, and means
`Vec3(column, row, 0)`; a `Vec3` can add a height toward the camera.
A waypoint (or a bezier control) can also be a node, such as another character or a body: a *live target*.
A path reads a live target's world position again every tick, so the mover heads for where it is now and
arrives on it exactly when the path finishes, however it moved.
A waypoint made by `Path.walk` is an amount instead: `coord` is `Vec3(columns, rows, 0)`, and where the walk ends
is worked out from the previous waypoint when the path is activated.
Attributes:
waypoint_id (str): Unique identifier for the waypoint.
coord (Coord | g3.Vec3 | SpatialNode): Position of the waypoint as given, or the node it homes in on.
bezier_control (tuple[Coord | g3.Vec3 | SpatialNode, ...] | None): Optional bezier control point(s).
Defaults to None.
point (g3.Vec3): `coord` as a `Vec3`. For a live target, where it was last read, in the mover's frame. For a
walk, where it ended on the last activation.
"""
waypoint_id: str
coord: PointT
bezier_control: tuple[Point | SpatialNode, ...] | None = None
_xyz: XYZ = field(init=False, repr=False, compare=False)
_curve_controls: tuple[XYZ | SpatialNode, ...] | None = field(init=False, repr=False, compare=False)
_target: SpatialNode | None = field(init=False, repr=False, compare=False)
_live: bool = field(init=False, repr=False, compare=False)
_walk: tuple[float, float] | None = field(init=False, repr=False, compare=False)
def __post_init__(self) -> None:
"""Keep the position as floats too, for stepping."""
# Written to __dict__ directly: the dataclass is frozen, and this runs for every waypoint.
attributes = self.__dict__
coord = self.coord
target = None
if type(coord) is Coord:
attributes["_xyz"] = (coord.column, coord.row, 0.0)
elif isinstance(coord, SpatialNode):
target = coord
attributes["_xyz"] = (0.0, 0.0, 0.0) # read when the path is activated
else:
attributes["_xyz"] = _as_xyz(coord)
attributes["_target"] = target
attributes["_walk"] = None
controls = self.bezier_control
if controls:
curve = tuple(c if isinstance(c, SpatialNode) else _as_xyz(c) for c in controls)
attributes["_curve_controls"] = curve
attributes["_live"] = target is not None or any(isinstance(c, SpatialNode) for c in curve)
else:
attributes["_curve_controls"] = None
attributes["_live"] = target is not None
@property
def point(self) -> g3.Vec3:
"""`coord` as a `Vec3`. For a live target, where it was last read, in the mover's frame."""
return g3.Vec3(*self._xyz)
|
point
property
coord as a Vec3. For a live target, where it was last read, in the mover's frame.
__post_init__()
Keep the position as floats too, for stepping.
Source code in terminaltexteffects/engine/motion.py
| def __post_init__(self) -> None:
"""Keep the position as floats too, for stepping."""
# Written to __dict__ directly: the dataclass is frozen, and this runs for every waypoint.
attributes = self.__dict__
coord = self.coord
target = None
if type(coord) is Coord:
attributes["_xyz"] = (coord.column, coord.row, 0.0)
elif isinstance(coord, SpatialNode):
target = coord
attributes["_xyz"] = (0.0, 0.0, 0.0) # read when the path is activated
else:
attributes["_xyz"] = _as_xyz(coord)
attributes["_target"] = target
attributes["_walk"] = None
controls = self.bezier_control
if controls:
curve = tuple(c if isinstance(c, SpatialNode) else _as_xyz(c) for c in controls)
attributes["_curve_controls"] = curve
attributes["_live"] = target is not None or any(isinstance(c, SpatialNode) for c in curve)
else:
attributes["_curve_controls"] = None
attributes["_live"] = target is not None
|