Begin implementing triangle hittable
This commit is contained in:
parent
89bcc587d2
commit
8cb017283d
2 changed files with 68 additions and 8 deletions
|
@ -14,6 +14,13 @@ pub struct Sphere {
|
||||||
pub mat_ptr: Arc<dyn Material>,
|
pub mat_ptr: Arc<dyn Material>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct Triangle {
|
||||||
|
a: Point3,
|
||||||
|
b: Point3,
|
||||||
|
c: Point3,
|
||||||
|
pub mat_ptr: Arc<dyn Material>,
|
||||||
|
}
|
||||||
|
|
||||||
pub trait Hittable: Sync + Send {
|
pub trait Hittable: Sync + Send {
|
||||||
fn hit(&self, r: &Ray, t_min: f64, t_max: f64, rec: &mut HitRecord) -> bool;
|
fn hit(&self, r: &Ray, t_min: f64, t_max: f64, rec: &mut HitRecord) -> bool;
|
||||||
}
|
}
|
||||||
|
@ -92,3 +99,55 @@ impl Hittable for Sphere {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Triangle {
|
||||||
|
pub fn new(a: Point3, b: Point3, c: Point3, m: Arc<dyn Material>) -> Self {
|
||||||
|
Triangle {
|
||||||
|
a,
|
||||||
|
b,
|
||||||
|
c,
|
||||||
|
mat_ptr: m,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Hittable for Triangle {
|
||||||
|
fn hit(&self, r: &Ray, t_min: f64, t_max: f64, rec: &mut HitRecord) -> bool {
|
||||||
|
let a_to_b = self.b - self.a;
|
||||||
|
let a_to_c = self.c - self.a;
|
||||||
|
|
||||||
|
let u_vec = Vec3::cross(r.direction(), a_to_c);
|
||||||
|
|
||||||
|
let det = Vec3::dot(a_to_b, u_vec);
|
||||||
|
|
||||||
|
if det < 0.0 { // only positive bound
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
let inv_det = 1.0 / det;
|
||||||
|
|
||||||
|
let a_to_origin = r.origin() - self.a;
|
||||||
|
|
||||||
|
let u = Vec3::dot(a_to_origin, u_vec) * inv_det;
|
||||||
|
|
||||||
|
if u < 0.0 || u > 1.0 { //check if outside of triangle
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
let v_vec = Vec3::cross(a_to_origin, a_to_b);
|
||||||
|
|
||||||
|
let v = Vec3::dot(r.direction(), v_vec) * inv_det;
|
||||||
|
|
||||||
|
if v < 0.0 || u+v > 1.0 { // intersection outside of triangle
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
let dist = Vec3::dot(a_to_c, v_vec) * inv_det;
|
||||||
|
|
||||||
|
if dist > 0.0 {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
17
src/main.rs
17
src/main.rs
|
@ -50,23 +50,24 @@ fn ray_color(r: &Ray, world: &HittableList, depth: u32) -> Color {
|
||||||
fn random_world() -> HittableList {
|
fn random_world() -> HittableList {
|
||||||
let mut world = HittableList::new();
|
let mut world = HittableList::new();
|
||||||
|
|
||||||
let material_ground = Arc::new(Lambertian::new(&Color::new(0.05, 0.05, 0.05)));
|
let material_ground = Arc::new(Lambertian::new(&Color::new(0.05, 0.05,0.05)));
|
||||||
|
|
||||||
world.add(Box::<Sphere>::new(Sphere::new(
|
world.add(Box::<Sphere>::new(Sphere::new(
|
||||||
Point3::new(0.0, -50000.0, 0.0),
|
Point3::new(0.0, -50000.0, 0.0),
|
||||||
50000.0,
|
50000.0,
|
||||||
material_ground.clone(),
|
material_ground.clone(),
|
||||||
)));
|
)));
|
||||||
|
|
||||||
|
|
||||||
(-6..5).into_iter().for_each(|a| {
|
(-6..5).into_iter().for_each(|a| {
|
||||||
(-6..5).into_iter().for_each(|b| {
|
(-6..5).into_iter().for_each(|b| {
|
||||||
let choose_mat = utility::random_f64();
|
let choose_mat = utility::random_f64();
|
||||||
|
let rad = utility::random_rng(0.1, 0.5);
|
||||||
let center = Point3::new(
|
let center = Point3::new(
|
||||||
1.5 * a as f64 + 1.3 * utility::random_f64(),
|
1.5 * a as f64 + 1.3 * utility::random_f64(),
|
||||||
0.2,
|
rad,
|
||||||
1.5 * b as f64 + 1.3 * utility::random_f64(),
|
1.5 * b as f64 + 1.3 * utility::random_f64(),
|
||||||
);
|
);
|
||||||
if (center - Point3::new(4.0, 0.2, 0.0)).length() > 0.9 {
|
if (center - Point3::new(4.0, rad, 0.0)).length() > 0.9 {
|
||||||
if choose_mat < 0.8 {
|
if choose_mat < 0.8 {
|
||||||
// diffuse
|
// diffuse
|
||||||
let sphere_material = Arc::new(Lambertian::new(
|
let sphere_material = Arc::new(Lambertian::new(
|
||||||
|
@ -74,7 +75,7 @@ fn random_world() -> HittableList {
|
||||||
));
|
));
|
||||||
world.add(Box::<Sphere>::new(Sphere::new(
|
world.add(Box::<Sphere>::new(Sphere::new(
|
||||||
center,
|
center,
|
||||||
0.2,
|
rad,
|
||||||
sphere_material.clone(),
|
sphere_material.clone(),
|
||||||
)));
|
)));
|
||||||
} else if choose_mat < 0.95 {
|
} else if choose_mat < 0.95 {
|
||||||
|
@ -146,12 +147,12 @@ fn main() {
|
||||||
|
|
||||||
// Image
|
// Image
|
||||||
let aspect_ratio = 16.0 / 9.0;
|
let aspect_ratio = 16.0 / 9.0;
|
||||||
let image_width = 1920;
|
let image_width = 600;
|
||||||
let image_height = (image_width as f64 / aspect_ratio) as u32;
|
let image_height = (image_width as f64 / aspect_ratio) as u32;
|
||||||
let samples_per_pixel = 200_u32;
|
let samples_per_pixel = 50_u32;
|
||||||
let max_depth = 50;
|
let max_depth = 50;
|
||||||
|
|
||||||
let vfov = 25.0;
|
let vfov = 40.0;
|
||||||
let lookfrom = Point3::new(10.0, 4.0, 13.0);
|
let lookfrom = Point3::new(10.0, 4.0, 13.0);
|
||||||
let lookat = Point3::new(0.0, 0.0, 0.0);
|
let lookat = Point3::new(0.0, 0.0, 0.0);
|
||||||
let vup = Vec3::new(0.0, 1.0, 0.0);
|
let vup = Vec3::new(0.0, 1.0, 0.0);
|
||||||
|
|
Loading…
Reference in a new issue