Refactor tonemapping example's image viewer update into two systems (#11519)
# Objective Alternative to #11515. Fixes change detection being triggered on the "image viewer image material" every frame. ## Solution - Split the megasystem into two separate systems: one to handle drop events, and one to handle asset change events. - Move the event reader iteration "outside." so that we're only doing stuff when there are events. - Flatten some of the more extreme nesting - Other bits of cleanup, removing an unnecessary clone and unused variable. I think these systems can even run in parallel now, not that it particularly matters.
This commit is contained in:
parent
45e920c2e1
commit
7da144bc3d
@ -40,7 +40,8 @@ fn main() {
|
|||||||
.add_systems(
|
.add_systems(
|
||||||
Update,
|
Update,
|
||||||
(
|
(
|
||||||
update_image_viewer,
|
drag_drop_image,
|
||||||
|
resize_image,
|
||||||
toggle_scene,
|
toggle_scene,
|
||||||
toggle_tonemapping_method,
|
toggle_tonemapping_method,
|
||||||
update_color_grading_settings,
|
update_color_grading_settings,
|
||||||
@ -292,58 +293,68 @@ fn setup_image_viewer_scene(
|
|||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
#[allow(clippy::too_many_arguments)]
|
fn drag_drop_image(
|
||||||
fn update_image_viewer(
|
image_mat: Query<&Handle<StandardMaterial>, With<HDRViewer>>,
|
||||||
image_mesh: Query<(&Handle<StandardMaterial>, &Handle<Mesh>), With<HDRViewer>>,
|
|
||||||
text: Query<Entity, (With<Text>, With<SceneNumber>)>,
|
text: Query<Entity, (With<Text>, With<SceneNumber>)>,
|
||||||
mut materials: ResMut<Assets<StandardMaterial>>,
|
mut materials: ResMut<Assets<StandardMaterial>>,
|
||||||
mut meshes: ResMut<Assets<Mesh>>,
|
|
||||||
images: Res<Assets<Image>>,
|
|
||||||
mut drop_events: EventReader<FileDragAndDrop>,
|
mut drop_events: EventReader<FileDragAndDrop>,
|
||||||
mut drop_hovered: Local<bool>,
|
|
||||||
asset_server: Res<AssetServer>,
|
asset_server: Res<AssetServer>,
|
||||||
mut image_events: EventReader<AssetEvent<Image>>,
|
|
||||||
mut commands: Commands,
|
mut commands: Commands,
|
||||||
) {
|
) {
|
||||||
let mut new_image: Option<Handle<Image>> = None;
|
let Some(new_image) = drop_events.read().find_map(|e| match e {
|
||||||
|
FileDragAndDrop::DroppedFile { path_buf, .. } => {
|
||||||
|
Some(asset_server.load(path_buf.to_string_lossy().to_string()))
|
||||||
|
}
|
||||||
|
_ => None,
|
||||||
|
}) else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
for event in drop_events.read() {
|
for mat_h in &image_mat {
|
||||||
match event {
|
if let Some(mat) = materials.get_mut(mat_h) {
|
||||||
FileDragAndDrop::DroppedFile { path_buf, .. } => {
|
mat.base_color_texture = Some(new_image.clone());
|
||||||
new_image = Some(asset_server.load(&path_buf.to_string_lossy().to_string()));
|
|
||||||
*drop_hovered = false;
|
// Despawn the image viewer instructions
|
||||||
|
if let Ok(text_entity) = text.get_single() {
|
||||||
|
commands.entity(text_entity).despawn();
|
||||||
}
|
}
|
||||||
FileDragAndDrop::HoveredFile { .. } => *drop_hovered = true,
|
|
||||||
FileDragAndDrop::HoveredFileCanceled { .. } => *drop_hovered = false,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (mat_h, mesh_h) in &image_mesh {
|
fn resize_image(
|
||||||
if let Some(mat) = materials.get_mut(mat_h) {
|
image_mesh: Query<(&Handle<StandardMaterial>, &Handle<Mesh>), With<HDRViewer>>,
|
||||||
if let Some(ref new_image) = new_image {
|
materials: Res<Assets<StandardMaterial>>,
|
||||||
mat.base_color_texture = Some(new_image.clone());
|
mut meshes: ResMut<Assets<Mesh>>,
|
||||||
|
images: Res<Assets<Image>>,
|
||||||
|
mut image_events: EventReader<AssetEvent<Image>>,
|
||||||
|
) {
|
||||||
|
for event in image_events.read() {
|
||||||
|
let (AssetEvent::Added { id } | AssetEvent::Modified { id }) = event else {
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
|
||||||
if let Ok(text_entity) = text.get_single() {
|
for (mat_h, mesh_h) in &image_mesh {
|
||||||
commands.entity(text_entity).despawn();
|
let Some(mat) = materials.get(mat_h) else {
|
||||||
}
|
continue;
|
||||||
}
|
};
|
||||||
|
|
||||||
for event in image_events.read() {
|
let Some(ref base_color_texture) = mat.base_color_texture else {
|
||||||
let image_changed_id = *match event {
|
continue;
|
||||||
AssetEvent::Added { id } | AssetEvent::Modified { id } => id,
|
};
|
||||||
_ => continue,
|
|
||||||
};
|
if *id != base_color_texture.id() {
|
||||||
if let Some(base_color_texture) = mat.base_color_texture.clone() {
|
continue;
|
||||||
if image_changed_id == base_color_texture.id() {
|
};
|
||||||
if let Some(image_changed) = images.get(image_changed_id) {
|
|
||||||
let size = image_changed.size_f32().normalize_or_zero() * 1.4;
|
let Some(image_changed) = images.get(*id) else {
|
||||||
// Resize Mesh
|
continue;
|
||||||
let quad = Mesh::from(shape::Quad::new(size));
|
};
|
||||||
meshes.insert(mesh_h, quad);
|
|
||||||
}
|
let size = image_changed.size_f32().normalize_or_zero() * 1.4;
|
||||||
}
|
// Resize Mesh
|
||||||
}
|
let quad = Mesh::from(shape::Quad::new(size));
|
||||||
}
|
meshes.insert(mesh_h, quad);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user