Created abbreviations for common geometry types
This commit is contained in:
parent
ed6e84a240
commit
07445dd4be
|
@ -19,11 +19,11 @@ pub trait Surface {
|
||||||
|
|
||||||
// Takes in a point (assumed to be on the object's surface)
|
// Takes in a point (assumed to be on the object's surface)
|
||||||
// and returns the normal vector off of that point.
|
// and returns the normal vector off of that point.
|
||||||
fn normal(&self, point: Point3<f32>) -> Unit<Vector3<f32>>;
|
fn normal(&self, point: Point3f) -> Unit3f;
|
||||||
|
|
||||||
// Takes in a point (assumed to be on the object's surface)
|
// Takes in a point (assumed to be on the object's surface)
|
||||||
// and returns the color information on that point.
|
// and returns the color information on that point.
|
||||||
fn getcolor(&self, point: Point3<f32>) -> Color;
|
fn getcolor(&self, point: Point3f) -> Color;
|
||||||
|
|
||||||
// Creates a bounding sphere around the object.
|
// Creates a bounding sphere around the object.
|
||||||
fn bound(&self) -> Bound;
|
fn bound(&self) -> Bound;
|
||||||
|
@ -50,14 +50,17 @@ impl Object {
|
||||||
self.surface.intersect(ray)
|
self.surface.intersect(ray)
|
||||||
} else { None }
|
} else { None }
|
||||||
}
|
}
|
||||||
pub fn normal(&self, point: Point3<f32>) -> Unit<Vector3<f32>> { self.surface.normal(point) }
|
pub fn normal(&self, point: Point3f) -> Unit3f { self.surface.normal(point) }
|
||||||
pub fn getcolor(&self, point: Point3<f32>) -> Color { self.surface.getcolor(point) }
|
pub fn getcolor(&self, point: Point3f) -> Color { self.surface.getcolor(point) }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait Light {
|
pub trait Light {
|
||||||
// Determine if the light is able to illuminate the point.
|
// Determine if the light is able to illuminate the point.
|
||||||
// If so, return the color of the light.
|
// If so, return the color of the light.
|
||||||
fn illuminate(&self, point: Point3<f32>, objects: &Vec<Object>) -> Option<Color>;
|
fn illuminate(&self, point: Point3f, objects: &Vec<Object>) -> Option<Color>;
|
||||||
|
|
||||||
|
// Return the direction from the point to the light source.
|
||||||
|
fn direction(&self, point: Point3f) -> Unit3f;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Scene {
|
pub struct Scene {
|
||||||
|
|
|
@ -3,13 +3,13 @@ extern crate nalgebra as na;
|
||||||
// use na::distance;
|
// use na::distance;
|
||||||
use na::geometry::Point3;
|
use na::geometry::Point3;
|
||||||
|
|
||||||
use crate::types::Ray;
|
use crate::types::*;
|
||||||
|
|
||||||
// A bounding sphere, used for
|
// A bounding sphere, used for
|
||||||
// intersection test optimization.
|
// intersection test optimization.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Bound {
|
pub struct Bound {
|
||||||
pub center: Point3<f32>,
|
pub center: Point3f,
|
||||||
pub radius: f32,
|
pub radius: f32,
|
||||||
|
|
||||||
// If true, then the bounding sphere is disabled.
|
// If true, then the bounding sphere is disabled.
|
||||||
|
@ -24,7 +24,7 @@ impl Bound {
|
||||||
l.norm_squared() >= self.radius * self.radius
|
l.norm_squared() >= self.radius * self.radius
|
||||||
}
|
}
|
||||||
|
|
||||||
// pub fn contains(&self, point: &Point3<f32>) -> bool { distance(&self.center, point) < self.radius }
|
// pub fn contains(&self, point: &Point3f) -> bool { distance(&self.center, point) < self.radius }
|
||||||
|
|
||||||
pub fn bypass() -> Self { Bound { center: Point3::origin(), radius: 0.0, bypass: true } }
|
pub fn bypass() -> Self { Bound { center: Point3::origin(), radius: 0.0, bypass: true } }
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,11 +7,11 @@ use crate::types::*;
|
||||||
use super::{Surface, bound::*};
|
use super::{Surface, bound::*};
|
||||||
|
|
||||||
pub struct Plane {
|
pub struct Plane {
|
||||||
pub center: Point3<f32>, // Plane origin (used for texture mapping).
|
pub center: Point3f, // Plane origin (used for texture mapping).
|
||||||
pub normal: Unit<Vector3<f32>>, // Precomputed plane normal.
|
pub normal: Unit3f, // Precomputed plane normal.
|
||||||
|
|
||||||
x_axis: Vector3<f32>, // Plane x-axis (The 3D direction that corresponds to the x-direction on the plane).
|
x_axis: Vector3f, // Plane x-axis (The 3D direction that corresponds to the x-direction on the plane).
|
||||||
y_axis: Vector3<f32>, // Plane y-axis (The 3D direction that corresponds to the y-direction on the plane).
|
y_axis: Vector3f, // Plane y-axis (The 3D direction that corresponds to the y-direction on the plane).
|
||||||
|
|
||||||
texture: Box<dyn Fn(f32, f32) -> Color> // Texture map.
|
texture: Box<dyn Fn(f32, f32) -> Color> // Texture map.
|
||||||
// Input coordinates are defined in terms of the axes above.
|
// Input coordinates are defined in terms of the axes above.
|
||||||
|
@ -20,7 +20,7 @@ pub struct Plane {
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
impl Plane {
|
impl Plane {
|
||||||
// Creates a new plane.
|
// Creates a new plane.
|
||||||
pub fn new<F: 'static>(center: Point3<f32>, x_axis: Vector3<f32>, y_axis: Vector3<f32>, texture: F) -> Self
|
pub fn new<F: 'static>(center: Point3f, x_axis: Vector3f, y_axis: Vector3f, texture: F) -> Self
|
||||||
where F: Fn(f32, f32) -> Color
|
where F: Fn(f32, f32) -> Color
|
||||||
{
|
{
|
||||||
Plane {
|
Plane {
|
||||||
|
@ -33,7 +33,7 @@ impl Plane {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Creates a new plane with the normal flipped.
|
// Creates a new plane with the normal flipped.
|
||||||
pub fn new_flip<F: 'static>(center: Point3<f32>, x_axis: Vector3<f32>, y_axis: Vector3<f32>, texture: F) -> Self
|
pub fn new_flip<F: 'static>(center: Point3f, x_axis: Vector3f, y_axis: Vector3f, texture: F) -> Self
|
||||||
where F: Fn(f32, f32) -> Color
|
where F: Fn(f32, f32) -> Color
|
||||||
{
|
{
|
||||||
Plane {
|
Plane {
|
||||||
|
@ -46,11 +46,11 @@ impl Plane {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Creates a new plane of a solid color.
|
// Creates a new plane of a solid color.
|
||||||
pub fn new_solid(center: Point3<f32>, x_axis: Vector3<f32>, y_axis: Vector3<f32>, color: Color) -> Self
|
pub fn new_solid(center: Point3f, x_axis: Vector3f, y_axis: Vector3f, color: Color) -> Self
|
||||||
{ Plane::new(center, x_axis, y_axis, move |_, _| color) }
|
{ Plane::new(center, x_axis, y_axis, move |_, _| color) }
|
||||||
|
|
||||||
// Creates a new flipped plane of a solid color.
|
// Creates a new flipped plane of a solid color.
|
||||||
pub fn new_solid_flip(center: Point3<f32>, x_axis: Vector3<f32>, y_axis: Vector3<f32>, color: Color) -> Self
|
pub fn new_solid_flip(center: Point3f, x_axis: Vector3f, y_axis: Vector3f, color: Color) -> Self
|
||||||
{ Plane::new_flip(center, x_axis, y_axis, move |_, _| color) }
|
{ Plane::new_flip(center, x_axis, y_axis, move |_, _| color) }
|
||||||
|
|
||||||
|
|
||||||
|
@ -75,9 +75,9 @@ impl Surface for Plane {
|
||||||
else { None }
|
else { None }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn normal(&self, _point: Point3<f32>) -> Unit<Vector3<f32>> { self.normal }
|
fn normal(&self, _point: Point3f) -> Unit3f { self.normal }
|
||||||
|
|
||||||
fn getcolor(&self, point: Point3<f32>) -> Color {
|
fn getcolor(&self, point: Point3f) -> Color {
|
||||||
let rel_pos = point - self.center;
|
let rel_pos = point - self.center;
|
||||||
let proj_point3 = rel_pos - (*self.normal * self.normal.dot(&rel_pos));
|
let proj_point3 = rel_pos - (*self.normal * self.normal.dot(&rel_pos));
|
||||||
|
|
||||||
|
|
|
@ -7,19 +7,21 @@ use crate::types::*;
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
pub struct PointLight {
|
pub struct PointLight {
|
||||||
pub pos: Point3<f32>,
|
pub pos: Point3f,
|
||||||
pub color: Color
|
pub color: Color,
|
||||||
|
pub intensity: f32
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PointLight {
|
impl PointLight {
|
||||||
pub fn new(pos: Point3<f32>, color: Color) -> PointLight {
|
pub fn new(pos: Point3f, color: Color, intensity: f32) -> PointLight {
|
||||||
PointLight {
|
PointLight {
|
||||||
pos: pos,
|
pos: pos,
|
||||||
color: color
|
color: color,
|
||||||
|
intensity: intensity
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_point(&self, point: Point3<f32>, objects: &Vec<Object>) -> bool {
|
fn check_point(&self, point: Point3f, objects: &Vec<Object>) -> bool {
|
||||||
let max_d = distance(&self.pos, &point);
|
let max_d = distance(&self.pos, &point);
|
||||||
objects.iter()
|
objects.iter()
|
||||||
.filter_map(|obj| obj.intersect(Ray::from_points(self.pos, point)))
|
.filter_map(|obj| obj.intersect(Ray::from_points(self.pos, point)))
|
||||||
|
@ -28,9 +30,13 @@ impl PointLight {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Light for PointLight {
|
impl Light for PointLight {
|
||||||
fn illuminate(&self, point: Point3<f32>, objects: &Vec<Object>) -> Option<Color> {
|
fn illuminate(&self, point: Point3f, objects: &Vec<Object>) -> Option<Color> {
|
||||||
if self.check_point(point, objects) {
|
if self.check_point(point, objects) {
|
||||||
Some(self.color)
|
Some(self.color)
|
||||||
} else { None }
|
} else { None }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn direction(&self, point: Point3f) -> Unit3f {
|
||||||
|
Unit::new_normalize(self.pos - point)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@ use crate::types::*;
|
||||||
use super::{Surface, bound::*};
|
use super::{Surface, bound::*};
|
||||||
|
|
||||||
pub struct Sphere {
|
pub struct Sphere {
|
||||||
pub center: Point3<f32>, // Center point of the sphere.
|
pub center: Point3f, // Center point of the sphere.
|
||||||
pub radius: f32, // Radius of the sphere.
|
pub radius: f32, // Radius of the sphere.
|
||||||
|
|
||||||
texture: Box<dyn Fn(f32, f32) -> Color> // Texture map.
|
texture: Box<dyn Fn(f32, f32) -> Color> // Texture map.
|
||||||
|
@ -62,11 +62,11 @@ impl Surface for Sphere {
|
||||||
else { None }
|
else { None }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn normal(&self, point: Point3<f32>) -> Unit<Vector3<f32>> {
|
fn normal(&self, point: Point3f) -> Unit3f {
|
||||||
Unit::new_normalize(point - self.center)
|
Unit::new_normalize(point - self.center)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn getcolor(&self, point: Point3<f32>) -> Color {
|
fn getcolor(&self, point: Point3f) -> Color {
|
||||||
let normal = self.normal(point);
|
let normal = self.normal(point);
|
||||||
|
|
||||||
// In this particular case, the normal is simular to a point on a unit sphere
|
// In this particular case, the normal is simular to a point on a unit sphere
|
||||||
|
|
|
@ -13,7 +13,7 @@ pub struct Triangle {
|
||||||
pub v2: usize,
|
pub v2: usize,
|
||||||
pub v3: usize,
|
pub v3: usize,
|
||||||
|
|
||||||
normal: Unit<Vector3<f32>>, // Precalculated normal vector.
|
normal: Unit3f, // Precalculated normal vector.
|
||||||
area: f32, // Precalculated area for barycentric calculations.
|
area: f32, // Precalculated area for barycentric calculations.
|
||||||
|
|
||||||
texture: Box<dyn Fn(f32, f32, f32) -> Color> // Texture map.
|
texture: Box<dyn Fn(f32, f32, f32) -> Color> // Texture map.
|
||||||
|
@ -21,28 +21,28 @@ pub struct Triangle {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct TriangleMesh {
|
pub struct TriangleMesh {
|
||||||
pub vertices: Vec<Point3<f32>>,
|
pub vertices: Vec<Point3f>,
|
||||||
pub tris: Vec<Triangle>
|
pub tris: Vec<Triangle>
|
||||||
}
|
}
|
||||||
|
|
||||||
fn tri_area(a: &Point3<f32>, b: &Point3<f32>, c: &Point3<f32>) -> f32 {
|
fn tri_area(a: &Point3f, b: &Point3f, c: &Point3f) -> f32 {
|
||||||
let prlg_area: f32 = (b - a).cross(&(c - a)).norm();
|
let prlg_area: f32 = (b - a).cross(&(c - a)).norm();
|
||||||
prlg_area / 2.0
|
prlg_area / 2.0
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Triangle {
|
impl Triangle {
|
||||||
fn vertex1<'a>(&self, vertices: &'a Vec<Point3<f32>>) -> &'a Point3<f32> { &vertices[self.v1] }
|
fn vertex1<'a>(&self, vertices: &'a Vec<Point3f>) -> &'a Point3f { &vertices[self.v1] }
|
||||||
fn vertex2<'a>(&self, vertices: &'a Vec<Point3<f32>>) -> &'a Point3<f32> { &vertices[self.v2] }
|
fn vertex2<'a>(&self, vertices: &'a Vec<Point3f>) -> &'a Point3f { &vertices[self.v2] }
|
||||||
fn vertex3<'a>(&self, vertices: &'a Vec<Point3<f32>>) -> &'a Point3<f32> { &vertices[self.v3] }
|
fn vertex3<'a>(&self, vertices: &'a Vec<Point3f>) -> &'a Point3f { &vertices[self.v3] }
|
||||||
|
|
||||||
// Conversion of barycentric coordinates to
|
// Conversion of barycentric coordinates to
|
||||||
// a point on the triangle.
|
// a point on the triangle.
|
||||||
fn from_bary(&self, vertices: &Vec<Point3<f32>>, t: f32, u: f32, v: f32) -> Point3<f32> {
|
fn from_bary(&self, vertices: &Vec<Point3f>, t: f32, u: f32, v: f32) -> Point3f {
|
||||||
Point::from(t * self.vertex1(vertices).coords + u * self.vertex2(vertices).coords + v * self.vertex3(vertices).coords)
|
Point::from(t * self.vertex1(vertices).coords + u * self.vertex2(vertices).coords + v * self.vertex3(vertices).coords)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Conversion of a point to barycentric coordinates.
|
// Conversion of a point to barycentric coordinates.
|
||||||
fn to_bary(&self, vertices: &Vec<Point3<f32>>, point: Point3<f32>) -> (f32, f32, f32) {
|
fn to_bary(&self, vertices: &Vec<Point3f>, point: Point3f) -> (f32, f32, f32) {
|
||||||
let t = tri_area(self.vertex2(vertices), self.vertex3(vertices), &point) / self.area;
|
let t = tri_area(self.vertex2(vertices), self.vertex3(vertices), &point) / self.area;
|
||||||
let u = tri_area(self.vertex1(vertices), self.vertex3(vertices), &point) / self.area;
|
let u = tri_area(self.vertex1(vertices), self.vertex3(vertices), &point) / self.area;
|
||||||
let v = tri_area(self.vertex1(vertices), self.vertex2(vertices), &point) / self.area;
|
let v = tri_area(self.vertex1(vertices), self.vertex2(vertices), &point) / self.area;
|
||||||
|
@ -50,7 +50,7 @@ impl Triangle {
|
||||||
(t, u, v)
|
(t, u, v)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn intersect_(&self, vertices: &Vec<Point3<f32>>, ray: Ray) -> Option<(f32, f32, f32)> {
|
fn intersect_(&self, vertices: &Vec<Point3f>, ray: Ray) -> Option<(f32, f32, f32)> {
|
||||||
let vect2_1 = self.vertex2(vertices) - self.vertex1(vertices);
|
let vect2_1 = self.vertex2(vertices) - self.vertex1(vertices);
|
||||||
let vect3_1 = self.vertex3(vertices) - self.vertex1(vertices);
|
let vect3_1 = self.vertex3(vertices) - self.vertex1(vertices);
|
||||||
|
|
||||||
|
@ -74,11 +74,11 @@ impl Triangle {
|
||||||
Some((t, u, v))
|
Some((t, u, v))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn intersect(&self, vertices: &Vec<Point3<f32>>, ray: Ray) -> Option<f32> {
|
fn intersect(&self, vertices: &Vec<Point3f>, ray: Ray) -> Option<f32> {
|
||||||
self.intersect_(vertices, ray).map(|(t, u, v)| distance(&ray.origin, &self.from_bary(vertices, t, u, v)))
|
self.intersect_(vertices, ray).map(|(t, u, v)| distance(&ray.origin, &self.from_bary(vertices, t, u, v)))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn getcolor(&self, vertices: &Vec<Point3<f32>>, point: Point3<f32>) -> Color {
|
fn getcolor(&self, vertices: &Vec<Point3f>, point: Point3f) -> Color {
|
||||||
let (t, u, v) = self.to_bary(vertices, point);
|
let (t, u, v) = self.to_bary(vertices, point);
|
||||||
(*self.texture)(t, u, v)
|
(*self.texture)(t, u, v)
|
||||||
}
|
}
|
||||||
|
@ -86,7 +86,7 @@ impl Triangle {
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
impl TriangleMesh {
|
impl TriangleMesh {
|
||||||
pub fn new(vertices: Vec<Point3<f32>>, tris: Vec<(usize, usize, usize, Box<dyn Fn(f32, f32, f32) -> Color>)>) -> Self {
|
pub fn new(vertices: Vec<Point3f>, tris: Vec<(usize, usize, usize, Box<dyn Fn(f32, f32, f32) -> Color>)>) -> Self {
|
||||||
let triangles = tris.into_iter()
|
let triangles = tris.into_iter()
|
||||||
.map(|(v1, v2, v3, f)| Triangle {
|
.map(|(v1, v2, v3, f)| Triangle {
|
||||||
v1: v1,
|
v1: v1,
|
||||||
|
@ -102,7 +102,7 @@ impl TriangleMesh {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_solid(vertices: Vec<Point3<f32>>, tris: Vec<(usize, usize, usize)>, color: Color) -> Self {
|
pub fn new_solid(vertices: Vec<Point3f>, tris: Vec<(usize, usize, usize)>, color: Color) -> Self {
|
||||||
let triangles = tris.into_iter()
|
let triangles = tris.into_iter()
|
||||||
.map(|(v1, v2, v3)| Triangle {
|
.map(|(v1, v2, v3)| Triangle {
|
||||||
v1: v1,
|
v1: v1,
|
||||||
|
@ -118,15 +118,15 @@ impl TriangleMesh {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn singleton<F: 'static>(vertex1: Point3<f32>, vertex2: Point3<f32>, vertex3: Point3<f32>, texture: F) -> Self
|
pub fn singleton<F: 'static>(vertex1: Point3f, vertex2: Point3f, vertex3: Point3f, texture: F) -> Self
|
||||||
where F: Fn(f32, f32, f32) -> Color
|
where F: Fn(f32, f32, f32) -> Color
|
||||||
{ TriangleMesh::new(vec![vertex1, vertex2, vertex3], vec![(0, 1, 2, Box::new(texture))]) }
|
{ TriangleMesh::new(vec![vertex1, vertex2, vertex3], vec![(0, 1, 2, Box::new(texture))]) }
|
||||||
|
|
||||||
pub fn singleton_solid(vertex1: Point3<f32>, vertex2: Point3<f32>, vertex3: Point3<f32>, color: Color) -> Self
|
pub fn singleton_solid(vertex1: Point3f, vertex2: Point3f, vertex3: Point3f, color: Color) -> Self
|
||||||
{ TriangleMesh::singleton(vertex1, vertex2, vertex3, move |_, _, _| color) }
|
{ TriangleMesh::singleton(vertex1, vertex2, vertex3, move |_, _, _| color) }
|
||||||
|
|
||||||
|
|
||||||
fn closest_tri(&self, point: Point3<f32>) -> &Triangle {
|
fn closest_tri(&self, point: Point3f) -> &Triangle {
|
||||||
self.tris.iter()
|
self.tris.iter()
|
||||||
.map(move |tri| {
|
.map(move |tri| {
|
||||||
|
|
||||||
|
@ -155,17 +155,17 @@ impl Surface for TriangleMesh {
|
||||||
.min_by(|a, b| a.partial_cmp(&b).unwrap_or(Ordering::Equal))
|
.min_by(|a, b| a.partial_cmp(&b).unwrap_or(Ordering::Equal))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn normal(&self, point: Point3<f32>) -> Unit<Vector3<f32>> {
|
fn normal(&self, point: Point3f) -> Unit3f {
|
||||||
self.closest_tri(point).normal
|
self.closest_tri(point).normal
|
||||||
}
|
}
|
||||||
|
|
||||||
fn getcolor(&self, point: Point3<f32>) -> Color {
|
fn getcolor(&self, point: Point3f) -> Color {
|
||||||
self.closest_tri(point).getcolor(&self.vertices, point)
|
self.closest_tri(point).getcolor(&self.vertices, point)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Uses Welzl's algorithm to solve the bounding sphere problem
|
// Uses Welzl's algorithm to solve the bounding sphere problem
|
||||||
fn bound(&self) -> Bound {
|
fn bound(&self) -> Bound {
|
||||||
fn triangle_sphere(point1: &Point3<f32>, point2: &Point3<f32>, point3: &Point3<f32>) -> (Point3<f32>, f32) {
|
fn triangle_sphere(point1: &Point3f, point2: &Point3f, point3: &Point3f) -> (Point3f, f32) {
|
||||||
let a = point3 - point1;
|
let a = point3 - point1;
|
||||||
let b = point2 - point1;
|
let b = point2 - point1;
|
||||||
|
|
||||||
|
@ -179,7 +179,7 @@ impl Surface for TriangleMesh {
|
||||||
(point1 + to_center, radius)
|
(point1 + to_center, radius)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn tetrahedron_sphere(point1: &Point3<f32>, point2: &Point3<f32>, point3: &Point3<f32>, point4: &Point3<f32>) -> (Point3<f32>, f32) {
|
fn tetrahedron_sphere(point1: &Point3f, point2: &Point3f, point3: &Point3f, point4: &Point3f) -> (Point3f, f32) {
|
||||||
let matrix = Matrix4::from_rows(&[point1.to_homogeneous().transpose(),
|
let matrix = Matrix4::from_rows(&[point1.to_homogeneous().transpose(),
|
||||||
point2.to_homogeneous().transpose(),
|
point2.to_homogeneous().transpose(),
|
||||||
point3.to_homogeneous().transpose(),
|
point3.to_homogeneous().transpose(),
|
||||||
|
@ -204,7 +204,7 @@ impl Surface for TriangleMesh {
|
||||||
(center, radius)
|
(center, radius)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn smallest_sphere(points: Vec<&Point3<f32>>, boundary: Vec<&Point3<f32>>) -> (Point3<f32>, f32) {
|
fn smallest_sphere(points: Vec<&Point3f>, boundary: Vec<&Point3f>) -> (Point3f, f32) {
|
||||||
if points.len() == 0 || boundary.len() == 4 {
|
if points.len() == 0 || boundary.len() == 4 {
|
||||||
match boundary.len() {
|
match boundary.len() {
|
||||||
0 => (Point3::new(0.0, 0.0, 0.0), 0.0),
|
0 => (Point3::new(0.0, 0.0, 0.0), 0.0),
|
||||||
|
@ -233,7 +233,7 @@ impl Surface for TriangleMesh {
|
||||||
use rand::thread_rng;
|
use rand::thread_rng;
|
||||||
use rand::seq::SliceRandom;
|
use rand::seq::SliceRandom;
|
||||||
|
|
||||||
let mut points: Vec<&Point3<f32>> = self.vertices.iter().collect();
|
let mut points: Vec<&Point3f> = self.vertices.iter().collect();
|
||||||
points.shuffle(&mut thread_rng());
|
points.shuffle(&mut thread_rng());
|
||||||
|
|
||||||
let (center, radius) = smallest_sphere(points, Vec::new());
|
let (center, radius) = smallest_sphere(points, Vec::new());
|
||||||
|
|
|
@ -18,8 +18,8 @@ fn trace(ray: Ray, objects: &Vec<Object>) -> Option<(&Object, f32)> {
|
||||||
pub fn cast_ray(ray: Ray, scene: &Scene) -> Color {
|
pub fn cast_ray(ray: Ray, scene: &Scene) -> Color {
|
||||||
if let Some((obj, dist)) = trace(ray, &scene.objects) {
|
if let Some((obj, dist)) = trace(ray, &scene.objects) {
|
||||||
let point = ray.project(dist);
|
let point = ray.project(dist);
|
||||||
|
let surface_color = obj.getcolor(point);
|
||||||
obj.getcolor(point)
|
surface_color
|
||||||
}
|
}
|
||||||
else { scene.background }
|
else { scene.background }
|
||||||
}
|
}
|
||||||
|
|
16
src/types.rs
16
src/types.rs
|
@ -5,23 +5,27 @@ use std::ops::{Add, Mul};
|
||||||
use na::*;
|
use na::*;
|
||||||
use na::geometry::Point3;
|
use na::geometry::Point3;
|
||||||
|
|
||||||
|
pub type Point3f = Point3<f32>;
|
||||||
|
pub type Vector3f = Vector3<f32>;
|
||||||
|
pub type Unit3f = Unit<Vector3<f32>>;
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug)]
|
#[derive(Clone, Copy, Debug)]
|
||||||
pub struct Ray {
|
pub struct Ray {
|
||||||
pub origin: Point3<f32>,
|
pub origin: Point3f,
|
||||||
pub direction: Unit<Vector3<f32>>
|
pub direction: Unit3f
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Ray {
|
impl Ray {
|
||||||
pub fn from_parts(origin: Point3<f32>, direction: Unit<Vector3<f32>>) -> Self {
|
pub fn from_parts(origin: Point3f, direction: Unit3f) -> Self {
|
||||||
Ray {
|
Ray {
|
||||||
origin: origin,
|
origin: origin,
|
||||||
direction: direction
|
direction: direction
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn new(origin: Point3<f32>, direction: Vector3<f32>) -> Self { Ray::from_parts(origin, Unit::new_normalize(direction)) }
|
pub fn new(origin: Point3f, direction: Vector3f) -> Self { Ray::from_parts(origin, Unit::new_normalize(direction)) }
|
||||||
pub fn from_points(origin: Point3<f32>, points_to: Point3<f32>) -> Self { Ray::new(origin, points_to - origin) }
|
pub fn from_points(origin: Point3f, points_to: Point3f) -> Self { Ray::new(origin, points_to - origin) }
|
||||||
|
|
||||||
pub fn project(&self, t: f32) -> Point3<f32> { self.origin + t * self.direction.into_inner() }
|
pub fn project(&self, t: f32) -> Point3f { self.origin + t * self.direction.into_inner() }
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||||
|
|
Loading…
Reference in a new issue