Add BVH bounding boxes
This commit is contained in:
@ -1,5 +1,8 @@
|
||||
use crate::{Point3, Ray, Vec3};
|
||||
use crate::material::{Material};
|
||||
use crate::aabb::Aabb;
|
||||
|
||||
pub type HittableList = Vec<Box<dyn Hittable + Sync>>;
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct HitRecord<'material> {
|
||||
@ -12,7 +15,10 @@ pub struct HitRecord<'material> {
|
||||
|
||||
pub trait Hittable {
|
||||
fn hit(&self, ray: &Ray, t_min: f64, t_max: f64) -> Option<HitRecord>;
|
||||
fn bounding_box(&self, time0: f64, time1: f64) -> Option<Aabb>;
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Sphere {
|
||||
pub center: Point3,
|
||||
pub radius: f64,
|
||||
@ -32,7 +38,6 @@ impl Default for Sphere {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Hittable for Sphere {
|
||||
fn hit(&self, ray: &Ray, t_min: f64, t_max: f64) -> Option<HitRecord> {
|
||||
let oc = &ray.origin() - &self.center;
|
||||
@ -61,8 +66,16 @@ impl Hittable for Sphere {
|
||||
material: &self.material
|
||||
})
|
||||
}
|
||||
fn bounding_box(&self, _time0: f64, _time1: f64) -> Option<Aabb> {
|
||||
let s = Vec3::new(self.radius, self.radius, self.radius);
|
||||
Some(Aabb {
|
||||
minimum: self.center - s,
|
||||
maximum: self.center + s,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct MovableSphere {
|
||||
pub center0: Point3,
|
||||
pub center1: Point3,
|
||||
@ -126,4 +139,16 @@ impl Hittable for MovableSphere {
|
||||
material: &self.material
|
||||
})
|
||||
}
|
||||
}
|
||||
fn bounding_box(&self, time0: f64, time1: f64) -> Option<Aabb> {
|
||||
let s = Vec3::new(self.radius, self.radius, self.radius);
|
||||
let center0 = self.center(time0);
|
||||
let center1 = self.center(time1);
|
||||
Some(Aabb {
|
||||
minimum: center0 - s,
|
||||
maximum: center0 + s,
|
||||
}.surrounding(&Aabb {
|
||||
minimum: center1 - s,
|
||||
maximum: center1 + s
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
39
src/main.rs
39
src/main.rs
@ -2,8 +2,8 @@ use std::sync::Mutex;
|
||||
use std::time::Instant;
|
||||
|
||||
use crate::camera::Camera;
|
||||
use crate::hittable::{Hittable, Sphere};
|
||||
use crate::output::{Output, P3, PNG};
|
||||
use crate::hittable::{Hittable, Sphere, HittableList};
|
||||
use crate::output::{Output, PNG};
|
||||
use crate::ray::Ray;
|
||||
use crate::vec3::{Color, Point3, Vec3};
|
||||
use hittable::MovableSphere;
|
||||
@ -11,6 +11,8 @@ use rand::Rng;
|
||||
use rand::distributions::{Distribution, Uniform};
|
||||
use rayon::iter::{IntoParallelIterator, ParallelIterator};
|
||||
use crate::material::{Dielectric, Lambertian, Material, Metal};
|
||||
use crate::aabb::Aabb;
|
||||
use crate::bvh::BVH;
|
||||
|
||||
mod vec3;
|
||||
mod ray;
|
||||
@ -18,9 +20,11 @@ mod hittable;
|
||||
mod material;
|
||||
mod camera;
|
||||
mod output;
|
||||
mod aabb;
|
||||
mod bvh;
|
||||
|
||||
fn random_scene() -> Vec<Box<dyn Hittable + Sync>> {
|
||||
let mut world:Vec<Box<dyn Hittable + Sync>> = Vec::new();
|
||||
fn random_scene() -> HittableList {
|
||||
let mut world:HittableList = Vec::new();
|
||||
|
||||
let material_ground = Material::Lambertian(Lambertian::new(Color::new(0.5, 0.5, 0.5)));
|
||||
let ground = Sphere {
|
||||
@ -99,9 +103,9 @@ fn random_scene() -> Vec<Box<dyn Hittable + Sync>> {
|
||||
fn main() {
|
||||
// Image
|
||||
const ASPECT_RATIO: f64 = 3.0 / 2.0;
|
||||
const IMAGE_WIDTH: usize = 1200;
|
||||
const IMAGE_WIDTH: usize = 400;
|
||||
const IMAGE_HEIGHT: usize = (IMAGE_WIDTH as f64 / ASPECT_RATIO) as usize;
|
||||
const SAMPLES_PER_PIXEL: i32 = 100;
|
||||
const SAMPLES_PER_PIXEL: i32 = 50;
|
||||
const MAX_DEPTH: i32 = 50;
|
||||
|
||||
let look_from = Point3::new(13.0, 2.0, 3.0);
|
||||
@ -157,3 +161,26 @@ fn main() {
|
||||
PNG::write("imc.png", &pixels, IMAGE_WIDTH, IMAGE_HEIGHT).expect("Error writing image: {}");
|
||||
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)
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
use crate::{Color, Hittable, Vec3};
|
||||
use crate::hittable::HitRecord;
|
||||
use crate::{Color, Vec3};
|
||||
use crate::hittable::{HitRecord, HittableList};
|
||||
use crate::material::Scatterable;
|
||||
use crate::vec3::Point3;
|
||||
|
||||
@ -25,7 +25,7 @@ impl Ray {
|
||||
pub fn direction(&self) -> Vec3 { self.direction }
|
||||
pub fn origin(&self) -> Point3 { self.origin }
|
||||
pub fn time(&self) -> f64 { self.time }
|
||||
pub fn pixel_color(&self, world: &Vec<Box<dyn Hittable + Sync>>, depth: i32) -> Color {
|
||||
pub fn pixel_color(&self, world: &HittableList, depth: i32) -> Color {
|
||||
if depth <= 0 {
|
||||
return Color::default();
|
||||
}
|
||||
@ -52,7 +52,7 @@ impl Ray {
|
||||
}
|
||||
fn hit_world<'material>(
|
||||
&self,
|
||||
world: &'material Vec<Box<dyn Hittable + Sync>>,
|
||||
world: &'material HittableList,
|
||||
t_min: f64,
|
||||
t_max: f64,
|
||||
) -> Option<HitRecord<'material>> {
|
||||
|
25
src/vec3.rs
25
src/vec3.rs
@ -1,5 +1,5 @@
|
||||
use std::fmt::{Display, Formatter};
|
||||
use std::ops::{Add, AddAssign, Div, Mul, Neg, Sub};
|
||||
use std::ops::{Add, AddAssign, Div, Mul, Neg, Sub, Index};
|
||||
use rand::distributions::{Distribution, Uniform};
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
@ -257,3 +257,26 @@ impl PartialEq for Vec3 {
|
||||
self.x == other.x() && self.y == other.y() && self.z == other.z()
|
||||
}
|
||||
}
|
||||
|
||||
impl Index<i32> for Vec3 {
|
||||
type Output = f64;
|
||||
fn index(&self, index: i32) -> &Self::Output {
|
||||
match index {
|
||||
0 => &self.x,
|
||||
1 => &self.y,
|
||||
2 => &self.z,
|
||||
_ => panic!("Unknown index")
|
||||
}
|
||||
}
|
||||
}
|
||||
impl Index<usize> for Vec3 {
|
||||
type Output = f64;
|
||||
fn index(&self, index: usize) -> &Self::Output {
|
||||
match index {
|
||||
0 => &self.x,
|
||||
1 => &self.y,
|
||||
2 => &self.z,
|
||||
_ => panic!("Unknown index")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user