clean up method order and add some doc
This commit is contained in:
		
							parent
							
								
									34a7708c0d
								
							
						
					
					
						commit
						1c6d05946b
					
				
					 1 changed files with 259 additions and 244 deletions
				
			
		
							
								
								
									
										503
									
								
								src/main.rs
									
									
									
									
									
								
							
							
						
						
									
										503
									
								
								src/main.rs
									
									
									
									
									
								
							| 
						 | 
					@ -22,6 +22,7 @@ use std::sync::Arc;
 | 
				
			||||||
use tobj;
 | 
					use tobj;
 | 
				
			||||||
use vec3::{Color, Point3, Vec3};
 | 
					use vec3::{Color, Point3, Vec3};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Gets the pixel color for the passed ray */
 | 
				
			||||||
fn ray_color(r: &Ray, world: &HittableList, depth: u32) -> Color {
 | 
					fn ray_color(r: &Ray, world: &HittableList, depth: u32) -> Color {
 | 
				
			||||||
    let mut rec = HitRecord::empty();
 | 
					    let mut rec = HitRecord::empty();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -46,251 +47,19 @@ fn ray_color(r: &Ray, world: &HittableList, depth: u32) -> Color {
 | 
				
			||||||
    return (1.0 - t) * Color::new(1.0, 1.0, 1.0) + t * Color::new(0.5, 0.7, 1.0);
 | 
					    return (1.0 - t) * Color::new(1.0, 1.0, 1.0) + t * Color::new(0.5, 0.7, 1.0);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
fn random_world() -> HittableList {
 | 
					// Current world view:
 | 
				
			||||||
    let mut world = HittableList::new();
 | 
					//
 | 
				
			||||||
 | 
					//             I y
 | 
				
			||||||
    let material_ground = Arc::new(Lambertian::new(&Color::new(0.05, 0.05, 0.05)));
 | 
					//             I
 | 
				
			||||||
    world.add(Box::<Sphere>::new(Sphere::new(
 | 
					//             I
 | 
				
			||||||
        Point3::new(0.0, -50000.0, 0.0),
 | 
					//             I
 | 
				
			||||||
        50000.0,
 | 
					//           /   \
 | 
				
			||||||
        material_ground.clone(),
 | 
					//         /       \
 | 
				
			||||||
    )));
 | 
					//       /           \
 | 
				
			||||||
 | 
					//     / z             \ x
 | 
				
			||||||
    (-6..5).into_iter().for_each(|a| {
 | 
					 | 
				
			||||||
        (-6..5).into_iter().for_each(|b| {
 | 
					 | 
				
			||||||
            let choose_mat = utility::random_f64();
 | 
					 | 
				
			||||||
            let rad = utility::random_rng(0.1, 0.5);
 | 
					 | 
				
			||||||
            let center = Point3::new(
 | 
					 | 
				
			||||||
                1.5 * a as f64 + 1.3 * utility::random_f64(),
 | 
					 | 
				
			||||||
                rad,
 | 
					 | 
				
			||||||
                1.5 * b as f64 + 1.3 * utility::random_f64(),
 | 
					 | 
				
			||||||
            );
 | 
					 | 
				
			||||||
            if (center - Point3::new(4.0, rad, 0.0)).length() > 0.9 {
 | 
					 | 
				
			||||||
                if choose_mat < 0.8 {
 | 
					 | 
				
			||||||
                    // diffuse
 | 
					 | 
				
			||||||
                    let sphere_material = Arc::new(Lambertian::new(
 | 
					 | 
				
			||||||
                        &(Color::random_f64() * Color::random_f64()),
 | 
					 | 
				
			||||||
                    ));
 | 
					 | 
				
			||||||
                    world.add(Box::<Sphere>::new(Sphere::new(
 | 
					 | 
				
			||||||
                        center,
 | 
					 | 
				
			||||||
                        rad,
 | 
					 | 
				
			||||||
                        sphere_material.clone(),
 | 
					 | 
				
			||||||
                    )));
 | 
					 | 
				
			||||||
                } else if choose_mat < 0.95 {
 | 
					 | 
				
			||||||
                    // metal
 | 
					 | 
				
			||||||
                    let sphere_material = Arc::new(Metal::new(
 | 
					 | 
				
			||||||
                        &Color::random_rng(0.5, 1.0),
 | 
					 | 
				
			||||||
                        utility::random_rng(0.0, 0.5),
 | 
					 | 
				
			||||||
                    ));
 | 
					 | 
				
			||||||
                    world.add(Box::<Sphere>::new(Sphere::new(
 | 
					 | 
				
			||||||
                        center,
 | 
					 | 
				
			||||||
                        0.2,
 | 
					 | 
				
			||||||
                        sphere_material.clone(),
 | 
					 | 
				
			||||||
                    )));
 | 
					 | 
				
			||||||
                } else {
 | 
					 | 
				
			||||||
                    // glass
 | 
					 | 
				
			||||||
                    let sphere_material = Arc::new(Dielectric::new(1.5));
 | 
					 | 
				
			||||||
                    world.add(Box::<Sphere>::new(Sphere::new(
 | 
					 | 
				
			||||||
                        center,
 | 
					 | 
				
			||||||
                        0.2,
 | 
					 | 
				
			||||||
                        sphere_material.clone(),
 | 
					 | 
				
			||||||
                    )));
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    let material1 = Arc::new(Dielectric::new(1.5));
 | 
					 | 
				
			||||||
    let material2 = Arc::new(Lambertian::new(&Color::new(0.4, 0.2, 0.1)));
 | 
					 | 
				
			||||||
    let material3 = Arc::new(Metal::new(&Color::new(0.7, 0.6, 0.5), 0.0));
 | 
					 | 
				
			||||||
    let material4 = Arc::new(Dielectric::new(2.0));
 | 
					 | 
				
			||||||
    let material5 = Arc::new(Metal::new(&Color::new(0.9, 0.9, 0.7), 0.0));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    world.add(Box::<Sphere>::new(Sphere::new(
 | 
					 | 
				
			||||||
        Point3::new(0.0, 1.0, 0.0),
 | 
					 | 
				
			||||||
        1.0,
 | 
					 | 
				
			||||||
        material2.clone(),
 | 
					 | 
				
			||||||
    )));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    world.add(Box::<Sphere>::new(Sphere::new(
 | 
					 | 
				
			||||||
        Point3::new(-4.0, 1.0, 0.0),
 | 
					 | 
				
			||||||
        1.0,
 | 
					 | 
				
			||||||
        material1.clone(),
 | 
					 | 
				
			||||||
    )));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    world.add(Box::<Sphere>::new(Sphere::new(
 | 
					 | 
				
			||||||
        Point3::new(4.0, 1.0, 0.0),
 | 
					 | 
				
			||||||
        1.0,
 | 
					 | 
				
			||||||
        material3.clone(),
 | 
					 | 
				
			||||||
    )));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    world.add(Box::<Sphere>::new(Sphere::new(
 | 
					 | 
				
			||||||
        Point3::new(-2.0, 2.0, -5.0),
 | 
					 | 
				
			||||||
        2.0,
 | 
					 | 
				
			||||||
        material4.clone(),
 | 
					 | 
				
			||||||
    )));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    world.add(Box::<Sphere>::new(Sphere::new(
 | 
					 | 
				
			||||||
        Point3::new(-3.6, 2.0, -2.0),
 | 
					 | 
				
			||||||
        0.6,
 | 
					 | 
				
			||||||
        material5.clone(),
 | 
					 | 
				
			||||||
    )));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /*
 | 
					 | 
				
			||||||
    world.add(Box::<Triangle>::new(Triangle::new(
 | 
					 | 
				
			||||||
        Point3::new(0.0, 1.0, 5.0),
 | 
					 | 
				
			||||||
        Point3::new(3.0, 2.0, 0.0),
 | 
					 | 
				
			||||||
        Point3::new(0.0, 4.0, 0.0),
 | 
					 | 
				
			||||||
        material2.clone(),
 | 
					 | 
				
			||||||
    )));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    world.add(Box::<Triangle>::new(Triangle::new(
 | 
					 | 
				
			||||||
        Point3::new(5.0, 1.0, -6.0),
 | 
					 | 
				
			||||||
        Point3::new(1.0, 3.0, -5.0),
 | 
					 | 
				
			||||||
        Point3::new(6.0, 4.0, -6.0),
 | 
					 | 
				
			||||||
        material5.clone(),
 | 
					 | 
				
			||||||
    )));
 | 
					 | 
				
			||||||
    world.add(Box::<Triangle>::new(Triangle::new(
 | 
					 | 
				
			||||||
        Point3::new(5.0, 1.0, -6.0),
 | 
					 | 
				
			||||||
        Point3::new(8.0, 1.0, -7.0),
 | 
					 | 
				
			||||||
        Point3::new(6.0, 4.0, -6.0),
 | 
					 | 
				
			||||||
        material5.clone(),
 | 
					 | 
				
			||||||
    )));
 | 
					 | 
				
			||||||
    world.add(Box::<Triangle>::new(Triangle::new(
 | 
					 | 
				
			||||||
        Point3::new(8.0, 4.0, -5.0),
 | 
					 | 
				
			||||||
        Point3::new(8.0, 1.0, -7.0),
 | 
					 | 
				
			||||||
        Point3::new(6.0, 4.0, -6.0),
 | 
					 | 
				
			||||||
        material5.clone(),
 | 
					 | 
				
			||||||
    )));
 | 
					 | 
				
			||||||
    */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return world;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
fn from_obj(path: &str) -> HittableList {
 | 
					 | 
				
			||||||
    let mut world = HittableList::new();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /*
 | 
					 | 
				
			||||||
    let material_ground = Arc::new(Lambertian::new(&Color::new(
 | 
					 | 
				
			||||||
        29.0 / 255.0,
 | 
					 | 
				
			||||||
        71.0 / 255.0,
 | 
					 | 
				
			||||||
        14.0 / 255.0,
 | 
					 | 
				
			||||||
    )));
 | 
					 | 
				
			||||||
    world.add(Box::<Sphere>::new(Sphere::new(
 | 
					 | 
				
			||||||
        Point3::new(0.0, -5005.0, 0.0),
 | 
					 | 
				
			||||||
        5000.0,
 | 
					 | 
				
			||||||
        material_ground.clone(),
 | 
					 | 
				
			||||||
    )));
 | 
					 | 
				
			||||||
    */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    //let material = Arc::new(Lambertian::new(&Color::new(
 | 
					 | 
				
			||||||
    //    77.0 / 255.0,
 | 
					 | 
				
			||||||
    //    77.0 / 255.0,
 | 
					 | 
				
			||||||
    //    118.0 / 255.0,
 | 
					 | 
				
			||||||
    //)));
 | 
					 | 
				
			||||||
    //let material = Arc::new(Dielectric::new(2.0));
 | 
					 | 
				
			||||||
    //let material = Arc::new(Metal::new(&Color::new(0.9, 0.9, 0.7), 1.0));
 | 
					 | 
				
			||||||
    let material = Arc::new(Rainbow::new());
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    let cornell_box = tobj::load_obj(path, &tobj::OFFLINE_RENDERING_LOAD_OPTIONS);
 | 
					 | 
				
			||||||
    let (models, materials) = cornell_box.expect("Failed to load OBJ file");
 | 
					 | 
				
			||||||
    let materials = materials.expect("Failed to load MTL file");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    for (i, m) in models.iter().enumerate() {
 | 
					 | 
				
			||||||
        let mesh = &m.mesh;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        /* Mesh vector lengths
 | 
					 | 
				
			||||||
        println!("positions: {}", mesh.positions.len());
 | 
					 | 
				
			||||||
        println!("vertex_color: {}", mesh.vertex_color.len());
 | 
					 | 
				
			||||||
        println!("normals: {}", mesh.normals.len());
 | 
					 | 
				
			||||||
        println!("texcoords: {}", mesh.texcoords.len());
 | 
					 | 
				
			||||||
        println!("indices: {}", mesh.indices.len());
 | 
					 | 
				
			||||||
        println!("face_arities: {}", mesh.face_arities.len());
 | 
					 | 
				
			||||||
        println!("texcoord_indices: {}", mesh.texcoord_indices.len());
 | 
					 | 
				
			||||||
        println!("normal_indices: {}", mesh.normal_indices.len());
 | 
					 | 
				
			||||||
        */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        let mut next_face = 0;
 | 
					 | 
				
			||||||
        for f in 0..mesh.face_arities.len() {
 | 
					 | 
				
			||||||
            let end = next_face + mesh.face_arities[f] as usize;
 | 
					 | 
				
			||||||
            let face_indices: Vec<_> = mesh.indices[next_face..end].iter().collect();
 | 
					 | 
				
			||||||
            println!("    face[{}] = {:?}", f, face_indices);
 | 
					 | 
				
			||||||
            next_face = end;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        for v in 0..mesh.indices.len() / 3 {
 | 
					 | 
				
			||||||
            let index_a = mesh.indices[3 * v] as usize;
 | 
					 | 
				
			||||||
            let index_b = mesh.indices[3 * v + 1] as usize;
 | 
					 | 
				
			||||||
            let index_c = mesh.indices[3 * v + 2] as usize;
 | 
					 | 
				
			||||||
            let index_normal_a = mesh.normal_indices[3 * v] as usize;
 | 
					 | 
				
			||||||
            let index_normal_b = mesh.normal_indices[3 * v + 1] as usize;
 | 
					 | 
				
			||||||
            let index_normal_c = mesh.normal_indices[3 * v + 2] as usize;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            let normal_avg = Vec3::unit_vector(
 | 
					 | 
				
			||||||
                Vec3::new(
 | 
					 | 
				
			||||||
                    mesh.positions[3 * index_normal_a] as f64,
 | 
					 | 
				
			||||||
                    mesh.positions[3 * index_normal_a + 1] as f64,
 | 
					 | 
				
			||||||
                    mesh.positions[3 * index_normal_a + 2] as f64,
 | 
					 | 
				
			||||||
                ) + Vec3::new(
 | 
					 | 
				
			||||||
                    mesh.positions[3 * index_normal_b] as f64,
 | 
					 | 
				
			||||||
                    mesh.positions[3 * index_normal_b + 1] as f64,
 | 
					 | 
				
			||||||
                    mesh.positions[3 * index_normal_b + 2] as f64,
 | 
					 | 
				
			||||||
                ) + Vec3::new(
 | 
					 | 
				
			||||||
                    mesh.positions[3 * index_normal_c] as f64,
 | 
					 | 
				
			||||||
                    mesh.positions[3 * index_normal_c + 1] as f64,
 | 
					 | 
				
			||||||
                    mesh.positions[3 * index_normal_c + 2] as f64,
 | 
					 | 
				
			||||||
                ),
 | 
					 | 
				
			||||||
            );
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            /*
 | 
					 | 
				
			||||||
            println!("a:{},{},{}; b:{},{},{}; c:{},{},{}",
 | 
					 | 
				
			||||||
            mesh.normals[3*index_normal_a],
 | 
					 | 
				
			||||||
            mesh.normals[3*index_normal_a+1],
 | 
					 | 
				
			||||||
            mesh.normals[3*index_normal_a+2],
 | 
					 | 
				
			||||||
            mesh.normals[3*index_normal_b],
 | 
					 | 
				
			||||||
            mesh.normals[3*index_normal_b+1],
 | 
					 | 
				
			||||||
            mesh.normals[3*index_normal_b+2],
 | 
					 | 
				
			||||||
            mesh.normals[3*index_normal_c],
 | 
					 | 
				
			||||||
            mesh.normals[3*index_normal_c+1],
 | 
					 | 
				
			||||||
            mesh.normals[3*index_normal_c+2]);
 | 
					 | 
				
			||||||
            */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            world.add(Box::<Triangle>::new(Triangle::new(
 | 
					 | 
				
			||||||
                Point3::new(
 | 
					 | 
				
			||||||
                    mesh.positions[3 * index_a] as f64,
 | 
					 | 
				
			||||||
                    mesh.positions[3 * index_a + 1] as f64,
 | 
					 | 
				
			||||||
                    mesh.positions[3 * index_a + 2] as f64,
 | 
					 | 
				
			||||||
                ),
 | 
					 | 
				
			||||||
                Point3::new(
 | 
					 | 
				
			||||||
                    mesh.positions[3 * index_b] as f64,
 | 
					 | 
				
			||||||
                    mesh.positions[3 * index_b + 1] as f64,
 | 
					 | 
				
			||||||
                    mesh.positions[3 * index_b + 2] as f64,
 | 
					 | 
				
			||||||
                ),
 | 
					 | 
				
			||||||
                Point3::new(
 | 
					 | 
				
			||||||
                    mesh.positions[3 * index_c] as f64,
 | 
					 | 
				
			||||||
                    mesh.positions[3 * index_c + 1] as f64,
 | 
					 | 
				
			||||||
                    mesh.positions[3 * index_c + 2] as f64,
 | 
					 | 
				
			||||||
                ),
 | 
					 | 
				
			||||||
                normal_avg,
 | 
					 | 
				
			||||||
                material.clone(),
 | 
					 | 
				
			||||||
            )));
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    return world;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
Current world view:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            I y
 | 
					 | 
				
			||||||
            I
 | 
					 | 
				
			||||||
            I
 | 
					 | 
				
			||||||
            I
 | 
					 | 
				
			||||||
          /   \
 | 
					 | 
				
			||||||
        /       \
 | 
					 | 
				
			||||||
      /           \
 | 
					 | 
				
			||||||
    / z             \ x
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* 
 | 
				
			||||||
 | 
					* Main function that builds everything and runs the raytracing
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
fn main() {
 | 
					fn main() {
 | 
				
			||||||
    // File
 | 
					    // File
 | 
				
			||||||
| 
						 | 
					@ -467,3 +236,249 @@ fn main() {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    image.save(default_file).unwrap();
 | 
					    image.save(default_file).unwrap();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/********************
 | 
				
			||||||
 | 
					*  WORLD GENERATION *
 | 
				
			||||||
 | 
					*********************
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					* Generates world based on .obj mesh file passed by path
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					fn from_obj(path: &str) -> HittableList {
 | 
				
			||||||
 | 
					    let mut world = HittableList::new();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /*
 | 
				
			||||||
 | 
					    let material_ground = Arc::new(Lambertian::new(&Color::new(
 | 
				
			||||||
 | 
					        29.0 / 255.0,
 | 
				
			||||||
 | 
					        71.0 / 255.0,
 | 
				
			||||||
 | 
					        14.0 / 255.0,
 | 
				
			||||||
 | 
					    )));
 | 
				
			||||||
 | 
					    world.add(Box::<Sphere>::new(Sphere::new(
 | 
				
			||||||
 | 
					        Point3::new(0.0, -5005.0, 0.0),
 | 
				
			||||||
 | 
					        5000.0,
 | 
				
			||||||
 | 
					        material_ground.clone(),
 | 
				
			||||||
 | 
					    )));
 | 
				
			||||||
 | 
					    */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    //let material = Arc::new(Lambertian::new(&Color::new(
 | 
				
			||||||
 | 
					    //    77.0 / 255.0,
 | 
				
			||||||
 | 
					    //    77.0 / 255.0,
 | 
				
			||||||
 | 
					    //    118.0 / 255.0,
 | 
				
			||||||
 | 
					    //)));
 | 
				
			||||||
 | 
					    //let material = Arc::new(Dielectric::new(2.0));
 | 
				
			||||||
 | 
					    //let material = Arc::new(Metal::new(&Color::new(0.9, 0.9, 0.7), 1.0));
 | 
				
			||||||
 | 
					    let material = Arc::new(Rainbow::new());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let cornell_box = tobj::load_obj(path, &tobj::OFFLINE_RENDERING_LOAD_OPTIONS);
 | 
				
			||||||
 | 
					    let (models, materials) = cornell_box.expect("Failed to load OBJ file");
 | 
				
			||||||
 | 
					    let materials = materials.expect("Failed to load MTL file");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (i, m) in models.iter().enumerate() {
 | 
				
			||||||
 | 
					        let mesh = &m.mesh;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /* Mesh vector lengths
 | 
				
			||||||
 | 
					        println!("positions: {}", mesh.positions.len());
 | 
				
			||||||
 | 
					        println!("vertex_color: {}", mesh.vertex_color.len());
 | 
				
			||||||
 | 
					        println!("normals: {}", mesh.normals.len());
 | 
				
			||||||
 | 
					        println!("texcoords: {}", mesh.texcoords.len());
 | 
				
			||||||
 | 
					        println!("indices: {}", mesh.indices.len());
 | 
				
			||||||
 | 
					        println!("face_arities: {}", mesh.face_arities.len());
 | 
				
			||||||
 | 
					        println!("texcoord_indices: {}", mesh.texcoord_indices.len());
 | 
				
			||||||
 | 
					        println!("normal_indices: {}", mesh.normal_indices.len());
 | 
				
			||||||
 | 
					        */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        let mut next_face = 0;
 | 
				
			||||||
 | 
					        for f in 0..mesh.face_arities.len() {
 | 
				
			||||||
 | 
					            let end = next_face + mesh.face_arities[f] as usize;
 | 
				
			||||||
 | 
					            let face_indices: Vec<_> = mesh.indices[next_face..end].iter().collect();
 | 
				
			||||||
 | 
					            println!("    face[{}] = {:?}", f, face_indices);
 | 
				
			||||||
 | 
					            next_face = end;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        for v in 0..mesh.indices.len() / 3 {
 | 
				
			||||||
 | 
					            let index_a = mesh.indices[3 * v] as usize;
 | 
				
			||||||
 | 
					            let index_b = mesh.indices[3 * v + 1] as usize;
 | 
				
			||||||
 | 
					            let index_c = mesh.indices[3 * v + 2] as usize;
 | 
				
			||||||
 | 
					            let index_normal_a = mesh.normal_indices[3 * v] as usize;
 | 
				
			||||||
 | 
					            let index_normal_b = mesh.normal_indices[3 * v + 1] as usize;
 | 
				
			||||||
 | 
					            let index_normal_c = mesh.normal_indices[3 * v + 2] as usize;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            let normal_avg = Vec3::unit_vector(
 | 
				
			||||||
 | 
					                Vec3::new(
 | 
				
			||||||
 | 
					                    mesh.positions[3 * index_normal_a] as f64,
 | 
				
			||||||
 | 
					                    mesh.positions[3 * index_normal_a + 1] as f64,
 | 
				
			||||||
 | 
					                    mesh.positions[3 * index_normal_a + 2] as f64,
 | 
				
			||||||
 | 
					                ) + Vec3::new(
 | 
				
			||||||
 | 
					                    mesh.positions[3 * index_normal_b] as f64,
 | 
				
			||||||
 | 
					                    mesh.positions[3 * index_normal_b + 1] as f64,
 | 
				
			||||||
 | 
					                    mesh.positions[3 * index_normal_b + 2] as f64,
 | 
				
			||||||
 | 
					                ) + Vec3::new(
 | 
				
			||||||
 | 
					                    mesh.positions[3 * index_normal_c] as f64,
 | 
				
			||||||
 | 
					                    mesh.positions[3 * index_normal_c + 1] as f64,
 | 
				
			||||||
 | 
					                    mesh.positions[3 * index_normal_c + 2] as f64,
 | 
				
			||||||
 | 
					                ),
 | 
				
			||||||
 | 
					            );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            /*
 | 
				
			||||||
 | 
					            println!("a:{},{},{}; b:{},{},{}; c:{},{},{}",
 | 
				
			||||||
 | 
					            mesh.normals[3*index_normal_a],
 | 
				
			||||||
 | 
					            mesh.normals[3*index_normal_a+1],
 | 
				
			||||||
 | 
					            mesh.normals[3*index_normal_a+2],
 | 
				
			||||||
 | 
					            mesh.normals[3*index_normal_b],
 | 
				
			||||||
 | 
					            mesh.normals[3*index_normal_b+1],
 | 
				
			||||||
 | 
					            mesh.normals[3*index_normal_b+2],
 | 
				
			||||||
 | 
					            mesh.normals[3*index_normal_c],
 | 
				
			||||||
 | 
					            mesh.normals[3*index_normal_c+1],
 | 
				
			||||||
 | 
					            mesh.normals[3*index_normal_c+2]);
 | 
				
			||||||
 | 
					            */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            world.add(Box::<Triangle>::new(Triangle::new(
 | 
				
			||||||
 | 
					                Point3::new(
 | 
				
			||||||
 | 
					                    mesh.positions[3 * index_a] as f64,
 | 
				
			||||||
 | 
					                    mesh.positions[3 * index_a + 1] as f64,
 | 
				
			||||||
 | 
					                    mesh.positions[3 * index_a + 2] as f64,
 | 
				
			||||||
 | 
					                ),
 | 
				
			||||||
 | 
					                Point3::new(
 | 
				
			||||||
 | 
					                    mesh.positions[3 * index_b] as f64,
 | 
				
			||||||
 | 
					                    mesh.positions[3 * index_b + 1] as f64,
 | 
				
			||||||
 | 
					                    mesh.positions[3 * index_b + 2] as f64,
 | 
				
			||||||
 | 
					                ),
 | 
				
			||||||
 | 
					                Point3::new(
 | 
				
			||||||
 | 
					                    mesh.positions[3 * index_c] as f64,
 | 
				
			||||||
 | 
					                    mesh.positions[3 * index_c + 1] as f64,
 | 
				
			||||||
 | 
					                    mesh.positions[3 * index_c + 2] as f64,
 | 
				
			||||||
 | 
					                ),
 | 
				
			||||||
 | 
					                normal_avg,
 | 
				
			||||||
 | 
					                material.clone(),
 | 
				
			||||||
 | 
					            )));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return world;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					* Generates a world with a bunch of spheres
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					fn random_world() -> HittableList {
 | 
				
			||||||
 | 
					    let mut world = HittableList::new();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let material_ground = Arc::new(Lambertian::new(&Color::new(0.05, 0.05, 0.05)));
 | 
				
			||||||
 | 
					    world.add(Box::<Sphere>::new(Sphere::new(
 | 
				
			||||||
 | 
					        Point3::new(0.0, -50000.0, 0.0),
 | 
				
			||||||
 | 
					        50000.0,
 | 
				
			||||||
 | 
					        material_ground.clone(),
 | 
				
			||||||
 | 
					    )));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    (-6..5).into_iter().for_each(|a| {
 | 
				
			||||||
 | 
					        (-6..5).into_iter().for_each(|b| {
 | 
				
			||||||
 | 
					            let choose_mat = utility::random_f64();
 | 
				
			||||||
 | 
					            let rad = utility::random_rng(0.1, 0.5);
 | 
				
			||||||
 | 
					            let center = Point3::new(
 | 
				
			||||||
 | 
					                1.5 * a as f64 + 1.3 * utility::random_f64(),
 | 
				
			||||||
 | 
					                rad,
 | 
				
			||||||
 | 
					                1.5 * b as f64 + 1.3 * utility::random_f64(),
 | 
				
			||||||
 | 
					            );
 | 
				
			||||||
 | 
					            if (center - Point3::new(4.0, rad, 0.0)).length() > 0.9 {
 | 
				
			||||||
 | 
					                if choose_mat < 0.8 {
 | 
				
			||||||
 | 
					                    // diffuse
 | 
				
			||||||
 | 
					                    let sphere_material = Arc::new(Lambertian::new(
 | 
				
			||||||
 | 
					                        &(Color::random_f64() * Color::random_f64()),
 | 
				
			||||||
 | 
					                    ));
 | 
				
			||||||
 | 
					                    world.add(Box::<Sphere>::new(Sphere::new(
 | 
				
			||||||
 | 
					                        center,
 | 
				
			||||||
 | 
					                        rad,
 | 
				
			||||||
 | 
					                        sphere_material.clone(),
 | 
				
			||||||
 | 
					                    )));
 | 
				
			||||||
 | 
					                } else if choose_mat < 0.95 {
 | 
				
			||||||
 | 
					                    // metal
 | 
				
			||||||
 | 
					                    let sphere_material = Arc::new(Metal::new(
 | 
				
			||||||
 | 
					                        &Color::random_rng(0.5, 1.0),
 | 
				
			||||||
 | 
					                        utility::random_rng(0.0, 0.5),
 | 
				
			||||||
 | 
					                    ));
 | 
				
			||||||
 | 
					                    world.add(Box::<Sphere>::new(Sphere::new(
 | 
				
			||||||
 | 
					                        center,
 | 
				
			||||||
 | 
					                        0.2,
 | 
				
			||||||
 | 
					                        sphere_material.clone(),
 | 
				
			||||||
 | 
					                    )));
 | 
				
			||||||
 | 
					                } else {
 | 
				
			||||||
 | 
					                    // glass
 | 
				
			||||||
 | 
					                    let sphere_material = Arc::new(Dielectric::new(1.5));
 | 
				
			||||||
 | 
					                    world.add(Box::<Sphere>::new(Sphere::new(
 | 
				
			||||||
 | 
					                        center,
 | 
				
			||||||
 | 
					                        0.2,
 | 
				
			||||||
 | 
					                        sphere_material.clone(),
 | 
				
			||||||
 | 
					                    )));
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let material1 = Arc::new(Dielectric::new(1.5));
 | 
				
			||||||
 | 
					    let material2 = Arc::new(Lambertian::new(&Color::new(0.4, 0.2, 0.1)));
 | 
				
			||||||
 | 
					    let material3 = Arc::new(Metal::new(&Color::new(0.7, 0.6, 0.5), 0.0));
 | 
				
			||||||
 | 
					    let material4 = Arc::new(Dielectric::new(2.0));
 | 
				
			||||||
 | 
					    let material5 = Arc::new(Metal::new(&Color::new(0.9, 0.9, 0.7), 0.0));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    world.add(Box::<Sphere>::new(Sphere::new(
 | 
				
			||||||
 | 
					        Point3::new(0.0, 1.0, 0.0),
 | 
				
			||||||
 | 
					        1.0,
 | 
				
			||||||
 | 
					        material2.clone(),
 | 
				
			||||||
 | 
					    )));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    world.add(Box::<Sphere>::new(Sphere::new(
 | 
				
			||||||
 | 
					        Point3::new(-4.0, 1.0, 0.0),
 | 
				
			||||||
 | 
					        1.0,
 | 
				
			||||||
 | 
					        material1.clone(),
 | 
				
			||||||
 | 
					    )));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    world.add(Box::<Sphere>::new(Sphere::new(
 | 
				
			||||||
 | 
					        Point3::new(4.0, 1.0, 0.0),
 | 
				
			||||||
 | 
					        1.0,
 | 
				
			||||||
 | 
					        material3.clone(),
 | 
				
			||||||
 | 
					    )));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    world.add(Box::<Sphere>::new(Sphere::new(
 | 
				
			||||||
 | 
					        Point3::new(-2.0, 2.0, -5.0),
 | 
				
			||||||
 | 
					        2.0,
 | 
				
			||||||
 | 
					        material4.clone(),
 | 
				
			||||||
 | 
					    )));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    world.add(Box::<Sphere>::new(Sphere::new(
 | 
				
			||||||
 | 
					        Point3::new(-3.6, 2.0, -2.0),
 | 
				
			||||||
 | 
					        0.6,
 | 
				
			||||||
 | 
					        material5.clone(),
 | 
				
			||||||
 | 
					    )));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /*
 | 
				
			||||||
 | 
					    world.add(Box::<Triangle>::new(Triangle::new(
 | 
				
			||||||
 | 
					        Point3::new(0.0, 1.0, 5.0),
 | 
				
			||||||
 | 
					        Point3::new(3.0, 2.0, 0.0),
 | 
				
			||||||
 | 
					        Point3::new(0.0, 4.0, 0.0),
 | 
				
			||||||
 | 
					        material2.clone(),
 | 
				
			||||||
 | 
					    )));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    world.add(Box::<Triangle>::new(Triangle::new(
 | 
				
			||||||
 | 
					        Point3::new(5.0, 1.0, -6.0),
 | 
				
			||||||
 | 
					        Point3::new(1.0, 3.0, -5.0),
 | 
				
			||||||
 | 
					        Point3::new(6.0, 4.0, -6.0),
 | 
				
			||||||
 | 
					        material5.clone(),
 | 
				
			||||||
 | 
					    )));
 | 
				
			||||||
 | 
					    world.add(Box::<Triangle>::new(Triangle::new(
 | 
				
			||||||
 | 
					        Point3::new(5.0, 1.0, -6.0),
 | 
				
			||||||
 | 
					        Point3::new(8.0, 1.0, -7.0),
 | 
				
			||||||
 | 
					        Point3::new(6.0, 4.0, -6.0),
 | 
				
			||||||
 | 
					        material5.clone(),
 | 
				
			||||||
 | 
					    )));
 | 
				
			||||||
 | 
					    world.add(Box::<Triangle>::new(Triangle::new(
 | 
				
			||||||
 | 
					        Point3::new(8.0, 4.0, -5.0),
 | 
				
			||||||
 | 
					        Point3::new(8.0, 1.0, -7.0),
 | 
				
			||||||
 | 
					        Point3::new(6.0, 4.0, -6.0),
 | 
				
			||||||
 | 
					        material5.clone(),
 | 
				
			||||||
 | 
					    )));
 | 
				
			||||||
 | 
					    */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return world;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Loading…
	
		Reference in a new issue