RiA-weekend work
1. Refactored vec3. 2. Completed ray_demo from chapter 3.
This commit is contained in:
parent
89a179dc18
commit
8823d685ba
|
@ -27,14 +27,16 @@ fn main() {
|
||||||
width = input[0];
|
width = input[0];
|
||||||
}
|
}
|
||||||
let file_name = format!("ppm_sample{}x{}.ppm", width, height);
|
let file_name = format!("ppm_sample{}x{}.ppm", width, height);
|
||||||
let ppm_sample = ppm::create_sample(height, width);
|
let mut buf = format!("P3\n{} {}\n255\n", width, height);
|
||||||
|
|
||||||
|
ppm::create_sample(&mut buf, height, width);
|
||||||
|
|
||||||
let mut file = match File::create(&file_name) {
|
let mut file = match File::create(&file_name) {
|
||||||
Ok(file) => file,
|
Ok(file) => file,
|
||||||
Err(e) => panic!("couldn't create {}: {}", file_name, e.description()),
|
Err(e) => panic!("couldn't create {}: {}", file_name, e.description()),
|
||||||
};
|
};
|
||||||
|
|
||||||
match file.write_all(ppm_sample.as_bytes()) {
|
match file.write_all(buf.as_bytes()) {
|
||||||
Ok(_) => println!("Succesfully wrote to {}", file_name),
|
Ok(_) => println!("Succesfully wrote to {}", file_name),
|
||||||
Err(e) => panic!("couldn't write to {}: {}", file_name, e.description()),
|
Err(e) => panic!("couldn't write to {}: {}", file_name, e.description()),
|
||||||
}
|
}
|
||||||
|
|
41
ria-weekend/examples/ray_demo.rs
Normal file
41
ria-weekend/examples/ray_demo.rs
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
extern crate ria_weekend;
|
||||||
|
|
||||||
|
use ria_weekend::ray;
|
||||||
|
use std::error::Error;
|
||||||
|
use std::fs::File;
|
||||||
|
use std::{io, io::Write};
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let mut height = 100;
|
||||||
|
let mut width = 200;
|
||||||
|
|
||||||
|
println!("Enter width and height seperated by space");
|
||||||
|
|
||||||
|
let mut input = String::new();
|
||||||
|
io::stdin()
|
||||||
|
.read_line(&mut input)
|
||||||
|
.expect("error in reading input");
|
||||||
|
|
||||||
|
let input = input
|
||||||
|
.trim()
|
||||||
|
.split(" ")
|
||||||
|
.map(|v| v.parse::<u32>().expect("error in parsing input"))
|
||||||
|
.collect::<Vec<u32>>();
|
||||||
|
|
||||||
|
if input.len() >= 2 {
|
||||||
|
height = input[1];
|
||||||
|
width = input[0];
|
||||||
|
}
|
||||||
|
let file_name = format!("ray_demo{}x{}.ppm", width, height);
|
||||||
|
let mut buf = format!("P3\n{} {}\n255\n", width, height);
|
||||||
|
let mut file = match File::create(&file_name) {
|
||||||
|
Ok(file) => file,
|
||||||
|
Err(e) => panic!("couldn't create {}: {}", file_name, e.description()),
|
||||||
|
};
|
||||||
|
ray::create_ray_demo(&mut buf, width, height);
|
||||||
|
|
||||||
|
match file.write_all(buf.as_bytes()) {
|
||||||
|
Ok(_) => println!("Succesfully wrote to {}", file_name),
|
||||||
|
Err(e) => panic!("couldn't write to {}: {}", file_name, e.description()),
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,7 +1,6 @@
|
||||||
use crate::vec3::Vec3;
|
use crate::vec3::Vec3;
|
||||||
|
|
||||||
pub fn create_sample(h: u32, w: u32) -> String {
|
pub fn create_sample(buf: &mut String, h: u32, w: u32) {
|
||||||
let mut buf = format!("P3\n{} {}\n255\n", w, h);
|
|
||||||
for j in (0..h).rev() {
|
for j in (0..h).rev() {
|
||||||
for i in 0..w {
|
for i in 0..w {
|
||||||
let color = Vec3::new((i as f32) / (w as f32), (j as f32) / (h as f32), 0.5_f32);
|
let color = Vec3::new((i as f32) / (w as f32), (j as f32) / (h as f32), 0.5_f32);
|
||||||
|
@ -12,5 +11,4 @@ pub fn create_sample(h: u32, w: u32) -> String {
|
||||||
buf.push_str(&format!("{} {} {}\n", ir, ig, ib));
|
buf.push_str(&format!("{} {} {}\n", ir, ig, ib));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
buf
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,19 +6,45 @@ pub struct Ray {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Ray {
|
impl Ray {
|
||||||
pub const fn new(a: Vec3, b: Vec3) -> Ray {
|
pub fn new(a: Vec3, b: Vec3) -> Ray {
|
||||||
Ray { a, b }
|
Ray { a, b }
|
||||||
}
|
}
|
||||||
|
pub fn origin(&self) -> Vec3 {
|
||||||
pub const fn origin(&self) -> &Vec3 {
|
return self.a;
|
||||||
return &self.a;
|
|
||||||
}
|
}
|
||||||
|
pub fn direction(&self) -> Vec3 {
|
||||||
pub const fn direction(&self) -> &Vec3 {
|
return self.b;
|
||||||
return &self.b;
|
|
||||||
}
|
}
|
||||||
|
pub fn point_at_parameter(&self, t: f32) -> Vec3 {
|
||||||
pub const fn point_at_diameter(&self, t: f32) -> Vec3 {
|
return self.a + self.b * t;
|
||||||
return self.a + t * self.b;
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn color(ray: Ray) -> Vec3 {
|
||||||
|
let unit_direction = ray.direction().unit_vector();
|
||||||
|
let t = 0.5 * (unit_direction.y() + 1.0);
|
||||||
|
return Vec3::new(1.0, 1.0, 1.0) * (1.0 - t) + Vec3::new(0.5, 0.7, 1.0) * t;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn create_ray_demo(buf: &mut String, w: u32, h: u32) {
|
||||||
|
let lower_left_corner = Vec3::new(-2.0, -1.0, -1.0);
|
||||||
|
let horizontal = Vec3::new(4.0, 0.0, 0.0);
|
||||||
|
let vertical = Vec3::new(0.0, 2.0, 0.0);
|
||||||
|
let origin = Vec3::new(0.0, 0.0, 0.0);
|
||||||
|
|
||||||
|
for j in (0..h).rev() {
|
||||||
|
for i in 0..w {
|
||||||
|
let u = i as f32 / w as f32;
|
||||||
|
let v = j as f32 / h as f32;
|
||||||
|
|
||||||
|
let ray = Ray::new(origin, lower_left_corner + horizontal * u + vertical * v);
|
||||||
|
|
||||||
|
let color = color(ray);
|
||||||
|
let ir = (255.99 * color[0]) as u32;
|
||||||
|
let ig = (255.99 * color[1]) as u32;
|
||||||
|
let ib = (255.99 * color[2]) as u32;
|
||||||
|
let output = format!("{} {} {}\n", ir, ig, ib);
|
||||||
|
buf.push_str(&output);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
use std::ops::{Add, Div, Index, Mul, Sub};
|
use std::ops::{Add, Div, Index, IndexMut, Mul, MulAssign, Sub};
|
||||||
|
|
||||||
|
#[derive(Debug, Copy, Clone)]
|
||||||
pub struct Vec3 {
|
pub struct Vec3 {
|
||||||
inner: [f32; 3],
|
inner: [f32; 3],
|
||||||
}
|
}
|
||||||
|
@ -10,50 +11,54 @@ impl Vec3 {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn x(&self) -> f32 {
|
pub fn x(&self) -> f32 {
|
||||||
self.inner[0]
|
self[0]
|
||||||
}
|
}
|
||||||
pub fn y(&self) -> f32 {
|
pub fn y(&self) -> f32 {
|
||||||
self.inner[1]
|
self[1]
|
||||||
}
|
}
|
||||||
pub fn z(&self) -> f32 {
|
pub fn z(&self) -> f32 {
|
||||||
self.inner[2]
|
self[2]
|
||||||
}
|
}
|
||||||
pub fn r(&self) -> f32 {
|
pub fn r(&self) -> f32 {
|
||||||
self.inner[0]
|
self[0]
|
||||||
}
|
}
|
||||||
pub fn g(&self) -> f32 {
|
pub fn g(&self) -> f32 {
|
||||||
self.inner[1]
|
self[1]
|
||||||
}
|
}
|
||||||
pub fn b(&self) -> f32 {
|
pub fn b(&self) -> f32 {
|
||||||
self.inner[2]
|
self[2]
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn length(&self) -> f32 {
|
pub fn length(&self) -> f32 {
|
||||||
(self.inner[0] * self.inner[0]
|
self.sq_len().sqrt()
|
||||||
+ self.inner[1] * self.inner[1]
|
|
||||||
+ self.inner[2] * self.inner[2])
|
|
||||||
.sqrt()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn sq_len(&self) -> f32 {
|
pub fn sq_len(&self) -> f32 {
|
||||||
self.inner[0] * self.inner[0]
|
self[0] * self[0]
|
||||||
+ self.inner[1] * self.inner[1]
|
+ self[1] * self[1]
|
||||||
+ self.inner[2] * self.inner[2]
|
+ self[2] * self[2]
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn dot(&self, v: &Vec3) -> f32 {
|
pub fn dot(&self, v: &Vec3) -> f32 {
|
||||||
self.inner[0] * v.inner[0] + self.inner[1] * v.inner[1] + self.inner[2] * v.inner[2]
|
self[0] * v[0] + self[1] * v[1] + self[2] * v[2]
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn cross(&self, v: &Vec3) -> Vec3 {
|
pub fn cross(&self, v: &Vec3) -> Vec3 {
|
||||||
Vec3 {
|
Vec3 {
|
||||||
inner: [
|
inner: [
|
||||||
self.inner[1] * v.inner[2] - self.inner[2] * v.inner[1],
|
self[1] * v[2] - self[2] * v[1],
|
||||||
self.inner[2] * v.inner[0] - self.inner[0] * v.inner[2],
|
self[2] * v[0] - self[0] * v[2],
|
||||||
self.inner[0] * v.inner[1] - self.inner[1] * v.inner[0],
|
self[0] * v[1] - self[1] * v[0],
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn unit_vector(&self) -> Vec3 {
|
||||||
|
let length = self.length();
|
||||||
|
Vec3 {
|
||||||
|
inner: [self[0] / length, self[1] / length, self[2] / length],
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Add for Vec3 {
|
impl Add for Vec3 {
|
||||||
|
@ -62,9 +67,9 @@ impl Add for Vec3 {
|
||||||
fn add(self, o: Vec3) -> Vec3 {
|
fn add(self, o: Vec3) -> Vec3 {
|
||||||
Vec3 {
|
Vec3 {
|
||||||
inner: [
|
inner: [
|
||||||
self.inner[0] + o.inner[0],
|
self[0] + o[0],
|
||||||
self.inner[1] + o.inner[1],
|
self[1] + o[1],
|
||||||
self.inner[2] + o.inner[2],
|
self[2] + o[2],
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -76,34 +81,35 @@ impl Sub for Vec3 {
|
||||||
fn sub(self, o: Vec3) -> Vec3 {
|
fn sub(self, o: Vec3) -> Vec3 {
|
||||||
Vec3 {
|
Vec3 {
|
||||||
inner: [
|
inner: [
|
||||||
self.inner[0] - o.inner[0],
|
self[0] - o[0],
|
||||||
self.inner[1] - o.inner[1],
|
self[1] - o[1],
|
||||||
self.inner[2] - o.inner[2],
|
self[2] - o[2],
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Mul<Vec3> for Vec3 {
|
impl MulAssign<Vec3> for Vec3 {
|
||||||
type Output = Vec3;
|
fn mul_assign(&mut self, o: Vec3) {
|
||||||
|
self[0] *= o[0];
|
||||||
|
self[1] *= o[1];
|
||||||
|
self[2] *= o[2];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn mul(self, o: Vec3) -> Vec3 {
|
impl MulAssign<f32> for Vec3 {
|
||||||
Vec3 {
|
fn mul_assign(&mut self, o: f32) {
|
||||||
inner: [
|
self[0] *= o;
|
||||||
self.inner[0] * o.inner[0],
|
self[1] *= o;
|
||||||
self.inner[1] * o.inner[1],
|
self[2] *= o;
|
||||||
self.inner[2] * o.inner[2],
|
|
||||||
],
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Mul<f32> for Vec3 {
|
impl Mul<f32> for Vec3 {
|
||||||
type Output = Vec3;
|
type Output = Vec3;
|
||||||
|
|
||||||
fn mul(self, o: f32) -> Vec3 {
|
fn mul(self, o: f32) -> Vec3 {
|
||||||
Vec3 {
|
Vec3 {
|
||||||
inner: [self.inner[0] * o, self.inner[1] * o, self.inner[2] * o],
|
inner: [self[0] * o, self[1] * o, self[2] * o],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -114,9 +120,9 @@ impl Div<Vec3> for Vec3 {
|
||||||
fn div(self, o: Vec3) -> Vec3 {
|
fn div(self, o: Vec3) -> Vec3 {
|
||||||
Vec3 {
|
Vec3 {
|
||||||
inner: [
|
inner: [
|
||||||
self.inner[0] / o.inner[0],
|
self[0] / o[0],
|
||||||
self.inner[1] / o.inner[1],
|
self[1] / o[1],
|
||||||
self.inner[2] / o.inner[2],
|
self[2] / o[2],
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -128,7 +134,7 @@ impl Div<f32> for Vec3 {
|
||||||
fn div(self, o: f32) -> Vec3 {
|
fn div(self, o: f32) -> Vec3 {
|
||||||
let o = 1.0 / o;
|
let o = 1.0 / o;
|
||||||
Vec3 {
|
Vec3 {
|
||||||
inner: [self.inner[0] * o, self.inner[1] * o, self.inner[2] * o],
|
inner: [self[0] * o, self[1] * o, self[2] * o],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -140,3 +146,9 @@ impl Index<usize> for Vec3 {
|
||||||
&self.inner[q]
|
&self.inner[q]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl IndexMut<usize> for Vec3 {
|
||||||
|
fn index_mut(&mut self, q: usize) -> &mut f32 {
|
||||||
|
&mut self.inner[q]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user