Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove gz compression and color swap #19

Merged
merged 3 commits into from
Dec 22, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,12 @@ Subheadings to categorize changes are `added, changed, deprecated, removed, fixe

- `DebugVisualizations` are now feature-gated behind the `debug` cargo feature

### removed

- `.svg.gz` support - [Since a Gzip plugin is now possble](https://github.com/bevyengine/bevy/issues/10518)
- `.json.gz` support - [Since a Gzip plugin is now possble](https://github.com/bevyengine/bevy/issues/10518)
- color swapping: color swapping will be re-introduced in a future version when it is stabilized

## 0.3

### added
Expand Down
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ members = ["demo"]

[workspace.package]
edition = "2021"
version = "0.3.13"
version = "0.3.14"
license = "MIT OR Apache-2.0"
repository = "https://github.com/vectorgameexperts/bevy-vello"

Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@ A bevy plugin which provides rendering support for [lottie](https://lottiefiles.

## Bevy version support

**NOTE**: You must use a git rev for now, we cannot publish to crates.io. See [issue #3](https://github.com/vectorgameexperts/bevy-vello/issues/3).
**NOTE**: You must use a git rev for now, and match our version of vello. We cannot publish to crates.io. See [issue #3](https://github.com/vectorgameexperts/bevy-vello/issues/3).

|bevy|bevy-vello|
|---|---|
|0.12|0.3, main|
|0.11|0.2, main|
|0.11|0.2|
|<= 0.10|0.1|

## Cargo features
Expand Down
36 changes: 9 additions & 27 deletions demo/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,9 @@
use bevy::{asset::AssetMetaCheck, prelude::*};
use bevy_vello::{
debug::DebugVisualizations, ColorPaletteSwap, Origin, VelloPlugin, VelloText, VelloTextBundle,
VelloVector, VelloVectorBundle,
debug::DebugVisualizations, Origin, VelloPlugin, VelloText, VelloTextBundle, VelloVector,
VelloVectorBundle,
};

const BODY_BASE: Color = Color::rgba(129. / 255., 94. / 255., 1.0, 1.0);
const BODY_DARK: Color = Color::rgba(73. / 255., 20. / 255., 165. / 255., 1.0);
const TENTACLES_HIGHLIGHT: Color = Color::rgba(178. / 255., 168. / 255., 1.0, 1.0);
const SUCKERS: Color = Color::rgba(235. / 255., 189. / 255., 1.0, 1.0);

fn main() {
App::new()
.insert_resource(AssetMetaCheck::Never)
Expand All @@ -21,26 +16,13 @@ fn main() {

fn setup_vector_graphics(mut commands: Commands, asset_server: ResMut<AssetServer>) {
commands.spawn(Camera2dBundle::default());
commands
.spawn(VelloVectorBundle {
origin: bevy_vello::Origin::Center,
// Can only load *.json (Lottie animations) and *.svg (static vector graphics)
vector: asset_server.load("../assets/squid.json"),
debug_visualizations: DebugVisualizations::Visible,
..default()
})
.insert(
// This is optional, but demonstrates the ability to, at runtime, swap colors of individual layers on the vector animation programmatically
ColorPaletteSwap::empty()
.add("Arm", 1..=1, TENTACLES_HIGHLIGHT)
.add("Arm", 0..=0, BODY_BASE)
.add("Legs", 0..=0, BODY_BASE)
.add("Legs", 1..=1, TENTACLES_HIGHLIGHT)
.add("head", 4..=4, BODY_BASE)
.add("head", 1..=3, BODY_DARK)
.add("head", 5..=5, BODY_DARK)
.add("suckers", 0..=16, SUCKERS),
);
commands.spawn(VelloVectorBundle {
origin: bevy_vello::Origin::Center,
// Can only load *.json (Lottie animations) and *.svg (static vector graphics)
vector: asset_server.load("../assets/squid.json"),
debug_visualizations: DebugVisualizations::Visible,
..default()
});

commands.spawn(VelloTextBundle {
font: asset_server.load("../assets/Rubik-Medium.vttf"),
Expand Down
23 changes: 3 additions & 20 deletions src/assets/asset_loader.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::{
assets::parser::{load_lottie_from_bytes, load_svg_from_bytes},
compression, VelloVector,
VelloVector,
};
use bevy::{
asset::{io::Reader, AssetLoader, AsyncReadExt, LoadContext},
Expand Down Expand Up @@ -45,29 +45,12 @@ impl AssetLoader for VelloVectorLoader {
let mut bytes = Vec::new();
reader.read_to_end(&mut bytes).await?;
let path = load_context.path().to_owned();
let mut ext = path
let ext = path
.extension()
.and_then(std::ffi::OsStr::to_str)
.ok_or(VectorLoaderError::Parse("Invalid extension".to_string()))?
.to_owned();

let gzipped = ext == "gz";
if gzipped {
debug!("decompressing {}...", path.display());
// Decompress
let decrompressed_bytes = compression::decompress_gzip(&bytes)?;
let path_without_gz = path.with_extension("");
bytes = decrompressed_bytes.into_bytes();
// Remove .gz extension
ext = path_without_gz
.extension()
.and_then(std::ffi::OsStr::to_str)
.ok_or(VectorLoaderError::Parse(
"No extension before .gz?".to_string(),
))?
.to_string();
}

debug!("parsing {}...", load_context.path().display());
match ext.as_str() {
"svg" => {
Expand Down Expand Up @@ -101,6 +84,6 @@ impl AssetLoader for VelloVectorLoader {
}

fn extensions(&self) -> &[&str] {
&["svg", "json", "svg.gz", "json.gz"]
&["svg", "json"]
}
}
26 changes: 0 additions & 26 deletions src/compression.rs

This file was deleted.

48 changes: 1 addition & 47 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,11 @@
// #![deny(missing_docs)] - to add before 1.0
//! An integration to render SVG and Lottie assets in Bevy with Vello.

use bevy::{asset::load_internal_asset, prelude::*, sprite::Material2dPlugin, utils::HashMap};
use bevy::{asset::load_internal_asset, prelude::*, sprite::Material2dPlugin};
use font::VelloFont;
use renderer::VelloRenderPlugin;
use std::ops::RangeInclusive;

mod assets;
mod compression;
mod font;
mod metadata;
mod renderer;
Expand Down Expand Up @@ -79,50 +77,6 @@ pub enum Origin {
Center,
}

#[derive(PartialEq, Component, Default, Clone, Debug, Reflect)]
#[reflect(Component)]
/// Add this component to a `VelloVectorBundle` entity to enable runtime color editing.
/// This interface allows swapping colors in a lottie composition by selecting the desired layer
/// and shape and overriding the original color with a new color.
///
/// Only works for layer shapes with fill or stroke elements,
/// which must be fixed (non-animated, for now) and solid-colored (no gradients, for now)
pub struct ColorPaletteSwap {
colors: HashMap<(String, RangeInclusive<usize>), Color>,
}

impl ColorPaletteSwap {
pub fn empty() -> Self {
Self {
colors: HashMap::default(),
}
}

/// Swap a color for the selected layer and shape combination. `layer_filter` will select any layer which
/// contains the provided string. Select shapes within the layer with `shape_numbers`. Adding the same swap
/// (layer,shape) key will override the previous entry's color
pub fn add(
mut self,
layer_filter: &str,
shape_numbers: RangeInclusive<usize>,
color: Color,
) -> Self {
self.colors
.insert((layer_filter.to_string(), shape_numbers), color);
Self {
colors: self.colors,
}
}

/// Swap a color for the selected layer and shape combination. `layer_filter` will select any layer which
/// contains the provided string. Select shapes within the layer with `shape_numbers`. Editing colors with
/// an existing (layer,shape) key will override the previous entry's color
pub fn edit(&mut self, layer_filter: &str, shape_numbers: RangeInclusive<usize>, color: Color) {
self.colors
.insert((layer_filter.to_string(), shape_numbers), color);
}
}

#[derive(Bundle)]
pub struct VelloVectorBundle {
pub vector: Handle<VelloVector>,
Expand Down
6 changes: 1 addition & 5 deletions src/renderer/extract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use bevy::{
window::PrimaryWindow,
};

use crate::{font::VelloFont, ColorPaletteSwap, Origin, RenderMode, VelloText, VelloVector};
use crate::{font::VelloFont, Origin, RenderMode, VelloText, VelloVector};

#[derive(Component, Clone)]
pub struct ExtractedRenderVector {
Expand All @@ -13,7 +13,6 @@ pub struct ExtractedRenderVector {
pub transform: GlobalTransform,
pub render_mode: RenderMode,
pub origin: Origin,
pub color_pallette_swap: Option<ColorPaletteSwap>,
pub ui_node: Option<Node>,
}

Expand All @@ -25,7 +24,6 @@ pub fn vector_instances(
&RenderMode,
Option<&Origin>,
&GlobalTransform,
Option<&ColorPaletteSwap>,
Option<&Node>,
&ViewVisibility,
&InheritedVisibility,
Expand All @@ -38,7 +36,6 @@ pub fn vector_instances(
render_mode,
origin,
transform,
color_pallette_swap,
ui_node,
view_visibility,
inherited_visibility,
Expand All @@ -52,7 +49,6 @@ pub fn vector_instances(
transform: *transform,
render_mode: *render_mode,
origin: origin.copied().unwrap_or_default(),
color_pallette_swap: color_pallette_swap.cloned(),
ui_node: ui_node.cloned(),
});
}
Expand Down
4 changes: 0 additions & 4 deletions src/renderer/plugin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,6 @@ impl Plugin for VelloRenderPlugin {
Render,
prepare::prepare_vector_affines.in_set(RenderSet::Prepare),
);
render_app.add_systems(
Render,
prepare::prepare_vector_composition_edits.in_set(RenderSet::Prepare),
);
render_app.add_systems(
Render,
prepare::prepare_text_affines.in_set(RenderSet::Prepare),
Expand Down
55 changes: 1 addition & 54 deletions src/renderer/prepare.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,63 +4,10 @@ use bevy::{
};
use vello::kurbo::Affine;

use crate::{
assets::vector::{Vector, VelloVector},
ColorPaletteSwap, RenderMode,
};
use crate::{assets::vector::VelloVector, RenderMode};

use super::extract::{ExtractedPixelScale, ExtractedRenderText, ExtractedRenderVector};

pub fn prepare_vector_composition_edits(mut render_vectors: Query<&mut ExtractedRenderVector>) {
// Big-O: O(n), where n = shapes;
// Nesting: "vectors * layers * shape groups * shapes"
'vectors: for mut render_vector in render_vectors.iter_mut() {
// Get vector and color swap or there's no use continuing...

let Some(ColorPaletteSwap { colors }) = render_vector.color_pallette_swap.clone() else {
continue 'vectors;
};

// Perform recolors!
let Vector::Animated(ref mut composition) = render_vector.render_data.data else {
continue 'vectors;
};
'layers: for (_layer_index, layer) in composition.layers.iter_mut().enumerate() {
let vellottie::runtime::model::Content::Shape(ref mut shapes) = layer.content else {
continue 'layers;
};
'shapegroups: for (shape_index, shape) in shapes.iter_mut().enumerate() {
let vellottie::runtime::model::Shape::Group(ref mut shapes, _transform) = shape
else {
continue 'shapegroups;
};
'shapes: for shape in shapes.iter_mut() {
let vellottie::runtime::model::Shape::Draw(ref mut draw) = shape else {
continue 'shapes;
};
let vellottie::runtime::model::Brush::Fixed(ref mut brush) = draw.brush else {
continue 'shapes;
};
let vello::peniko::Brush::Solid(ref mut solid) = brush else {
continue 'shapes;
};

for ((layer_name, shape_indices), color) in colors.iter() {
if layer.name.contains(layer_name) && shape_indices.contains(&shape_index) {
*solid = vello::peniko::Color::rgba(
color.r().into(),
color.g().into(),
color.b().into(),
color.a().into(),
);
}
}
}
}
}
}
}

#[derive(Component, Copy, Clone)]
pub struct PreparedAffine(pub Affine);

Expand Down