Skip to content

Commit

Permalink
feat: added bvbh.rs
Browse files Browse the repository at this point in the history
  • Loading branch information
Wafelack committed Dec 21, 2020
1 parent 88e76b4 commit 60cde23
Show file tree
Hide file tree
Showing 11 changed files with 252 additions and 50,427 deletions.
50,403 changes: 0 additions & 50,403 deletions image.ppm

Large diffs are not rendered by default.

88 changes: 88 additions & 0 deletions src/aabb.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
use crate::*;

#[derive(Copy, Clone, Default)]
pub struct Aabb {
minimum: point3,
maximum: point3,
}
pub fn surrounding_box(box0: &Aabb, box1: &Aabb) -> Aabb {
let small = point3::from(
min(box0.min().x(), box1.min().x()),
min(box0.min().y(), box1.min().y()),
min(box0.min().z(), box1.min().z()),
);

let big = point3::from(
max(box0.min().x(), box1.min().x()),
max(box0.min().y(), box1.min().y()),
max(box0.min().z(), box1.min().z()),
);

Aabb::from(&small, &big)
}
impl Aabb {
pub fn new() -> Self {
Self {
minimum: point3::new(),
maximum: point3::new(),
}
}
pub fn from(a: &point3, b: &point3) -> Self {
Self {
minimum: *a,
maximum: *b,
}
}
pub fn min(&self) -> point3 {
self.minimum
}
pub fn max(&self) -> point3 {
self.maximum
}
pub fn hit(&self, r: &Ray, mut t_min: f32, mut t_max: f32) -> bool {
for i in 0..3 {
let invD = 1.0 / r.direction()[i];

let mut t0 = (self.min()[i] - r.origin()[i]) * invD;
let mut t1 = (self.max()[i] - r.origin()[i]) * invD;

if invD < 0.0 {
let prev_t0 = t0;
t0 = t1;
t1 = prev_t0;
}
t_min = if t0 > t_min { t0 } else { t_min };
t_max = if t1 < t_max { t1 } else { t_max };

if t_max <= t_min {
return false;
}
}
true
}
}

fn min(a: f32, b: f32) -> f32 {
if a == std::f32::NAN {
return b;
} else if b == std::f32::NAN {
return a;
}
if a < b {
return a;
} else {
return b;
}
}
fn max(a: f32, b: f32) -> f32 {
if a == std::f32::NAN {
return b;
} else if b == std::f32::NAN {
return a;
}
if a > b {
return a;
} else {
return b;
}
}
76 changes: 76 additions & 0 deletions src/bvh.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
use crate::{aabb::*, objects::hittable::*, objects::hittable_list::*, ray::*, utils::*};
use std::sync::Arc;

pub struct BvhNode {
left: Arc<dyn Hittable>,
right: Arc<dyn Hittable>,
boxx: Aabb,
}

impl BvhNode {
pub fn from(list: &HittableList, time0: f32, time1: f32) -> Self {
Self::fromvec(&list.objects, 0, list.objects.len(), time0, time1)
}
pub fn fromvec(
src_objects: &Vec<Arc<dyn Hittable>>,
start: usize,
end: usize,
time0: f32,
time1: f32,
) -> Self {
let mut objects = src_objects;
let axis = random_int(0, 2);

let mut left = objects[start];
let mut right = objects[start];

let comparator = if axis == 0 {
box_x_compare
} else if axis == 1 {
box_y_compare
} else {
box_z_compare
};
let object_span = end - start;

if object_span == 1 {
} else if object_span == 1 {
if comparator(objects[start], objects[start + 1]) {
left = objects[start];
right = objects[start + 1];
} else {
right = objects[start];
left = objects[start + 1];
}
} else {
}
}
}

impl Hittable for BvhNode {
fn bounding_box<'a>(&'a self, time0: f32, time1: f32, output_box: &mut Aabb) -> bool {
*output_box = self.boxx;
true
}
fn hit<'a>(&'a self, r: &Ray, t_min: f32, t_max: f32, rec: &mut HitRecord<'a>) -> bool {
if !self.boxx.hit(r, t_min, t_max) {
return false;
}

let hit_left = self.left.hit(r, t_min, t_max, rec);
let hit_right = self.right.hit(
r,
t_min,
{
if hit_left {
rec.t
} else {
t_max
}
},
rec,
);

hit_left || hit_right
}
}
18 changes: 10 additions & 8 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
use std::sync::Arc;

mod aabb;
mod bvh;
mod camera;
mod canvas;
mod colors;
Expand All @@ -9,13 +11,13 @@ mod ray;
mod utils;
mod vec3;

use camera::Camera;
use canvas::Canvas;
use material::material::*;
use objects::{hittable_list::*, moving_sphere::*, sphere::*};
use ray::*;
use utils::*;
use vec3::*;
pub use camera::Camera;
pub use canvas::Canvas;
pub use material::material::*;
pub use objects::{hittable_list::*, moving_sphere::*, sphere::*};
pub use ray::*;
pub use utils::*;
pub use vec3::*;

fn random_scene() -> HittableList {
let mut world = HittableList::new();
Expand Down Expand Up @@ -142,7 +144,7 @@ fn main() {
render_pixel,
|total, num_done| {
eprint!(
"\r{:.2} percent done",
"\r{:.2}% done",
((num_done as f32 / total as f32) * 100.).min(100.)
);
},
Expand Down
13 changes: 8 additions & 5 deletions src/objects/hittable.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::{material::material::*, ray::*, vec3::*};
use crate::{aabb::*, material::material::*, ray::*, vec3::*};

#[derive(Clone , Copy)]
#[derive(Clone, Copy)]
pub struct HitRecord<'a> {
pub p: point3,
pub normal: Vec3,
Expand All @@ -9,8 +9,8 @@ pub struct HitRecord<'a> {
pub front_face: bool,
}

static DFL_LAMBERTIAN: Lambertian = Lambertian{
albedo: color{e: [0. , 0. , 0.]}
static DFL_LAMBERTIAN: Lambertian = Lambertian {
albedo: color { e: [0., 0., 0.] },
};

impl HitRecord<'_> {
Expand All @@ -34,5 +34,8 @@ impl HitRecord<'_> {
}

pub trait Hittable: Send + Sync {
fn hit<'a>(&'a self, r: Ray, t_min: f32, t_max: f32, rec: &mut HitRecord<'a>) -> bool;
fn hit<'a>(&'a self, r: &Ray, t_min: f32, t_max: f32, rec: &mut HitRecord<'a>) -> bool;
fn bounding_box<'a>(&'a self, time0: f32, time1: f32, output_box: &mut Aabb) -> bool {
true
}
}
24 changes: 22 additions & 2 deletions src/objects/hittable_list.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::sync::Arc;

use crate::{objects::hittable::*, ray::*};
use crate::{aabb::*, objects::hittable::*, ray::*};

pub struct HittableList {
pub objects: Vec<Arc<dyn Hittable>>,
Expand All @@ -20,7 +20,27 @@ impl HittableList {
}

impl Hittable for HittableList {
fn hit<'a>(&'a self, r: Ray, t_min: f32, t_max: f32, rec: &mut HitRecord<'a>) -> bool {
fn bounding_box<'a>(&'a self, time0: f32, time1: f32, output_box: &mut Aabb) -> bool {
if self.objects.is_empty() {
return false;
}
let mut temp_box = Aabb::new();
let mut first_box = true;

for object in &self.objects {
if !object.bounding_box(time0, time1, &mut temp_box) {
return false;
}
*output_box = if first_box {
temp_box
} else {
surrounding_box(&output_box, &temp_box)
};
first_box = false;
}
true
}
fn hit<'a>(&'a self, r: &Ray, t_min: f32, t_max: f32, rec: &mut HitRecord<'a>) -> bool {
let mut temp_rec = HitRecord::void();
let mut hit_anything = false;
let mut closest_so_far = t_max;
Expand Down
18 changes: 15 additions & 3 deletions src/objects/moving_sphere.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::{material::material::*, objects::hittable::*, ray::*, vec3::*};
use crate::{aabb::*, material::material::*, objects::hittable::*, ray::*, vec3::*};
use std::sync::Arc;

pub struct MovingSphere {
Expand Down Expand Up @@ -34,7 +34,19 @@ impl MovingSphere {
}
}
impl Hittable for MovingSphere {
fn hit<'a>(&'a self, r: Ray, t_min: f32, t_max: f32, rec: &mut HitRecord<'a>) -> bool {
fn bounding_box<'a>(&'a self, time0: f32, time1: f32, output_box: &mut Aabb) -> bool {
let box0 = Aabb::from(
&Vec3::from(self.radius, self.radius, self.radius + -time0),
&Vec3::from(self.radius, self.radius, self.radius + time0),
);
let box1 = Aabb::from(
&Vec3::from(self.radius, self.radius, self.radius + -time1),
&Vec3::from(self.radius, self.radius, self.radius + time1),
);
*output_box = surrounding_box(&box0, &box1);
true
}
fn hit<'a>(&'a self, r: &Ray, t_min: f32, t_max: f32, rec: &mut HitRecord<'a>) -> bool {
let oc = r.origin() - self.center(r.time());
let a = r.direction().len_squared();
let half_b = dot(oc, r.direction());
Expand All @@ -61,7 +73,7 @@ impl Hittable for MovingSphere {
rec.t = root;
rec.p = r.at(rec.t);
let outward_normal = (rec.p - self.center(r.time())) / self.radius;
rec.set_face_normal(r, outward_normal);
rec.set_face_normal(*r, outward_normal);
rec.mat_ptr = &*self.mat_ptr;

true
Expand Down
14 changes: 11 additions & 3 deletions src/objects/sphere.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::{material::material::Material, objects::hittable::*, ray::*, vec3::*};
use crate::{aabb::*, material::material::Material, objects::hittable::*, ray::*, vec3::*};
use std::sync::Arc;
pub struct Sphere {
pub center: point3,
Expand All @@ -16,7 +16,7 @@ impl Sphere {
}

impl Hittable for Sphere {
fn hit<'a>(&'a self, r: Ray, t_min: f32, t_max: f32, rec: &mut HitRecord<'a>) -> bool {
fn hit<'a>(&'a self, r: &Ray, t_min: f32, t_max: f32, rec: &mut HitRecord<'a>) -> bool {
let oc = r.origin() - self.center;
let a = r.direction().len_squared();
let half_b = dot(oc, r.direction());
Expand All @@ -43,9 +43,17 @@ impl Hittable for Sphere {
rec.t = root;
rec.p = r.at(rec.t);
let outward_normal = (rec.p - self.center) / self.radius;
rec.set_face_normal(r, outward_normal);
rec.set_face_normal(*r, outward_normal);
rec.mat_ptr = &*self.mat_ptr;

true
}

fn bounding_box<'a>(&'a self, time0: f32, time1: f32, output_box: &mut Aabb) -> bool {
*output_box = Aabb::from(
&(self.center - Vec3::from(self.radius, self.radius, self.radius)),
&(self.center + Vec3::from(self.radius, self.radius, self.radius)),
);
true
}
}
4 changes: 2 additions & 2 deletions src/ray.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,12 @@ pub fn ray_color(r: Ray, world: &impl Hittable, depth: i32) -> color {
return color::new();
}

if world.hit(r, 0.001, f32::INFINITY, &mut rec) {
if world.hit(&r, 0.001, f32::INFINITY, &mut rec) {
let mut scattered = Ray::new(point3::new(), Vec3::new(), 0.);
let mut attenuation = color::new();
if rec
.mat_ptr
.scatter(r, rec , &mut attenuation, &mut scattered)
.scatter(r, rec, &mut attenuation, &mut scattered)
{
return attenuation * ray_color(scattered, world, depth - 1);
}
Expand Down
12 changes: 11 additions & 1 deletion src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,19 @@ pub fn degrees_to_radians(degrees: f32) -> f32 {
degrees.to_radians()
}
pub fn clamp(x: f32, min: f32, max: f32) -> f32 {
x.clamp(min, max)
if x < min {
min
} else if x > max {
max
} else {
x
}
}
pub fn random_double(min: f32, max: f32) -> f32 {
// TODO likely a huge bottleneck especially for multi thread
rand::thread_rng().gen_range(min, max)
}

pub fn random_int(min: i32, max: i32) -> i32 {
rand::thread_rng().gen_range(min, max)
}
9 changes: 9 additions & 0 deletions src/vec3.rs
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,15 @@ pub fn cross(u: Vec3, v: Vec3) -> Vec3 {
u.e[0] * v.e[1] - u.e[1] * v.e[0],
)
}

impl std::ops::Index<usize> for Vec3 {
type Output = f32;

fn index(&self, index: usize) -> &Self::Output {
&self.e[index]
}
}

pub fn unit_vector(v: Vec3) -> Vec3 {
v / v.len()
}
Expand Down

0 comments on commit 60cde23

Please sign in to comment.