A bevy 3D text mesh generator plugin for displaying text in 3D scenes
The text mesh is generated at runtime from runtime-tessellated (and cached) TrueType font glyphs. Tessellation of glyphs is done with C-based github.com/fetisov/ttf2mesh library that is being interfaced through Rust-based FFI API (see ttf2glyph-rs).
Consider this as a preview of the plugin for gathering feedback about the API:
- The API will change in future - still iterating
- Multiple
TextMesh
configuration fields are not implemented yet, see example below - Text color update is not implemented yet
- Spacing of characters are incorrect
- Mesh cache purging is not implemented - this implementation will leak memory (see #2)
- WASM builds are not supported (see #11)
bevy | bevy_text_mesh |
---|---|
0.12 | 0.9.0 |
0.11 | 0.7.0 |
0.10 | 0.6.0 |
0.9 | 0.5.0 |
0.8 | 0.4.0 |
0.7 | 0.2.0 |
0.6 | 0.1.0 |
0.5 | 0.0.2 |
Prequisites (for compiling ttf2mesh-rs):
apt-get install build-essential patch
See the examples -folder.
git clone https://github.com/blaind/bevy_text_mesh.git
cd bevy_text_mesh
cargo run --example 3d_scene --release # or
cargo run --example performance --release
Add to Cargo.toml:
[dependencies]
bevy_text_mesh = "0.9.0"
Include the library:
use bevy_text_mesh::prelude::*;
Second, add a TextMeshPlugin
to your app:
App::new()
...
.add_plugins(TextMeshPlugin)
...;
Then, add the desired TrueType-fonts (with suffix .ttf
) into your assets folder, a good convention is to store them to assets/fonts
folder.
For example, see Fira fonts. Please read also their LICENSE.
mkdir -p assets/fonts
wget https://github.com/mozilla/Fira/raw/master/ttf/FiraSans-Medium.ttf -O assets/fonts/FiraSans-Medium.ttf
Next, you are ready to spawn a text in your scene at a system:
First, load a font asset:
let font: Handle<TextMeshFont> = asset_server.load("fonts/FiraSans-Medium.ttf#mesh");
Then, spawn a textmesh bundle:
commands.spawn(TextMeshBundle {
text_mesh: TextMesh::new_with_color("Hello Bevy", font, Color::rgb(1., 1., 0.)),
transform: Transform::from_xyz(-1., 1.75, 0.),
..Default::default()
});
Or with expanded syntax:
commands.spawn(TextMeshBundle {
text_mesh: TextMesh {
text: String::from("Hello Bevy!"),
style: TextMeshStyle {
font,
font_size: SizeUnit::NonStandard(36.),
color: Color::rgb(1.0, 1.0, 0.0),
font_style: FontStyle::UPPERCASE, // only UPPERCASE & LOWERCASE implemented currently
mesh_quality: Quality::Low,
..Default::default()
},
alignment: TextMeshAlignment {
vertical: VerticalAlign::Top, // FUNCTIONALITY NOT IMPLEMENTED YET - NO EFFECT
horizontal: HorizontalAlign::Left, // FUNCTIONALITY NOT IMPLEMENTED YET - NO EFFECT
..Default::default()
},
size: TextMeshSize {
width: SizeUnit::NonStandard(135.), // partially implemented
height: SizeUnit::NonStandard(50.), // partially implemented
depth: Some(SizeUnit::NonStandard(50.0)), // must be > 0 currently, 2d mesh not supported yet
wrapping: true, // partially implemented
overflow: false, // NOT IMPLEMENTED YET
..Default::default()
},
..Default::default()
},
transform: Transform {
translation: Vec3::new(-1., 1.75, 0.),
..Default::default()
},
..Default::default()
});
Licensed under MIT license
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the software by you, shall be licensed as above, without any additional terms or conditions.