Implemented get_aabb for primitive

This commit is contained in:
STP
2023-11-29 11:43:29 -05:00
parent d12eace0b2
commit f7eaaabe93
2 changed files with 165 additions and 217 deletions

View File

@@ -449,9 +449,9 @@ pub fn init_engine() -> Engine {
engine engine
.register_type::<Mesh>() .register_type::<Mesh>()
.register_fn("Mesh", Mesh::from_file); .register_fn("Mesh", Mesh::from_file);
engine // engine
.register_type::<Rectangle>() // .register_type::<Rectangle>()
.register_fn("Rectange", Rectangle::new) // .register_fn("Rectange", Rectangle::new)
.register_fn("RectangleUnit", Rectangle::unit); // .register_fn("RectangleUnit", Rectangle::unit);
engine engine
} }

View File

@@ -13,7 +13,7 @@ use std::rc::Rc;
// PRIMITIVE TRAIT ----------------------------------------------------------------- // PRIMITIVE TRAIT -----------------------------------------------------------------
pub trait Primitive { pub trait Primitive {
fn intersect_ray(&self, ray: &Ray) -> Option<Intersection>; fn intersect_ray(&self, ray: &Ray) -> Option<Intersection>;
fn intersect_bounding_box(&self, ray: &Ray) -> bool; fn get_aabb(&self) -> AABB;
} }
// SPHERE ----------------------------------------------------------------- // SPHERE -----------------------------------------------------------------
@@ -21,20 +21,11 @@ pub trait Primitive {
pub struct Sphere { pub struct Sphere {
position: Point3<f64>, position: Point3<f64>,
radius: f64, radius: f64,
bounding_box: AABB,
} }
impl Sphere { impl Sphere {
pub fn new(position: Point3<f64>, radius: f64) -> Rc<dyn Primitive> { pub fn new(position: Point3<f64>, radius: f64) -> Rc<dyn Primitive> {
let radius_vec = Vector3::new(radius, radius, radius); Rc::new(Sphere { position, radius })
let bln = position - radius_vec;
let trf = position + radius_vec;
let bounding_box = AABB::new(bln, trf);
Rc::new(Sphere {
position,
radius,
bounding_box,
})
} }
pub fn unit() -> Rc<dyn Primitive> { pub fn unit() -> Rc<dyn Primitive> {
@@ -78,8 +69,12 @@ impl Primitive for Sphere {
}) })
} }
fn intersect_bounding_box(&self, ray: &Ray) -> bool { fn get_aabb(&self) -> AABB {
return self.bounding_box.intersect_bounding_box(ray); let radius = self.radius;
let radius_vec = Vector3::new(radius, radius, radius);
let bln = self.position - radius_vec;
let trf = self.position + radius_vec;
AABB::new(bln, trf)
} }
} }
@@ -90,16 +85,10 @@ pub struct Circle {
radius: f64, radius: f64,
normal: Vector3<f64>, normal: Vector3<f64>,
constant: f64, constant: f64,
bounding_box: AABB,
} }
impl Circle { impl Circle {
pub fn new(position: Point3<f64>, radius: f64, normal: Vector3<f64>) -> Rc<dyn Primitive> { pub fn new(position: Point3<f64>, radius: f64, normal: Vector3<f64>) -> Rc<dyn Primitive> {
let radius_vec = Vector3::new(radius, radius, radius);
let bln = position - radius_vec;
let trf = position + radius_vec;
let bounding_box = AABB::new(bln, trf);
let normal = normal.normalize(); let normal = normal.normalize();
let constant = normal.dot(&position.coords); let constant = normal.dot(&position.coords);
Rc::new(Circle { Rc::new(Circle {
@@ -107,7 +96,6 @@ impl Circle {
radius, radius,
normal, normal,
constant, constant,
bounding_box,
}) })
} }
@@ -144,8 +132,13 @@ impl Primitive for Circle {
} }
} }
fn intersect_bounding_box(&self, ray: &Ray) -> bool { fn get_aabb(&self) -> AABB {
self.bounding_box.intersect_bounding_box(ray) let radius = self.radius;
let position = self.position;
let radius_vec = Vector3::new(radius, radius, radius);
let bln = position - radius_vec;
let trf = position + radius_vec;
AABB::new(bln, trf)
} }
} }
@@ -156,7 +149,6 @@ pub struct Cylinder {
height: f64, height: f64,
base_circle: Rc<dyn Primitive>, base_circle: Rc<dyn Primitive>,
top_circle: Rc<dyn Primitive>, top_circle: Rc<dyn Primitive>,
bounding_box: AABB,
} }
impl Cylinder { impl Cylinder {
@@ -171,14 +163,11 @@ impl Cylinder {
radius, radius,
Vector3::new(0.0, 1.0, 0.0), Vector3::new(0.0, 1.0, 0.0),
); );
let bln = Point3::new(-radius, 0.0, -radius);
let trf = Point3::new(radius, height, radius);
Rc::new(Cylinder { Rc::new(Cylinder {
radius, radius,
height, height,
base_circle, base_circle,
top_circle, top_circle,
bounding_box: AABB { bln, trf },
}) })
} }
} }
@@ -261,8 +250,12 @@ impl Primitive for Cylinder {
} }
} }
fn intersect_bounding_box(&self, ray: &Ray) -> bool { fn get_aabb(&self) -> AABB {
self.bounding_box.intersect_bounding_box(ray) let radius = self.radius;
let height = self.height;
let bln = Point3::new(-radius, 0.0, -radius);
let trf = Point3::new(radius, height, radius);
AABB::new(bln, trf)
} }
} }
@@ -272,7 +265,6 @@ pub struct Cone {
height: f64, height: f64,
constant: f64, constant: f64,
circle: Rc<dyn Primitive>, circle: Rc<dyn Primitive>,
bounding_box: AABB,
} }
impl Cone { impl Cone {
@@ -282,14 +274,11 @@ impl Cone {
radius, radius,
Vector3::new(0.0, -1.0, 0.0), Vector3::new(0.0, -1.0, 0.0),
); );
let bln = Point3::new(-radius, 0.0, -radius);
let trf = Point3::new(radius, height, radius);
let constant = radius * radius / (height * height); let constant = radius * radius / (height * height);
Rc::new(Cone { Rc::new(Cone {
height, height,
constant, constant,
circle, circle,
bounding_box: AABB { bln, trf },
}) })
} }
pub fn unit() -> Rc<dyn Primitive> { pub fn unit() -> Rc<dyn Primitive> {
@@ -363,104 +352,106 @@ impl Primitive for Cone {
} }
} }
fn intersect_bounding_box(&self, ray: &Ray) -> bool { fn get_aabb(&self) -> AABB {
self.bounding_box.intersect_bounding_box(ray) let height = self.height;
let radius = (self.constant * height * height).sqrt();
let bln = Point3::new(-radius, 0.0, -radius);
let trf = Point3::new(radius, height, radius);
AABB::new(bln, trf)
} }
} }
// RECTANGLE ----------------------------------------------------------------- // RECTANGLE -----------------------------------------------------------------
#[derive(Clone)] // #[derive(Clone)]
pub struct Rectangle { // pub struct Rectangle {
position: Point3<f64>, // position: Point3<f64>,
normal: Vector3<f64>, // normal: Vector3<f64>,
width_direction: Vector3<f64>, // width_direction: Vector3<f64>,
width: f64, // width: f64,
height: f64, // height: f64,
bounding_box: AABB, // }
}
impl Rectangle { // impl Rectangle {
pub fn new( // pub fn new(
position: Point3<f64>, // position: Point3<f64>,
normal: Vector3<f64>, // normal: Vector3<f64>,
width_direction: Vector3<f64>, // width_direction: Vector3<f64>,
width: f64, // width: f64,
height: f64, // height: f64,
) -> Rc<dyn Primitive> { // ) -> Rc<dyn Primitive> {
let normal = normal.normalize(); // let normal = normal.normalize();
let width_direction = width_direction.normalize(); // let width_direction = width_direction.normalize();
let height_direction = width_direction.cross(&normal); // let height_direction = width_direction.cross(&normal);
let bln = position - width / 2.0 * width_direction - height / 2.0 * height_direction; // Rc::new(Rectangle {
let trf = position + width / 2.0 * width_direction + height / 2.0 * height_direction; // position,
Rc::new(Rectangle { // normal: normal.normalize(),
position, // width_direction: width_direction.normalize(),
normal: normal.normalize(), // width,
width_direction: width_direction.normalize(), // height,
width, // })
height, // }
bounding_box: AABB { bln, trf }, // pub fn unit() -> Rc<dyn Primitive> {
}) // Rectangle::new(
} // Point3::new(0.0, 0.0, 0.0),
pub fn unit() -> Rc<dyn Primitive> { // Vector3::new(0.0, 1.0, 0.0),
Rectangle::new( // Vector3::new(1.0, 0.0, 0.0),
Point3::new(0.0, 0.0, 0.0), // 2.0,
Vector3::new(0.0, 1.0, 0.0), // 2.0,
Vector3::new(1.0, 0.0, 0.0), // )
2.0, // }
2.0, // }
)
}
}
impl Primitive for Rectangle { // impl Primitive for Rectangle {
fn intersect_ray(&self, ray: &Ray) -> Option<Intersection> { // fn intersect_ray(&self, ray: &Ray) -> Option<Intersection> {
let constant = self.position.coords.dot(&self.normal); // let constant = self.position.coords.dot(&self.normal);
let denominator = ray.b.dot(&self.normal); // let denominator = ray.b.dot(&self.normal);
let t = (constant - ray.a.coords.dot(&self.normal)) / denominator; // let t = (constant - ray.a.coords.dot(&self.normal)) / denominator;
if t > INFINITY { // if t > INFINITY {
return None; // return None;
} // }
let intersect = ray.at_t(t); // let intersect = ray.at_t(t);
let height_direction = self.width_direction.cross(&self.normal); // let height_direction = self.width_direction.cross(&self.normal);
let (w2, h2) = (self.width / 2.0, self.height / 2.0); // let (w2, h2) = (self.width / 2.0, self.height / 2.0);
let r1 = w2 * self.width_direction; // let r1 = w2 * self.width_direction;
let r2 = h2 * height_direction; // let r2 = h2 * height_direction;
let pi = intersect - self.position; // let pi = intersect - self.position;
let pi_dot_r1 = pi.dot(&r1); // let pi_dot_r1 = pi.dot(&r1);
let pi_dot_r2 = pi.dot(&r2); // let pi_dot_r2 = pi.dot(&r2);
if pi_dot_r1 >= -w2 && pi_dot_r1 <= w2 && pi_dot_r2 >= -h2 && pi_dot_r2 <= h2 { // if pi_dot_r1 >= -w2 && pi_dot_r1 <= w2 && pi_dot_r2 >= -h2 && pi_dot_r2 <= h2 {
return Some(Intersection { // return Some(Intersection {
point: intersect, // point: intersect,
normal: self.normal, // normal: self.normal,
distance: t, // distance: t,
}); // });
} // }
None // None
} // }
fn intersect_bounding_box(&self, ray: &Ray) -> bool { // fn get_bounding_box(&self) -> AABB {
self.bounding_box.intersect_bounding_box(ray) // let position = self.position;
} // let width = self.width;
} // let height = self.height;
// let width_direction = self.width_direction;
// let bln = position - width / 2.0 * width_direction - height / 2.0 * height_direction;
// let trf = position + width / 2.0 * width_direction + height / 2.0 * height_direction;
// AABB::new(bln, trf);
// todo!()
// }
// }
// Cube ----------------------------------------------------------------- // Cube -----------------------------------------------------------------
#[derive(Clone)] #[derive(Clone)]
pub struct Cube { pub struct Cube {
bln: Point3<f64>, bln: Point3<f64>,
trf: Point3<f64>, trf: Point3<f64>,
bounding_box: AABB,
} }
impl Cube { impl Cube {
pub fn new(bln: Point3<f64>, trf: Point3<f64>) -> Rc<dyn Primitive> { pub fn new(bln: Point3<f64>, trf: Point3<f64>) -> Rc<dyn Primitive> {
Rc::new(Cube { Rc::new(Cube { bln, trf })
bln,
trf,
bounding_box: AABB { bln, trf },
})
} }
pub fn unit() -> Rc<dyn Primitive> { pub fn unit() -> Rc<dyn Primitive> {
@@ -524,8 +515,8 @@ impl Primitive for Cube {
} }
} }
fn intersect_bounding_box(&self, ray: &Ray) -> bool { fn get_aabb(&self) -> AABB {
self.bounding_box.intersect_bounding_box(ray) AABB::new(self.bln, self.trf)
} }
} }
@@ -539,7 +530,6 @@ pub struct Triangle {
v: Point3<f64>, v: Point3<f64>,
w: Point3<f64>, w: Point3<f64>,
normal: Vector3<f64>, normal: Vector3<f64>,
bounding_box: AABB,
} }
impl Triangle { impl Triangle {
@@ -547,16 +537,7 @@ impl Triangle {
let uv = v - u; let uv = v - u;
let uw = w - u; let uw = w - u;
let normal = uw.cross(&uv).normalize(); let normal = uw.cross(&uv).normalize();
let bln = u.inf(&v).inf(&w); Rc::new(Triangle { u, v, w, normal })
let trf = u.sup(&v).sup(&w);
let bounding_box = AABB { bln, trf };
Rc::new(Triangle {
u,
v,
w,
normal,
bounding_box,
})
} }
#[allow(dead_code)] #[allow(dead_code)]
pub fn unit() -> Rc<dyn Primitive> { pub fn unit() -> Rc<dyn Primitive> {
@@ -608,8 +589,13 @@ impl Primitive for Triangle {
None None
} }
fn intersect_bounding_box(&self, ray: &Ray) -> bool { fn get_aabb(&self) -> AABB {
self.bounding_box.intersect_bounding_box(ray) let u = self.u;
let v = self.v;
let w = self.w;
let bln = u.inf(&v).inf(&w);
let trf = u.sup(&v).sup(&w);
AABB::new(bln, trf)
} }
} }
@@ -617,17 +603,13 @@ impl Primitive for Triangle {
#[derive(Clone)] #[derive(Clone)]
pub struct Mesh { pub struct Mesh {
triangles: Vec<Triangle>, triangles: Vec<Triangle>,
bounding_box: AABB,
} }
impl Mesh { impl Mesh {
pub fn new(triangles: Vec<Triangle>) -> Rc<dyn Primitive> { pub fn new(triangles: Vec<Triangle>) -> Rc<dyn Primitive> {
// Calculate the bounding box for the entire mesh based on the bounding boxes of individual triangles // Calculate the bounding box for the entire mesh based on the bounding boxes of individual triangles
let bounding_box = Mesh::compute_bounding_box(&triangles); let bounding_box = Mesh::compute_bounding_box(&triangles);
Rc::new(Mesh { Rc::new(Mesh { triangles })
triangles,
bounding_box,
})
} }
fn compute_bounding_box(triangles: &Vec<Triangle>) -> AABB { fn compute_bounding_box(triangles: &Vec<Triangle>) -> AABB {
@@ -685,16 +667,7 @@ impl Mesh {
let uv = u - v; let uv = u - v;
let uw = w - v; let uw = w - v;
let normal = uv.cross(&uw).normalize(); let normal = uv.cross(&uw).normalize();
let bln = u.inf(&v).inf(&w); triangles.push(Triangle { u, v, w, normal });
let trf = u.sup(&v).sup(&w);
let bounding_box = AABB { bln, trf };
triangles.push(Triangle {
u,
v,
w,
normal,
bounding_box,
});
} }
} }
_ => {} _ => {}
@@ -727,8 +700,8 @@ impl Primitive for Mesh {
closest_intersect closest_intersect
} }
fn intersect_bounding_box(&self, ray: &Ray) -> bool { fn get_aabb(&self) -> AABB {
self.bounding_box.intersect_bounding_box(ray) Mesh::compute_bounding_box(&self.triangles)
} }
} }
@@ -737,18 +710,14 @@ impl Primitive for Mesh {
pub struct Torus { pub struct Torus {
inner_rad: f64, inner_rad: f64,
outer_rad: f64, outer_rad: f64,
bounding_box: AABB,
} }
impl Torus { impl Torus {
pub fn new(inner_rad: f64, outer_rad: f64) -> Rc<dyn Primitive> { pub fn new(inner_rad: f64, outer_rad: f64) -> Rc<dyn Primitive> {
// I need to find the bounding box for this shape // I need to find the bounding box for this shape
let trf = Point3::new(1.0, 1.0, 1.0);
let bln = Point3::new(-1.0, -1.0, -1.0);
Rc::new(Torus { Rc::new(Torus {
inner_rad, inner_rad,
outer_rad, outer_rad,
bounding_box: AABB { bln, trf },
}) })
} }
} }
@@ -854,8 +823,11 @@ impl Primitive for Torus {
}) })
} }
fn intersect_bounding_box(&self, ray: &Ray) -> bool { fn get_aabb(&self) -> AABB {
self.bounding_box.intersect_bounding_box(ray) //TODO!
let trf = Point3::new(1.0, 1.0, 1.0);
let bln = Point3::new(-1.0, -1.0, -1.0);
AABB::new(bln, trf)
} }
} }
@@ -865,7 +837,6 @@ pub struct Gnonom {
x_cube: Rc<dyn Primitive>, x_cube: Rc<dyn Primitive>,
y_cube: Rc<dyn Primitive>, y_cube: Rc<dyn Primitive>,
z_cube: Rc<dyn Primitive>, z_cube: Rc<dyn Primitive>,
bounding_box: AABB,
} }
impl Gnonom { impl Gnonom {
@@ -884,23 +855,10 @@ impl Gnonom {
Point3::new(-Self::GNONOM_WIDTH, -Self::GNONOM_WIDTH, 0.0), Point3::new(-Self::GNONOM_WIDTH, -Self::GNONOM_WIDTH, 0.0),
Point3::new(Self::GNONOM_WIDTH, Self::GNONOM_WIDTH, Self::GNONOM_LENGTH), Point3::new(Self::GNONOM_WIDTH, Self::GNONOM_WIDTH, Self::GNONOM_LENGTH),
); );
let bounding_box = AABB {
bln: Point3::new(
-Self::GNONOM_WIDTH,
-Self::GNONOM_WIDTH,
-Self::GNONOM_WIDTH,
),
trf: Point3::new(
Self::GNONOM_LENGTH,
Self::GNONOM_LENGTH,
Self::GNONOM_LENGTH,
),
};
Rc::new(Gnonom { Rc::new(Gnonom {
x_cube, x_cube,
y_cube, y_cube,
z_cube, z_cube,
bounding_box,
}) })
} }
} }
@@ -922,25 +880,30 @@ impl Primitive for Gnonom {
None None
} }
fn intersect_bounding_box(&self, ray: &Ray) -> bool { fn get_aabb(&self) -> AABB {
self.bounding_box.intersect_bounding_box(ray) AABB {
bln: Point3::new(
-Self::GNONOM_WIDTH,
-Self::GNONOM_WIDTH,
-Self::GNONOM_WIDTH,
),
trf: Point3::new(
Self::GNONOM_LENGTH,
Self::GNONOM_LENGTH,
Self::GNONOM_LENGTH,
),
}
} }
} }
// CROSS CAP --------- // CROSS CAP ---------
#[derive(Clone)] #[derive(Clone)]
pub struct CrossCap { pub struct CrossCap {}
bounding_box: AABB,
}
impl CrossCap { impl CrossCap {
pub fn new() -> Rc<dyn Primitive> { pub fn new() -> Rc<dyn Primitive> {
// I need to find the bounding box for this shape // I need to find the bounding box for this shape
let trf = Point3::new(1.0, 1.0, 1.0); Rc::new(CrossCap {})
let bln = Point3::new(-1.0, -1.0, -1.0);
Rc::new(CrossCap {
bounding_box: AABB { bln, trf },
})
} }
} }
@@ -1014,8 +977,10 @@ impl Primitive for CrossCap {
}) })
} }
fn intersect_bounding_box(&self, ray: &Ray) -> bool { fn get_aabb(&self) -> AABB {
self.bounding_box.intersect_bounding_box(ray) let trf = Point3::new(1.0, 1.0, 1.0);
let bln = Point3::new(-1.0, -1.0, -1.0);
AABB::new(bln, trf)
} }
} }
@@ -1024,19 +989,12 @@ impl Primitive for CrossCap {
pub struct CrossCap2 { pub struct CrossCap2 {
p: f64, p: f64,
q: f64, q: f64,
bounding_box: AABB,
} }
impl CrossCap2 { impl CrossCap2 {
pub fn new(p: f64, q: f64) -> Rc<dyn Primitive> { pub fn new(p: f64, q: f64) -> Rc<dyn Primitive> {
// I need to find the bounding box for this shape // I need to find the bounding box for this shape
let trf = Point3::new(1.0, 1.0, 1.0); Rc::new(CrossCap2 { p, q })
let bln = Point3::new(-1.0, -1.0, -1.0);
Rc::new(CrossCap2 {
p,
q,
bounding_box: AABB { bln, trf },
})
} }
} }
@@ -1135,25 +1093,21 @@ impl Primitive for CrossCap2 {
}) })
} }
fn intersect_bounding_box(&self, ray: &Ray) -> bool { fn get_aabb(&self) -> AABB {
self.bounding_box.intersect_bounding_box(ray) let trf = Point3::new(1.0, 1.0, 1.0);
let bln = Point3::new(-1.0, -1.0, -1.0);
AABB::new(bln, trf)
} }
} }
// Steiner --------- // Steiner ---------
#[derive(Clone)] #[derive(Clone)]
pub struct Steiner { pub struct Steiner {}
bounding_box: AABB,
}
impl Steiner { impl Steiner {
pub fn new() -> Rc<dyn Primitive> { pub fn new() -> Rc<dyn Primitive> {
// I need to find the bounding box for this shape // I need to find the bounding box for this shape
let trf = Point3::new(1.0, 1.0, 1.0); Rc::new(Steiner {})
let bln = Point3::new(-1.0, -1.0, -1.0);
Rc::new(Steiner {
bounding_box: AABB { bln, trf },
})
} }
} }
@@ -1216,25 +1170,21 @@ impl Primitive for Steiner {
}) })
} }
fn intersect_bounding_box(&self, ray: &Ray) -> bool { fn get_aabb(&self) -> AABB {
self.bounding_box.intersect_bounding_box(ray) let trf = Point3::new(1.0, 1.0, 1.0);
let bln = Point3::new(-1.0, -1.0, -1.0);
AABB::new(bln, trf)
} }
} }
// Steiner 2 --------- // Steiner 2 ---------
#[derive(Clone)] #[derive(Clone)]
pub struct Steiner2 { pub struct Steiner2 {}
bounding_box: AABB,
}
impl Steiner2 { impl Steiner2 {
pub fn new() -> Rc<dyn Primitive> { pub fn new() -> Rc<dyn Primitive> {
// I need to find the bounding box for this shape // I need to find the bounding box for this shape
let trf = Point3::new(1.0, 1.0, 1.0); Rc::new(Steiner2 {})
let bln = Point3::new(-1.0, -1.0, -1.0);
Rc::new(Steiner2 {
bounding_box: AABB { bln, trf },
})
} }
} }
@@ -1308,8 +1258,10 @@ impl Primitive for Steiner2 {
}) })
} }
fn intersect_bounding_box(&self, ray: &Ray) -> bool { fn get_aabb(&self) -> AABB {
self.bounding_box.intersect_bounding_box(ray) let trf = Point3::new(1.0, 1.0, 1.0);
let bln = Point3::new(-1.0, -1.0, -1.0);
AABB::new(bln, trf)
} }
} }
@@ -1317,18 +1269,12 @@ impl Primitive for Steiner2 {
#[derive(Clone)] #[derive(Clone)]
pub struct Roman { pub struct Roman {
k: f64, k: f64,
bounding_box: AABB,
} }
impl Roman { impl Roman {
pub fn new(k: f64) -> Rc<dyn Primitive> { pub fn new(k: f64) -> Rc<dyn Primitive> {
// I need to find the bounding box for this shape // I need to find the bounding box for this shape
let trf = Point3::new(1.0, 1.0, 1.0); Rc::new(Roman { k })
let bln = Point3::new(-1.0, -1.0, -1.0);
Rc::new(Roman {
k,
bounding_box: AABB { bln, trf },
})
} }
} }
@@ -1419,8 +1365,10 @@ impl Primitive for Roman {
}) })
} }
fn intersect_bounding_box(&self, ray: &Ray) -> bool { fn get_aabb(&self) -> AABB {
self.bounding_box.intersect_bounding_box(ray) let trf = Point3::new(1.0, 1.0, 1.0);
let bln = Point3::new(-1.0, -1.0, -1.0);
AABB::new(bln, trf)
} }
} }