// Demo code (c) by SEGFAULT
//
// This code and all image licensed under a
// Creative Commons Attribution-ShareAlike 4.0 International License.
//
// You should have received a copy of the license along with this
// work. If not, see .
//
// The images produced by this code are of a likeness to original art (c) Micha Scott
// All images generated by this program are (c) Micha Scott - All rights reserved.
extern crate png;
extern crate rand;
extern crate rustic_zen;
use std::fs::File;
use std::io::BufWriter;
use std::path::Path;
use std::sync::Arc;
use std::time;
// To use encoder.set()
use png::HasParameters;
use rand::Rng;
//Scene Parameters
use rustic_zen::prelude::*;
fn laser(angle: f64, wavelength: f64) -> Light {
Light::new(
(180.0, 80.0),
1.0,
(2.0, 0.0),
(360.0, 0.0),
angle,
wavelength,
)
}
fn main() {
//Initialising scene!
let now = time::Instant::now();
let width: f64 = 1920.0;
let height: f64 = 1080.0;
let rays = 1_000_000; //(width * height).round() as usize;
let threads = 8;
let wall_m = material::hqz_legacy(1.0, 0.0, 0.0);
let floor_m = material::hqz_legacy(0.1, 0.3, 0.5);
let top = Segment::line_from_points((0.0, 0.0), (width, 0.0), wall_m.clone());
let bottom = Segment::line_from_points((0.0, height), (width, height), wall_m.clone());
let left = Segment::line_from_points((0.0, 0.0), (0.0, height), wall_m.clone());
let right = Segment::line_from_points((width, 0.0), (width, height), wall_m.clone());
let floor = Segment::line_from_points(
(0.0, height * 0.72),
(width, ((height * 0.72) + 70.0, (height * 0.72) - 20.0)),
floor_m,
);
let r = Scene::new(width as usize, height as usize)
.with_light(laser(30.0, 694.0))
.with_light(laser(31.0, 676.0))
.with_light(laser(32.0, 647.0))
.with_light(laser(33.0, 635.0))
.with_light(laser(34.0, 633.0))
.with_light(laser(35.0, 628.0))
.with_light(laser(36.0, 612.0))
.with_light(laser(37.0, 594.0))
.with_light(laser(38.0, 578.0))
.with_light(laser(39.0, 568.0))
.with_light(laser(40.0, 543.0))
.with_light(laser(41.0, 532.0))
.with_light(laser(42.0, 530.0))
.with_light(laser(43.0, 514.0))
.with_light(laser(44.0, 511.0))
.with_light(laser(45.0, 501.0))
.with_light(laser(46.0, 496.0))
.with_light(laser(47.0, 488.0))
.with_light(laser(48.0, 475.0))
.with_light(laser(49.0, 458.0))
.with_light(laser(50.0, 442.0))
.with_light(laser(51.0, 428.0))
.with_light(laser(52.0, 416.0))
.with_object(floor)
.with_object(top)
.with_object(bottom)
.with_object(left)
.with_object(right);
let mut image = Arc::new(Image::new(width as usize, height as usize));
let setup = now.elapsed();
println!("Tracing {} rays, with {} threads!\n", rays, threads);
let now = time::Instant::now();
let rays = r.render(rays, threads, &mut image);
let tracing = now.elapsed();
//Downsampling Image!
let now: time::Instant = time::Instant::now();
let data = image.to_rgba8(rays, 0.2, 1.0 / 2.2); //1.0/2.2
let downsampling = now.elapsed();
//Saving!
let path = Path::new("laser-rainbow.png");
let file = File::create(path).unwrap();
let ref mut w = BufWriter::new(file);
let mut encoder = png::Encoder::new(w, width as u32, height as u32);
encoder.set(png::ColorType::RGBA).set(png::BitDepth::Eight);
let mut writer = encoder.write_header().unwrap();
writer.write_image_data(&data).unwrap();
println!("\nTiming Summary:");
println!(" Setup: {}ms", setup.as_millis());
println!(
" Tracing: {}ms ({}cpu ms)",
tracing.as_millis(),
tracing.as_millis() * threads as u128
);
println!(" Downsampling: {}ms\n", downsampling.as_millis());
println!(
"{} rays in {}ms: {}rays/s",
rays,
tracing.as_millis(),
rays as f32 / (tracing.as_millis() as f32 / 1000.0)
);
}