summaryrefslogtreecommitdiff
path: root/racer-tracer/src/scene/random.rs
diff options
context:
space:
mode:
Diffstat (limited to 'racer-tracer/src/scene/random.rs')
-rw-r--r--racer-tracer/src/scene/random.rs87
1 files changed, 87 insertions, 0 deletions
diff --git a/racer-tracer/src/scene/random.rs b/racer-tracer/src/scene/random.rs
new file mode 100644
index 0000000..ddbcfc1
--- /dev/null
+++ b/racer-tracer/src/scene/random.rs
@@ -0,0 +1,87 @@
+use std::sync::Arc;
+
+use crate::{
+ error::TracerError,
+ geometry::{sphere::Sphere, Hittable},
+ material::{dialectric::Dialectric, lambertian::Lambertian, metal::Metal, SharedMaterial},
+ scene::SceneLoader,
+ util::{random_double, random_double_range},
+ vec3::{Color, Vec3},
+};
+
+pub struct Random {}
+
+impl Random {
+ pub fn new() -> Self {
+ Self {}
+ }
+}
+
+impl SceneLoader for Random {
+ fn load(&self) -> Result<Vec<Box<dyn crate::geometry::Hittable>>, TracerError> {
+ let mut geometry: Vec<Box<dyn Hittable>> = Vec::new();
+ let ground_material: SharedMaterial =
+ Arc::new(Box::new(Lambertian::new(Color::new(0.5, 0.5, 0.5))));
+ geometry.push(Box::new(Sphere::new(
+ Vec3::new(0.0, -1000.0, 0.0),
+ 1000.0,
+ ground_material,
+ )));
+
+ for a in -11..11 {
+ for b in -11..11 {
+ let choose_mat = random_double();
+ let center = Vec3::new(
+ a as f64 + 0.9 * random_double(),
+ 0.2,
+ b as f64 + 0.9 * random_double(),
+ );
+
+ if (center - Vec3::new(4.0, 0.2, 0.0)).length() > 0.9 {
+ if choose_mat < 0.8 {
+ // diffuse
+ let albedo = Color::random() * Color::random();
+ let mat: SharedMaterial = Arc::new(Box::new(Lambertian::new(albedo)));
+ geometry.push(Box::new(Sphere::new(center, 0.2, mat)));
+ } else if choose_mat > 0.95 {
+ // metal
+ let albedo = Color::random_range(0.5, 1.0);
+ let fuzz = random_double_range(0.0, 0.5);
+ let mat: SharedMaterial = Arc::new(Box::new(Metal::new(albedo, fuzz)));
+ geometry.push(Box::new(Sphere::new(center, 0.2, mat)));
+ } else {
+ // glass
+ let mat: SharedMaterial = Arc::new(Box::new(Dialectric::new(1.5)));
+ geometry.push(Box::new(Sphere::new(center, 0.2, mat)));
+ }
+ }
+ }
+ }
+
+ let dial_mat: SharedMaterial = Arc::new(Box::new(Dialectric::new(1.5)));
+ geometry.push(Box::new(Sphere::new(
+ Vec3::new(0.0, 1.0, 0.0),
+ 1.0,
+ dial_mat,
+ )));
+
+ let lamb_mat: SharedMaterial =
+ Arc::new(Box::new(Lambertian::new(Color::new(0.4, 0.2, 0.1))));
+ geometry.push(Box::new(Sphere::new(
+ Vec3::new(-4.0, 1.0, 0.0),
+ 1.0,
+ lamb_mat,
+ )));
+
+ let metal_mat: SharedMaterial =
+ Arc::new(Box::new(Metal::new(Color::new(0.7, 0.6, 0.5), 0.0)));
+
+ geometry.push(Box::new(Sphere::new(
+ Vec3::new(4.0, 1.0, 0.0),
+ 1.0,
+ metal_mat,
+ )));
+
+ Ok(geometry)
+ }
+}