library: render: move helpers to utils module
Those helper functions are used by `Scene` to render the scene, but they have no use being in the same file. Instead make it a crate-public module of `render`.
This commit is contained in:
parent
c0c332e3fa
commit
8e09f45f69
|
@ -8,3 +8,5 @@ pub use object::*;
|
||||||
|
|
||||||
pub mod scene;
|
pub mod scene;
|
||||||
pub use scene::*;
|
pub use scene::*;
|
||||||
|
|
||||||
|
pub(crate) mod utils;
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
use std::cmp::Ordering;
|
use std::cmp::Ordering;
|
||||||
|
|
||||||
use super::{light_aggregate::LightAggregate, object::Object};
|
use super::{light_aggregate::LightAggregate, object::Object, utils::*};
|
||||||
use crate::{
|
use crate::{
|
||||||
core::{Camera, LightProperties, LinearColor, ReflTransEnum},
|
core::{Camera, LightProperties, LinearColor, ReflTransEnum},
|
||||||
material::Material,
|
material::Material,
|
||||||
|
@ -296,72 +296,6 @@ impl Scene {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn reflected(incident: Vector, normal: Vector) -> Vector {
|
|
||||||
let proj = incident.dot(&normal);
|
|
||||||
let delt = normal * (proj * 2.);
|
|
||||||
(incident - delt).normalize()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns None if the ray was totally reflected, Some(refracted_ray, reflected_amount) if not
|
|
||||||
/// Adds an element to the top of indices that should be removed
|
|
||||||
fn refracted(
|
|
||||||
incident: Vector,
|
|
||||||
normal: Vector,
|
|
||||||
indices: &mut RefractionInfo,
|
|
||||||
new_index: f32,
|
|
||||||
) -> Option<(Vector, f32)> {
|
|
||||||
let cos1 = incident.dot(&normal);
|
|
||||||
let normal = if cos1 < 0. {
|
|
||||||
// Entering object, change the medium
|
|
||||||
indices.enter_medium(new_index); // The old index is now in old_index
|
|
||||||
normal
|
|
||||||
} else {
|
|
||||||
// Exiting object, exit the medium
|
|
||||||
indices.exit_medium(); // We swapped the indices
|
|
||||||
-normal
|
|
||||||
};
|
|
||||||
let (n_1, n_2) = (indices.old_index, indices.new_index);
|
|
||||||
let eta = n_1 / n_2;
|
|
||||||
let k = 1. - eta * eta * (1. - cos1 * cos1);
|
|
||||||
if k < 0. {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
let cos1 = cos1.abs();
|
|
||||||
let cos2 = k.sqrt();
|
|
||||||
let refracted = eta * incident + (eta * cos1 - cos2) * normal;
|
|
||||||
let f_r = (n_2 * cos1 - n_1 * cos2) / (n_2 * cos1 + n_1 * cos2);
|
|
||||||
let f_t = (n_1 * cos2 - n_2 * cos1) / (n_1 * cos2 + n_2 * cos1);
|
|
||||||
let refl_t = (f_r * f_r + f_t * f_t) / 2.;
|
|
||||||
//Some((refracted, 0.))
|
|
||||||
Some((refracted.normalize(), refl_t))
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone)]
|
|
||||||
struct RefractionInfo {
|
|
||||||
pub old_index: f32,
|
|
||||||
pub new_index: f32,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl RefractionInfo {
|
|
||||||
pub fn with_index(index: f32) -> Self {
|
|
||||||
RefractionInfo {
|
|
||||||
old_index: index,
|
|
||||||
new_index: index,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn enter_medium(&mut self, index: f32) {
|
|
||||||
*self = RefractionInfo {
|
|
||||||
old_index: self.new_index,
|
|
||||||
new_index: index,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn exit_medium(&mut self) {
|
|
||||||
std::mem::swap(&mut self.old_index, &mut self.new_index)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Deserialize)]
|
#[derive(Debug, PartialEq, Deserialize)]
|
||||||
struct SerializedScene {
|
struct SerializedScene {
|
||||||
camera: Camera,
|
camera: Camera,
|
||||||
|
|
67
src/render/utils.rs
Normal file
67
src/render/utils.rs
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
use crate::Vector;
|
||||||
|
|
||||||
|
pub fn reflected(incident: Vector, normal: Vector) -> Vector {
|
||||||
|
let proj = incident.dot(&normal);
|
||||||
|
let delt = normal * (proj * 2.);
|
||||||
|
(incident - delt).normalize()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns None if the ray was totally reflected, Some(refracted_ray, reflected_amount) if not
|
||||||
|
/// Adds an element to the top of indices that should be removed
|
||||||
|
pub fn refracted(
|
||||||
|
incident: Vector,
|
||||||
|
normal: Vector,
|
||||||
|
indices: &mut RefractionInfo,
|
||||||
|
new_index: f32,
|
||||||
|
) -> Option<(Vector, f32)> {
|
||||||
|
let cos1 = incident.dot(&normal);
|
||||||
|
let normal = if cos1 < 0. {
|
||||||
|
// Entering object, change the medium
|
||||||
|
indices.enter_medium(new_index); // The old index is now in old_index
|
||||||
|
normal
|
||||||
|
} else {
|
||||||
|
// Exiting object, exit the medium
|
||||||
|
indices.exit_medium(); // We swapped the indices
|
||||||
|
-normal
|
||||||
|
};
|
||||||
|
let (n_1, n_2) = (indices.old_index, indices.new_index);
|
||||||
|
let eta = n_1 / n_2;
|
||||||
|
let k = 1. - eta * eta * (1. - cos1 * cos1);
|
||||||
|
if k < 0. {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
let cos1 = cos1.abs();
|
||||||
|
let cos2 = k.sqrt();
|
||||||
|
let refracted = eta * incident + (eta * cos1 - cos2) * normal;
|
||||||
|
let f_r = (n_2 * cos1 - n_1 * cos2) / (n_2 * cos1 + n_1 * cos2);
|
||||||
|
let f_t = (n_1 * cos2 - n_2 * cos1) / (n_1 * cos2 + n_2 * cos1);
|
||||||
|
let refl_t = (f_r * f_r + f_t * f_t) / 2.;
|
||||||
|
//Some((refracted, 0.))
|
||||||
|
Some((refracted.normalize(), refl_t))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Clone)]
|
||||||
|
pub struct RefractionInfo {
|
||||||
|
pub old_index: f32,
|
||||||
|
pub new_index: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl RefractionInfo {
|
||||||
|
pub fn with_index(index: f32) -> Self {
|
||||||
|
RefractionInfo {
|
||||||
|
old_index: index,
|
||||||
|
new_index: index,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn enter_medium(&mut self, index: f32) {
|
||||||
|
*self = RefractionInfo {
|
||||||
|
old_index: self.new_index,
|
||||||
|
new_index: index,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn exit_medium(&mut self) {
|
||||||
|
std::mem::swap(&mut self.old_index, &mut self.new_index)
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue