aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulian T <julian@jtle.dk>2021-01-31 17:21:11 +0100
committerJulian T <julian@jtle.dk>2021-01-31 17:21:11 +0100
commitc4369f86c920888bfaa00e46d74e3f5a1872a9ab (patch)
tree0bbfa3fa0d6db98b43b3854034def7f028a7a847
parent86303936ab3180828b984ebb256bab8e69dab5cf (diff)
Add Scene type and Sphere intersect
-rw-r--r--src/core/ray.rs5
-rw-r--r--src/core/vector3.rs45
-rw-r--r--src/lib.rs6
-rw-r--r--src/main.rs8
-rw-r--r--src/scene/mod.rs5
-rw-r--r--src/scene/scene.rs38
-rw-r--r--src/scene/shapes/mod.rs6
-rw-r--r--src/scene/shapes/sphere.rs37
8 files changed, 128 insertions, 22 deletions
diff --git a/src/core/ray.rs b/src/core/ray.rs
index 7d73b93..54af639 100644
--- a/src/core/ray.rs
+++ b/src/core/ray.rs
@@ -1,6 +1,7 @@
use crate::core::Vector3f;
pub struct Ray {
- origin: Vector3f,
- direction: Vector3f,
+ pub origin: Vector3f,
+ pub direction: Vector3f,
}
+
diff --git a/src/core/vector3.rs b/src/core/vector3.rs
index da09ceb..e3aa9a6 100644
--- a/src/core/vector3.rs
+++ b/src/core/vector3.rs
@@ -1,5 +1,5 @@
use crate::{Float, Number};
-use std::ops::{Sub, Add};
+use std::ops::{Sub, Add, DivAssign};
#[derive(Clone, Copy)]
pub struct Vector3<T: Number> {
@@ -19,7 +19,7 @@ impl<T: Number> Vector3<T> {
}
}
- pub fn new_xy(x: T, y: T, z: T) -> Vector3<T> {
+ pub fn new_xyz(x: T, y: T, z: T) -> Vector3<T> {
Vector3 { x, y, z}
}
}
@@ -27,7 +27,7 @@ impl<T: Number> Vector3<T> {
impl<T: Number> Sub for Vector3<T> {
type Output = Self;
fn sub(self, op: Self) -> Self::Output {
- Self::new_xy(
+ Self::new_xyz(
self.x - op.x,
self.y - op.y,
self.z - op.z,
@@ -38,10 +38,47 @@ impl<T: Number> Sub for Vector3<T> {
impl<T: Number> Add for Vector3<T> {
type Output = Self;
fn add(self, op: Self) -> Self::Output {
- Self::new_xy(
+ Self::new_xyz(
self.x + op.x,
self.y + op.y,
self.z + op.z,
)
}
}
+
+impl<T: Number> DivAssign<T> for Vector3<T> {
+ fn div_assign(&mut self, op: T) {
+ self.x /= op;
+ self.y /= op;
+ self.z /= op;
+ }
+}
+
+impl Vector3f {
+ pub fn len_squared(&self) -> Float {
+ self.x * self.x + self.y * self.y + self.z * self.z
+ }
+
+ pub fn len(&self) -> Float {
+ self.len_squared().sqrt()
+ }
+
+ pub fn dot(&self, op: &Self) -> Float {
+ self.x * op.x + self.y * op.y + self.z * op.z
+ }
+
+ pub fn norm_in(&mut self) {
+ let len = self.len();
+ if len == 0.0 {
+ *self = Self::new(0.0);
+ }
+
+ *self /= len;
+ }
+
+ pub fn norm(&self) -> Self {
+ let mut new = self.clone();
+ new.norm_in();
+ new
+ }
+}
diff --git a/src/lib.rs b/src/lib.rs
index c78c51e..a120f0d 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -1,8 +1,9 @@
pub mod core;
pub mod camera;
mod scene;
+mod render;
-use std::ops::{Add, Sub, Mul};
+use std::ops::{Add, Sub, Mul, DivAssign};
use std::cmp;
pub trait Number:
@@ -10,7 +11,8 @@ pub trait Number:
cmp::PartialOrd +
Sub<Output = Self> +
Add<Output = Self> +
- Mul<Output = Self>
+ Mul<Output = Self> +
+ DivAssign
{}
impl Number for usize {}
diff --git a/src/main.rs b/src/main.rs
index c984176..524f613 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,12 +1,4 @@
-use pathtrace::camera::film::Film;
-use pathtrace::vector::{Vector2i};
-use pathtrace::bound::Bound2i;
fn main() {
-
- let film = Film::new(Vector2i::new(100));
- let tile = film.get_tile(&Bound2i::new_xyxy(10, 10, 100, 100));
-
- //println!("Yo {}", tile.bounds.min.x);
}
diff --git a/src/scene/mod.rs b/src/scene/mod.rs
index 3482bb6..13c5e23 100644
--- a/src/scene/mod.rs
+++ b/src/scene/mod.rs
@@ -1,3 +1,4 @@
-mod shapes;
-
+pub mod shapes;
+mod scene;
+pub use scene::*;
diff --git a/src/scene/scene.rs b/src/scene/scene.rs
new file mode 100644
index 0000000..a2f5b88
--- /dev/null
+++ b/src/scene/scene.rs
@@ -0,0 +1,38 @@
+use super::shapes::Shape;
+use crate::Float;
+use crate::core::Ray;
+
+pub struct Scene {
+ shps: Vec<Box<dyn Shape>>,
+}
+
+pub struct Intersection<'a> {
+ pub shp: &'a dyn Shape,
+ pub t: Float,
+}
+
+impl Scene {
+ pub fn new() -> Self {
+ Self {
+ shps: Vec::new(),
+ }
+ }
+
+ pub fn add_shape(&mut self, shp: Box<dyn Shape>) {
+ self.shps.push(shp);
+ }
+
+ pub fn intersect(&self, ray: Ray) -> Option<Intersection> {
+ for shp in self.shps.iter() {
+ if let Some(t) = shp.intersect(&ray) {
+ return Some(Intersection {
+ shp: shp.as_ref(),
+ t,
+ })
+ }
+ }
+
+ None
+ }
+}
+
diff --git a/src/scene/shapes/mod.rs b/src/scene/shapes/mod.rs
index 76fb6f2..7fbb8db 100644
--- a/src/scene/shapes/mod.rs
+++ b/src/scene/shapes/mod.rs
@@ -5,8 +5,6 @@ pub use sphere::Sphere;
use crate::core::Ray;
use crate::Float;
-trait Shape {
- //
- fn intersect(ray: Ray) -> Float;
- fn intersect_
+pub trait Shape {
+ fn intersect(&self, ray: &Ray) -> Option<Float>;
}
diff --git a/src/scene/shapes/sphere.rs b/src/scene/shapes/sphere.rs
index 9598422..f8ae11e 100644
--- a/src/scene/shapes/sphere.rs
+++ b/src/scene/shapes/sphere.rs
@@ -1,5 +1,6 @@
use crate::Float;
use crate::core::{Ray, Vector3f};
+use super::Shape;
pub struct Sphere {
radius: Float,
@@ -14,3 +15,39 @@ impl Sphere {
}
}
}
+
+impl Shape for Sphere {
+ // Implementation from ray tracing in a weekend
+ fn intersect(&self, ray: &Ray) -> Option<Float> {
+ let oc = ray.origin - self.center;
+ let a = ray.direction.len_squared();
+ let half_b = oc.dot(&ray.direction);
+ let c = oc.len_squared() - self.radius * self.radius;
+ let disc = half_b*half_b - a*c;
+
+ if disc < 0.0 {
+ None
+ } else {
+ Some( (-half_b - disc.sqrt()) / a)
+ }
+
+ }
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ #[test]
+ fn sphere_intersect() {
+ let sph = Sphere::new(2.0, Vector3f::new_xyz(2.0, 3.0, 4.0));
+
+ let ray = Ray {
+ origin: Vector3f::new_xyz(1.0, 0.0, 0.0),
+ direction: Vector3f::new_xyz(0.0, 1.0, 1.5).norm(),
+ };
+
+ let dist = sph.intersect(&ray);
+ assert!((dist.unwrap() - 3.28).abs() < 0.01);
+ }
+}