diff --git a/rtchallenge/examples/balls.rs b/rtchallenge/examples/balls.rs index 0111172..5397597 100644 --- a/rtchallenge/examples/balls.rs +++ b/rtchallenge/examples/balls.rs @@ -16,9 +16,9 @@ use rtchallenge::{ Float, WHITE, }; -/// End of chapter 9 challenge. +/// Experimenting with balls. #[derive(StructOpt, Debug)] -#[structopt(name = "eoc9")] +#[structopt(name = "balls")] struct Opt { #[structopt(long, default_value = "rayon")] render_strategy: RenderStrategy, @@ -47,39 +47,66 @@ fn main() -> Result<()> { .intensity([0.2, 0.2, 0.1]) .build()?; - let from = Tuple::point(0., 1.5, -5.); - let to = Tuple::point(0., 1., 0.); + let ball_size = 0.5; + let num_per_axis = 3; + let center_to_center = 4. * ball_size; + let from = Tuple::point( + -5. * center_to_center, + 5. * center_to_center, + -4. * center_to_center, + ); + let to = Tuple::point( + num_per_axis as Float * center_to_center / 2., + 0., //num_per_axis as Float * center_to_center / 2., + num_per_axis as Float * center_to_center / 2., + ); let up = Tuple::point(0., 1., 0.); - let mut camera = Camera::new(width, height, PI / 4.); + let mut camera = Camera::new(width, height, PI / 6.); camera.set_transform(view_transform(from, to, up)); camera.render_strategy = opt.render_strategy; camera.samples_per_pixel = opt.samples; let floor = ShapeBuilder::default() .geometry(Geometry::Plane) + .transform(Matrix4x4::translation(0., -ball_size, 0.)) .material( MaterialBuilder::default() - .color([1., 0.2, 0.2]) + .color([0.2, 0.2, 0.2]) .specular(0.) .build()?, ) .build()?; + let mut objects = vec![floor]; - const BALL_SIZE: Float = 0.2; - let middle = ShapeBuilder::default() - .transform(Matrix4x4::scaling(BALL_SIZE, BALL_SIZE, BALL_SIZE)) - .material( - MaterialBuilder::default() - .color([0.1, 1., 0.5]) - .diffuse(0.7) - .specular(0.3) - .build()?, - ) - .build()?; + for z in 0..num_per_axis { + for y in 0..num_per_axis { + for x in 0..num_per_axis { + objects.push( + ShapeBuilder::default() + .transform( + Matrix4x4::translation( + x as Float * center_to_center, + y as Float * center_to_center, + z as Float * center_to_center, + ) * Matrix4x4::scaling(ball_size, ball_size, ball_size), + ) + .material( + MaterialBuilder::default() + .color([0.1, 1., 0.5]) + .ambient(y as Float / 4.) + .diffuse(x as Float / 4.) + .specular(z as Float / 4.) + .build()?, + ) + .build()?, + ); + } + } + } let world = WorldBuilder::default() .lights(vec![light1, light2, light3]) - .objects(vec![floor, middle]) + .objects(objects) .build()?; let image = camera.render(&world);