From 4c02a98eb47f1f1cfc067270ed7dda0a887fd194 Mon Sep 17 00:00:00 2001 From: Nolan Darilek Date: Mon, 2 Dec 2024 11:34:28 -0600 Subject: [PATCH] fix: Clear generator when source is cleared, and improve handling for changing source types. --- src/lib.rs | 213 +++++++++++++++++++++++++++++------------------------ 1 file changed, 115 insertions(+), 98 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index c32ab22..ecfd8e2 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -403,6 +403,7 @@ fn update_source_properties( Option<&AngularPan>, Option<&ScalarPan>, Option<&GlobalTransform>, + Option<&mut Sound>, )>, ) { for ( @@ -416,110 +417,126 @@ fn update_source_properties( angular_pan, scalar_pan, transform, + sound, ) in &mut query { let Source { gain, .. } = *source; assert!(gain >= 0.); - if let Some(handle) = source.handle.as_mut() { - handle.gain().set(gain).expect("Failed to set gain"); - let mut clear_source = false; + let Some(handle) = source.handle.as_mut() else { + continue; + }; + handle.gain().set(gain).expect("Failed to set gain"); + let mut clear_source = false; + if let Some(source) = handle.cast_to::().expect("Failed to cast") { if let Some(transform) = transform { - if let Some(source) = handle.cast_to::().expect("Failed to cast") { - let translation = transform.translation(); - source - .position() - .set(( - translation.x as f64, - translation.y as f64, - translation.z as f64, - )) - .expect("Failed to set position"); - let distance_model = distance_model - .cloned() - .map(|v| *v) - .unwrap_or_else(|| context.default_distance_model().get().unwrap()); - source - .distance_model() - .set(distance_model) - .expect("Failed to set distance_model"); - let distance_ref = distance_ref - .map(|v| **v) - .unwrap_or_else(|| context.default_distance_ref().get().unwrap()); - assert!(distance_ref >= 0.); - source - .distance_ref() - .set(distance_ref) - .expect("Failed to set distance_ref"); - let distance_max = distance_max - .map(|v| **v) - .unwrap_or_else(|| context.default_distance_max().get().unwrap()); - assert!(distance_max >= 0.); - source - .distance_max() - .set(distance_max) - .expect("Failed to set distance_max"); - let rolloff = rolloff - .map(|v| **v) - .unwrap_or_else(|| context.default_rolloff().get().unwrap()); - assert!(rolloff >= 0.); - source - .rolloff() - .set(rolloff) - .expect("Failed to set rolloff"); - let closeness_boost = closeness_boost - .map(|v| **v) - .unwrap_or_else(|| context.default_closeness_boost().get().unwrap()); - assert!(closeness_boost >= 0.); - source - .closeness_boost() - .set(closeness_boost) - .expect("Failed to set closeness_boost"); - let closeness_boost_distance = - closeness_boost_distance.map(|v| **v).unwrap_or_else(|| { - context.default_closeness_boost_distance().get().unwrap() - }); - assert!(closeness_boost_distance >= 0.); - source - .closeness_boost_distance() - .set(closeness_boost_distance) - .expect("Failed to set closeness_boost_distance"); - } else { - clear_source = true; - } - } else if let Some(angular_pan) = angular_pan { - if let Some(source) = handle - .cast_to::() - .expect("Failed to cast") - { - assert!(angular_pan.azimuth >= 0. && angular_pan.azimuth <= 360.); - source - .azimuth() - .set(angular_pan.azimuth) - .expect("Failed to set azimuth"); - assert!(angular_pan.elevation >= -90. && angular_pan.elevation <= 90.); - source - .elevation() - .set(angular_pan.elevation) - .expect("Failed to set elevation"); - } else { - clear_source = true; - } - } else if let Some(scalar_pan) = scalar_pan { - if let Some(source) = handle - .cast_to::() - .expect("Failed to cast") - { - assert!(**scalar_pan >= -1. && **scalar_pan <= 1.); - source - .panning_scalar() - .set(**scalar_pan) - .expect("Failed to set scalar panning"); - } else { - clear_source = true; - } + let translation = transform.translation(); + source + .position() + .set(( + translation.x as f64, + translation.y as f64, + translation.z as f64, + )) + .expect("Failed to set position"); + let distance_model = distance_model + .cloned() + .map(|v| *v) + .unwrap_or_else(|| context.default_distance_model().get().unwrap()); + source + .distance_model() + .set(distance_model) + .expect("Failed to set distance_model"); + let distance_ref = distance_ref + .map(|v| **v) + .unwrap_or_else(|| context.default_distance_ref().get().unwrap()); + assert!(distance_ref >= 0.); + source + .distance_ref() + .set(distance_ref) + .expect("Failed to set distance_ref"); + let distance_max = distance_max + .map(|v| **v) + .unwrap_or_else(|| context.default_distance_max().get().unwrap()); + assert!(distance_max >= 0.); + source + .distance_max() + .set(distance_max) + .expect("Failed to set distance_max"); + let rolloff = rolloff + .map(|v| **v) + .unwrap_or_else(|| context.default_rolloff().get().unwrap()); + assert!(rolloff >= 0.); + assert!(rolloff >= 0.); + source + .rolloff() + .set(rolloff) + .expect("Failed to set rolloff"); + let closeness_boost = closeness_boost + .map(|v| **v) + .unwrap_or_else(|| context.default_closeness_boost().get().unwrap()); + assert!(closeness_boost >= 0.); + source + .closeness_boost() + .set(closeness_boost) + .expect("Failed to set closeness_boost"); + let closeness_boost_distance = closeness_boost_distance + .map(|v| **v) + .unwrap_or_else(|| context.default_closeness_boost_distance().get().unwrap()); + assert!(closeness_boost_distance >= 0.); + source + .closeness_boost_distance() + .set(closeness_boost_distance) + .expect("Failed to set closeness_boost_distance"); + } else { + println!("Clearing 3D source because no transform"); + clear_source = true; } - if clear_source { - source.handle = None; + } else if let Some(source) = handle + .cast_to::() + .expect("Failed to cast") + { + if let Some(angular_pan) = angular_pan { + assert!(angular_pan.azimuth >= 0. && angular_pan.azimuth <= 360.); + source + .azimuth() + .set(angular_pan.azimuth) + .expect("Failed to set azimuth"); + assert!(angular_pan.elevation >= -90. && angular_pan.elevation <= 90.); + source + .elevation() + .set(angular_pan.elevation) + .expect("Failed to set elevation"); + } else { + clear_source = true; + } + } else if let Some(source) = handle + .cast_to::() + .expect("Failed to cast") + { + if let Some(scalar_pan) = scalar_pan { + assert!(**scalar_pan >= -1. && **scalar_pan <= 1.); + source + .panning_scalar() + .set(**scalar_pan) + .expect("Failed to set scalar panning"); + } else { + clear_source = true; + } + } else if handle + .cast_to::() + .expect("Failed to cast") + .is_some() + { + if transform.is_some() || angular_pan.is_some() || scalar_pan.is_some() { + clear_source = true; + } + } else if source.handle.is_some() { + clear_source = true; + } + if clear_source { + source.handle = None; + if let Some(mut sound) = sound { + sound.generator = None; } } }