aboutsummaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
Diffstat (limited to 'src/core')
-rw-r--r--src/core/bound2.rs (renamed from src/core/bound.rs)17
-rw-r--r--src/core/bound3.rs69
-rw-r--r--src/core/hittable.rs25
-rw-r--r--src/core/mod.rs31
-rw-r--r--src/core/vector3.rs16
5 files changed, 110 insertions, 48 deletions
diff --git a/src/core/bound.rs b/src/core/bound2.rs
index 37918d4..bc0e7cd 100644
--- a/src/core/bound.rs
+++ b/src/core/bound2.rs
@@ -1,7 +1,8 @@
-//! Implements a 2d region
+//! Implements a 2d axis aligned bounding box
use crate::{Number, Float};
use super::vector2::Vector2;
use crate::core;
+use crate::core::{min, max};
/// Implements a region between min and max
#[derive(Clone)]
@@ -13,20 +14,6 @@ pub struct Bound2<T: Number> {
pub type Bound2i = Bound2<i32>;
pub type Bound2f = Bound2<Float>;
-fn min<T: Number> (a: T, b: T) -> T {
- if b < a {
- return b;
- }
- a
-}
-
-fn max<T: Number> (a: T, b: T) -> T {
- if b > a {
- return b;
- }
- a
-}
-
impl<T: Number> Bound2<T> {
/// Creates a new bound from two points
///
diff --git a/src/core/bound3.rs b/src/core/bound3.rs
new file mode 100644
index 0000000..7f54e03
--- /dev/null
+++ b/src/core/bound3.rs
@@ -0,0 +1,69 @@
+//! Implements 3d axis aligned bounding box
+use crate::{Number, Float};
+use super::vector3::Vector3;
+use crate::core::{min, max};
+use crate::core::Ray;
+
+#[derive(Clone)]
+pub struct Bound3<T: Number> {
+ pub min: Vector3<T>,
+ pub max: Vector3<T>
+}
+
+pub type Bound3f = Bound3<Float>;
+
+impl<T: Number> Bound3<T> {
+ /// Creates a bound from two points
+ pub fn new(p0: Vector3<T>, p1: Vector3<T>) -> Self {
+ // Elliminate some code duplication here
+ let min = Vector3::new_xyz(
+ min(p0.x, p1.x),
+ min(p0.y, p1.y),
+ min(p0.z, p1.z)
+ );
+ let max = Vector3::new_xyz(
+ max(p0.x, p1.x),
+ max(p0.y, p1.y),
+ max(p0.z, p1.z)
+ );
+
+ Self {min, max}
+ }
+}
+
+impl Bound3f {
+ /// Calculate whether there is a intersect between a bounding box and a ray
+ ///
+ /// # Examples:
+ ///
+ /// ```
+ /// use rendering::core::{Bound3f, Vector3f, Ray};
+ /// let b = Bound3f::new(Vector3f::new(7.0), Vector3f::new(10.0));
+ /// let r1 = Ray::new_to(Vector3f::new(0.0), Vector3f::new(5.0));
+ /// let r3 = Ray::new(Vector3f::new_xyz(-1.0, 0.0, 0.0), Vector3f::new_xyz(1.0, 0.0, 0.0));
+ ///
+ /// assert!(b.intersect(&r1));
+ /// assert!(!b.intersect(&r3));
+ /// ```
+ pub fn intersect(&self, ray: &Ray) -> bool {
+ // Method stolen from Ray tracing the next week.
+ // They mention its from pixar
+ for i in 0..3 {
+ let inv = 1.0 / ray.direction[i];
+ let mut t0 = (self.min[i] - ray.origin[i]) * inv;
+ let mut t1 = (self.max[i] - ray.origin[i]) * inv;
+
+ if inv < 0.0 {
+ let tmp = t0;
+ t0 = t1;
+ t1 = tmp;
+ }
+
+ if t1 <= t0 {
+ return false;
+ }
+ }
+
+ return true;
+ }
+}
diff --git a/src/core/hittable.rs b/src/core/hittable.rs
deleted file mode 100644
index e495d5b..0000000
--- a/src/core/hittable.rs
+++ /dev/null
@@ -1,25 +0,0 @@
-use crate::core::{Vector3f, Ray};
-use crate::Float;
-
-/// Returns the context of a intersection
-pub struct Intersection {
- /// Normal vector at intersection
- pub n: Vector3f,
- pub p: Vector3f,
- pub t: Float,
-}
-
-impl Intersection {
- pub fn norm_against_ray(&self, r: &Ray) -> Vector3f {
- if self.n.dot(&r.direction) < 0.0 {
- self.n
- } else {
- -self.n
- }
- }
-}
-
-/// Defines a common trait for objects in the scene
-pub trait Hittable {
- fn intersect(&self, ray: &Ray) -> Option<Intersection>;
-}
diff --git a/src/core/mod.rs b/src/core/mod.rs
index c2b3771..07793ec 100644
--- a/src/core/mod.rs
+++ b/src/core/mod.rs
@@ -2,16 +2,33 @@
//!
//! Also creates a shortcut for some common types
-pub mod vector2;
-pub mod vector3;
-pub mod bound;
-pub mod spectrum;
-pub mod hittable;
+mod vector2;
+mod vector3;
+mod bound2;
+mod bound3;
+mod spectrum;
mod ray;
pub use vector2::{Vector2i, Vector2f};
pub use vector3::Vector3f;
-pub use bound::{Bound2i, Bound2f};
+pub use bound2::{Bound2i, Bound2f};
+pub use bound3::Bound3f;
pub use spectrum::Spectrum;
pub use ray::Ray;
-pub use hittable::{Hittable, Intersection};
+
+use crate::Number;
+
+fn min<T: Number> (a: T, b: T) -> T {
+ if b < a {
+ return b;
+ }
+ a
+}
+
+fn max<T: Number> (a: T, b: T) -> T {
+ if b > a {
+ return b;
+ }
+ a
+}
+
diff --git a/src/core/vector3.rs b/src/core/vector3.rs
index e26c07c..1cc6f60 100644
--- a/src/core/vector3.rs
+++ b/src/core/vector3.rs
@@ -2,7 +2,7 @@
//!
//! Also add more 3d math things needed for shading and 3d calculations.
use crate::{Float, Number, NEAR_ZERO};
-use std::ops::{Mul, Sub, Add, DivAssign, Neg, AddAssign};
+use std::ops::{Mul, Sub, Add, DivAssign, Neg, AddAssign, Index};
use std::fmt;
#[derive(Clone, Copy)]
@@ -107,6 +107,20 @@ impl<T: Number> fmt::Display for Vector3<T> {
}
}
+// Ohh god
+impl<T: Number> Index<u32> for Vector3<T> {
+ type Output = T;
+
+ fn index(&self, i: u32) -> &Self::Output {
+ match i {
+ 0 => &self.x,
+ 1 => &self.y,
+ 2 => &self.z,
+ _ => panic!("index out of bounds: index {} is not possible with 3d vector", i)
+ }
+ }
+}
+
impl Vector3f {
pub const ZERO: Self = Vector3f {x: 0.0, y: 0.0, z: 0.0};