Skip to content

Commit

Permalink
fix color swap collision with vector instances
Browse files Browse the repository at this point in the history
Co-authored-by: Spencer C. Imbleau, M.Sc. (he/him) <[email protected]>
  • Loading branch information
seabassjh and simbleau committed Aug 16, 2023
1 parent 31368d7 commit c5191f8
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 81 deletions.
2 changes: 1 addition & 1 deletion src/assets/vector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ pub enum Vector {
Animated(velato::Composition),
}

#[derive(TypeUuid, TypePath)]
#[derive(TypeUuid, TypePath, Clone)]
#[uuid = "39cadc56-aa9c-4543-3640-a018b74b5053"]
pub struct VelloVector {
pub data: Vector,
Expand Down
54 changes: 28 additions & 26 deletions src/renderer/extract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,38 +23,40 @@ pub fn tag_vectors_for_render(

#[derive(Component, Clone)]
pub struct ExtractedRenderVector {
pub vector: Handle<VelloVector>,
pub vector_handle: Handle<VelloVector>,
pub render_data: VelloVector,
pub transform: GlobalTransform,
pub layer: Layer,
pub color_pallette_swap: Option<ColorPaletteSwap>,
pub ui_node: Option<Node>,
}

impl ExtractComponent for ExtractedRenderVector {
type Query = (
&'static Handle<VelloVector>,
&'static Layer,
&'static GlobalTransform,
Option<&'static ColorPaletteSwap>,
Option<&'static Node>,
);

type Filter = &'static RenderReadyTag;
type Out = Self;

fn extract_component(
(vello_vector_handle, layer, transform, color_pallette_swap, ui_node): bevy::ecs::query::QueryItem<
'_,
Self::Query,
>,
) -> Option<Self> {
Some(Self {
vector: vello_vector_handle.clone(),
transform: *transform,
layer: *layer,
color_pallette_swap: color_pallette_swap.cloned(),
ui_node: ui_node.cloned(),
})
pub fn vector_instances(
mut commands: Commands,
query_vectors: Extract<
Query<(
&Handle<VelloVector>,
&Layer,
&GlobalTransform,
Option<&ColorPaletteSwap>,
Option<&Node>,
)>,
>,
assets: Extract<Res<Assets<VelloVector>>>,
) {
for (vello_vector_handle, layer, transform, color_pallette_swap, ui_node) in
query_vectors.iter()
{
if let Some(asset_data) = assets.get(vello_vector_handle) {
commands.spawn(ExtractedRenderVector {
vector_handle: vello_vector_handle.clone(),
render_data: asset_data.to_owned(),
transform: *transform,
layer: *layer,
color_pallette_swap: color_pallette_swap.cloned(),
ui_node: ui_node.cloned(),
});
}
}
}

Expand Down
6 changes: 4 additions & 2 deletions src/renderer/plugin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,13 @@ impl Plugin for VelloRenderPlugin {
render_app.add_systems(Render, render::render_scene.in_set(RenderSet::Render));
render_app.add_systems(
ExtractSchedule,
extract::extract_pixel_scale.in_set(RenderSet::ExtractCommands),
(
extract::extract_pixel_scale.in_set(RenderSet::ExtractCommands),
extract::vector_instances,
),
);

app.add_plugins((
ExtractComponentPlugin::<extract::ExtractedRenderVector>::default(),
ExtractComponentPlugin::<extract::ExtractedRenderText>::default(),
ExtractComponentPlugin::<extract::SSRenderTarget>::default(),
RenderAssetPlugin::<VelloVector>::default(),
Expand Down
37 changes: 17 additions & 20 deletions src/renderer/prepare.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,18 @@ use crate::{

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

pub fn prepare_vector_composition_edits(
mut render_vectors: Query<&mut ExtractedRenderVector>,
mut render_vector_assets: ResMut<RenderAssets<VelloVector>>,
) {
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 render_vector in render_vectors.iter_mut() {
let Some(vector) = render_vector_assets.get_mut(&render_vector.vector) else {
'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;
};
let Vector::Animated(ref mut composition) = vector.data else {

// 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() {
Expand Down Expand Up @@ -49,18 +50,14 @@ pub fn prepare_vector_composition_edits(
// (solid.r, solid.g, solid.b, solid.a)
// );

if let Some(ColorPaletteSwap { colors }) = &render_vector.color_pallette_swap {
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(),
);
}
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(),
);
}
}
}
Expand Down Expand Up @@ -93,7 +90,7 @@ pub fn prepare_vector_affines(

let world_transform = render_vector.transform;
let (local_bottom_center_matrix, local_center_matrix, vector_size) =
match render_vector_assets.get(&render_vector.vector) {
match render_vector_assets.get(&render_vector.vector_handle) {
Some(render_instance_data) => (
render_instance_data.local_bottom_center_matrix,
render_instance_data.local_center_matrix,
Expand Down
43 changes: 11 additions & 32 deletions src/renderer/render.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
use std::sync::Arc;

use bevy::{
prelude::*,
reflect::TypeUuid,
Expand All @@ -8,7 +6,7 @@ use bevy::{
renderer::{RenderDevice, RenderQueue},
},
};
use vello::{RenderParams, Scene, SceneBuilder, SceneFragment};
use vello::{RenderParams, Scene, SceneBuilder};

use crate::{
assets::vector::{Vector, VelloVector},
Expand All @@ -24,7 +22,6 @@ use super::{

#[derive(Clone)]
pub struct ExtractedVectorAssetData {
vector: Vector,
local_transform_bottom_center: Transform,
local_transform_center: Transform,
size: Vec2,
Expand All @@ -39,7 +36,6 @@ impl RenderAsset for VelloVector {

fn extract_asset(&self) -> Self::ExtractedAsset {
ExtractedVectorAssetData {
vector: self.data.clone(),
local_transform_bottom_center: self.local_transform_bottom_center,
local_transform_center: self.local_transform_center,
size: Vec2::new(self.width, self.height),
Expand All @@ -62,7 +58,6 @@ impl RenderAsset for VelloVector {
pub struct PreparedVectorAssetData {
pub local_bottom_center_matrix: Mat4,
pub local_center_matrix: Mat4,
pub data: Vector,
pub size: Vec2,
}

Expand All @@ -73,29 +68,16 @@ impl From<ExtractedVectorAssetData> for PreparedVectorAssetData {
.compute_matrix()
.inverse();
let local_center_matrix = value.local_transform_center.compute_matrix().inverse();
let vector_data = value.vector;
let size = value.size;

PreparedVectorAssetData {
data: vector_data,
local_bottom_center_matrix,
local_center_matrix,
size,
}
}
}

impl Default for PreparedVectorAssetData {
fn default() -> Self {
Self {
data: Vector::Static(Arc::new(SceneFragment::default())),
local_bottom_center_matrix: Mat4::default(),
local_center_matrix: Mat4::default(),
size: Vec2::default(),
}
}
}

/// Transforms all the vectors extracted from the game world and places them in
/// a scene, and renders the scene to a texture with WGPU
#[allow(clippy::complexity)]
Expand All @@ -104,7 +86,6 @@ pub fn render_scene(
ss_render_target: Query<&SSRenderTarget>,
render_vectors: Query<(&PreparedAffine, &ExtractedRenderVector)>,
query_render_texts: Query<(&PreparedAffine, &ExtractedRenderText)>,
vector_render_assets: Res<RenderAssets<VelloVector>>,
mut font_render_assets: ResMut<RenderAssets<VelloFont>>,
gpu_images: Res<RenderAssets<Image>>,
device: Res<RenderDevice>,
Expand Down Expand Up @@ -184,20 +165,19 @@ pub fn render_scene(

// Apply transforms to the respective fragments and add them to the
// scene to be rendered
for (PreparedAffine(affine), ExtractedRenderVector { vector, .. }) in
vector_render_queue.iter()
for (
PreparedAffine(affine),
ExtractedRenderVector {
render_data: vector_data,
..
},
) in vector_render_queue.iter()
{
match vector_render_assets.get(vector) {
Some(PreparedVectorAssetData {
data: Vector::Static(fragment),
..
}) => {
match &vector_data.data {
Vector::Static(fragment) => {
builder.append(fragment, Some(*affine));
}
Some(PreparedVectorAssetData {
data: Vector::Animated(composition),
..
}) => {
Vector::Animated(composition) => {
velato_renderer.0.render(
composition,
time.elapsed_seconds(),
Expand All @@ -206,7 +186,6 @@ pub fn render_scene(
&mut builder,
);
}
None => {}
}
}

Expand Down

0 comments on commit c5191f8

Please sign in to comment.