diff --git a/voxygen/src/scene/smoke_cycle.rs b/voxygen/src/scene/smoke_cycle.rs index 0c883808ca..3cf14d4d8e 100644 --- a/voxygen/src/scene/smoke_cycle.rs +++ b/voxygen/src/scene/smoke_cycle.rs @@ -40,6 +40,7 @@ fn seed_from_pos(pos: Vec3) -> [u8; 32] { ] } +#[derive(Debug)] struct FireplaceTiming { // all this assumes sunrise at 6am, sunset at 6pm breakfast: f32, // 5am to 7am @@ -62,6 +63,7 @@ const SMOKE_MAX_TEMP_VALUE: f32 = 1.0; const SMOKE_TEMP_MULTIPLIER: f32 = 96.0; const SMOKE_DAILY_VARIATION: f32 = 32.0; +#[derive(Debug)] struct FireplaceClimate { daily_strength: f32, // can be negative (offset) day_start: f32, // seconds since breakfast for daily cycle @@ -100,7 +102,7 @@ fn create_climate(temperature: f32, _humidity: f32) -> FireplaceClimate { } } -type Increasing = bool; +pub type Increasing = bool; pub fn smoke_at_time( position: Vec3, @@ -112,7 +114,6 @@ pub fn smoke_at_time( let timing = create_timing(&mut pseudorandom); let climate = create_climate(temperature, humidity); let after_breakfast = time_of_day - timing.breakfast; - //let after_dinner = time_of_day-timing.dinner; if after_breakfast < -SMOKE_BREAKFAST_HALF_DURATION { /* night */ (0.0, false) @@ -123,16 +124,16 @@ pub fn smoke_at_time( * (SMOKE_BREAKFAST_STRENGTH / SMOKE_BREAKFAST_HALF_DURATION), true, ) - } else if time_of_day < climate.day_start { + } else if after_breakfast < climate.day_start { /* cooling */ ( (SMOKE_BREAKFAST_HALF_DURATION - after_breakfast) * (SMOKE_BREAKFAST_STRENGTH / SMOKE_BREAKFAST_HALF_DURATION), false, ) - } else if time_of_day < climate.day_end { + } else if time_of_day < timing.dinner - climate.day_end { /* day cycle */ - let day_phase = ((time_of_day - climate.day_start) / timing.daily_cycle).fract(); + let day_phase = ((after_breakfast - climate.day_start) / timing.daily_cycle).fract(); if day_phase < 0.5 { ( (climate.daily_strength + day_phase * (2.0 * SMOKE_DAILY_VARIATION)).max(0.0), @@ -148,15 +149,15 @@ pub fn smoke_at_time( } else if time_of_day < timing.dinner { /* cooking dinner */ ( - (SMOKE_BREAKFAST_HALF_DURATION + time_of_day - timing.dinner) - * (SMOKE_BREAKFAST_STRENGTH / SMOKE_BREAKFAST_HALF_DURATION), + (SMOKE_DINNER_HALF_DURATION + time_of_day - timing.dinner) + * (SMOKE_DINNER_STRENGTH / SMOKE_DINNER_HALF_DURATION), true, ) } else { /* cooling + night */ ( - (SMOKE_BREAKFAST_HALF_DURATION - time_of_day + timing.dinner).max(0.0) - * (SMOKE_BREAKFAST_STRENGTH / SMOKE_BREAKFAST_HALF_DURATION), + (SMOKE_DINNER_HALF_DURATION - time_of_day + timing.dinner).max(0.0) + * (SMOKE_DINNER_STRENGTH / SMOKE_DINNER_HALF_DURATION), false, ) } @@ -166,18 +167,41 @@ pub fn smoke_at_time( mod tests { use super::*; - #[test] - fn test_smoke() { - let position = Vec3::new(22_i32, 11, 33); - let temperature = -0.5; - let humidity = 0.5; - for i in (0..24 * 4) { - let time_of_day = 15.0 * 60.0 * (i as f32); - println!( - "{:.2} {}", - time_of_day / (60.0 * 60.0), - smoke_at_time(position, temperature, humidity, time_of_day) + fn test_conditions(position: Vec3, temperature: f32, humidity: f32) { + print!("{} T{:.1} ", position, temperature); + let mut pseudorandom = ChaCha8Rng::from_seed(seed_from_pos(position)); + if true { + let timing = create_timing(&mut pseudorandom); + let climate = create_climate(temperature, humidity); + print!( + "B{:.1}+{:.1} D{:.1}-{:.1} C{:.0} S{:.0} ", + timing.breakfast / 3600.0, + climate.day_start / 3600.0, + timing.dinner / 3600.0, + climate.day_end / 3600.0, + timing.daily_cycle / 60.0, + climate.daily_strength ); } + for i in 0..24 { + print!(" {}:", i); + for j in 0..6 { + let time_of_day = 60.0 * 60.0 * (i as f32) + 60.0 * 10.0 * (j as f32); + let res = smoke_at_time(position, temperature, humidity, time_of_day); + print!("{:.0}{} ", res.0, if res.1 { "^" } else { "" },); + assert!(res.0>=0.0); + assert!(res.0<=SMOKE_DINNER_STRENGTH); + } + } + println!(); + } + + #[test] + fn test_smoke() { + test_conditions(Vec3::new(25_i32, 11, 33), -1.0, 0.5); + test_conditions(Vec3::new(22_i32, 11, 33), -0.5, 0.5); + test_conditions(Vec3::new(27_i32, 11, 33), 0.0, 0.5); + test_conditions(Vec3::new(24_i32, 11, 33), 0.5, 0.5); + test_conditions(Vec3::new(26_i32, 11, 33), 1.0, 0.5); } }