summaryrefslogtreecommitdiff
path: root/src/material.rs
blob: 731eb0c16bb8eb40d5eefaf590fc9c7998e3dd6f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
use crate::calculus::calculus::{Ray, Vec3};
use crate::common::Color;
use crate::object::HitRecord;

#[derive(Clone)]
pub enum MaterialType {
    Diffuse,
    Metal,
}

pub struct Material {
    pub material_type: MaterialType,
    pub albedo: Color,
    pub fuzz: f32,
}

impl Material {
    pub fn new(albedo: Color, material_type: MaterialType, fuzz: f32) -> Self {
        let fuzz = if fuzz < 1.0 { fuzz } else { 1.0 };
        Self { albedo, material_type, fuzz }
    }

    pub fn scatter(&self, r_in: &Ray, rec: &HitRecord, attenuation: &mut Color, scattered: &mut Ray) -> bool {
        scattered.direction = match self.material_type {
            MaterialType::Diffuse => {
                let  scatter_direction = rec.normal.add(&Vec3::random_unit());
                if scatter_direction.is_near_zero() {
                    rec.normal.clone()
                } else {
                    scatter_direction
                }
            }
            MaterialType::Metal => {
                let mut reflected = r_in.reflect(&rec.normal);
                reflected.unit().add(&Vec3::random_unit().scalar_mul(self.fuzz))

            }
        };
        scattered.origin = rec.position;
        attenuation.r = self.albedo.r;
        attenuation.g = self.albedo.g;
        attenuation.b = self.albedo.b;
        true
    }
}