Replace Vector3 with Point3 where appropriate
This commit is contained in:
parent
a7e1f1c134
commit
9eca3a4cfe
|
|
@ -1,4 +1,4 @@
|
||||||
use nalgebra::{convert, RealField, Vector3};
|
use nalgebra::{convert, Point3, RealField, Vector3};
|
||||||
|
|
||||||
use super::colour::{ColourRgbF, NamedColour};
|
use super::colour::{ColourRgbF, NamedColour};
|
||||||
use super::image::ImageRgbF;
|
use super::image::ImageRgbF;
|
||||||
|
|
@ -14,12 +14,12 @@ struct ImageSampler<T: RealField> {
|
||||||
film_width: T,
|
film_width: T,
|
||||||
film_height: T,
|
film_height: T,
|
||||||
|
|
||||||
camera_location: Vector3<T>,
|
camera_location: Point3<T>,
|
||||||
film_distance: T,
|
film_distance: T,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: RealField> ImageSampler<T> {
|
impl<T: RealField> ImageSampler<T> {
|
||||||
pub fn new(width: u32, height: u32, camera_location: Vector3<T>) -> ImageSampler<T> {
|
pub fn new(width: u32, height: u32, camera_location: Point3<T>) -> ImageSampler<T> {
|
||||||
let (film_width, film_height) = {
|
let (film_width, film_height) = {
|
||||||
let width: T = convert(width as f64);
|
let width: T = convert(width as f64);
|
||||||
let height: T = convert(height as f64);
|
let height: T = convert(height as f64);
|
||||||
|
|
@ -146,7 +146,7 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn ray_for_pixel_returns_value_that_intersects_film_plane_at_expected_location() {
|
fn ray_for_pixel_returns_value_that_intersects_film_plane_at_expected_location() {
|
||||||
let target = ImageSampler::new(800, 600, Vector3::new(0.0, 0.0, 0.0));
|
let target = ImageSampler::new(800, 600, Point3::new(0.0, 0.0, 0.0));
|
||||||
let ray = target.ray_for_pixel(100, 200);
|
let ray = target.ray_for_pixel(100, 200);
|
||||||
let film_plane = Plane::new(
|
let film_plane = Plane::new(
|
||||||
Vector3::new(0.0, 0.0, 1.0),
|
Vector3::new(0.0, 0.0, 1.0),
|
||||||
|
|
|
||||||
20
src/main.rs
20
src/main.rs
|
|
@ -5,7 +5,7 @@ use sdl2::render::{Canvas, Texture};
|
||||||
use sdl2::Sdl;
|
use sdl2::Sdl;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
use nalgebra::Vector3;
|
use nalgebra::{Point3, Vector3};
|
||||||
|
|
||||||
use std::cmp::min;
|
use std::cmp::min;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
@ -46,8 +46,8 @@ fn init_canvas(
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn main() -> Result<(), Box<dyn std::error::Error>> {
|
pub fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
let image_width = 1200;
|
let image_width = 2400;
|
||||||
let image_height = 900;
|
let image_height = 1800;
|
||||||
|
|
||||||
let (sdl_context, mut canvas) = init_canvas(image_width, image_height)?;
|
let (sdl_context, mut canvas) = init_canvas(image_width, image_height)?;
|
||||||
|
|
||||||
|
|
@ -60,7 +60,7 @@ pub fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
let mut output_image = ImageRgbF::<f64>::new(image_width, image_height);
|
let mut output_image = ImageRgbF::<f64>::new(image_width, image_height);
|
||||||
|
|
||||||
let scene = Scene {
|
let scene = Scene {
|
||||||
camera_location: Vector3::new(0.0, 0.0, 0.0),
|
camera_location: Point3::new(0.0, 0.0, 0.0),
|
||||||
objects: vec![
|
objects: vec![
|
||||||
Box::new(Plane::new(
|
Box::new(Plane::new(
|
||||||
Vector3::new(0.0, 1.0, 0.0),
|
Vector3::new(0.0, 1.0, 0.0),
|
||||||
|
|
@ -71,7 +71,7 @@ pub fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
}),
|
}),
|
||||||
)),
|
)),
|
||||||
Box::new(Sphere::new(
|
Box::new(Sphere::new(
|
||||||
Vector3::new(1.25, -0.5, 6.0),
|
Point3::new(1.25, -0.5, 6.0),
|
||||||
1.0,
|
1.0,
|
||||||
Rc::new(LambertianMaterial {
|
Rc::new(LambertianMaterial {
|
||||||
colour: ColourRgbF::from_named(NamedColour::Green),
|
colour: ColourRgbF::from_named(NamedColour::Green),
|
||||||
|
|
@ -79,7 +79,7 @@ pub fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
}),
|
}),
|
||||||
)),
|
)),
|
||||||
Box::new(Sphere::new(
|
Box::new(Sphere::new(
|
||||||
Vector3::new(-1.25, -0.5, 6.0),
|
Point3::new(-1.25, -0.5, 6.0),
|
||||||
1.0,
|
1.0,
|
||||||
Rc::new(ReflectiveMaterial {
|
Rc::new(ReflectiveMaterial {
|
||||||
colour: ColourRgbF::from_named(NamedColour::Blue),
|
colour: ColourRgbF::from_named(NamedColour::Blue),
|
||||||
|
|
@ -88,7 +88,7 @@ pub fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
}),
|
}),
|
||||||
)),
|
)),
|
||||||
Box::new(Sphere::new(
|
Box::new(Sphere::new(
|
||||||
Vector3::new(0.0, 1.5, 6.0),
|
Point3::new(0.0, 1.5, 6.0),
|
||||||
1.0,
|
1.0,
|
||||||
Rc::new(PhongMaterial {
|
Rc::new(PhongMaterial {
|
||||||
colour: ColourRgbF::from_named(NamedColour::Red),
|
colour: ColourRgbF::from_named(NamedColour::Red),
|
||||||
|
|
@ -99,9 +99,9 @@ pub fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
)),
|
)),
|
||||||
Box::new(Triangle {
|
Box::new(Triangle {
|
||||||
vertices: [
|
vertices: [
|
||||||
Vector3::new(0.5, 2.0, 6.0),
|
Point3::new(0.5, 2.0, 6.0),
|
||||||
Vector3::new(1.5, 2.0, 4.0),
|
Point3::new(1.5, 2.0, 4.0),
|
||||||
Vector3::new(1.0, 1.0, 6.0),
|
Point3::new(1.0, 1.0, 6.0),
|
||||||
],
|
],
|
||||||
normals: [Vector3::new(0.0, 0.0, 1.0); 3],
|
normals: [Vector3::new(0.0, 0.0, 1.0); 3],
|
||||||
material: Rc::new(LambertianMaterial {
|
material: Rc::new(LambertianMaterial {
|
||||||
|
|
|
||||||
62
src/mesh.rs
62
src/mesh.rs
|
|
@ -1,4 +1,4 @@
|
||||||
use nalgebra::{RealField, Vector2, Vector3};
|
use nalgebra::{Point3, RealField, Vector2, Vector3};
|
||||||
|
|
||||||
use super::materials::Material;
|
use super::materials::Material;
|
||||||
use super::raycasting::{Intersect, IntersectionInfo, Ray};
|
use super::raycasting::{Intersect, IntersectionInfo, Ray};
|
||||||
|
|
@ -6,14 +6,14 @@ use super::raycasting::{Intersect, IntersectionInfo, Ray};
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
pub struct Triangle<T: RealField> {
|
pub struct Triangle<T: RealField> {
|
||||||
pub vertices: [Vector3<T>; 3],
|
pub vertices: [Point3<T>; 3],
|
||||||
pub normals: [Vector3<T>; 3],
|
pub normals: [Vector3<T>; 3],
|
||||||
pub material: Rc<dyn Material<T>>,
|
pub material: Rc<dyn Material<T>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: RealField> Intersect<T> for Triangle<T> {
|
impl<T: RealField> Intersect<T> for Triangle<T> {
|
||||||
fn intersect<'a>(&'a self, ray: &Ray<T>) -> Option<IntersectionInfo<T>> {
|
fn intersect<'a>(&'a self, ray: &Ray<T>) -> Option<IntersectionInfo<T>> {
|
||||||
let translation = -ray.origin;
|
let translation = -ray.origin.coords;
|
||||||
let indices = indices_with_index_of_largest_element_last(&ray.direction);
|
let indices = indices_with_index_of_largest_element_last(&ray.direction);
|
||||||
let permuted_ray_direction = permute_vector_elements(&ray.direction, &indices);
|
let permuted_ray_direction = permute_vector_elements(&ray.direction, &indices);
|
||||||
let shear_slopes = calculate_shear_to_z_axis(&permuted_ray_direction);
|
let shear_slopes = calculate_shear_to_z_axis(&permuted_ray_direction);
|
||||||
|
|
@ -22,7 +22,7 @@ impl<T: RealField> Intersect<T> for Triangle<T> {
|
||||||
.iter()
|
.iter()
|
||||||
.map(|elem| {
|
.map(|elem| {
|
||||||
apply_shear_to_z_axis(
|
apply_shear_to_z_axis(
|
||||||
&permute_vector_elements(&(elem + translation), &indices),
|
&permute_vector_elements(&(elem.coords + translation), &indices),
|
||||||
&shear_slopes,
|
&shear_slopes,
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
@ -37,11 +37,11 @@ impl<T: RealField> Intersect<T> for Triangle<T> {
|
||||||
)),
|
)),
|
||||||
&indices,
|
&indices,
|
||||||
);
|
);
|
||||||
let location: Vector3<T> = barycentric_coordinates
|
let location: Point3<T> = barycentric_coordinates
|
||||||
.iter()
|
.iter()
|
||||||
.zip(self.vertices.iter())
|
.zip(self.vertices.iter())
|
||||||
.map(|(&coord, vertex)| vertex * coord)
|
.map(|(&coord, vertex)| vertex.coords * coord)
|
||||||
.sum();
|
.fold(Point3::new(T::zero(), T::zero(), T::zero()), |a, e| a + e);
|
||||||
let distance = (ray.origin - location).norm();
|
let distance = (ray.origin - location).norm();
|
||||||
let normal = barycentric_coordinates
|
let normal = barycentric_coordinates
|
||||||
.iter()
|
.iter()
|
||||||
|
|
@ -295,14 +295,14 @@ mod tests {
|
||||||
fn intersection_passes_with_ray_along_z_axis_ccw_winding() {
|
fn intersection_passes_with_ray_along_z_axis_ccw_winding() {
|
||||||
let target_triangle = Triangle {
|
let target_triangle = Triangle {
|
||||||
vertices: [
|
vertices: [
|
||||||
Vector3::new(0.0, 1.0, 1.0),
|
Point3::new(0.0, 1.0, 1.0),
|
||||||
Vector3::new(1.0, -1.0, 1.0),
|
Point3::new(1.0, -1.0, 1.0),
|
||||||
Vector3::new(-1.0, -1.0, 1.0),
|
Point3::new(-1.0, -1.0, 1.0),
|
||||||
],
|
],
|
||||||
normals: [Vector3::zeros(); 3],
|
normals: [Vector3::zeros(); 3],
|
||||||
material: Rc::new(LambertianMaterial::new_dummy()),
|
material: Rc::new(LambertianMaterial::new_dummy()),
|
||||||
};
|
};
|
||||||
let target_ray = Ray::new(Vector3::zeros(), Vector3::new(0.0, 0.0, 1.0));
|
let target_ray = Ray::new(Point3::new(0.0, 0.0, 0.0), Vector3::new(0.0, 0.0, 1.0));
|
||||||
if let None = target_triangle.intersect(&target_ray) {
|
if let None = target_triangle.intersect(&target_ray) {
|
||||||
panic!()
|
panic!()
|
||||||
}
|
}
|
||||||
|
|
@ -312,14 +312,14 @@ mod tests {
|
||||||
fn intersection_passes_with_ray_along_z_axis_cw_winding() {
|
fn intersection_passes_with_ray_along_z_axis_cw_winding() {
|
||||||
let target_triangle = Triangle {
|
let target_triangle = Triangle {
|
||||||
vertices: [
|
vertices: [
|
||||||
Vector3::new(0.0, 1.0, 1.0),
|
Point3::new(0.0, 1.0, 1.0),
|
||||||
Vector3::new(-1.0, -1.0, 1.0),
|
Point3::new(-1.0, -1.0, 1.0),
|
||||||
Vector3::new(1.0, -1.0, 1.0),
|
Point3::new(1.0, -1.0, 1.0),
|
||||||
],
|
],
|
||||||
normals: [Vector3::zeros(); 3],
|
normals: [Vector3::zeros(); 3],
|
||||||
material: Rc::new(LambertianMaterial::new_dummy()),
|
material: Rc::new(LambertianMaterial::new_dummy()),
|
||||||
};
|
};
|
||||||
let target_ray = Ray::new(Vector3::zeros(), Vector3::new(0.0, 0.0, 1.0));
|
let target_ray = Ray::new(Point3::new(0.0, 0.0, 0.0), Vector3::new(0.0, 0.0, 1.0));
|
||||||
if let None = target_triangle.intersect(&target_ray) {
|
if let None = target_triangle.intersect(&target_ray) {
|
||||||
panic!()
|
panic!()
|
||||||
}
|
}
|
||||||
|
|
@ -329,14 +329,14 @@ mod tests {
|
||||||
fn intersection_passes_with_ray_along_nagative_z_axis_ccw_winding() {
|
fn intersection_passes_with_ray_along_nagative_z_axis_ccw_winding() {
|
||||||
let target_triangle = Triangle {
|
let target_triangle = Triangle {
|
||||||
vertices: [
|
vertices: [
|
||||||
Vector3::new(0.0, 1.0, -1.0),
|
Point3::new(0.0, 1.0, -1.0),
|
||||||
Vector3::new(1.0, -1.0, -1.0),
|
Point3::new(1.0, -1.0, -1.0),
|
||||||
Vector3::new(-1.0, -1.0, -1.0),
|
Point3::new(-1.0, -1.0, -1.0),
|
||||||
],
|
],
|
||||||
normals: [Vector3::zeros(); 3],
|
normals: [Vector3::zeros(); 3],
|
||||||
material: Rc::new(LambertianMaterial::new_dummy()),
|
material: Rc::new(LambertianMaterial::new_dummy()),
|
||||||
};
|
};
|
||||||
let target_ray = Ray::new(Vector3::zeros(), Vector3::new(0.0, 0.0, -1.0));
|
let target_ray = Ray::new(Point3::new(0.0, 0.0, 0.0), Vector3::new(0.0, 0.0, -1.0));
|
||||||
if let None = target_triangle.intersect(&target_ray) {
|
if let None = target_triangle.intersect(&target_ray) {
|
||||||
panic!()
|
panic!()
|
||||||
}
|
}
|
||||||
|
|
@ -346,14 +346,14 @@ mod tests {
|
||||||
fn intersection_passes_with_ray_along_negativez_axis_cw_winding() {
|
fn intersection_passes_with_ray_along_negativez_axis_cw_winding() {
|
||||||
let target_triangle = Triangle {
|
let target_triangle = Triangle {
|
||||||
vertices: [
|
vertices: [
|
||||||
Vector3::new(0.0, 1.0, -1.0),
|
Point3::new(0.0, 1.0, -1.0),
|
||||||
Vector3::new(-1.0, -1.0, -1.0),
|
Point3::new(-1.0, -1.0, -1.0),
|
||||||
Vector3::new(1.0, -1.0, -1.0),
|
Point3::new(1.0, -1.0, -1.0),
|
||||||
],
|
],
|
||||||
normals: [Vector3::zeros(); 3],
|
normals: [Vector3::zeros(); 3],
|
||||||
material: Rc::new(LambertianMaterial::new_dummy()),
|
material: Rc::new(LambertianMaterial::new_dummy()),
|
||||||
};
|
};
|
||||||
let target_ray = Ray::new(Vector3::zeros(), Vector3::new(0.0, 0.0, -1.0));
|
let target_ray = Ray::new(Point3::new(0.0, 0.0, 0.0), Vector3::new(0.0, 0.0, -1.0));
|
||||||
if let None = target_triangle.intersect(&target_ray) {
|
if let None = target_triangle.intersect(&target_ray) {
|
||||||
panic!()
|
panic!()
|
||||||
}
|
}
|
||||||
|
|
@ -363,14 +363,14 @@ mod tests {
|
||||||
fn intersection_passes_with_ray_along_z_axis_but_translated_ccw_winding() {
|
fn intersection_passes_with_ray_along_z_axis_but_translated_ccw_winding() {
|
||||||
let target_triangle = Triangle {
|
let target_triangle = Triangle {
|
||||||
vertices: [
|
vertices: [
|
||||||
Vector3::new(5.0, 6.0, 6.0),
|
Point3::new(5.0, 6.0, 6.0),
|
||||||
Vector3::new(6.0, 4.0, 6.0),
|
Point3::new(6.0, 4.0, 6.0),
|
||||||
Vector3::new(4.0, 4.0, 6.0),
|
Point3::new(4.0, 4.0, 6.0),
|
||||||
],
|
],
|
||||||
normals: [Vector3::zeros(); 3],
|
normals: [Vector3::zeros(); 3],
|
||||||
material: Rc::new(LambertianMaterial::new_dummy()),
|
material: Rc::new(LambertianMaterial::new_dummy()),
|
||||||
};
|
};
|
||||||
let target_ray = Ray::new(Vector3::new(5.0, 5.0, 5.0), Vector3::new(0.0, 0.0, 1.0));
|
let target_ray = Ray::new(Point3::new(5.0, 5.0, 5.0), Vector3::new(0.0, 0.0, 1.0));
|
||||||
if let None = target_triangle.intersect(&target_ray) {
|
if let None = target_triangle.intersect(&target_ray) {
|
||||||
panic!()
|
panic!()
|
||||||
}
|
}
|
||||||
|
|
@ -380,14 +380,14 @@ mod tests {
|
||||||
fn intersection_passes_with_ray_at_angle_to_z_axisand_translated_ccw_winding() {
|
fn intersection_passes_with_ray_at_angle_to_z_axisand_translated_ccw_winding() {
|
||||||
let target_triangle = Triangle {
|
let target_triangle = Triangle {
|
||||||
vertices: [
|
vertices: [
|
||||||
Vector3::new(6.0, 6.5, 6.0),
|
Point3::new(6.0, 6.5, 6.0),
|
||||||
Vector3::new(7.0, 4.5, 6.0),
|
Point3::new(7.0, 4.5, 6.0),
|
||||||
Vector3::new(5.0, 4.5, 6.0),
|
Point3::new(5.0, 4.5, 6.0),
|
||||||
],
|
],
|
||||||
normals: [Vector3::zeros(); 3],
|
normals: [Vector3::zeros(); 3],
|
||||||
material: Rc::new(LambertianMaterial::new_dummy()),
|
material: Rc::new(LambertianMaterial::new_dummy()),
|
||||||
};
|
};
|
||||||
let target_ray = Ray::new(Vector3::new(5.0, 5.0, 5.0), Vector3::new(1.0, 0.5, 1.0));
|
let target_ray = Ray::new(Point3::new(5.0, 5.0, 5.0), Vector3::new(1.0, 0.5, 1.0));
|
||||||
if let None = target_triangle.intersect(&target_ray) {
|
if let None = target_triangle.intersect(&target_ray) {
|
||||||
panic!()
|
panic!()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
use nalgebra::{convert, RealField, Vector3};
|
use nalgebra::{convert, Point3, RealField, Vector3};
|
||||||
|
|
||||||
use super::materials::Material;
|
use super::materials::Material;
|
||||||
|
|
||||||
|
|
@ -6,19 +6,19 @@ use std::rc::Rc;
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct Ray<T: RealField> {
|
pub struct Ray<T: RealField> {
|
||||||
pub origin: Vector3<T>,
|
pub origin: Point3<T>,
|
||||||
pub direction: Vector3<T>,
|
pub direction: Vector3<T>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: RealField> Ray<T> {
|
impl<T: RealField> Ray<T> {
|
||||||
pub fn new(origin: Vector3<T>, direction: Vector3<T>) -> Ray<T> {
|
pub fn new(origin: Point3<T>, direction: Vector3<T>) -> Ray<T> {
|
||||||
Ray {
|
Ray {
|
||||||
origin,
|
origin,
|
||||||
direction: direction.normalize(),
|
direction: direction.normalize(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn point_at(&self, t: T) -> Vector3<T> {
|
pub fn point_at(&self, t: T) -> Point3<T> {
|
||||||
self.origin + self.direction * t
|
self.origin + self.direction * t
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -30,7 +30,7 @@ impl<T: RealField> Ray<T> {
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct IntersectionInfo<T: RealField> {
|
pub struct IntersectionInfo<T: RealField> {
|
||||||
pub distance: T,
|
pub distance: T,
|
||||||
pub location: Vector3<T>,
|
pub location: Point3<T>,
|
||||||
pub normal: Vector3<T>,
|
pub normal: Vector3<T>,
|
||||||
pub tangent: Vector3<T>,
|
pub tangent: Vector3<T>,
|
||||||
pub cotangent: Vector3<T>,
|
pub cotangent: Vector3<T>,
|
||||||
|
|
@ -43,13 +43,13 @@ pub trait Intersect<T: RealField> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Sphere<T: RealField> {
|
pub struct Sphere<T: RealField> {
|
||||||
centre: Vector3<T>,
|
centre: Point3<T>,
|
||||||
radius: T,
|
radius: T,
|
||||||
material: Rc<dyn Material<T>>,
|
material: Rc<dyn Material<T>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: RealField> Sphere<T> {
|
impl<T: RealField> Sphere<T> {
|
||||||
pub fn new(centre: Vector3<T>, radius: T, material: Rc<dyn Material<T>>) -> Sphere<T> {
|
pub fn new(centre: Point3<T>, radius: T, material: Rc<dyn Material<T>>) -> Sphere<T> {
|
||||||
Sphere {
|
Sphere {
|
||||||
centre,
|
centre,
|
||||||
radius,
|
radius,
|
||||||
|
|
@ -98,18 +98,19 @@ impl<T: RealField> Intersect<T> for Sphere<T> {
|
||||||
let retro = -ray.direction;*/
|
let retro = -ray.direction;*/
|
||||||
let two: T = convert(2.0);
|
let two: T = convert(2.0);
|
||||||
let four: T = convert(4.0);
|
let four: T = convert(4.0);
|
||||||
|
let r_o = ray.origin.coords;
|
||||||
|
let centre_coords = self.centre.coords;
|
||||||
let a = ray
|
let a = ray
|
||||||
.direction
|
.direction
|
||||||
.component_mul(&ray.direction)
|
.component_mul(&ray.direction)
|
||||||
.iter()
|
.iter()
|
||||||
.fold(T::zero(), |a, b| a + *b);
|
.fold(T::zero(), |a, b| a + *b);
|
||||||
let b = ((ray.origin.component_mul(&ray.direction)
|
let b = ((r_o.component_mul(&ray.direction) - centre_coords.component_mul(&ray.direction))
|
||||||
- self.centre.component_mul(&ray.direction))
|
|
||||||
* two)
|
* two)
|
||||||
.iter()
|
.iter()
|
||||||
.fold(T::zero(), |a, b| a + *b);
|
.fold(T::zero(), |a, b| a + *b);
|
||||||
let c = (ray.origin.component_mul(&ray.origin) + self.centre.component_mul(&self.centre)
|
let c = (r_o.component_mul(&r_o) + centre_coords.component_mul(¢re_coords)
|
||||||
- self.centre.component_mul(&ray.origin) * two)
|
- centre_coords.component_mul(&r_o) * two)
|
||||||
.iter()
|
.iter()
|
||||||
.fold(T::zero(), |a, b| a + *b)
|
.fold(T::zero(), |a, b| a + *b)
|
||||||
- self.radius * self.radius;
|
- self.radius * self.radius;
|
||||||
|
|
@ -182,7 +183,7 @@ impl<T: RealField> Intersect<T> for Plane<T> {
|
||||||
let ray_direction_dot_plane_normal = ray.direction.dot(&self.normal);
|
let ray_direction_dot_plane_normal = ray.direction.dot(&self.normal);
|
||||||
let point_on_plane = self.normal * self.distance_from_origin;
|
let point_on_plane = self.normal * self.distance_from_origin;
|
||||||
let point_on_plane_minus_ray_origin_dot_normal =
|
let point_on_plane_minus_ray_origin_dot_normal =
|
||||||
(point_on_plane - ray.origin).dot(&self.normal);
|
(point_on_plane - ray.origin.coords).dot(&self.normal);
|
||||||
if ray_direction_dot_plane_normal == convert(0.0) {
|
if ray_direction_dot_plane_normal == convert(0.0) {
|
||||||
//Ray is parallel to plane
|
//Ray is parallel to plane
|
||||||
if point_on_plane_minus_ray_origin_dot_normal != convert(0.0) {
|
if point_on_plane_minus_ray_origin_dot_normal != convert(0.0) {
|
||||||
|
|
@ -225,7 +226,7 @@ mod tests {
|
||||||
use quickcheck::{Arbitrary, Gen, TestResult};
|
use quickcheck::{Arbitrary, Gen, TestResult};
|
||||||
impl<T: Arbitrary + RealField> Arbitrary for Ray<T> {
|
impl<T: Arbitrary + RealField> Arbitrary for Ray<T> {
|
||||||
fn arbitrary<G: Gen>(g: &mut G) -> Ray<T> {
|
fn arbitrary<G: Gen>(g: &mut G) -> Ray<T> {
|
||||||
let origin = <Vector3<T> as Arbitrary>::arbitrary(g);
|
let origin = <Point3<T> as Arbitrary>::arbitrary(g);
|
||||||
let direction = <Vector3<T> as Arbitrary>::arbitrary(g);
|
let direction = <Vector3<T> as Arbitrary>::arbitrary(g);
|
||||||
return Ray::new(origin, direction);
|
return Ray::new(origin, direction);
|
||||||
}
|
}
|
||||||
|
|
@ -261,9 +262,9 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn ray_intersects_sphere() {
|
fn ray_intersects_sphere() {
|
||||||
let r = Ray::new(Vector3::new(1.0, 2.0, 3.0), Vector3::new(0.0, 0.0, 1.0));
|
let r = Ray::new(Point3::new(1.0, 2.0, 3.0), Vector3::new(0.0, 0.0, 1.0));
|
||||||
let s = Sphere::new(
|
let s = Sphere::new(
|
||||||
Vector3::new(1.5, 1.5, 15.0),
|
Point3::new(1.5, 1.5, 15.0),
|
||||||
5.0,
|
5.0,
|
||||||
Rc::new(LambertianMaterial::new_dummy()),
|
Rc::new(LambertianMaterial::new_dummy()),
|
||||||
);
|
);
|
||||||
|
|
@ -272,9 +273,9 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn ray_does_not_intersect_sphere_when_sphere_is_in_front() {
|
fn ray_does_not_intersect_sphere_when_sphere_is_in_front() {
|
||||||
let r = Ray::new(Vector3::new(1.0, 2.0, 3.0), Vector3::new(0.0, 0.0, 1.0));
|
let r = Ray::new(Point3::new(1.0, 2.0, 3.0), Vector3::new(0.0, 0.0, 1.0));
|
||||||
let s = Sphere::new(
|
let s = Sphere::new(
|
||||||
Vector3::new(-5.0, 1.5, 15.0),
|
Point3::new(-5.0, 1.5, 15.0),
|
||||||
5.0,
|
5.0,
|
||||||
Rc::new(LambertianMaterial::new_dummy()),
|
Rc::new(LambertianMaterial::new_dummy()),
|
||||||
);
|
);
|
||||||
|
|
@ -283,9 +284,9 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn ray_does_not_intersect_sphere_when_sphere_is_behind() {
|
fn ray_does_not_intersect_sphere_when_sphere_is_behind() {
|
||||||
let r = Ray::new(Vector3::new(1.0, 2.0, 3.0), Vector3::new(0.0, 0.0, 1.0));
|
let r = Ray::new(Point3::new(1.0, 2.0, 3.0), Vector3::new(0.0, 0.0, 1.0));
|
||||||
let s = Sphere::new(
|
let s = Sphere::new(
|
||||||
Vector3::new(1.5, 1.5, -15.0),
|
Point3::new(1.5, 1.5, -15.0),
|
||||||
5.0,
|
5.0,
|
||||||
Rc::new(LambertianMaterial::new_dummy()),
|
Rc::new(LambertianMaterial::new_dummy()),
|
||||||
);
|
);
|
||||||
|
|
@ -294,9 +295,9 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn ray_intersects_sphere_when_origin_is_inside() {
|
fn ray_intersects_sphere_when_origin_is_inside() {
|
||||||
let r = Ray::new(Vector3::new(1.0, 2.0, 3.0), Vector3::new(0.0, 0.0, 1.0));
|
let r = Ray::new(Point3::new(1.0, 2.0, 3.0), Vector3::new(0.0, 0.0, 1.0));
|
||||||
let s = Sphere::new(
|
let s = Sphere::new(
|
||||||
Vector3::new(1.5, 1.5, 2.0),
|
Point3::new(1.5, 1.5, 2.0),
|
||||||
5.0,
|
5.0,
|
||||||
Rc::new(LambertianMaterial::new_dummy()),
|
Rc::new(LambertianMaterial::new_dummy()),
|
||||||
);
|
);
|
||||||
|
|
@ -305,8 +306,8 @@ mod tests {
|
||||||
|
|
||||||
#[quickcheck]
|
#[quickcheck]
|
||||||
fn ray_intersects_sphere_centre_at_correct_distance(
|
fn ray_intersects_sphere_centre_at_correct_distance(
|
||||||
ray_origin: Vector3<f64>,
|
ray_origin: Point3<f64>,
|
||||||
sphere_centre: Vector3<f64>,
|
sphere_centre: Point3<f64>,
|
||||||
radius: f64,
|
radius: f64,
|
||||||
) -> TestResult {
|
) -> TestResult {
|
||||||
if radius <= 0.0 || radius + 0.000001 >= (ray_origin - sphere_centre).norm() {
|
if radius <= 0.0 || radius + 0.000001 >= (ray_origin - sphere_centre).norm() {
|
||||||
|
|
@ -327,7 +328,7 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn ray_intersects_plane() {
|
fn ray_intersects_plane() {
|
||||||
let r = Ray::new(Vector3::new(1.0, 2.0, 3.0), Vector3::new(-1.0, 0.0, 1.0));
|
let r = Ray::new(Point3::new(1.0, 2.0, 3.0), Vector3::new(-1.0, 0.0, 1.0));
|
||||||
let p = Plane::new(
|
let p = Plane::new(
|
||||||
Vector3::new(1.0, 0.0, 0.0),
|
Vector3::new(1.0, 0.0, 0.0),
|
||||||
-5.0,
|
-5.0,
|
||||||
|
|
@ -338,7 +339,7 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn ray_does_not_intersect_plane() {
|
fn ray_does_not_intersect_plane() {
|
||||||
let r = Ray::new(Vector3::new(1.0, 2.0, 3.0), Vector3::new(1.0, 0.0, 1.0));
|
let r = Ray::new(Point3::new(1.0, 2.0, 3.0), Vector3::new(1.0, 0.0, 1.0));
|
||||||
let p = Plane::new(
|
let p = Plane::new(
|
||||||
Vector3::new(1.0, 0.0, 0.0),
|
Vector3::new(1.0, 0.0, 0.0),
|
||||||
-5.0,
|
-5.0,
|
||||||
|
|
@ -349,7 +350,7 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn intersection_point_is_on_plane() {
|
fn intersection_point_is_on_plane() {
|
||||||
let r = Ray::new(Vector3::new(1.0, 2.0, 3.0), Vector3::new(-1.0, 0.0, 1.0));
|
let r = Ray::new(Point3::new(1.0, 2.0, 3.0), Vector3::new(-1.0, 0.0, 1.0));
|
||||||
let p = Plane::new(
|
let p = Plane::new(
|
||||||
Vector3::new(1.0, 0.0, 0.0),
|
Vector3::new(1.0, 0.0, 0.0),
|
||||||
-5.0,
|
-5.0,
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
use nalgebra::{RealField, Vector3};
|
use nalgebra::{Point3, RealField};
|
||||||
|
|
||||||
use crate::raycasting::Intersect;
|
use crate::raycasting::Intersect;
|
||||||
|
|
||||||
pub struct Scene<T: RealField> {
|
pub struct Scene<T: RealField> {
|
||||||
pub camera_location: Vector3<T>,
|
pub camera_location: Point3<T>,
|
||||||
pub objects: Vec<Box<dyn Intersect<T>>>,
|
pub objects: Vec<Box<dyn Intersect<T>>>,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue