//! noise generation demo extern crate noise; extern crate rexpaint; use noise::{NoiseFn, Perlin, Seedable, Turbulence}; use rand::random; use rexpaint::{XpColor, XpFile}; use std::env; use std::fs::File; #[cfg_attr(rustfmt, rustfmt_skip)] const CMAP_FIRE: &'static [XpColor] = &[ XpColor { r: 0, g: 0, b: 0 }, XpColor { r: 255, g: 0, b: 0 }, XpColor { r: 255, g: 255, b: 0 }, XpColor { r: 255, g: 255, b: 255 }, ]; #[cfg_attr(rustfmt, rustfmt_skip)] const CMAP_NEBULA: &'static [XpColor] = &[ XpColor { r: 0, g: 0, b: 0 }, XpColor { r: 0, g: 0, b: 128 }, XpColor { r: 128, g: 0, b: 254 }, ]; fn lerp(a: XpColor, b: XpColor, i: f32) -> XpColor { if i <= 0.0 { a } else if i >= 1.0 { b } else { XpColor::new( ((a.r as f32) * (1.0 - i) + (b.r as f32) * i) as u8, ((a.g as f32) * (1.0 - i) + (b.g as f32) * i) as u8, ((a.b as f32) * (1.0 - i) + (b.b as f32) * i) as u8, ) } } fn cmap_lookup(cmap: &[XpColor], value: f32) -> XpColor { let i = ((value + 1.0) / 2.0) * ((cmap.len() - 1) as f32); let n = (i as i32).max(0).min((cmap.len() as i32) - 2); /* could use .clamp later */ lerp(cmap[n as usize], cmap[n as usize + 1], i - n as f32) } fn main() { let args: Vec = env::args().collect(); let width = args .get(1) .and_then(|x| x.parse::().ok()) .unwrap_or(80); let height = args .get(2) .and_then(|x| x.parse::().ok()) .unwrap_or(60); let cmap_name = args.get(3).cloned().unwrap_or("fire".to_string()); let mut xp = XpFile::new(width, height); let cmap = if cmap_name == "fire" { CMAP_FIRE } else if cmap_name == "nebula" { CMAP_NEBULA } else { panic!("unknown color map {}", cmap_name); }; println!( "generating {}×{} noise.xp, color map \"{}\"", width, height, cmap_name ); // Create some Turbulence noise let perlin = Perlin::new().set_seed(random()); let turbulence = Turbulence::new(&perlin); for y in 0..height { for x in 0..width { let val = turbulence.get([ (x as f64) / ((width - 1) as f64), (y as f64) / ((height - 1) as f64), ]) as f32; let cell = xp.layers[0].get_mut(x, y).unwrap(); cell.bg = cmap_lookup(cmap, val); } } let mut f = File::create("noise.xp").unwrap(); xp.write(&mut f).unwrap(); }