rtiow: break project into multiple workspaces.
Some checks failed
continuous-integration/drone/push Build is failing
Some checks failed
continuous-integration/drone/push Build is failing
This commit is contained in:
88
rtiow/renderer/src/constant_medium.rs
Normal file
88
rtiow/renderer/src/constant_medium.rs
Normal file
@@ -0,0 +1,88 @@
|
||||
use std;
|
||||
|
||||
use rand;
|
||||
use rand::Rng;
|
||||
|
||||
use crate::aabb::AABB;
|
||||
use crate::hitable::Hit;
|
||||
use crate::hitable::HitRecord;
|
||||
use crate::material::Isotropic;
|
||||
use crate::ray::Ray;
|
||||
use crate::texture::Texture;
|
||||
use crate::vec3::Vec3;
|
||||
|
||||
pub struct ConstantMedium<H, T>
|
||||
where
|
||||
H: Hit,
|
||||
T: Texture,
|
||||
{
|
||||
density: f32,
|
||||
material: Isotropic<T>,
|
||||
hitable: H,
|
||||
}
|
||||
|
||||
impl<H, T> ConstantMedium<H, T>
|
||||
where
|
||||
H: Hit,
|
||||
T: Texture,
|
||||
{
|
||||
pub fn new(hitable: H, density: f32, texture: T) -> ConstantMedium<H, T>
|
||||
where
|
||||
T: Texture,
|
||||
{
|
||||
ConstantMedium {
|
||||
density,
|
||||
material: Isotropic::new(texture),
|
||||
hitable,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<H, T> Hit for ConstantMedium<H, T>
|
||||
where
|
||||
H: Hit,
|
||||
T: Texture,
|
||||
{
|
||||
fn hit(&self, r: Ray, t_min: f32, t_max: f32) -> Option<HitRecord> {
|
||||
let mut rng = rand::thread_rng();
|
||||
if let Some(mut rec1) = self.hitable.hit(r, std::f32::MIN, std::f32::MAX) {
|
||||
if let Some(mut rec2) = self.hitable.hit(r, rec1.t + 0.001, std::f32::MAX) {
|
||||
if rec1.t < t_min {
|
||||
rec1.t = t_min;
|
||||
}
|
||||
if rec2.t > t_max {
|
||||
rec2.t = t_max;
|
||||
}
|
||||
if rec1.t >= rec2.t {
|
||||
return None;
|
||||
}
|
||||
if rec1.t < 0. {
|
||||
rec1.t = 0.;
|
||||
}
|
||||
let distance_inside_boundary = (rec2.t - rec1.t) * r.direction.length();
|
||||
let hit_distance = -(1. / self.density) * rng.gen_range::<f32>(0., 1.).ln();
|
||||
if hit_distance < distance_inside_boundary {
|
||||
let t = rec1.t + hit_distance / r.direction.length();
|
||||
let normal = Vec3::new(
|
||||
rng.gen_range(0., 1.),
|
||||
rng.gen_range(0., 1.),
|
||||
rng.gen_range(0., 1.),
|
||||
)
|
||||
.unit_vector();
|
||||
return Some(HitRecord {
|
||||
t,
|
||||
p: r.point_at_parameter(t),
|
||||
normal,
|
||||
material: &self.material,
|
||||
uv: (0., 0.),
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
fn bounding_box(&self, t_min: f32, t_max: f32) -> Option<AABB> {
|
||||
self.hitable.bounding_box(t_min, t_max)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user