Files
raytracing/src/objects/quad.rs
2026-05-02 13:48:27 +02:00

89 lines
2.3 KiB
Rust

use crate::objects::hit::Hit;
use crate::objects::sphere::Sphere;
use crate::objects::traits::Hittable;
use crate::objects::triangle::Triangle;
use crate::ray::Ray;
use crate::{objects::materials::traits::Material, vec3::Vec3};
use log::{info, warn};
use std::fmt::Debug;
use std::sync::Arc;
pub struct Quad {
p1: Vec3,
p2: Vec3,
p3: Vec3,
p4: Vec3,
material: Arc<dyn Material>,
normal: Vec3,
}
impl Quad {
pub fn new(p1: Vec3, p2: Vec3, p3: Vec3, p4: Vec3, material: Arc<dyn Material>) -> Self {
warn!("quad normal {}", (p2 - p1).cross(&(p4 - p1)).get_unit());
Self {
p1,
p2,
p3,
p4,
material,
normal: (p2 - p1).cross(&(p4 - p1)).get_unit(),
}
}
pub fn corner_spheres(&self) -> Vec<Sphere> {
let mut out: Vec<Sphere> = vec![];
out.push(Sphere::new(self.p1, 1., self.material.clone()));
out.push(Sphere::new(self.p2, 1., self.material.clone()));
out.push(Sphere::new(self.p3, 1., self.material.clone()));
out.push(Sphere::new(self.p4, 1., self.material.clone()));
return out;
}
pub fn hit(
p1: Vec3,
p2: Vec3,
p3: Vec3,
p4: Vec3,
material: Arc<dyn Material>,
normal: Vec3,
r: &Ray,
) -> Option<Hit> {
let isct1 = Triangle::hit(p1, p2, p4, material.clone(), normal, r);
let isct2 = Triangle::hit(p2, p3, p4, material.clone(), normal, r);
if isct1.is_some() {
return isct1;
}
return isct2;
}
}
impl Debug for Quad {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("Triangle")
.field("p1", &self.p1)
.field("p2", &self.p2)
.field("p3", &self.p3)
.field("p4", &self.p4)
.field("material", &self.material)
.finish()
}
}
impl Hittable for Quad {
fn hit(&self, r: &Ray) -> Option<Hit> {
Quad::hit(
self.p1,
self.p2,
self.p3,
self.p4,
self.material.clone(),
self.normal,
r,
)
}
fn normal_at(&self, _p: &Vec3) -> Vec3 {
// FIXME: might cause ownership issues
return self.normal;
}
}