Fix bounding box and BVH
This commit is contained in:
parent
a0eda53be1
commit
526e92f582
@ -20,9 +20,7 @@ impl Default for Aabb {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Aabb {
|
impl Aabb {
|
||||||
pub fn hit(&self, ray: &Ray, t_min: f64, t_max: f64) -> bool {
|
pub fn hit(&self, ray: &Ray, mut t_min: f64, mut t_max: f64) -> bool {
|
||||||
let mut t_min = t_min;
|
|
||||||
let mut t_max = t_max;
|
|
||||||
for a in 0..3 {
|
for a in 0..3 {
|
||||||
let inv_d = 1.0 / ray.direction()[a];
|
let inv_d = 1.0 / ray.direction()[a];
|
||||||
let mut t0 = (self.minimum[a] - ray.origin()[a]) * inv_d;
|
let mut t0 = (self.minimum[a] - ray.origin()[a]) * inv_d;
|
||||||
@ -42,11 +40,11 @@ impl Aabb {
|
|||||||
let minimum = Point3::new(
|
let minimum = Point3::new(
|
||||||
self.minimum.x().min(other.minimum.x()),
|
self.minimum.x().min(other.minimum.x()),
|
||||||
self.minimum.y().min(other.minimum.y()),
|
self.minimum.y().min(other.minimum.y()),
|
||||||
self.minimum.y().min(other.minimum.z()));
|
self.minimum.z().min(other.minimum.z()));
|
||||||
let maximum = Point3::new(
|
let maximum = Point3::new(
|
||||||
self.maximum.x().max(other.maximum.x()),
|
self.maximum.x().max(other.maximum.x()),
|
||||||
self.maximum.y().max(other.maximum.y()),
|
self.maximum.y().max(other.maximum.y()),
|
||||||
self.maximum.y().max(other.maximum.z()));
|
self.maximum.z().max(other.maximum.z()));
|
||||||
Aabb {minimum, maximum}
|
Aabb {minimum, maximum}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -83,10 +83,7 @@ impl Hittable for BVH {
|
|||||||
let hit_left = left.hit(ray, t_min, t_max);
|
let hit_left = left.hit(ray, t_min, t_max);
|
||||||
if let Some(hl) = &hit_left { t_max = hl.t };
|
if let Some(hl) = &hit_left { t_max = hl.t };
|
||||||
let hit_right = right.hit(ray, t_min, t_max);
|
let hit_right = right.hit(ray, t_min, t_max);
|
||||||
match hit_left {
|
if hit_right.is_some() { hit_right } else { hit_left }
|
||||||
Some(hit_left) => Some(hit_left),
|
|
||||||
_ => hit_right
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
83
src/main.rs
83
src/main.rs
@ -43,8 +43,8 @@ mod isotropic;
|
|||||||
|
|
||||||
// Image
|
// Image
|
||||||
const DEFAULT_ASPECT_RATIO: f64 = 3.0 / 2.0;
|
const DEFAULT_ASPECT_RATIO: f64 = 3.0 / 2.0;
|
||||||
const IMAGE_WIDTH: usize = 800;
|
const IMAGE_WIDTH: usize = 1600;
|
||||||
const SAMPLES_PER_PIXEL: i32 = 200;
|
const SAMPLES_PER_PIXEL: i32 = 1_000;
|
||||||
const MAX_DEPTH: i32 = 50;
|
const MAX_DEPTH: i32 = 50;
|
||||||
|
|
||||||
struct Scene {
|
struct Scene {
|
||||||
@ -643,6 +643,7 @@ fn next_week_final() -> Scene {
|
|||||||
light
|
light
|
||||||
)));
|
)));
|
||||||
|
|
||||||
|
// Moving Sphere
|
||||||
let moving_sphere_material = Arc::new(
|
let moving_sphere_material = Arc::new(
|
||||||
Material::Lambertian(Lambertian::from(Color::new(0.7, 0.3, 0.1))));
|
Material::Lambertian(Lambertian::from(Color::new(0.7, 0.3, 0.1))));
|
||||||
let center1 = Point3::new(400.0, 400.0, 200.0);
|
let center1 = Point3::new(400.0, 400.0, 200.0);
|
||||||
@ -656,11 +657,15 @@ fn next_week_final() -> Scene {
|
|||||||
)));
|
)));
|
||||||
|
|
||||||
let glass = Arc::new(Material::Dielectric(Dielectric::new(1.5)));
|
let glass = Arc::new(Material::Dielectric(Dielectric::new(1.5)));
|
||||||
|
|
||||||
|
// Glass
|
||||||
world.push(Arc::new(Sphere::new(
|
world.push(Arc::new(Sphere::new(
|
||||||
Point3::new(260.0, 150.0, 45.0),
|
Point3::new(260.0, 150.0, 45.0),
|
||||||
50.0,
|
50.0,
|
||||||
glass.clone()
|
glass.clone()
|
||||||
)));
|
)));
|
||||||
|
|
||||||
|
// Metal sphere
|
||||||
world.push(Arc::new(Sphere::new(
|
world.push(Arc::new(Sphere::new(
|
||||||
Point3::new(0.0, 150.0, 145.0),
|
Point3::new(0.0, 150.0, 145.0),
|
||||||
50.0,
|
50.0,
|
||||||
@ -694,6 +699,7 @@ fn next_week_final() -> Scene {
|
|||||||
Color::new(1.0, 1.0, 1.0),
|
Color::new(1.0, 1.0, 1.0),
|
||||||
0.0001)));
|
0.0001)));
|
||||||
|
|
||||||
|
// Earth
|
||||||
let earth_material = Arc::new(Material::Lambertian(
|
let earth_material = Arc::new(Material::Lambertian(
|
||||||
Lambertian::textured(
|
Lambertian::textured(
|
||||||
Arc::new(ImageTexture::new("textures/earthmap.jpg")))));
|
Arc::new(ImageTexture::new("textures/earthmap.jpg")))));
|
||||||
@ -703,6 +709,7 @@ fn next_week_final() -> Scene {
|
|||||||
earth_material
|
earth_material
|
||||||
)));
|
)));
|
||||||
|
|
||||||
|
// Gray sphere
|
||||||
let pertext = Arc::new(Material::Lambertian(Lambertian::textured(
|
let pertext = Arc::new(Material::Lambertian(Lambertian::textured(
|
||||||
Arc::new(NoiseTexture {
|
Arc::new(NoiseTexture {
|
||||||
noise: Perlin::new(),
|
noise: Perlin::new(),
|
||||||
@ -710,7 +717,7 @@ fn next_week_final() -> Scene {
|
|||||||
}))));
|
}))));
|
||||||
world.push(Arc::new(Sphere::new(
|
world.push(Arc::new(Sphere::new(
|
||||||
Point3::new(220.0, 280.0, 300.0),
|
Point3::new(220.0, 280.0, 300.0),
|
||||||
100.0,
|
80.0,
|
||||||
pertext
|
pertext
|
||||||
)));
|
)));
|
||||||
|
|
||||||
@ -718,38 +725,29 @@ fn next_week_final() -> Scene {
|
|||||||
let mut boxes2: HittableList = Vec::with_capacity(ns);
|
let mut boxes2: HittableList = Vec::with_capacity(ns);
|
||||||
let white = Arc::new(Material::Lambertian(
|
let white = Arc::new(Material::Lambertian(
|
||||||
Lambertian::from(Color::new(0.73, 0.73, 0.73))));
|
Lambertian::from(Color::new(0.73, 0.73, 0.73))));
|
||||||
/*
|
|
||||||
|
|
||||||
for _i in 0..ns {
|
for _i in 0..ns {
|
||||||
world.push(Arc::new(
|
let sphere = Sphere::new(
|
||||||
|
Point3::random(0.0, 165.0),
|
||||||
|
10.0,
|
||||||
|
white.clone()
|
||||||
|
);
|
||||||
|
boxes2.push(Arc::new(sphere));
|
||||||
|
}
|
||||||
|
world.push(
|
||||||
|
Arc::new(
|
||||||
Translate::new(
|
Translate::new(
|
||||||
Sphere::new(
|
RotateY::new(
|
||||||
Point3::random(0.0, 165.0),
|
BVH::new(boxes2, 0.0, 1.0),
|
||||||
10.0,
|
15.0
|
||||||
white.clone()
|
),
|
||||||
),Vec3::new(-100.0, 270.0, 395.0))
|
Vec3::new(-100.0, 270.0, 395.0)
|
||||||
));
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
for _i in 0..ns {
|
|
||||||
boxes2.push(Arc::new(
|
|
||||||
Sphere::new(
|
|
||||||
Point3::random(0.0, 165.0),
|
|
||||||
10.0,
|
|
||||||
white.clone()
|
|
||||||
)
|
)
|
||||||
));
|
)
|
||||||
}
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
let boxes2_bvh = BVH::new(boxes2, 0.0, 1.0);
|
|
||||||
//let rotated_bvh = RotateY::new(boxes2_bvh, 0.0);
|
|
||||||
//let rotated_bvh = RotateY::new(boxes2_bvh, 15.0);
|
|
||||||
//let translated_bvh = Translate::new(rotated_bvh, Vec3::new(-100.0, 270.0, 395.0));
|
|
||||||
let translated_bvh = Translate::new(boxes2_bvh, Vec3::new(-100.0, 270.0, 395.0));
|
|
||||||
world.push(Arc::new(translated_bvh));
|
|
||||||
|
|
||||||
let look_from = Point3::new(478.0, 278.0, -600.0);
|
let look_from = Point3::new(478.0, 278.0, -600.0);
|
||||||
let look_at = Point3::new(278.0, 278.0, 0.0);
|
let look_at = Point3::new(278.0, 278.0, 0.0);
|
||||||
let focus_dist = 2.0;
|
let focus_dist = 2.0;
|
||||||
@ -773,7 +771,7 @@ fn next_week_final() -> Scene {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
rayon::ThreadPoolBuilder::new().num_threads(3).build_global().unwrap(); // Enable, to reduce load
|
//rayon::ThreadPoolBuilder::new().num_threads(3).build_global().unwrap(); // Enable, to reduce load
|
||||||
// World
|
// World
|
||||||
let scene: u8 = 7;
|
let scene: u8 = 7;
|
||||||
let scene_setup = match scene {
|
let scene_setup = match scene {
|
||||||
@ -825,26 +823,3 @@ fn main() {
|
|||||||
PNG::write("imc.png", &pixels, IMAGE_WIDTH, image_height).expect("Error writing image: {}");
|
PNG::write("imc.png", &pixels, IMAGE_WIDTH, image_height).expect("Error writing image: {}");
|
||||||
eprintln!("\nDone. Time: {}ms", start.elapsed().as_millis());
|
eprintln!("\nDone. Time: {}ms", start.elapsed().as_millis());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn world_bounding_box(time0: f64, time1: f64, world: &HittableList) -> Option<Aabb> {
|
|
||||||
if world.is_empty() {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
let mut is_first = true;
|
|
||||||
let mut output_box: Aabb = Aabb {
|
|
||||||
minimum: Point3::default(),
|
|
||||||
maximum: Point3::default()
|
|
||||||
};
|
|
||||||
for object in world {
|
|
||||||
if let Some(bb) = object.bounding_box(time0, time1) {
|
|
||||||
output_box = match is_first {
|
|
||||||
true => bb,
|
|
||||||
false => output_box.surrounding(&bb)
|
|
||||||
};
|
|
||||||
is_first = false;
|
|
||||||
} else {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Some(output_box)
|
|
||||||
}
|
|
||||||
|
Loading…
Reference in New Issue
Block a user