Source code for simvx.core.nodes_3d.text

"""Text3D -- depth-tested MSDF text billboard at a 3D world position."""

from ..descriptors import Property
from ..math.types import Vec2
from ..properties import Colour
from .node3d import Node3D


[docs] class Text3D(Node3D): """Text that floats at a 3D world position as a depth-tested billboard. Rendered by the graphics backend's ``Billboard2DPass`` (design §5.2) as a camera-facing run of MSDF glyph quads, depth-tested against the 3D scene so the label is correctly occluded by (and occludes) geometry -- unlike a plain screen-space overlay. Symmetric with ``Text2D`` / ``Sprite3D``. ``font_scale`` is the text-size multiplier (the canonical ``font_scale * 16`` logical-pixel unit shared with the whole text family); ``pixel_size`` maps those logical pixels to world units, so the on-screen size scales with both the node's distance from the camera and ``pixel_size``. Example:: label = self.add_child(Text3D(text="Boss", position=(0, 2, -5))) label.font_scale = 2.0 """ text = Property("", hint="Text to display") font_scale = Property(1.0, range=(0.1, 100.0), hint="Text size multiplier (font_scale * 16 logical px)") pixel_size = Property(0.01, range=(0.0001, 1.0), hint="World units per logical pixel") colour = Colour((1.0, 1.0, 1.0, 1.0)) alignment = Property("centre", enum=["left", "centre", "right"], hint="Horizontal alignment about the anchor") billboard = Property(True, hint="Always face the camera") offset = Property(None, hint="Logical-pixel offset from position (Vec2)")
[docs] @property def pixel_offset(self) -> Vec2: """Offset from the anchor in logical pixels (``(0, 0)`` when unset).""" if self.offset is None: return Vec2(0.0, 0.0) return Vec2(float(self.offset[0]), float(self.offset[1]))
[docs] def on_draw(self, renderer) -> None: """Emit a depth-tested MSDF text billboard for the renderer (design §5.2).""" if not self.text or not self.visible: return draw = getattr(renderer, "draw_text_3d", None) if draw is None: # backend without the billboard pass return po = self.pixel_offset draw( text=self.text, position=self.world_position, font_scale=float(self.font_scale), pixel_size=float(self.pixel_size), colour=tuple(self.colour), alignment=str(self.alignment), offset=(float(po.x), float(po.y)), )