|
| 1 | +use dot_vox; |
| 2 | +use euclid::Angle; |
| 3 | +use raydeon::lights::PointLight; |
| 4 | +use raydeon::shapes::AxisAlignedCuboid; |
| 5 | +use raydeon::{Camera, CameraOptions, DrawableShape, Material, Scene, SceneLighting}; |
| 6 | +use std::sync::Arc; |
| 7 | + |
| 8 | +const CASTLE_VOX: &[u8] = include_bytes!("./assets/castle.vox"); |
| 9 | + |
| 10 | +fn main() { |
| 11 | + env_logger::Builder::from_default_env() |
| 12 | + .format_timestamp_nanos() |
| 13 | + .init(); |
| 14 | + |
| 15 | + let castle_vox = dot_vox::load_bytes(CASTLE_VOX).expect("Could not load castle.vox"); |
| 16 | + |
| 17 | + let geometry: Vec<_> = castle_vox.models[0] |
| 18 | + .voxels |
| 19 | + .iter() |
| 20 | + .map(|v| { |
| 21 | + let x = v.x as f64; |
| 22 | + let y = v.y as f64; |
| 23 | + let z = v.z as f64; |
| 24 | + DrawableShape::new() |
| 25 | + .geometry(Arc::new( |
| 26 | + AxisAlignedCuboid::new() |
| 27 | + .min((x + 0.05, y + 0.05, z + 0.05)) |
| 28 | + .max((x + 0.95, y + 0.95, z + 0.95)) |
| 29 | + .build(), |
| 30 | + )) |
| 31 | + .material(Material::new().diffuse(5.0).build()) |
| 32 | + .build() |
| 33 | + }) |
| 34 | + .collect(); |
| 35 | + |
| 36 | + let eye = (10.0, -20.0, 0.0); |
| 37 | + let focus = (10.0, 0.0, 0.0); |
| 38 | + let up = (0.0, 0.0, 1.0); |
| 39 | + |
| 40 | + let fovy = 40.0; |
| 41 | + let width = 2048; |
| 42 | + let height = 2048; |
| 43 | + let znear = 0.1; |
| 44 | + let zfar = 200.0; |
| 45 | + |
| 46 | + let mut camera = Camera::configure() |
| 47 | + .observation(Camera::look_at(eye, focus, up)) |
| 48 | + .perspective(Camera::perspective(fovy, width, height, znear, zfar)) |
| 49 | + .render_options(CameraOptions::configure().pen_px_size(4.0).build()) |
| 50 | + .build(); |
| 51 | + |
| 52 | + camera.translate((-15.0, 10.75, 0.0)); |
| 53 | + camera.adjust_yaw(Angle::degrees(-45.0)); |
| 54 | + camera.translate((-10.5, 0.0, 12.0)); |
| 55 | + |
| 56 | + let scene = Scene::new() |
| 57 | + .geometry(geometry) |
| 58 | + .lighting( |
| 59 | + SceneLighting::new() |
| 60 | + .with_ambient_lighting(0.37) |
| 61 | + .with_lights(vec![Arc::new(PointLight::new( |
| 62 | + 55.0, |
| 63 | + 10.0, |
| 64 | + (-10.81, -20.0, 30.0), |
| 65 | + 0.0, |
| 66 | + 0.13, |
| 67 | + 0.19, |
| 68 | + ))]), |
| 69 | + ) |
| 70 | + .construct(); |
| 71 | + |
| 72 | + let paths = scene |
| 73 | + .attach_camera(camera) |
| 74 | + .with_seed(0) |
| 75 | + .render_with_lighting(); |
| 76 | + |
| 77 | + let mut svg_doc = svg::Document::new() |
| 78 | + .set("width", "8in") |
| 79 | + .set("height", "8in") |
| 80 | + .set("viewBox", (0, 0, width, height)) |
| 81 | + .set("stroke-width", "0.7mm") |
| 82 | + .set("stroke", "black") |
| 83 | + .set("fill", "none") |
| 84 | + .add( |
| 85 | + svg::node::element::Group::new().add( |
| 86 | + svg::node::element::Rectangle::new() |
| 87 | + .set("x", 0) |
| 88 | + .set("y", 0) |
| 89 | + .set("width", "100%") |
| 90 | + .set("height", "100%") |
| 91 | + .set("fill", "white"), |
| 92 | + ), |
| 93 | + ); |
| 94 | + |
| 95 | + // We have to flip the y-axis in our svg... |
| 96 | + let mut item_group = svg::node::element::Group::new() |
| 97 | + .set("transform", format!("translate(0, {}) scale(1,-1)", height)); |
| 98 | + |
| 99 | + for path in paths { |
| 100 | + let (p1, p2) = (path.p1, path.p2); |
| 101 | + item_group = item_group.add( |
| 102 | + svg::node::element::Line::new() |
| 103 | + .set("x1", p1.x) |
| 104 | + .set("y1", p1.y) |
| 105 | + .set("x2", p2.x) |
| 106 | + .set("y2", p2.y), |
| 107 | + ); |
| 108 | + } |
| 109 | + |
| 110 | + svg_doc = svg_doc.add(item_group); |
| 111 | + println!("{}", svg_doc); |
| 112 | +} |
0 commit comments