Compare commits

..

1 Commits

Author SHA1 Message Date
c0e422a7eb shapes: create generic Shape object with Sphere implementation.
All checks were successful
continuous-integration/drone/push Build is passing
2021-07-20 22:17:50 -07:00
5 changed files with 36 additions and 52 deletions

View File

@ -21,13 +21,13 @@ fn main() -> Result<()> {
let pixel_size = wall_size / w as Float;
let half = wall_size / 2.;
let mut shape = Shape::sphere();
shape.set_material(Material {
shape.material = Material {
color: Color::new(1., 0.2, 1.),
specular: 0.5,
diffuse: 0.7,
shininess: 30.,
..Material::default()
});
};
let light_position = Tuple::point(-10., 10., -10.);
let light_color = WHITE;
let light = PointLight::new(light_position, light_color);
@ -44,14 +44,7 @@ fn main() -> Result<()> {
let point = r.position(hit.t);
let normal = hit.object.normal_at(point);
let eye = -r.direction;
let color = lighting(
&hit.object.material(),
&light,
point,
eye,
normal,
in_shadow,
);
let color = lighting(&hit.object.material, &light, point, eye, normal, in_shadow);
c.set(x, y, color);
}
}

View File

@ -41,11 +41,11 @@ fn main() -> Result<()> {
let mut floor = Shape::sphere();
floor.set_transform(Matrix4x4::scaling(10., 0.01, 10.));
floor.set_material(Material {
floor.material = Material {
color: Color::new(1., 0.9, 0.9),
specular: 0.,
..Material::default()
});
};
let mut left_wall = Shape::sphere();
left_wall.set_transform(
@ -54,7 +54,7 @@ fn main() -> Result<()> {
* Matrix4x4::rotation_x(PI / 2.)
* Matrix4x4::scaling(10., 0.01, 10.),
);
left_wall.set_material(floor.material().clone());
left_wall.material = floor.material.clone();
let mut right_wall = Shape::sphere();
right_wall.set_transform(
@ -63,36 +63,36 @@ fn main() -> Result<()> {
* Matrix4x4::rotation_x(PI / 2.)
* Matrix4x4::scaling(10., 0.01, 10.),
);
right_wall.set_material(floor.material().clone());
right_wall.material = floor.material.clone();
let mut middle = Shape::sphere();
middle.set_transform(Matrix4x4::translation(-0.5, 1., 0.5));
middle.set_material(Material {
middle.material = Material {
color: Color::new(0.1, 1., 0.5),
diffuse: 0.7,
specular: 0.3,
..Material::default()
});
};
let mut right = Shape::sphere();
right.set_transform(Matrix4x4::translation(1.5, 0.5, -0.5) * Matrix4x4::scaling(0.5, 0.5, 0.5));
right.set_material(Material {
right.material = Material {
color: Color::new(0.5, 1., 0.1),
diffuse: 0.7,
specular: 0.3,
..Material::default()
});
};
let mut left = Shape::sphere();
left.set_transform(
Matrix4x4::translation(-1.5, 0.33, -0.75) * Matrix4x4::scaling(0.33, 0.33, 0.33),
);
left.set_material(Material {
left.material = Material {
color: Color::new(1., 0.8, 0.1),
diffuse: 0.7,
specular: 0.3,
..Material::default()
});
};
let mut world = World::default();
world.lights = vec![light];

View File

@ -53,11 +53,11 @@ fn main() -> Result<()> {
let mut floor = Shape::sphere();
floor.set_transform(Matrix4x4::scaling(10., 0.01, 10.));
floor.set_material(Material {
floor.material = Material {
color: Color::new(1., 0.9, 0.9),
specular: 0.,
..Material::default()
});
};
let mut left_wall = Shape::sphere();
left_wall.set_transform(
@ -66,7 +66,7 @@ fn main() -> Result<()> {
* Matrix4x4::rotation_x(PI / 2.)
* Matrix4x4::scaling(10., 0.01, 10.),
);
left_wall.set_material(floor.material().clone());
left_wall.material = floor.material.clone();
let mut right_wall = Shape::sphere();
right_wall.set_transform(
@ -75,36 +75,36 @@ fn main() -> Result<()> {
* Matrix4x4::rotation_x(PI / 2.)
* Matrix4x4::scaling(10., 0.00001, 10.),
);
right_wall.set_material(floor.material().clone());
right_wall.material = floor.material.clone();
let mut middle = Shape::sphere();
middle.set_transform(Matrix4x4::translation(-0.5, 1., 0.5));
middle.set_material(Material {
middle.material = Material {
color: Color::new(0.1, 1., 0.5),
diffuse: 0.7,
specular: 0.3,
..Material::default()
});
};
let mut right = Shape::sphere();
right.set_transform(Matrix4x4::translation(1.5, 0.5, -0.5) * Matrix4x4::scaling(0.5, 0.5, 0.5));
right.set_material(Material {
right.material = Material {
color: Color::new(1., 1., 1.),
diffuse: 0.7,
specular: 0.0,
..Material::default()
});
};
let mut left = Shape::sphere();
left.set_transform(
Matrix4x4::translation(-1.5, 0.33, -0.75) * Matrix4x4::scaling(0.33, 0.33, 0.33),
);
left.set_material(Material {
left.material = Material {
color: Color::new(1., 0.8, 0.1),
diffuse: 0.7,
specular: 0.3,
..Material::default()
});
};
let mut world = World::default();
world.lights = vec![light1, light2, light3];

View File

@ -12,11 +12,14 @@ enum Geometry {
Sphere,
}
/// Shape represents visible objects. A signal instance of Shape can generically represent one of
/// many different shapes based on the value of it's geometry field. Users chose the shape by
/// calling the appropriate constructor, i.e. [Shape::sphere].
#[derive(Debug, PartialEq, Clone)]
pub struct Shape {
transform: Matrix4x4,
inverse_transform: Matrix4x4,
material: Material,
pub material: Material,
geometry: Geometry,
}
@ -36,13 +39,13 @@ impl Shape {
/// assert_eq!(s.transform(), t);
///
/// // Default Sphere has the default material.
/// assert_eq!(s.material(), &Material::default());
/// assert_eq!(s.material, Material::default());
/// // It can be overridden.
/// let mut s = Shape::sphere();
/// let mut m = Material::default();
/// m.ambient = 1.;
/// *s.material_mut() = m.clone();
/// assert_eq!(s.material(), &m);
/// s.material = m.clone();
/// assert_eq!(s.material, m);
/// ```
pub fn sphere() -> Shape {
Shape {
@ -145,18 +148,6 @@ impl Shape {
self.transform = t;
self.inverse_transform = t.inverse();
}
pub fn material(&self) -> &Material {
&self.material
}
pub fn material_mut(&mut self) -> &mut Material {
&mut self.material
}
pub fn set_material(&mut self, m: Material) {
self.material = m;
}
}
/// Intersect a ray with a sphere.

View File

@ -40,12 +40,12 @@ impl World {
pub fn test_world() -> World {
let light = PointLight::new(Tuple::point(-10., 10., -10.), WHITE);
let mut s1 = Shape::sphere();
s1.set_material(Material {
s1.material = Material {
color: Color::new(0.8, 1., 0.6),
diffuse: 0.7,
specular: 0.2,
..Material::default()
});
};
let mut s2 = Shape::sphere();
s2.set_transform(Matrix4x4::scaling(0.5, 0.5, 0.5));
World {
@ -137,7 +137,7 @@ impl World {
.fold(Color::new(0., 0., 0.), |acc, light| {
let shadowed = self.is_shadowed(comps.over_point, light);
acc + lighting(
&comps.object.material(),
&comps.object.material,
light,
comps.over_point,
comps.eyev,
@ -177,15 +177,15 @@ impl World {
/// let w = {
/// let mut w = World::test_world();
/// let mut outer = &mut w.objects[0];
/// let m = outer.material_mut().ambient = 1.;
/// let m = outer.material.ambient = 1.;
/// let inner = &mut w.objects[1];
/// inner.material_mut().ambient = 1.;
/// inner.material.ambient = 1.;
/// w
/// };
/// let inner = &w.objects[1];
/// let r = Ray::new(Tuple::point(0., 0., 0.75), Tuple::vector(0., 0., -1.));
/// let c = w.color_at(&r);
/// assert_eq!(c, inner.material().color);
/// assert_eq!(c, inner.material.color);
/// ```
pub fn color_at(&self, r: &Ray) -> Color {
match self.intersect(r).hit() {