Skip to content

Commit 08ca628

Browse files
simbleauegenard
andauthored
Split VelloAsset into VelloSvg and VelloLottie (#90)
Builds upon #87. Merge that first. Closes #89. --------- Co-authored-by: Elie Génard <[email protected]>
1 parent 6a2d483 commit 08ca628

File tree

31 files changed

+1051
-649
lines changed

31 files changed

+1051
-649
lines changed

CHANGELOG.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@ This release supports Bevy version 0.14 and has an [MSRV][] of 1.80.
1818
### Changed
1919

2020
- bevy_vello now uses Bevy 0.15
21+
- `VelloAsset` assets have been separated into `VelloSvg` and `VelloLottie`
22+
- `VelloAssetBundle` has been separated into `VelloSvgBundle` and `VelloLottieBundle`
23+
- `Handle<VelloAsset>` has been separated into `VelloSvgHandle` and `VelloLottieHandle`
24+
- `VelloAssetAnchor` has been separated into `VelloSvgAnchor` and `VelloLottieAnchor`
2125
- The license on bevy_vello no longer includes OFL 1.1
2226

2327
### Fixed
@@ -265,4 +269,4 @@ This release supports Bevy version 0.13 and has an [MSRV][] of 1.77.
265269
[0.1.1]: https://github.com/linebender/bevy_vello/compare/v0.1.0...v0.1.1
266270
[0.1.0]: https://github.com/linebender/bevy_vello/releases/tag/v0.1.0
267271

268-
[MSRV]: README.md#minimum-supported-rust-version-msrv
272+
[MSRV]: README.md#minimum-supported-rust-version-msrv

examples/demo/src/main.rs

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,8 @@ fn main() {
2727
fn setup_vector_graphics(mut commands: Commands, asset_server: ResMut<AssetServer>) {
2828
commands.spawn((Camera2d, bevy_pancam::PanCam::default()));
2929
commands
30-
.spawn(VelloAssetBundle {
31-
asset: VelloAssetHandle(
32-
asset_server.load::<VelloAsset>("embedded://demo/assets/calendar.json"),
33-
),
30+
.spawn(VelloLottieBundle {
31+
asset: VelloLottieHandle(asset_server.load("embedded://demo/assets/calendar.json")),
3432
transform: Transform::from_translation(Vec3::new(0.0, 0.0, 0.0))
3533
.with_scale(Vec3::splat(20.0)),
3634
debug_visualizations: DebugVisualizations::Visible,
@@ -74,19 +72,16 @@ fn setup_vector_graphics(mut commands: Commands, asset_server: ResMut<AssetServe
7472
}
7573

7674
fn print_metadata(
77-
mut asset_ev: EventReader<AssetEvent<VelloAsset>>,
78-
assets: Res<Assets<VelloAsset>>,
75+
mut asset_ev: EventReader<AssetEvent<VelloLottie>>,
76+
assets: Res<Assets<VelloLottie>>,
7977
) {
8078
for ev in asset_ev.read() {
8179
if let AssetEvent::LoadedWithDependencies { id } = ev {
8280
let asset = assets.get(*id).unwrap();
83-
#[allow(irrefutable_let_patterns)]
84-
if let VectorFile::Lottie(composition) = &asset.file {
85-
info!(
86-
"Animated asset loaded. Layers:\n{:#?}",
87-
composition.as_ref().get_layers().collect::<Vec<_>>()
88-
);
89-
}
81+
info!(
82+
"Animated asset loaded. Layers:\n{:#?}",
83+
asset.composition.as_ref().get_layers().collect::<Vec<_>>()
84+
);
9085
}
9186
}
9287
}

examples/demo/src/ui.rs

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,21 +13,17 @@ pub fn controls_ui(
1313
&mut Playhead,
1414
&mut PlaybackOptions,
1515
&mut Theme,
16-
&VelloAssetHandle,
16+
&VelloLottieHandle,
1717
)>,
18-
assets: Res<Assets<VelloAsset>>,
18+
assets: Res<Assets<VelloLottie>>,
1919
) {
2020
let Ok((mut player, mut playhead, mut options, mut theme, handle)) = player.get_single_mut()
2121
else {
2222
return;
2323
};
2424

2525
let asset = assets.get(handle.id()).unwrap();
26-
#[allow(irrefutable_let_patterns)]
27-
let VectorFile::Lottie(composition) = &asset.file
28-
else {
29-
return;
30-
};
26+
let composition = asset.composition.as_ref();
3127

3228
let window = egui::Window::new("Controls")
3329
.resizable(false)
@@ -250,7 +246,7 @@ pub fn controls_ui(
250246
});
251247

252248
ui.heading("Theme");
253-
for layer in composition.as_ref().get_layers() {
249+
for layer in composition.get_layers() {
254250
let color = theme.get_mut(layer).cloned().unwrap_or_default();
255251
let color = color.to_srgba().to_u8_array();
256252
let mut color32 =

examples/drag_n_drop/src/main.rs

Lines changed: 29 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use bevy::{
33
prelude::*,
44
};
55
use bevy_vello::{prelude::*, VelloPlugin};
6+
use std::ffi::OsStr;
67

78
fn main() {
89
let mut app = App::new();
@@ -19,10 +20,9 @@ fn main() {
1920

2021
fn setup_vector_graphics(mut commands: Commands, asset_server: ResMut<AssetServer>) {
2122
commands.spawn(Camera2d);
22-
commands.spawn(VelloAssetBundle {
23-
asset: VelloAssetHandle(
24-
asset_server.load::<VelloAsset>("embedded://drag_n_drop/assets/fountain.svg"),
25-
),
23+
24+
commands.spawn(VelloSvgBundle {
25+
asset: VelloSvgHandle(asset_server.load("embedded://drag_n_drop/assets/fountain.svg")),
2626
debug_visualizations: DebugVisualizations::Visible,
2727
transform: Transform::from_scale(Vec3::splat(5.0)),
2828
..default()
@@ -32,18 +32,37 @@ fn setup_vector_graphics(mut commands: Commands, asset_server: ResMut<AssetServe
3232
/// Drag and drop any SVG or Lottie JSON asset into the window and change the
3333
/// displayed asset
3434
fn drag_and_drop(
35-
mut query: Query<&mut VelloAssetHandle>,
35+
mut commands: Commands,
36+
query_lottie: Option<Single<Entity, With<VelloLottieHandle>>>,
37+
query_svg: Option<Single<Entity, With<VelloSvgHandle>>>,
3638
asset_server: ResMut<AssetServer>,
3739
mut dnd_evr: EventReader<FileDragAndDrop>,
3840
) {
39-
let Ok(mut asset) = query.get_single_mut() else {
40-
return;
41-
};
4241
for ev in dnd_evr.read() {
42+
if let Some(ref svg) = query_svg {
43+
commands.entity(**svg).despawn();
44+
}
45+
if let Some(ref lottie) = query_lottie {
46+
commands.entity(**lottie).despawn();
47+
}
4348
let FileDragAndDrop::DroppedFile { path_buf, .. } = ev else {
4449
continue;
4550
};
46-
let new_handle = VelloAssetHandle(asset_server.load(path_buf.clone()));
47-
*asset = new_handle;
51+
let Some(ext) = path_buf.extension() else {
52+
continue;
53+
};
54+
let svg_ext = OsStr::new("svg");
55+
let lottie_ext = OsStr::new("json");
56+
if ext == svg_ext {
57+
commands.spawn(VelloSvgBundle {
58+
asset: VelloSvgHandle(asset_server.load(path_buf.clone())),
59+
..default()
60+
});
61+
} else if ext == lottie_ext {
62+
commands.spawn(VelloLottieBundle {
63+
asset: VelloLottieHandle(asset_server.load(path_buf.clone())),
64+
..default()
65+
});
66+
}
4867
}
4968
}

examples/lottie/src/main.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ fn load_lottie(mut commands: Commands, asset_server: ResMut<AssetServer>) {
2020
commands.spawn(Camera2d);
2121

2222
// Yes, it's this simple.
23-
commands.spawn(VelloAssetBundle {
24-
asset: VelloAssetHandle(asset_server.load("embedded://lottie/assets/Tiger.json")),
23+
commands.spawn(VelloLottieBundle {
24+
asset: VelloLottieHandle(asset_server.load("embedded://lottie/assets/Tiger.json")),
2525
debug_visualizations: DebugVisualizations::Visible,
2626
transform: Transform::from_scale(Vec3::splat(0.5)),
2727
..default()

examples/svg/src/main.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ fn load_svg(mut commands: Commands, asset_server: ResMut<AssetServer>) {
2020
commands.spawn(Camera2d);
2121

2222
// Yes, it's this simple.
23-
commands.spawn(VelloAssetBundle {
24-
asset: VelloAssetHandle(asset_server.load("embedded://svg/assets/fountain.svg")),
23+
commands.spawn(VelloSvgBundle {
24+
asset: VelloSvgHandle(asset_server.load("embedded://svg/assets/fountain.svg")),
2525
debug_visualizations: DebugVisualizations::Visible,
2626
transform: Transform::from_scale(Vec3::splat(5.0)),
2727
..default()

src/debug.rs

Lines changed: 80 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,5 @@
11
//! Logic for rendering debug visualizations
2-
use crate::{
3-
text::VelloTextAnchor, CoordinateSpace, VelloAsset, VelloAssetAnchor, VelloAssetHandle,
4-
VelloFont, VelloTextSection,
5-
};
2+
use crate::prelude::*;
63
use bevy::{color::palettes::css, math::Vec3Swizzles, prelude::*};
74

85
const RED_X_SIZE: f32 = 8.0;
@@ -11,7 +8,15 @@ pub struct DebugVisualizationsPlugin;
118

129
impl Plugin for DebugVisualizationsPlugin {
1310
fn build(&self, app: &mut App) {
14-
app.add_systems(Update, (render_asset_debug, render_text_debug));
11+
// TODO: Would be great if we could render scene debug, but Vello doesn't tell us the AABB or BB.
12+
13+
app.add_systems(Update, render_text_debug);
14+
15+
#[cfg(feature = "svg")]
16+
app.add_systems(Update, render_svg_debug);
17+
18+
#[cfg(feature = "lottie")]
19+
app.add_systems(Update, render_lottie_debug);
1520
}
1621
}
1722

@@ -23,19 +28,81 @@ pub enum DebugVisualizations {
2328
Visible,
2429
}
2530

26-
/// A system to render debug visualizations for `VelloAsset`.
27-
fn render_asset_debug(
31+
#[cfg(feature = "svg")]
32+
/// A system to render debug visualizations for SVGs.
33+
fn render_svg_debug(
34+
query_vectors: Query<
35+
(
36+
&VelloSvgHandle,
37+
&VelloSvgAnchor,
38+
&GlobalTransform,
39+
&CoordinateSpace,
40+
&DebugVisualizations,
41+
),
42+
Without<Node>,
43+
>,
44+
assets: Res<Assets<VelloSvg>>,
45+
query_cam: Query<(&Camera, &GlobalTransform, &OrthographicProjection), With<Camera2d>>,
46+
mut gizmos: Gizmos,
47+
) {
48+
let Ok((camera, view, projection)) = query_cam.get_single() else {
49+
return;
50+
};
51+
52+
// Show vectors
53+
for (asset, asset_anchor, gtransform, space, _) in query_vectors
54+
.iter()
55+
.filter(|(_, _, _, _, d)| **d == DebugVisualizations::Visible)
56+
{
57+
if let Some(asset) = assets.get(asset.id()) {
58+
match space {
59+
CoordinateSpace::WorldSpace => {
60+
// Origin
61+
let origin = gtransform.translation().xy();
62+
draw_origin(&mut gizmos, projection, origin);
63+
// Bounding box
64+
let gtransform = &asset_anchor.compute(asset.width, asset.height, gtransform);
65+
let rect_center = gtransform.translation().xy();
66+
let rect = asset.bb_in_world_space(gtransform);
67+
draw_bounding_box(&mut gizmos, rect_center, rect.size());
68+
}
69+
CoordinateSpace::ScreenSpace => {
70+
// Origin
71+
let origin = gtransform.translation().xy();
72+
let Ok(origin) = camera.viewport_to_world_2d(view, origin) else {
73+
continue;
74+
};
75+
draw_origin(&mut gizmos, projection, origin);
76+
// Bounding box
77+
let gtransform = &asset_anchor.compute(asset.width, asset.height, gtransform);
78+
let rect_center = gtransform.translation().xy();
79+
let Ok(rect_center) = camera.viewport_to_world_2d(view, rect_center) else {
80+
continue;
81+
};
82+
let Some(rect) = asset.bb_in_screen_space(gtransform, camera, view) else {
83+
continue;
84+
};
85+
draw_bounding_box(&mut gizmos, rect_center, rect.size());
86+
}
87+
}
88+
}
89+
}
90+
}
91+
92+
#[cfg(feature = "lottie")]
93+
/// A system to render debug visualizations for SVGs.
94+
fn render_lottie_debug(
2895
query_vectors: Query<
2996
(
30-
&VelloAssetHandle,
31-
&VelloAssetAnchor,
97+
&VelloLottieHandle,
98+
&VelloLottieAnchor,
3299
&GlobalTransform,
33100
&CoordinateSpace,
34101
&DebugVisualizations,
35102
),
36103
Without<Node>,
37104
>,
38-
assets: Res<Assets<VelloAsset>>,
105+
assets: Res<Assets<VelloLottie>>,
39106
query_cam: Query<(&Camera, &GlobalTransform, &OrthographicProjection), With<Camera2d>>,
40107
mut gizmos: Gizmos,
41108
) {
@@ -55,7 +122,7 @@ fn render_asset_debug(
55122
let origin = gtransform.translation().xy();
56123
draw_origin(&mut gizmos, projection, origin);
57124
// Bounding box
58-
let gtransform = &asset_anchor.compute(asset, gtransform);
125+
let gtransform = &asset_anchor.compute(asset.width, asset.height, gtransform);
59126
let rect_center = gtransform.translation().xy();
60127
let rect = asset.bb_in_world_space(gtransform);
61128
draw_bounding_box(&mut gizmos, rect_center, rect.size());
@@ -68,7 +135,7 @@ fn render_asset_debug(
68135
};
69136
draw_origin(&mut gizmos, projection, origin);
70137
// Bounding box
71-
let gtransform = &asset_anchor.compute(asset, gtransform);
138+
let gtransform = &asset_anchor.compute(asset.width, asset.height, gtransform);
72139
let rect_center = gtransform.translation().xy();
73140
let Ok(rect_center) = camera.viewport_to_world_2d(view, rect_center) else {
74141
continue;
@@ -222,6 +289,7 @@ fn draw_origin(gizmos: &mut Gizmos, projection: &OrthographicProjection, origin:
222289
gizmos.line_2d(from, to, css::RED);
223290
}
224291

292+
#[cfg(any(feature = "svg", feature = "lottie"))]
225293
/// A helper method to draw the bounding box
226294
fn draw_bounding_box(gizmos: &mut Gizmos, position: Vec2, size: Vec2) {
227295
gizmos.rect_2d(

0 commit comments

Comments
 (0)