Saving my place

This was too much work to accidentally fuck it up with my "fixes"
main
Elijah C. Voigt 2 years ago
parent 8d88a54675
commit 399c1c6208

@ -4,23 +4,18 @@ use crate::{
tweak::Tweaks, tweak::Tweaks,
}; };
use bevy::{ use bevy::{
animation::RepeatAnimation, animation::RepeatAnimation, core_pipeline::{
core_pipeline::{
experimental::taa::{TemporalAntiAliasPlugin, TemporalAntiAliasSettings}, experimental::taa::{TemporalAntiAliasPlugin, TemporalAntiAliasSettings},
prepass::MotionVectorPrepass, prepass::MotionVectorPrepass,
tonemapping::{DebandDither, Tonemapping}, tonemapping::{DebandDither, Tonemapping},
Skybox, Skybox,
}, }, input::mouse::{MouseButtonInput, MouseMotion, MouseScrollUnit, MouseWheel}, pbr::{
input::mouse::{MouseButtonInput, MouseMotion, MouseScrollUnit, MouseWheel},
pbr::{
ExtendedMaterial, MaterialExtension, OpaqueRendererMethod, ExtendedMaterial, MaterialExtension, OpaqueRendererMethod,
ScreenSpaceAmbientOcclusionBundle, ScreenSpaceAmbientOcclusionSettings, ScreenSpaceAmbientOcclusionBundle, ScreenSpaceAmbientOcclusionSettings,
}, }, render::{
render::{
render_resource::{AsBindGroup, ShaderRef, TextureViewDescriptor, TextureViewDimension}, render_resource::{AsBindGroup, ShaderRef, TextureViewDescriptor, TextureViewDimension},
view::ColorGrading, view::ColorGrading,
}, }, utils::HashMap, window::PrimaryWindow
window::PrimaryWindow,
}; };
use tweaks::*; use tweaks::*;
@ -75,6 +70,7 @@ impl Plugin for Display3dPlugin {
.or_else(any_component_added::<PointLight>) .or_else(any_component_added::<PointLight>)
.or_else(on_event::<AssetEvent<Tweaks>>()), .or_else(on_event::<AssetEvent<Tweaks>>()),
), ),
setup_capture_piece.run_if(any_component_added::<Piece>),
capture_piece.run_if(any_with_component::<game::Captured>()), capture_piece.run_if(any_with_component::<game::Captured>()),
), ),
) )
@ -1283,6 +1279,58 @@ impl MaterialExtension for DissolveExtension {
#[derive(Debug, Component, Clone)] #[derive(Debug, Component, Clone)]
struct Backup<T: Component>(T); struct Backup<T: Component>(T);
/// Sets up all pieces to have an associated "dissolve" material ready for capture
fn setup_capture_piece(
// Only process newly created pieces (we do not delete pieces at runtime)
events: Query<Entity, Added<Piece>>,
// Children of pieces are the actual meshes that need materials
children: Query<&Children>,
// All entities with materials are candidates for this procedure
query: Query<(Entity, &Handle<StandardMaterial>)>,
// Used to create DissovleMaterial
standard_materials: Res<Assets<StandardMaterial>>,
// Used to create Handle<DissolveMaterial>
mut dissolve_materials: ResMut<Assets<DissolveMaterial>>,
// Used to insert Backup(Handle<DissolveMaterial>);
mut commands: Commands,
// Cache dissolve textures that have already been created
mut cache: Local<HashMap<Handle<StandardMaterial>, Handle<DissolveMaterial>>>,
) {
events.iter().for_each(|entity| {
query
.iter_many(children.iter_descendants(entity))
.for_each(|(child, std_handle)| {
let dis_handle = match cache.get(std_handle) {
// We have not seen this material, so create a new dissolve material
None => {
// Extension we will add to existing gltf-sourced materials
let extension = DissolveExtension { percentage: 1.0 };
// Base material we will extend for the duration of the dissolve effect
let mut base = standard_materials
.get(std_handle)
.expect("Resolve material data")
.clone();
base.opaque_render_method = OpaqueRendererMethod::Auto;
base.alpha_mode = AlphaMode::Mask(0.5);
dissolve_materials.add(ExtendedMaterial { base, extension })
},
Some(dis_handle) => dis_handle.clone(),
};
cache.insert(std_handle.clone(), dis_handle.clone());
commands
.entity(child)
.insert(dis_handle.clone())
.insert(Backup(std_handle.clone()))
.remove::<Handle<StandardMaterial>>();
})
}
);
}
/// When a piece is captured... /// When a piece is captured...
/// 1. Play a cool "captured" animation and a neat sound /// 1. Play a cool "captured" animation and a neat sound
/// 2. Move the piece to the side of the board /// 2. Move the piece to the side of the board
@ -1295,11 +1343,11 @@ fn capture_piece(
(With<Display3d>, With<game::Captured>), (With<Display3d>, With<game::Captured>),
>, >,
mut state: Local<Option<game::CaptureFlow>>, mut state: Local<Option<game::CaptureFlow>>,
standard_materials: ResMut<Assets<StandardMaterial>>, mut kids: Local<Vec<Entity>>,
mut prog: Local<f32>,
mut dissolve_materials: ResMut<Assets<DissolveMaterial>>, mut dissolve_materials: ResMut<Assets<DissolveMaterial>>,
object_standard_materials: Query<&Handle<StandardMaterial>>, object_standard_materials: Query<(Entity, &Handle<StandardMaterial>, &Backup<Handle<DissolveMaterial>>)>,
object_dissolve_materials: Query<&Handle<DissolveMaterial>>, object_dissolve_materials: Query<(Entity, &Handle<DissolveMaterial>, &Backup<Handle<StandardMaterial>>)>,
backup_material: Query<&Backup<Handle<StandardMaterial>>>,
children: Query<&Children>, children: Query<&Children>,
mut commands: Commands, mut commands: Commands,
time: Res<Time>, time: Res<Time>,
@ -1308,40 +1356,70 @@ fn capture_piece(
let duration: f32 = 3.0; let duration: f32 = 3.0;
match *state { match *state {
// State is None, so we need to initiate the animation by swapping the StadardMaterial for the DissolveMaterial
None => {
*state = events.iter().next().map(|entity| {
// Reset dissolve progress
*prog = 1.0;
// store the kids we want to process
*kids = children
.iter_descendants(entity)
.filter_map(|e| object_standard_materials.get(e).ok())
.map(|(child, std_handle, Backup(dis_handle))| {
// Swap standard and dissolve material
commands
.entity(child)
.insert(dis_handle.clone())
.insert(Backup(std_handle.clone()))
.remove::<Handle<StandardMaterial>>()
.remove::<Backup<Handle<DissolveMaterial>>>();
// Return child entity to be processed later in flow
child
}).collect();
// Set the next state to start fading out
game::CaptureFlow::FadeOut(entity)
});
}
Some(s) => { Some(s) => {
match s { match s {
game::CaptureFlow::FadeOut(entity) => { game::CaptureFlow::FadeOut(_entity) => {
// TODO: Do we need this?
let (_, _, _) = query
.get_mut(entity)
.expect("Visibility and Transform of captured piece");
// Play fade-out animation // Play fade-out animation
{ {
object_dissolve_materials.iter().for_each(|handle| {
let extended_material = dissolve_materials
.get_mut(handle)
.expect("Get the dissolve material");
// Calculate how much of the animation has passed // Calculate how much of the animation has passed
let delta = time.delta_seconds() / duration; let delta = time.delta_seconds() / duration;
// Change the material's value to create animation // Set progress to current - delta
extended_material.extension.percentage -= delta; // TODO: Tweak this timing *prog -= delta;
debug!( // If progress is less than zero
"Play fade out animation {:?} {:?}", if *prog <= 0.0 {
delta, extended_material.extension.percentage
);
if extended_material.extension.percentage <= 0.0 {
// Set to exactly 0 for simplicity // Set to exactly 0 for simplicity
extended_material.extension.percentage = 0.0; *prog = 0.0;
// Move to next state now that animation is done // Move to next state now that animation is done
*state = s.next(); *state = s.next();
// This takes effect after updating all children
} }
});
object_dissolve_materials
.iter_many(kids.iter())
.for_each(|(_child, dis_handle, _)| {
let dissolve_material = dissolve_materials
.get_mut(dis_handle)
.expect("Get the dissolve material");
// Change the material's value to create animation
dissolve_material.extension.percentage = *prog;
debug!(
"Play fade out animation {:?} {:?}",
delta, dissolve_material.extension.percentage
);
}
);
} }
} }
game::CaptureFlow::Store(entity) => { game::CaptureFlow::Store(entity) => {
@ -1366,76 +1444,50 @@ fn capture_piece(
// Show piece now that it is moved // Show piece now that it is moved
*v = Visibility::Inherited; *v = Visibility::Inherited;
// Play fade-in animation
{
object_dissolve_materials.iter().for_each(|handle| {
let extended_material = dissolve_materials
.get_mut(handle)
.expect("Get the dissolve material");
// Calculate how much of the animation has passed // Calculate how much of the animation has passed
let delta = time.delta_seconds() / duration; let delta = time.delta_seconds() / duration;
// Change the material's value to create animation // Move the animation forward by delta
extended_material.extension.percentage += delta; // TODO: Tweak this timing *prog += delta;
debug!( // If we have completed the animation
"Play fade in animation {:?} {:?}", if *prog >= 1.0 {
delta, extended_material.extension.percentage // Remove the captured component for bookkeeping
); commands.entity(entity).remove::<game::Captured>();
if extended_material.extension.percentage >= 1.0 {
// Move to next state now that animation is done // Move to next state now that animation is done
*state = s.next(); *state = s.next();
}
// Remove the captured component for bookkeeping // Play fade-in animation
commands.entity(entity).remove::<game::Captured>(); {
object_dissolve_materials.iter_many(kids.iter()).for_each(|(child, dis_handle, Backup(std_handle))| {
let dissolve_material = dissolve_materials
.get_mut(dis_handle)
.expect("Get the dissolve material");
// Remove the dissolve material // Change the material's value to create animation
commands.entity(entity).remove::<Handle<DissolveMaterial>>(); dissolve_material.extension.percentage = *prog;
debug!(
"Play fade in animation {:?} {:?}",
delta, dissolve_material.extension.percentage
);
// If we are done with the animation cleanup
if dissolve_material.extension.percentage >= 1.0 {
// Re-add the original material // Re-add the original material
if let Ok(Backup(orig)) = backup_material.get(entity) {
commands.entity(entity).insert(orig.clone());
commands commands
.entity(entity) .entity(child)
.insert(std_handle.clone())
.insert(Backup(dis_handle.clone()))
.remove::<Handle<DissolveMaterial>>()
.remove::<Backup<Handle<StandardMaterial>>>(); .remove::<Backup<Handle<StandardMaterial>>>();
} else {
warn!("Entity {:?} does not have original material", entity)
}
} }
}); });
} }
} }
} }
} }
None => {
*state = events.iter().next().map(|entity| {
children
.iter_descendants(entity)
.filter_map(|e| object_standard_materials.get(e).ok().map(|h| (e, h)))
.for_each(|(child, handle)| {
// Extension we will add to existing gltf-sourced materials
let extension = DissolveExtension { percentage: 1.0 };
// Base material we will extend for the duration of the dissolve effect
let mut base = standard_materials
.get(handle)
.expect("Resolve material data")
.clone();
base.opaque_render_method = OpaqueRendererMethod::Auto;
base.alpha_mode = AlphaMode::Mask(0.5);
commands
.entity(child)
.insert(dissolve_materials.add(ExtendedMaterial { base, extension }))
.insert(Backup(handle.clone()))
.remove::<Handle<StandardMaterial>>();
});
// Set the next state to start fading out
game::CaptureFlow::FadeOut(entity)
});
}
} }
} }

Loading…
Cancel
Save