Loading...
Searching...
No Matches
TextToMesh.hpp
1#pragma once
2#include "TransformHelper.hpp"
3
4#include <ossia/dataflow/geometry_port.hpp>
5
6#include <Gfx/Graph/GpuResourceRegistry.hpp>
7
8#include <Threedim/TinyObj.hpp>
9#include <halp/controls.hpp>
10#include <halp/meta.hpp>
11
12#include <cstdint>
13#include <memory>
14
15class QRhiResourceUpdateBatch;
16
17namespace score::gfx
18{
19class RenderList;
20struct Edge;
21}
22
23namespace Threedim
24{
25
26// Rasterize text into 3D geometry. Each glyph outline is triangulated with
27// Qt's path triangulator (qTriangulate) under the non-zero fill rule, so
28// counters and overlapping contours are filled as the font defines them.
29// Output is a scene_spec containing one scene_node with one mesh_component
30// whose vertices describe the text in the XY plane (normal = +Z) around the
31// origin. '\n' starts a new line, one line spacing lower.
32//
33// Limitations (v1):
34// - Extrusion = 0 (flat). A later revision will extrude along -Z
35// with properly-oriented side walls.
36// - Tangents are synthesized as (1, 0, 0, 1) by ScenePreprocessor's
37// fallback — no per-vertex tangent computed here.
38//
39// Designed for VJ / title-card use rather than typography. For paragraph
40// text, use TextToTexture on a quad.
42{
43public:
44 halp_meta(name, "Text to Mesh")
45 halp_meta(category, "Visuals/3D/Text")
46 halp_meta(c_name, "text_to_mesh")
47 halp_meta(description, "Triangulate text outlines into flat mesh geometry in a 3D scene.")
48 halp_meta(authors, "ossia team")
49 halp_meta(
50 manual_url,
51 "https://ossia.io/score-docs/processes/text-to-mesh.html")
52 halp_meta(uuid, "c8f2a4d5-6e9b-4d3a-b7f1-5c4e2d8a9f6b")
53
54 struct ins
55 {
56 // Port-driven rebuild: controls trigger TextToMesh::rebuild() via
57 // their update() callbacks; operator()() just republishes m_state.
58 struct : halp::lineedit<"Text", "Hello">
59 { void update(TextToMesh& n) { n.rebuild(); } } text;
60 struct : halp::lineedit<"Font family", "Sans">
61 { void update(TextToMesh& n) { n.rebuild(); } } font_family;
62 struct : halp::spinbox_i32<"Font size", halp::irange{4, 512, 72}>
63 { void update(TextToMesh& n) { n.rebuild(); } } font_size;
64 struct : halp::toggle<"Bold">
65 { void update(TextToMesh& n) { n.rebuild(); } } bold;
66 struct : halp::toggle<"Italic">
67 { void update(TextToMesh& n) { n.rebuild(); } } italic;
68 // World-space height of a capital 'H'. Glyph paths come out in
69 // pixel units from Qt; we scale them to this target so the mesh
70 // lives at a sensible world scale regardless of font_size.
71 struct : halp::hslider_f32<"Height", halp::range{0.01, 100., 1.}>
72 { void update(TextToMesh& n) { n.rebuild(); } } height;
73 // Centers the text around the origin on the X axis (vs. left-align
74 // at X=0). Useful for title cards.
75 struct : halp::toggle<"Center X">
76 { void update(TextToMesh& n) { n.rebuild(); } } center_x;
77
78 struct : PositionControl
79 { void update(TextToMesh& n) { n.rebuild(); } } position;
80 struct : RotationControl
81 { void update(TextToMesh& n) { n.rebuild(); } } rotation;
82 struct : ScaleControl
83 { void update(TextToMesh& n) { n.rebuild(); } } scale;
84 } inputs;
85
86 struct outs
87 {
88 struct
89 {
90 halp_meta(name, "Scene Out");
91 ossia::scene_spec scene;
92 uint8_t dirty{0};
93 } scene_out;
94 } outputs;
95
96 void rebuild();
97 void operator()();
98
99 void init(score::gfx::RenderList& r, QRhiResourceUpdateBatch& res);
100 void update(
101 score::gfx::RenderList& r, QRhiResourceUpdateBatch& res,
103 void release(score::gfx::RenderList& r);
104
105 std::shared_ptr<ossia::scene_state> m_wrapped_state;
106 CachedTRS m_cachedTRS{};
107 // Mesh-rebuild cache — expensive tessellation only re-runs when text
108 // or font parameters actually change.
109 std::string m_cached_text;
110 std::string m_cached_family;
111 int m_cached_size{-1};
112 bool m_cached_bold{false};
113 bool m_cached_italic{false};
114 float m_cached_height{-1.f};
115 bool m_cached_center{false};
116 std::shared_ptr<ossia::mesh_component> m_cached_mesh;
117 int64_t m_version_counter{0};
118 uint8_t m_pending_dirty{0xFF};
119 // One identity for the text's material across rebuilds: a fresh one per
120 // edit changes every downstream materials fingerprint.
121 uint64_t m_material_stable_id{ossia::mint_stable_id()};
122
123 score::gfx::GpuResourceRegistry::Slot raw_transform_slot;
124 ossia::gpu_slot_ref m_xform_ref{};
125};
126
127}
Definition TextToMesh.hpp:42
List of nodes to be rendered to an output.
Definition RenderList.hpp:33
Graphics rendering pipeline for ossia score.
Definition Filter/PreviewWidget.hpp:11
Definition TransformHelper.hpp:26
Definition TinyObj.hpp:98
Definition TinyObj.hpp:103
Definition TinyObj.hpp:107
Definition TextToMesh.hpp:55
Definition TextToMesh.hpp:87
Connection between two score::gfx::Port.
Definition score-plugin-gfx/Gfx/Graph/Utils.hpp:236
Definition GpuResourceRegistry.hpp:84