~ttt/ray_tracing_in_one_weekend

fb4d56d2f1e57d1a914d39e726743a3cf12119fb — Tomasz Kłak 4 years ago
up to chapter 4
5 files changed, 213 insertions(+), 0 deletions(-)

A .gitignore
A Cargo.lock
A Cargo.toml
A src/main.rs
A src/vec3.rs
A  => .gitignore +1 -0
@@ 1,1 @@
/target

A  => Cargo.lock +5 -0
@@ 1,5 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
[[package]]
name = "ray_tracing_in_one_weekend"
version = "0.1.0"

A  => Cargo.toml +9 -0
@@ 1,9 @@
[package]
name = "ray_tracing_in_one_weekend"
version = "0.1.0"
authors = ["Tomasz Kłak <ext-lux-tk@ad.datcon.co.uk>"]
edition = "2018"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]

A  => src/main.rs +27 -0
@@ 1,27 @@
mod vec3;
use vec3::*;

fn main() {
    let stdout = std::io::stdout();
    let mut handle = stdout.lock();

    // Image
    let image_width = 256i32;
    let image_height = 256i32;
    
    // Render
    
    print!("P3\n{} {}\n255\n", image_width, image_height);

    for j in (0..=(image_height-1)).rev() {
        eprint!("\rScanlines remaining: {} ", j);
        for i in 0..image_width {
            let pixel_color = Color::new(
                i as f64 / (image_width-1) as f64,
                j as f64 / (image_height-1) as f64,
                0.25);
            write_color(&mut handle, pixel_color);
        }
    }
    eprintln!("\nDone!");
}

A  => src/vec3.rs +171 -0
@@ 1,171 @@
#[derive(Debug, Clone, Copy)]
pub struct Vec3 {
    e: [f64; 3],
}

pub type Point3 = Vec3;
pub type Color = Vec3;

impl Vec3 {
    pub fn new(e0: f64, e1: f64, e2: f64) -> Self {
        Vec3 { e: [e0, e1, e2] }
    }

    pub fn x(&self) -> f64 {
        self.e[0]
    }
    pub fn y(&self) -> f64 {
        self.e[1]
    }
    pub fn z(&self) -> f64 {
        self.e[2]
    }

    pub fn lenght(&self) -> f64 {
        self.lenght_squared().sqrt()
    }

    pub fn lenght_squared(&self) -> f64 {
        self.e[0] * self.e[0] + self.e[1] * self.e[1] + self.e[2] * self.e[2]
    }
}

impl std::ops::Neg for &Vec3 {
    type Output = Vec3;

    fn neg(self) -> Vec3 {
        Vec3 {
            e: [-self.e[0], -self.e[1], -self.e[1]],
        }
    }
}

impl std::ops::Index<usize> for Vec3 {
    type Output = f64;

    fn index(&self, i: usize) -> &f64 {
        debug_assert!(i < 3);
        &self.e[i]
    }
}

impl std::ops::IndexMut<usize> for Vec3 {
    fn index_mut(&mut self, i: usize) -> &mut f64 {
        debug_assert!(i < 3);
        &mut self.e[i]
    }
}

impl std::ops::Add<&Vec3> for &Vec3 {
    type Output = Vec3;
    fn add(self, rhs: &Vec3) -> Vec3 {
        let mut c = self.clone();
        c += rhs;
        c
    }
}

impl std::ops::AddAssign<&Vec3> for Vec3 {
    fn add_assign(&mut self, rhs: &Vec3) {
        self.e[0] += rhs.e[0];
        self.e[1] += rhs.e[1];
        self.e[2] += rhs.e[2];
    }
}

impl std::ops::Sub<&Vec3> for &Vec3 {
    type Output = Vec3;
    fn sub(self, rhs: &Vec3) -> Vec3 {
        Vec3 {
            e: [
                self.e[0] - rhs.e[0],
                self.e[1] - rhs.e[1],
                self.e[2] - rhs.e[2],
            ],
        }
    }
}

impl std::ops::Mul<&Vec3> for &Vec3 {
    type Output = Vec3;
    fn mul(self, rhs: &Vec3) -> Vec3 {
        Vec3 {
            e: [
                self.e[0] * rhs.e[0],
                self.e[1] * rhs.e[1],
                self.e[2] * rhs.e[2],
            ],
        }
    }
}

impl std::ops::Mul<f64> for &Vec3 {
    type Output = Vec3;
    fn mul(self, rhs: f64) -> Vec3 {
        Vec3 {
            e: [self.e[0] * rhs, self.e[1] * rhs, self.e[2] * rhs],
        }
    }
}

impl std::ops::Mul<&Vec3> for f64 {
    type Output = Vec3;
    fn mul(self, rhs: &Vec3) -> Vec3 {
        rhs * self
    }
}

impl std::ops::MulAssign<f64> for Vec3 {
    fn mul_assign(&mut self, rhs: f64) {
        self.e[0] *= rhs;
        self.e[1] *= rhs;
        self.e[2] *= rhs;
    }
}

impl std::ops::DivAssign<f64> for Vec3 {
    fn div_assign(&mut self, rhs: f64) {
        *self *= 1f64 / rhs;
    }
}

impl std::ops::Div<f64> for &Vec3 {
    type Output = Vec3;

    fn div(self, rhs: f64) -> Vec3 {
        let mut c = self.clone();
        c *= 1f64 / rhs;
        c
    }
}

impl Default for Vec3 {
    fn default() -> Self {
        Vec3 {
            e: [0f64, 0f64, 0f64],
        }
    }
}

pub fn dot(u: &Vec3, v: &Vec3) -> f64 {
    u.e[0] * v.e[0] + u.e[1] * v.e[1] + u.e[2] * v.e[2]
}

pub fn cross(u: &Vec3, v: &Vec3) -> Vec3 {
    Vec3::new(
        u.e[1] * v.e[2] - u.e[2] * v.e[1],
        u.e[2] * v.e[0] - u.e[0] * v.e[2],
        u.e[0] * v.e[1] - u.e[1] * v.e[0],
    )
}

pub fn unit_vector(v: &Vec3) -> Vec3 {
    v / v.lenght()
}

pub fn write_color(out: &mut impl std::io::Write, pixel_color: Color) {
    write!(out, "{} {} {}\n", 
        (255.999 * pixel_color.x()) as i32,
        (255.999 * pixel_color.y()) as i32,
        (255.999 * pixel_color.z()) as i32).unwrap();
}