Add translation and rotation
This commit is contained in:
parent
f2a8db6430
commit
f5f46a7a0b
@ -19,6 +19,30 @@ pub struct HitRecord<'material> {
|
||||
pub material: &'material Arc<Material>
|
||||
}
|
||||
|
||||
impl<'material> HitRecord<'material> {
|
||||
pub fn normalized(&mut self, ray: &Ray) {
|
||||
let dot = ray.direction().dot(&self.normal);
|
||||
let front_face = dot < 0.0;
|
||||
let normal = if front_face { self.normal } else { -self.normal };
|
||||
self.normal = normal;
|
||||
self.front_face = front_face;
|
||||
}
|
||||
/*pub fn normalized(& self) -> Self {
|
||||
let dot = ray.direction().dot(self.normal);
|
||||
let front_face = dot < 0.0;
|
||||
let normal = if front_face { self.normal } else { -self.normal };
|
||||
HitRecord {
|
||||
point: self.point,
|
||||
normal,
|
||||
t: self.t,
|
||||
u: self.u,
|
||||
v: self.v,
|
||||
front_face,
|
||||
material: self.material
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
pub trait Hittable {
|
||||
fn hit(&self, ray: &Ray, t_min: f64, t_max: f64) -> Option<HitRecord>;
|
||||
fn bounding_box(&self, time0: f64, time1: f64) -> Option<Aabb>;
|
||||
@ -74,19 +98,18 @@ impl Hittable for Sphere {
|
||||
}
|
||||
let point = ray.at(root);
|
||||
let normal = (point - self.center) / self.radius;
|
||||
let dot = ray.direction().dot(&normal);
|
||||
let front_face = dot < 0.0;
|
||||
let (u, v) = Sphere::uv(&normal);
|
||||
let normal = if front_face { normal } else { -normal };
|
||||
Some(HitRecord {
|
||||
let mut rec = HitRecord {
|
||||
point,
|
||||
normal,
|
||||
t: root,
|
||||
u,
|
||||
v,
|
||||
front_face,
|
||||
front_face: false, // Will be set during normalied()
|
||||
material: &self.material
|
||||
})
|
||||
};
|
||||
rec.normalized(ray);
|
||||
Some(rec)
|
||||
}
|
||||
fn bounding_box(&self, _time0: f64, _time1: f64) -> Option<Aabb> {
|
||||
let s = Vec3::new(self.radius, self.radius, self.radius);
|
||||
|
38
src/main.rs
38
src/main.rs
@ -17,6 +17,8 @@ use crate::noise::NoiseTexture;
|
||||
use crate::perlin::Perlin;
|
||||
use crate::texture::CheckerTexture;
|
||||
use crate::rect::{Plane, Rect2D};
|
||||
use crate::rotate_y::RotateY;
|
||||
use crate::translate::Translate;
|
||||
|
||||
mod vec3;
|
||||
mod ray;
|
||||
@ -32,10 +34,12 @@ mod noise;
|
||||
mod image_texture;
|
||||
mod rect;
|
||||
mod cuboid;
|
||||
mod translate;
|
||||
mod rotate_y;
|
||||
|
||||
// Image
|
||||
const DEFAULT_ASPECT_RATIO: f64 = 3.0 / 2.0;
|
||||
const IMAGE_WIDTH: usize = 600;
|
||||
const IMAGE_WIDTH: usize = 400;
|
||||
const SAMPLES_PER_PIXEL: i32 = 100;
|
||||
const MAX_DEPTH: i32 = 50;
|
||||
|
||||
@ -113,16 +117,32 @@ fn cornell_box() -> Scene {
|
||||
)));
|
||||
|
||||
// Boxes
|
||||
world.push(Arc::new(Cuboid::new(
|
||||
Point3::new(130.0, 0.0, 65.0),
|
||||
Point3::new(295.0, 165.0, 230.0),
|
||||
let rotated1 = RotateY::new(
|
||||
Cuboid::new(
|
||||
Point3::new(0.0, 0.0, 0.0),
|
||||
Point3::new(165.0, 330.0, 165.0),
|
||||
white.clone()
|
||||
)));
|
||||
world.push(Arc::new(Cuboid::new(
|
||||
Point3::new(265.0, 0.0, 295.0),
|
||||
Point3::new(430.0, 330.0, 460.0),
|
||||
),
|
||||
15.0
|
||||
);
|
||||
let box1 = Translate::new(
|
||||
rotated1,
|
||||
Vec3::new(265.0, 0.0, 295.0)
|
||||
);
|
||||
world.push(Arc::new(box1));
|
||||
let rotated2 = RotateY::new(
|
||||
Cuboid::new(
|
||||
Point3::new(0.0, 0.0, 0.0),
|
||||
Point3::new(165.0, 165.0, 165.0),
|
||||
white.clone()
|
||||
)));
|
||||
),
|
||||
-18.0
|
||||
);
|
||||
let box2 = Translate::new(
|
||||
rotated2,
|
||||
Vec3::new(130.0,0.0,65.0)
|
||||
);
|
||||
world.push(Arc::new(box2));
|
||||
|
||||
|
||||
let look_from = Point3::new(278.0, 278.0, -800.0);
|
||||
|
48
src/translate.rs
Normal file
48
src/translate.rs
Normal file
@ -0,0 +1,48 @@
|
||||
use crate::hittable::{HitRecord, Hittable};
|
||||
use crate::{Aabb, Ray, Vec3};
|
||||
|
||||
pub struct Translate<H: Hittable> {
|
||||
hittable: H,
|
||||
offset: Vec3
|
||||
}
|
||||
|
||||
impl<H: Hittable> Translate<H> {
|
||||
pub fn new(hittable: H, offset: Vec3) -> Self {
|
||||
Self { hittable, offset }
|
||||
}
|
||||
}
|
||||
|
||||
impl<H: Hittable> Hittable for Translate<H> {
|
||||
fn hit(&self, ray: &Ray, t_min: f64, t_max: f64) -> Option<HitRecord> {
|
||||
let moved_ray = Ray::new(
|
||||
ray.origin() - self.offset,
|
||||
ray.direction(),
|
||||
ray.time());
|
||||
match &self.hittable.hit(&moved_ray, t_min, t_max) {
|
||||
Some(hit_record) => {
|
||||
let mut hr = HitRecord {
|
||||
point: hit_record.point,
|
||||
material: hit_record.material,
|
||||
front_face: hit_record.front_face, // Maybe need to calc normal and front_face again?
|
||||
normal: hit_record.normal,
|
||||
t: hit_record.t,
|
||||
u: hit_record.u,
|
||||
v: hit_record.v
|
||||
};
|
||||
hr.normalized(ray);
|
||||
Some(hr)
|
||||
}
|
||||
_ => None
|
||||
}
|
||||
}
|
||||
|
||||
fn bounding_box(&self, time0: f64, time1: f64) -> Option<Aabb> {
|
||||
match &self.hittable.bounding_box(time0, time1) {
|
||||
Some(bounding_box) => Some(Aabb {
|
||||
minimum: bounding_box.minimum + self.offset,
|
||||
maximum: bounding_box.maximum + self.offset,
|
||||
}),
|
||||
_ => None
|
||||
}
|
||||
}
|
||||
}
|
12
src/vec3.rs
12
src/vec3.rs
@ -1,5 +1,5 @@
|
||||
use std::fmt::{Display, Formatter};
|
||||
use std::ops::{Add, AddAssign, Div, Mul, Neg, Sub, Index, MulAssign};
|
||||
use std::ops::{Add, AddAssign, Div, Mul, Neg, Sub, Index, MulAssign, IndexMut};
|
||||
use rand::distributions::{Distribution, Uniform};
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
@ -295,6 +295,16 @@ impl Index<i32> for Vec3 {
|
||||
}
|
||||
}
|
||||
}
|
||||
impl IndexMut<i32> for Vec3 {
|
||||
fn index_mut(&mut self, index: i32) -> &mut f64{
|
||||
match index {
|
||||
0 => &mut self.x,
|
||||
1 => &mut self.y,
|
||||
2 => &mut self.z,
|
||||
_ => panic!("Unknown index")
|
||||
}
|
||||
}
|
||||
}
|
||||
impl Index<usize> for Vec3 {
|
||||
type Output = f64;
|
||||
fn index(&self, index: usize) -> &Self::Output {
|
||||
|
Loading…
Reference in New Issue
Block a user