Compare commits
1 Commits
c0e422a7eb
...
7de0f07f56
| Author | SHA1 | Date | |
|---|---|---|---|
| 7de0f07f56 |
@ -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.material = Material {
|
||||
shape.set_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,7 +44,14 @@ 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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -41,11 +41,11 @@ fn main() -> Result<()> {
|
||||
|
||||
let mut floor = Shape::sphere();
|
||||
floor.set_transform(Matrix4x4::scaling(10., 0.01, 10.));
|
||||
floor.material = Material {
|
||||
floor.set_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.material = floor.material.clone();
|
||||
left_wall.set_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.material = floor.material.clone();
|
||||
right_wall.set_material(floor.material().clone());
|
||||
|
||||
let mut middle = Shape::sphere();
|
||||
middle.set_transform(Matrix4x4::translation(-0.5, 1., 0.5));
|
||||
middle.material = Material {
|
||||
middle.set_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.material = Material {
|
||||
right.set_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.material = Material {
|
||||
left.set_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];
|
||||
|
||||
@ -53,11 +53,11 @@ fn main() -> Result<()> {
|
||||
|
||||
let mut floor = Shape::sphere();
|
||||
floor.set_transform(Matrix4x4::scaling(10., 0.01, 10.));
|
||||
floor.material = Material {
|
||||
floor.set_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.material = floor.material.clone();
|
||||
left_wall.set_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.material = floor.material.clone();
|
||||
right_wall.set_material(floor.material().clone());
|
||||
|
||||
let mut middle = Shape::sphere();
|
||||
middle.set_transform(Matrix4x4::translation(-0.5, 1., 0.5));
|
||||
middle.material = Material {
|
||||
middle.set_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.material = Material {
|
||||
right.set_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.material = Material {
|
||||
left.set_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];
|
||||
|
||||
@ -12,14 +12,11 @@ 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,
|
||||
pub material: Material,
|
||||
material: Material,
|
||||
geometry: Geometry,
|
||||
}
|
||||
|
||||
@ -39,13 +36,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 = m.clone();
|
||||
/// assert_eq!(s.material, m);
|
||||
/// *s.material_mut() = m.clone();
|
||||
/// assert_eq!(s.material(), &m);
|
||||
/// ```
|
||||
pub fn sphere() -> Shape {
|
||||
Shape {
|
||||
@ -148,6 +145,18 @@ 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.
|
||||
|
||||
@ -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.material = Material {
|
||||
s1.set_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.ambient = 1.;
|
||||
/// let m = outer.material_mut().ambient = 1.;
|
||||
/// let inner = &mut w.objects[1];
|
||||
/// inner.material.ambient = 1.;
|
||||
/// inner.material_mut().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() {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user