Refactor some method code

This commit is contained in:
bijan2005 2021-03-20 17:48:03 -04:00
parent 6ef2c65009
commit 0d3500ceb5
9 changed files with 38 additions and 50 deletions

View file

@ -36,15 +36,16 @@ fn render(camera: &Camera, scene: &Scene, filename: &str) -> std::io::Result<()>
fn main() -> std::io::Result<()> {
let camera = Camera::new(Point3::new(0.0,0.0,2.5), Vector3::new(0.0,0.0,-1.0), 1.0, 16.0 / 9.0, 2.0, 720);
let camera = Camera::new(Point3::new(0.0,0.0,3.0), Vector3::new(0.0,0.0,-1.0), 1.0, 16.0 / 9.0, 2.0, 720);
let scene = Scene {
objects: vec![
Object::new(Sphere::new(0.0, 0.0, 0.0, 1.0, |a, b| Texture::new(0.0, a, b, 1.0)))
Object::new(Sphere::new_solid(1.0, 0.2, 1.7, 0.2, Texture::new(1.0, 1.0, 1.0, 1.0))),
Object::new(Sphere::new_solid(0.0, -1.0, 0.0, 1.0, Texture::new(1.0, 1.0, 1.0, 1.0)))
],
lights: vec![
Box::new(PointLight::new(Point3::new(1.0, 0.7, 1.5), Color::white(), 3.0)),
Box::new(PointLight::new(Point3::new(-1.0, -0.3, 0.4), Color::new(1.0, 0.0, 0.0), 4.0))
Box::new(PointLight::new(Point3::new(1.5, 1.0, 2.5), Color::white(), 3.0)),
Box::new(PointLight::new(Point3::new(1.0, -0.4, 1.5), Color::white(), 2.0))
],
background: Color::gray(0.5)
};

View file

@ -3,7 +3,7 @@ mod sphere; pub use sphere::*;
mod plane; pub use plane::*;
mod triangle; pub use triangle::*;
mod bound; pub use bound::*;
mod pointlight; pub use pointlight::*;
mod point_light; pub use point_light::*;
use crate::types::*;
@ -21,7 +21,7 @@ pub trait Surface {
// Takes in a point (assumed to be on the object's surface)
// and returns the texture information on that point.
fn gettexture(&self, point: Point3f) -> Texture;
fn get_texture(&self, point: Point3f) -> Texture;
// Creates a bounding sphere around the object.
fn bound(&self) -> Bound;
@ -38,7 +38,7 @@ impl Object {
let bound = surface.bound();
Object {
surface: Box::new(surface),
bound: bound
bound
}
}
@ -49,7 +49,7 @@ impl Object {
} else { None }
}
pub fn normal(&self, point: Point3f) -> Unit3f { self.surface.normal(point) }
pub fn gettexture(&self, point: Point3f) -> Texture { self.surface.gettexture(point) }
pub fn get_texture(&self, point: Point3f) -> Texture { self.surface.get_texture(point) }
}
pub trait Light {
@ -57,7 +57,7 @@ pub trait Light {
fn check_shadow(&self, point: Point3f, objects: &Vec<Object>) -> bool;
// Compute color on a point.
fn getcolor(&self, point: Point3f) -> Color;
fn get_color(&self, point: Point3f) -> Color;
// Compute intensity on a point.
fn intensity(&self, point: Point3f) -> f32;

View file

@ -24,7 +24,7 @@ impl Plane {
where F: Fn(f32, f32) -> Texture
{
Plane {
center: center,
center,
normal: Unit::new_normalize(x_axis.cross(&y_axis)),
x_axis: x_axis,
y_axis: y_axis,
@ -77,7 +77,7 @@ impl Surface for Plane {
fn normal(&self, _point: Point3f) -> Unit3f { self.normal }
fn gettexture(&self, point: Point3f) -> Texture {
fn get_texture(&self, point: Point3f) -> Texture {
let rel_pos = point - self.center;
let proj_point3 = rel_pos - (*self.normal * self.normal.dot(&rel_pos));

View file

@ -14,11 +14,7 @@ pub struct PointLight {
#[allow(dead_code)]
impl PointLight {
pub fn new(pos: Point3f, color: Color, intensity: f32) -> PointLight {
PointLight {
pos: pos,
color: color,
intensity: intensity
}
PointLight { pos, color, intensity }
}
}
@ -26,11 +22,11 @@ impl Light for PointLight {
fn check_shadow(&self, point: Point3f, objects: &Vec<Object>) -> bool {
let max_d = distance(&self.pos, &point);
objects.iter()
.filter_map(|obj| obj.intersect(Ray::from_points(self.pos, point)))
.filter_map(|&obj| obj.intersect(Ray::from_points(self.pos, point)))
.all(|d| d - max_d > -1e-3 )
}
fn getcolor(&self, _point: Point3f) -> Color { self.color }
fn get_color(&self, _point: Point3f) -> Color { self.color }
fn intensity(&self, _point: Point3f) -> f32 { self.intensity }
@ -44,7 +40,7 @@ mod tests {
use super::*;
#[test]
fn pointlight_checkshadow() {
fn point_light_check_shadow() {
let light = PointLight::new(Point3::new(0.0, 1.0, 0.0), Color::white(), 1.0);
let block = Object::new(Sphere::new_solid(0.0, 0.5, 0.0, 0.1, Texture::new(0.0, 0.0, 0.0, 0.0)));

View file

@ -23,8 +23,7 @@ impl Sphere {
where F: Fn(f32, f32) -> Texture
{
Sphere {
center: Point3::new(x, y, z),
radius: radius,
center: Point3::new(x, y, z), radius,
texture: Box::new(texture)
}
}
@ -66,10 +65,10 @@ impl Surface for Sphere {
Unit::new_normalize(point - self.center)
}
fn gettexture(&self, point: Point3f) -> Texture {
fn get_texture(&self, point: Point3f) -> Texture {
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 similar to a point on a unit sphere
// centred around the origin. We can thus use the normal coordinates to compute
// the spherical coordinates of the point.
let x = 0.5 + normal.z.atan2(normal.x) / (2.0 * PI);
@ -78,5 +77,5 @@ impl Surface for Sphere {
(*self.texture)(x, y)
}
fn bound(&self) -> Bound { Bound::bypass() }
fn bound(&self) -> Bound { Bound { center: self.center, radius: self.radius, bypass: false } }
}

View file

@ -22,7 +22,7 @@ pub struct Triangle {
pub struct TriangleMesh {
pub vertices: Vec<Point3f>,
pub tris: Vec<Triangle>
pub triangles: Vec<Triangle>
}
fn tri_area(a: &Point3f, b: &Point3f, c: &Point3f) -> f32 {
@ -78,7 +78,7 @@ impl Triangle {
self.intersect_(vertices, ray).map(|(t, u, v)| distance(&ray.origin, &self.from_bary(vertices, t, u, v)))
}
fn gettexture(&self, vertices: &Vec<Point3f>, point: Point3f) -> Texture {
fn get_texture(&self, vertices: &Vec<Point3f>, point: Point3f) -> Texture {
let (t, u, v) = self.to_bary(vertices, point);
(*self.texture)(t, u, v)
}
@ -89,32 +89,27 @@ impl TriangleMesh {
pub fn new(vertices: Vec<Point3f>, tris: Vec<(usize, usize, usize, Box<dyn Fn(f32, f32, f32) -> Texture>)>) -> Self {
let triangles = tris.into_iter()
.map(|(v1, v2, v3, f)| Triangle {
v1: v1,
v2: v2,
v3: v3,
v1, v2, v3,
normal: Unit::new_normalize((&vertices[v2] - &vertices[v1]).cross(&(&vertices[v3] - &vertices[v1]))),
area: tri_area(&vertices[v1], &vertices[v2], &vertices[v3]),
texture: f
}).collect();
TriangleMesh {
vertices: vertices,
tris: triangles
vertices, triangles
}
}
pub fn new_solid(vertices: Vec<Point3f>, tris: Vec<(usize, usize, usize)>, texture: Texture) -> Self {
let triangles = tris.into_iter()
.map(|(v1, v2, v3)| Triangle {
v1: v1,
v2: v2,
v3: v3,
v1, v2, v3,
normal: Unit::new_normalize((&vertices[v2] - &vertices[v1]).cross(&(&vertices[v3] - &vertices[v1]))),
area: tri_area(&vertices[v1], &vertices[v2], &vertices[v3]),
texture: Box::new(move |_, _, _| texture)
}).collect();
TriangleMesh {
vertices: vertices,
tris: triangles
vertices,
triangles
}
}
@ -127,7 +122,7 @@ impl TriangleMesh {
fn closest_tri(&self, point: Point3f) -> &Triangle {
self.tris.iter()
self.triangles.iter()
.map(move |tri| {
let rel_pos = point - tri.vertex1(&self.vertices);
@ -150,7 +145,7 @@ impl TriangleMesh {
impl Surface for TriangleMesh {
fn intersect(&self, ray: Ray) -> Option<f32> {
self.tris.iter()
self.triangles.iter()
.filter_map(|tri| tri.intersect(&self.vertices, ray))
.min_by(|a, b| a.partial_cmp(&b).unwrap_or(Ordering::Equal))
}
@ -159,8 +154,8 @@ impl Surface for TriangleMesh {
self.closest_tri(point).normal
}
fn gettexture(&self, point: Point3f) -> Texture {
self.closest_tri(point).gettexture(&self.vertices, point)
fn get_texture(&self, point: Point3f) -> Texture {
self.closest_tri(point).get_texture(&self.vertices, point)
}
// Uses Welzl's algorithm to solve the bounding sphere problem
@ -238,6 +233,6 @@ impl Surface for TriangleMesh {
let (center, radius) = smallest_sphere(points, Vec::new());
Bound { center: center, radius: radius + 1e-3, bypass: false }
Bound { center, radius: radius + 1e-3, bypass: false }
}
}

View file

@ -11,9 +11,9 @@ use crate::object::*;
fn trace(ray: Ray, objects: &Vec<Object>) -> Option<(&Object, f32)> {
objects.iter()
.filter_map(|obj| obj.intersect(ray)
.filter_map(|&obj| obj.intersect(ray)
.map(|x| (obj, x)))
.min_by(|a, b| a.1.partial_cmp(&b.1).unwrap_or(Ordering::Equal))
.min_by(|&a, &b| a.1.partial_cmp(&b.1).unwrap_or(Ordering::Equal))
}
fn light_point(objects: &Vec<Object>, obj: &Object, point: Point3f, light: &dyn Light) -> Color {
@ -34,7 +34,7 @@ pub fn cast_ray(ray: Ray, scene: &Scene) -> Color {
let surface_color = obj.gettexture(point).color;
scene.lights.iter()
.map(|light| light_point(&scene.objects, obj, point, &**light))
.map(|&light| light_point(&scene.objects, obj, point, &*light))
.fold(Color::black(), |acc, c| acc + c) * surface_color
}
else { scene.background }

View file

@ -17,10 +17,7 @@ pub struct Ray {
impl Ray {
pub fn from_parts(origin: Point3f, direction: Unit3f) -> Self {
Ray {
origin: origin,
direction: direction
}
Ray { origin, direction }
}
pub fn new(origin: Point3f, direction: Vector3f) -> Self { Ray::from_parts(origin, Unit::new_normalize(direction)) }
pub fn from_points(origin: Point3f, points_to: Point3f) -> Self { Ray::new(origin, points_to - origin) }
@ -109,7 +106,7 @@ impl Texture {
pub fn new(red: f32, green: f32, blue: f32, albedo: f32) -> Self {
Texture {
color: Color::new(red, green, blue),
albedo: albedo
albedo
}
}
}