shapes: create generic Shape object with Sphere implementation.
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
Bill Thiede 2021-07-19 19:51:12 -07:00
parent 7741766635
commit c0e422a7eb
8 changed files with 117 additions and 93 deletions

View File

@ -4,7 +4,7 @@ use rtchallenge::{
canvas::Canvas,
matrices::Matrix4x4,
rays::Ray,
spheres::{intersect, Sphere},
shapes::{intersect, Shape},
tuples::{Color, Tuple},
Float,
};
@ -20,7 +20,7 @@ fn main() -> Result<()> {
let pixel_size = wall_size / w as Float;
let half = wall_size / 2.;
let color = Color::new(1., 0., 0.);
let mut shape = Sphere::default();
let mut shape = Shape::sphere();
shape.set_transform(
Matrix4x4::shearing(1., 0., 0., 0., 0., 0.) * Matrix4x4::scaling(0.5, 1., 1.0),
);

View File

@ -5,7 +5,7 @@ use rtchallenge::{
lights::PointLight,
materials::{lighting, Material},
rays::Ray,
spheres::{intersect, Sphere},
shapes::{intersect, Shape},
tuples::{Color, Tuple},
Float, WHITE,
};
@ -20,7 +20,7 @@ fn main() -> Result<()> {
let wall_size = 7.;
let pixel_size = wall_size / w as Float;
let half = wall_size / 2.;
let mut shape = Sphere::default();
let mut shape = Shape::sphere();
shape.material = Material {
color: Color::new(1., 0.2, 1.),
specular: 0.5,

View File

@ -9,7 +9,7 @@ use rtchallenge::{
lights::PointLight,
materials::Material,
matrices::Matrix4x4,
spheres::Sphere,
shapes::Shape,
transformations::view_transform,
tuples::{Color, Tuple},
world::World,
@ -39,7 +39,7 @@ fn main() -> Result<()> {
camera.set_transform(view_transform(from, to, up));
camera.render_strategy = opt.render_strategy;
let mut floor = Sphere::default();
let mut floor = Shape::sphere();
floor.set_transform(Matrix4x4::scaling(10., 0.01, 10.));
floor.material = Material {
color: Color::new(1., 0.9, 0.9),
@ -47,7 +47,7 @@ fn main() -> Result<()> {
..Material::default()
};
let mut left_wall = Sphere::default();
let mut left_wall = Shape::sphere();
left_wall.set_transform(
Matrix4x4::translation(0., 0., 5.)
* Matrix4x4::rotation_y(-PI / 4.)
@ -56,7 +56,7 @@ fn main() -> Result<()> {
);
left_wall.material = floor.material.clone();
let mut right_wall = Sphere::default();
let mut right_wall = Shape::sphere();
right_wall.set_transform(
Matrix4x4::translation(0., 0., 5.)
* Matrix4x4::rotation_y(PI / 4.)
@ -65,7 +65,7 @@ fn main() -> Result<()> {
);
right_wall.material = floor.material.clone();
let mut middle = Sphere::default();
let mut middle = Shape::sphere();
middle.set_transform(Matrix4x4::translation(-0.5, 1., 0.5));
middle.material = Material {
color: Color::new(0.1, 1., 0.5),
@ -74,7 +74,7 @@ fn main() -> Result<()> {
..Material::default()
};
let mut right = Sphere::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 {
color: Color::new(0.5, 1., 0.1),
@ -83,7 +83,7 @@ fn main() -> Result<()> {
..Material::default()
};
let mut left = Sphere::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),
);

View File

@ -9,7 +9,7 @@ use rtchallenge::{
lights::PointLight,
materials::Material,
matrices::Matrix4x4,
spheres::Sphere,
shapes::Shape,
transformations::view_transform,
tuples::{Color, Tuple},
world::World,
@ -51,7 +51,7 @@ fn main() -> Result<()> {
camera.render_strategy = opt.render_strategy;
camera.samples_per_pixel = opt.samples;
let mut floor = Sphere::default();
let mut floor = Shape::sphere();
floor.set_transform(Matrix4x4::scaling(10., 0.01, 10.));
floor.material = Material {
color: Color::new(1., 0.9, 0.9),
@ -59,7 +59,7 @@ fn main() -> Result<()> {
..Material::default()
};
let mut left_wall = Sphere::default();
let mut left_wall = Shape::sphere();
left_wall.set_transform(
Matrix4x4::translation(0., 0., 5.)
* Matrix4x4::rotation_y(-PI / 4.)
@ -68,7 +68,7 @@ fn main() -> Result<()> {
);
left_wall.material = floor.material.clone();
let mut right_wall = Sphere::default();
let mut right_wall = Shape::sphere();
right_wall.set_transform(
Matrix4x4::translation(0., 0., 5.)
* Matrix4x4::rotation_y(PI / 4.)
@ -77,7 +77,7 @@ fn main() -> Result<()> {
);
right_wall.material = floor.material.clone();
let mut middle = Sphere::default();
let mut middle = Shape::sphere();
middle.set_transform(Matrix4x4::translation(-0.5, 1., 0.5));
middle.material = Material {
color: Color::new(0.1, 1., 0.5),
@ -86,7 +86,7 @@ fn main() -> Result<()> {
..Material::default()
};
let mut right = Sphere::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 {
color: Color::new(1., 1., 1.),
@ -95,7 +95,7 @@ fn main() -> Result<()> {
..Material::default()
};
let mut left = Sphere::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),
);

View File

@ -2,7 +2,7 @@ use std::ops::Index;
use crate::{
rays::Ray,
spheres::Sphere,
shapes::Shape,
tuples::{dot, Tuple},
Float, EPSILON,
};
@ -10,7 +10,7 @@ use crate::{
#[derive(Debug, Clone, PartialEq)]
pub struct Intersection<'i> {
pub t: Float,
pub object: &'i Sphere,
pub object: &'i Shape,
}
impl<'i> Intersection<'i> {
@ -18,15 +18,15 @@ impl<'i> Intersection<'i> {
///
/// # Examples
/// ```
/// use rtchallenge::{intersections::Intersection, spheres::Sphere};
/// use rtchallenge::{intersections::Intersection, shapes::Shape};
///
/// // An intersection ecapsulates t and object.
/// let s = Sphere::default();
/// let s = Shape::sphere();
/// let i = Intersection::new(3.5, &s);
/// assert_eq!(i.t, 3.5);
/// assert_eq!(i.object, &s);
/// ```
pub fn new(t: Float, object: &Sphere) -> Intersection {
pub fn new(t: Float, object: &Shape) -> Intersection {
Intersection { t, object }
}
}
@ -38,11 +38,11 @@ impl<'i> Intersection<'i> {
/// use rtchallenge::{
/// intersections::{Intersection, Intersections},
/// rays::Ray,
/// spheres::{intersect, Sphere},
/// shapes::{intersect, Shape},
/// tuples::Tuple,
/// };
///
/// let s = Sphere::default();
/// let s = Shape::sphere();
/// let i1 = Intersection::new(1., &s);
/// let i2 = Intersection::new(2., &s);
/// let xs = Intersections::new(vec![i1, i2]);
@ -73,12 +73,12 @@ impl<'i> Intersections<'i> {
/// use rtchallenge::{
/// intersections::{Intersection, Intersections},
/// rays::Ray,
/// spheres::{intersect, Sphere},
/// shapes::{intersect, Shape},
/// tuples::Tuple,
/// };
///
/// // The hit, when all intersections have positive t.
/// let s = Sphere::default();
/// let s = Shape::sphere();
/// let i1 = Intersection::new(1., &s);
/// let i2 = Intersection::new(2., &s);
/// let xs = Intersections::new(vec![i2, i1.clone()]);
@ -86,7 +86,7 @@ impl<'i> Intersections<'i> {
/// assert_eq!(i, Some(&i1));
///
/// // The hit, when some intersections have negative t.
/// let s = Sphere::default();
/// let s = Shape::sphere();
/// let i1 = Intersection::new(-1., &s);
/// let i2 = Intersection::new(1., &s);
/// let xs = Intersections::new(vec![i2.clone(), i1]);
@ -94,7 +94,7 @@ impl<'i> Intersections<'i> {
/// assert_eq!(i, Some(&i2));
///
/// // The hit, when all intersections have negative t.
/// let s = Sphere::default();
/// let s = Shape::sphere();
/// let i1 = Intersection::new(-2., &s);
/// let i2 = Intersection::new(-1., &s);
/// let xs = Intersections::new(vec![i2, i1]);
@ -102,7 +102,7 @@ impl<'i> Intersections<'i> {
/// assert_eq!(i, None);
///
/// // The hit is always the lowest nonnegative intersection.
/// let s = Sphere::default();
/// let s = Shape::sphere();
/// let i1 = Intersection::new(5., &s);
/// let i2 = Intersection::new(7., &s);
/// let i3 = Intersection::new(-3., &s);
@ -138,7 +138,7 @@ impl<'i> Index<usize> for Intersections<'i> {
#[derive(Debug)]
pub struct PrecomputedData<'i> {
pub t: Float,
pub object: &'i Sphere,
pub object: &'i Shape,
pub point: Tuple,
pub over_point: Tuple,
pub eyev: Tuple,
@ -154,14 +154,14 @@ pub struct PrecomputedData<'i> {
/// intersections::{prepare_computations, Intersection, Intersections},
/// rays::Ray,
/// matrices::Matrix4x4,
/// spheres::{intersect, Sphere},
/// shapes::{intersect, Shape},
/// tuples::Tuple,
/// EPSILON
/// };
///
/// // Precomputing the state of an intersection.
/// let r = Ray::new(Tuple::point(0., 0., -5.), Tuple::vector(0., 0., 1.));
/// let shape = Sphere::default();
/// let shape = Shape::sphere();
/// let i = Intersection::new(4., &shape);
/// let comps = prepare_computations(&i, &r);
/// assert_eq!(comps.t, i.t);
@ -172,14 +172,14 @@ pub struct PrecomputedData<'i> {
///
/// // The hit, when an intersection occurs on the outside.
/// let r = Ray::new(Tuple::point(0., 0., -5.), Tuple::vector(0., 0., 1.));
/// let shape = Sphere::default();
/// let shape = Shape::sphere();
/// let i = Intersection::new(4., &shape);
/// let comps = prepare_computations(&i, &r);
/// assert_eq!(comps.inside, false);
///
/// // The hit, when an intersection occurs on the inside.
/// let r = Ray::new(Tuple::point(0., 0., 0.), Tuple::vector(0., 0., 1.));
/// let shape = Sphere::default();
/// let shape = Shape::sphere();
/// let i = Intersection::new(1., &shape);
/// let comps = prepare_computations(&i, &r);
/// assert_eq!(comps.point, Tuple::point(0., 0., 1.));
@ -190,7 +190,7 @@ pub struct PrecomputedData<'i> {
///
/// // The hit should offset the point.
/// let r = Ray::new(Tuple::point(0., 0., -5.), Tuple::vector(0., 0., 1.));
/// let mut shape = Sphere::default();
/// let mut shape = Shape::sphere();
/// shape .set_transform(Matrix4x4::translation(0.,0.,1.));
/// let i = Intersection::new(5., &shape);
/// let comps = prepare_computations(&i, &r);

View File

@ -5,7 +5,7 @@ pub mod lights;
pub mod materials;
pub mod matrices;
pub mod rays;
pub mod spheres;
pub mod shapes;
pub mod transformations;
pub mod tuples;
pub mod world;

View File

@ -7,71 +7,80 @@ use crate::{
};
#[derive(Debug, PartialEq, Clone)]
/// Sphere represents the unit-sphere (radius of unit 1.) at the origin 0., 0., 0.
pub struct Sphere {
enum Geometry {
/// Sphere represents the unit-sphere (radius of unit 1.) at the origin 0., 0., 0.
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,
geometry: Geometry,
}
impl Default for Sphere {
impl Shape {
/// # Examples
/// ```
/// use rtchallenge::{materials::Material, matrices::Matrix4x4, spheres::Sphere};
/// use rtchallenge::{materials::Material, matrices::Matrix4x4, shapes::Shape};
///
/// // A sphere's default transform is the identity matrix.
/// let s = Sphere::default();
/// let s = Shape::sphere();
/// assert_eq!(s.transform(), Matrix4x4::identity());
///
/// // It can be changed by directly setting the transform member.
/// let mut s = Sphere::default();
/// let mut s = Shape::sphere();
/// let t = Matrix4x4::translation(2., 3., 4.);
/// s.set_transform ( t.clone());
/// s.set_transform(t.clone());
/// assert_eq!(s.transform(), t);
///
/// // Default Sphere has the default material.
/// assert_eq!(s.material, Material::default());
/// // It can be overridden.
/// let mut s = Sphere::default();
/// let mut s = Shape::sphere();
/// let mut m = Material::default();
/// m.ambient = 1.;
/// s.material = m.clone();
/// assert_eq!(s.material, m);
/// ```
fn default() -> Sphere {
Sphere {
pub fn sphere() -> Shape {
Shape {
transform: Matrix4x4::identity(),
inverse_transform: Matrix4x4::identity(),
material: Material::default(),
geometry: Geometry::Sphere,
}
}
}
impl Sphere {
/// Find the normal at the point on the sphere.
///
/// # Examples
/// ```
/// use rtchallenge::{matrices::Matrix4x4, spheres::Sphere, tuples::Tuple,Float};
/// use rtchallenge::{
/// float::consts::PI, materials::Material, matrices::Matrix4x4, shapes::Shape, tuples::Tuple,
/// Float,
/// };
///
/// // Normal on X-axis
/// let s = Sphere::default();
/// let s = Shape::sphere();
/// let n = s.normal_at(Tuple::point(1., 0., 0.));
/// assert_eq!(n, Tuple::vector(1., 0., 0.));
///
/// // Normal on Y-axis
/// let s = Sphere::default();
/// let s = Shape::sphere();
/// let n = s.normal_at(Tuple::point(0., 1., 0.));
/// assert_eq!(n, Tuple::vector(0., 1., 0.));
///
/// // Normal on Z-axis
/// let s = Sphere::default();
/// let s = Shape::sphere();
/// let n = s.normal_at(Tuple::point(0., 0., 1.));
/// assert_eq!(n, Tuple::vector(0., 0., 1.));
///
/// // Normal on a sphere at a nonaxial point.
/// let s = Sphere::default();
/// let s = Shape::sphere();
/// let n = s.normal_at(Tuple::point(
/// (3. as Float).sqrt() / 3.,
/// (3. as Float).sqrt() / 3.,
@ -79,10 +88,14 @@ impl Sphere {
/// ));
/// assert_eq!(
/// n,
/// Tuple::vector((3. as Float).sqrt() / 3., (3. as Float).sqrt() / 3., (3. as Float).sqrt() / 3.,)
/// Tuple::vector(
/// (3. as Float).sqrt() / 3.,
/// (3. as Float).sqrt() / 3.,
/// (3. as Float).sqrt() / 3.,
/// )
/// );
/// // Normals returned are normalized.
/// let s = Sphere::default();
/// let s = Shape::sphere();
/// let n = s.normal_at(Tuple::point(
/// (3. as Float).sqrt() / 3.,
/// (3. as Float).sqrt() / 3.,
@ -91,23 +104,27 @@ impl Sphere {
/// assert_eq!(n, n.normalize());
///
/// // Compute the normal on a translated sphere.
/// let mut s = Sphere::default();
/// s.set_transform ( Matrix4x4::translation(0., 1., 0.));
/// let mut s = Shape::sphere();
/// s.set_transform(Matrix4x4::translation(0., 1., 0.));
/// let n = s.normal_at(Tuple::point(0., 1.70711, -0.70711));
/// assert_eq!(n, Tuple::vector(0., 0.70711, -0.70711));
/// // Compute the normal on a transformed sphere.
/// use rtchallenge::float::consts::PI;
///
/// let mut s = Sphere::default();
/// s.set_transform ( Matrix4x4::scaling(1.,0.5,1.) * Matrix4x4::rotation_z(PI/5.));
/// let n = s.normal_at(Tuple::point(0., (2. as Float).sqrt()/2., -(2. as Float).sqrt()/2.));
/// // Compute the normal on a transformed sphere.
/// let mut s = Shape::sphere();
/// s.set_transform(Matrix4x4::scaling(1., 0.5, 1.) * Matrix4x4::rotation_z(PI / 5.));
/// let n = s.normal_at(Tuple::point(
/// 0.,
/// (2. as Float).sqrt() / 2.,
/// -(2. as Float).sqrt() / 2.,
/// ));
/// assert_eq!(n, Tuple::vector(0., 0.97014, -0.24254));
/// ```
#[cfg(not(feature = "disable-inverse-cache"))]
pub fn normal_at(&self, world_point: Tuple) -> Tuple {
let object_point = self.inverse_transform * world_point;
let object_normal = object_point - Tuple::point(0., 0., 0.);
let object_normal = match self.geometry {
Geometry::Sphere => object_point - Tuple::point(0., 0., 0.),
};
let mut world_normal = self.inverse_transform.transpose() * object_normal;
world_normal.w = 0.;
world_normal.normalize()
@ -115,7 +132,9 @@ impl Sphere {
#[cfg(feature = "disable-inverse-cache")]
pub fn normal_at(&self, world_point: Tuple) -> Tuple {
let object_point = self.transform.inverse() * world_point;
let object_normal = object_point - Tuple::point(0., 0., 0.);
let object_normal = match self.geometry {
Geometry::Sphere => object_point - Tuple::point(0., 0., 0.),
};
let mut world_normal = self.transform.inverse().transpose() * object_normal;
world_normal.w = 0.;
world_normal.normalize()
@ -124,6 +143,7 @@ impl Sphere {
pub fn transform(&self) -> Matrix4x4 {
self.transform
}
pub fn set_transform(&mut self, t: Matrix4x4) {
self.transform = t;
self.inverse_transform = t.inverse();
@ -138,13 +158,13 @@ impl Sphere {
/// intersections::{Intersection, Intersections},
/// matrices::Matrix4x4,
/// rays::Ray,
/// spheres::{intersect, Sphere},
/// shapes::{intersect, Shape},
/// tuples::Tuple,
/// };
///
/// // A ray intersects a sphere in two points.
/// let r = Ray::new(Tuple::point(0., 0., -5.), Tuple::vector(0., 0., 1.));
/// let s = Sphere::default();
/// let s = Shape::sphere();
/// let xs = intersect(&s, &r);
/// assert_eq!(
/// xs,
@ -153,13 +173,13 @@ impl Sphere {
///
/// // A ray intersects a sphere at a tangent.
/// let r = Ray::new(Tuple::point(0., 2., -5.), Tuple::vector(0., 0., 1.));
/// let s = Sphere::default();
/// let s = Shape::sphere();
/// let xs = intersect(&s, &r);
/// assert_eq!(xs, Intersections::default());
///
/// // A ray originates inside a sphere.
/// let r = Ray::new(Tuple::point(0., 0., 0.), Tuple::vector(0., 0., 1.));
/// let s = Sphere::default();
/// let s = Shape::sphere();
/// let xs = intersect(&s, &r);
/// assert_eq!(
/// xs,
@ -168,7 +188,7 @@ impl Sphere {
///
/// // A sphere is behind a ray.
/// let r = Ray::new(Tuple::point(0., 0., 5.), Tuple::vector(0., 0., 1.));
/// let s = Sphere::default();
/// let s = Shape::sphere();
/// let xs = intersect(&s, &r);
/// assert_eq!(
/// xs,
@ -177,7 +197,7 @@ impl Sphere {
///
/// // Intersect a scaled sphere with a ray.
/// let r = Ray::new(Tuple::point(0., 0., -5.), Tuple::vector(0., 0., 1.));
/// let mut s = Sphere::default();
/// let mut s = Shape::sphere();
/// s.set_transform(Matrix4x4::scaling(2., 2., 2.));
/// let xs = intersect(&s, &r);
/// assert_eq!(xs.len(), 2, "xs {:?}", xs);
@ -186,17 +206,19 @@ impl Sphere {
///
/// // Intersect a translated sphere with a ray.
/// let r = Ray::new(Tuple::point(0., 0., -5.), Tuple::vector(0., 0., 1.));
/// let mut s = Sphere::default();
/// let mut s = Shape::sphere();
/// s.set_transform(Matrix4x4::translation(5., 0., 0.));
/// let xs = intersect(&s, &r);
/// assert_eq!(xs.len(), 0);
/// ```
pub fn intersect<'s>(sphere: &'s Sphere, ray: &Ray) -> Intersections<'s> {
intersect_rtc(sphere, ray)
pub fn intersect<'s>(shape: &'s Shape, ray: &Ray) -> Intersections<'s> {
match shape.geometry {
Geometry::Sphere => intersect_rtc(shape, ray),
}
}
fn intersect_rtc<'s>(sphere: &'s Sphere, ray: &Ray) -> Intersections<'s> {
let ray = ray.transform(sphere.inverse_transform);
fn intersect_rtc<'s>(shape: &'s Shape, ray: &Ray) -> Intersections<'s> {
let ray = ray.transform(shape.inverse_transform);
let sphere_to_ray = ray.origin - Tuple::point(0., 0., 0.);
let a = dot(ray.direction, ray.direction);
let b = 2. * dot(ray.direction, sphere_to_ray);
@ -206,12 +228,12 @@ fn intersect_rtc<'s>(sphere: &'s Sphere, ray: &Ray) -> Intersections<'s> {
return Intersections::default();
}
Intersections::new(vec![
Intersection::new((-b - discriminant.sqrt()) / (2. * a), &sphere),
Intersection::new((-b + discriminant.sqrt()) / (2. * a), &sphere),
Intersection::new((-b - discriminant.sqrt()) / (2. * a), &shape),
Intersection::new((-b + discriminant.sqrt()) / (2. * a), &shape),
])
}
fn intersect_rtiow<'s>(sphere: &'s Sphere, ray: &Ray) -> Intersections<'s> {
let ray = ray.transform(sphere.inverse_transform);
fn intersect_rtiow<'s>(shape: &'s Shape, ray: &Ray) -> Intersections<'s> {
let ray = ray.transform(shape.inverse_transform);
let oc = ray.origin - Tuple::point(0., 0., 0.);
let a = dot(ray.direction, ray.direction);
let b = dot(oc, ray.direction);
@ -221,7 +243,7 @@ fn intersect_rtiow<'s>(sphere: &'s Sphere, ray: &Ray) -> Intersections<'s> {
return Intersections::default();
}
Intersections::new(vec![
Intersection::new((-b - discriminant.sqrt()) / a, &sphere),
Intersection::new((-b + discriminant.sqrt()) / a, &sphere),
Intersection::new((-b - discriminant.sqrt()) / a, &shape),
Intersection::new((-b + discriminant.sqrt()) / a, &shape),
])
}

View File

@ -4,7 +4,7 @@ use crate::{
materials::{lighting, Material},
matrices::Matrix4x4,
rays::Ray,
spheres::{intersect, Sphere},
shapes::{intersect, Shape},
tuples::{Color, Tuple},
Float, BLACK, WHITE,
};
@ -23,7 +23,7 @@ use crate::{
#[derive(Clone, Debug, Default)]
pub struct World {
pub lights: Vec<PointLight>,
pub objects: Vec<Sphere>,
pub objects: Vec<Shape>,
}
impl World {
@ -39,14 +39,14 @@ impl World {
/// ```
pub fn test_world() -> World {
let light = PointLight::new(Tuple::point(-10., 10., -10.), WHITE);
let mut s1 = Sphere::default();
let mut s1 = Shape::sphere();
s1.material = Material {
color: Color::new(0.8, 1., 0.6),
diffuse: 0.7,
specular: 0.2,
..Material::default()
};
let mut s2 = Sphere::default();
let mut s2 = Shape::sphere();
s2.set_transform(Matrix4x4::scaling(0.5, 0.5, 0.5));
World {
lights: vec![light],
@ -92,7 +92,7 @@ impl World {
/// lights::PointLight,
/// matrices::Matrix4x4,
/// rays::Ray,
/// spheres::Sphere,
/// shapes::Shape,
/// tuples::{Color, Tuple},
/// world::World,
/// WHITE,
@ -120,8 +120,8 @@ impl World {
/// // Shading with an intersection in shadow.
/// let mut w = World::default();
/// w.lights = vec![PointLight::new(Tuple::point(0., 0., -10.), WHITE)];
/// let s1 = Sphere::default();
/// let mut s2 = Sphere::default();
/// let s1 = Shape::sphere();
/// let mut s2 = Shape::sphere();
/// s2.set_transform(Matrix4x4::translation(0., 0., 10.));
/// w.objects = vec![s1, s2.clone()];
/// let r = Ray::new(Tuple::point(0., 0., 5.), Tuple::vector(0., 0., 1.));
@ -155,6 +155,7 @@ impl World {
/// intersections::{prepare_computations, Intersection},
/// lights::PointLight,
/// rays::Ray,
/// shapes::Shape,
/// tuples::{Color, Tuple},
/// world::World,
/// BLACK,
@ -176,7 +177,7 @@ impl World {
/// let w = {
/// let mut w = World::test_world();
/// let mut outer = &mut w.objects[0];
/// outer.material.ambient = 1.;
/// let m = outer.material.ambient = 1.;
/// let inner = &mut w.objects[1];
/// inner.material.ambient = 1.;
/// w
@ -202,6 +203,7 @@ impl World {
/// ```
/// use rtchallenge::{
/// tuples::{ Tuple},
/// shapes::Shape,
/// world::World,
/// };
///