Skip to content

Commit

Permalink
Refactor to use type erased asset ids for materials.
Browse files Browse the repository at this point in the history
  • Loading branch information
tychedelia committed May 6, 2024
1 parent b65ca6a commit 79065e7
Show file tree
Hide file tree
Showing 9 changed files with 292 additions and 232 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion bevy_nannou_draw/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,5 @@ nannou_core = { path = "../nannou_core" }
rusttype = { version = "0.8", features = ["gpu_cache"] }
num-traits = "0.2"
bytemuck = "1.15.0"
rayon = "1.10"
rayon = "1.10"
uuid = "1.8"
8 changes: 2 additions & 6 deletions bevy_nannou_draw/src/draw/background.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use crate::draw::Draw;
use crate::draw::{Draw, DrawCommand};
use bevy::prelude::{Color, Material, World};
use crate::render::BackgroundColor;

/// A type used to update the background colour.
pub struct Background<'a, M>
Expand Down Expand Up @@ -32,10 +31,7 @@ impl<'a, M> Background<'a, M>
state.background_color = Some(color.into());
let color = state.background_color.unwrap();
let window = self.draw.window;
state.draw_commands.push(Some(Box::new(move |world: &mut World| {
world.entity_mut(window)
.insert(BackgroundColor(color));
})));
state.draw_commands.push(Some(DrawCommand::BackgroundColor(window, color)));
}
self
}
Expand Down
54 changes: 24 additions & 30 deletions bevy_nannou_draw/src/draw/drawing.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
use std::any::TypeId;
use std::marker::PhantomData;
use std::sync::{Arc, RwLock};
use bevy::asset::AsyncWriteExt;
use bevy::asset::{AsyncWriteExt, UntypedAssetId};

use bevy::pbr::{ExtendedMaterial, MaterialExtension};
use bevy::prelude::*;
use bevy::render::render_resource::BlendComponent;
use lyon::path::PathEvent;
use lyon::tessellation::{FillOptions, LineCap, LineJoin, StrokeOptions};
use uuid::Uuid;
use crate::changed::Cd;

use crate::draw::{Draw, DrawContext, DrawRef};
use crate::draw::{Draw, DrawCommand, DrawContext, DrawRef};
use crate::draw::mesh::MeshExt;
use crate::draw::primitive::Primitive;
use crate::draw::properties::{
Expand Down Expand Up @@ -120,32 +122,8 @@ where
// If we are "Owned", that means we mutated our material and so need to
// spawn a new entity just for this primitive.
DrawRef::Owned(draw) => {
let material = draw.material.clone();
state.draw_commands.push(Some(Box::new(move |world: &mut World| {
let mut materials = world.resource_mut::<Assets<M>>();
let material = materials.add(material);
let mut meshes = world.resource_mut::<Assets<Mesh>>();
let mesh = meshes.add(Mesh::init());

let entity = world.spawn((MaterialMeshBundle {
mesh: mesh.clone(),
material: material.clone(),
..Default::default()
}, NannouMesh)).id();

let mut render = world.get_resource_or_insert_with::<NannouRender>(|| {
NannouRender {
mesh: mesh.clone(),
entity: entity,
draw_context: DrawContext::default(),
}
});
render.mesh = mesh;
render.entity = entity;

// TODO: reset parent?? How does change detection work here?
// We should probably keep rendering into the same parent material.
})));
let id = draw.material.clone();
state.draw_commands.push(Some(DrawCommand::Material(id)));
},
DrawRef::Borrowed(_) => (),
}
Expand Down Expand Up @@ -184,13 +162,29 @@ where
{
self.finish_on_drop = false;
let Drawing { ref draw, index, .. } = self;
let material = map(self.draw.material.clone());

let state = draw.state.clone();
let material = state.read().unwrap().materials[&self.draw.material]
.downcast_ref::<M>()
.unwrap()
.clone();
let new_id = UntypedAssetId::Uuid {
type_id: TypeId::of::<M>(),
uuid: Uuid::new_v4(),
};

let material = map(material.clone());
let mut state = state.write().unwrap();
state.materials.insert(new_id.clone(), Box::new(material));

let draw = Draw {
state: draw.state.clone(),
context: draw.context.clone(),
material,
material: new_id.clone(),
window: draw.window,
_material: Default::default(),
};

Drawing {
draw: DrawRef::Owned(draw),
index,
Expand Down
55 changes: 5 additions & 50 deletions bevy_nannou_draw/src/draw/instanced.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
use crate::draw::mesh::MeshExt;
use crate::draw::primitive::Primitive;
use crate::draw::render::{GlyphCache, RenderContext, RenderPrimitive};
use crate::draw::{Background, Draw, primitive};
use crate::draw::{Background, Draw, DrawCommand, primitive};
use crate::render::{NannouMesh, NannouRender};
use bevy::{
core_pipeline::core_3d::Transparent3d,
Expand Down Expand Up @@ -77,59 +77,14 @@ where

fn insert_instanced_draw_command(&self, index: usize, data: InstanceMaterialData) {
let mut state = self.draw.state.write().unwrap();
let intermediary_state = state.intermediary_state.clone();
let theme = state.theme.clone();
let window = self.draw.window;
let primitive = state.drawing.remove(&index).unwrap();
state
.draw_commands
.push(Some(Box::new(move |world: &mut World| {
let mut fill_tessellator = FillTessellator::new();
let mut stroke_tessellator = StrokeTessellator::new();
let intermediary_state = intermediary_state.read().unwrap();
let mut q = world.query::<&crate::Draw>();
let draw = q.get(world, window).unwrap();
let primitive = draw.state.write().unwrap().drawing.remove(&index).unwrap();

world.resource_scope(|world, mut render: Mut<NannouRender>| {
world.resource_scope(|world, mut meshes: Mut<Assets<Mesh>>| {
world.resource_scope(|world, mut glyph_cache: Mut<GlyphCache>| {
let mut mesh = Mesh::init();
let ctxt = RenderContext {
intermediary_mesh: &intermediary_state.intermediary_mesh,
path_event_buffer: &intermediary_state.path_event_buffer,
path_points_colored_buffer: &intermediary_state
.path_points_colored_buffer,
path_points_textured_buffer: &intermediary_state
.path_points_textured_buffer,
text_buffer: &intermediary_state.text_buffer,
theme: &theme,
transform: &render.draw_context.transform,
fill_tessellator: &mut fill_tessellator,
stroke_tessellator: &mut stroke_tessellator,
glyph_cache: &mut glyph_cache,
// TODO: read from window
output_attachment_size: Vec2::new(100.0, 100.0),
output_attachment_scale_factor: 1.0,
};

primitive.render_primitive(ctxt, &mut mesh);
let mesh = mesh.with_removed_attribute(Mesh::ATTRIBUTE_COLOR);
let mesh = meshes.add(mesh);
world.spawn((
NannouMesh,
mesh,
SpatialBundle::INHERITED_IDENTITY,
data,
NoFrustumCulling,
));
});
});
});
})));
.push(Some(DrawCommand::Instanced(primitive, data)));
}
}

#[derive(Component, Deref)]
#[derive(Component, Deref, Clone, Debug)]
pub struct InstanceMaterialData(pub Vec<InstanceData>);

impl ExtractComponent for InstanceMaterialData {
Expand Down Expand Up @@ -165,7 +120,7 @@ impl Plugin for InstancingPlugin {
}
}

#[derive(Clone, Copy, Pod, Zeroable)]
#[derive(Debug, Clone, Copy, Pod, Zeroable)]
#[repr(C)]
pub struct InstanceData {
pub position: Vec3,
Expand Down
Loading

0 comments on commit 79065e7

Please sign in to comment.