2022-05-18 17:49:46 +02:00
|
|
|
use super::utility;
|
2022-06-01 20:13:55 +02:00
|
|
|
use std::ops::*;
|
2022-04-12 19:14:11 +02:00
|
|
|
|
|
|
|
#[derive(Clone, Copy, Debug)]
|
|
|
|
pub struct Vec3 {
|
|
|
|
pub e: [f64; 3],
|
2022-04-07 23:04:50 +02:00
|
|
|
}
|
|
|
|
|
2022-04-20 18:58:58 +02:00
|
|
|
pub type Color = Vec3;
|
|
|
|
pub type Point3 = Vec3;
|
2022-04-07 23:04:50 +02:00
|
|
|
|
|
|
|
impl Vec3 {
|
|
|
|
pub fn new(x: f64, y: f64, z: f64) -> Self {
|
|
|
|
Vec3 { e: [x, y, z] }
|
|
|
|
}
|
|
|
|
|
2022-06-08 18:28:45 +02:00
|
|
|
pub fn null() -> Self {
|
|
|
|
Self::new(0.0, 0.0, 0.0)
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn clone(&self) -> Self {
|
|
|
|
Self::new(self.x(), self.y(), self.z())
|
|
|
|
}
|
|
|
|
|
2022-04-12 19:14:11 +02:00
|
|
|
pub fn length(&self) -> f64 {
|
2022-04-07 23:04:50 +02:00
|
|
|
self.length_squared().sqrt()
|
|
|
|
}
|
|
|
|
|
2022-04-20 18:59:29 +02:00
|
|
|
pub fn length_squared(&self) -> f64 {
|
|
|
|
self.e[0] * self.e[0] + self.e[1] * self.e[1] + self.e[2] * self.e[2]
|
2022-04-07 23:04:50 +02:00
|
|
|
}
|
|
|
|
|
2022-04-12 19:14:11 +02:00
|
|
|
pub fn cross(a: Vec3, b: Vec3) -> Vec3 {
|
2022-04-20 18:59:29 +02:00
|
|
|
Vec3::new(
|
|
|
|
a.y() * b.z() - a.z() * b.y(),
|
|
|
|
a.z() * b.x() - a.x() * b.z(),
|
|
|
|
a.x() * b.y() - a.y() * b.x(),
|
|
|
|
)
|
2022-04-12 19:14:11 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn dot(a: Vec3, b: Vec3) -> f64 {
|
2022-04-20 18:59:29 +02:00
|
|
|
a.x() * b.x() + a.y() * b.y() + a.z() * b.z()
|
2022-04-12 19:14:11 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn unit_vector(a: Vec3) -> Vec3 {
|
|
|
|
a / a.length()
|
|
|
|
}
|
|
|
|
|
2022-06-08 18:28:45 +02:00
|
|
|
pub fn reflect(v: &Self, n: &Self) -> Self {
|
|
|
|
*v - 2.0*Self::dot(*v, *n) * *(n)
|
|
|
|
}
|
|
|
|
|
2022-06-21 18:10:52 +02:00
|
|
|
pub fn refract(uv: &Self, n: &Self, etai_over_etat: f64) -> Self {
|
|
|
|
let cos_theta = Self::dot(-1.0 * *uv, *n).min(1.0); // Minimum aus 1.0 und Punktprodukt
|
|
|
|
let r_out_perp = etai_over_etat * (*uv + cos_theta * *n);
|
|
|
|
let r_out_parallel = -(1.0 - r_out_perp.length_squared()).abs().sqrt() * *n;
|
|
|
|
return r_out_perp + r_out_parallel;
|
|
|
|
}
|
|
|
|
|
2022-06-08 18:28:45 +02:00
|
|
|
pub fn near_zero(&self) -> bool {
|
|
|
|
let s = 1e-8;
|
|
|
|
return (self.e[0].abs() < s) && (self.e[1].abs() < s) && (self.e[2].abs() < s);
|
|
|
|
}
|
|
|
|
|
2022-05-18 17:49:46 +02:00
|
|
|
pub fn random_f64() -> Vec3 {
|
2022-06-01 20:13:55 +02:00
|
|
|
Vec3::new(
|
|
|
|
utility::random_f64(),
|
|
|
|
utility::random_f64(),
|
|
|
|
utility::random_f64(),
|
|
|
|
)
|
2022-05-18 17:49:46 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn random_rng(min: f64, max: f64) -> Self {
|
2022-06-01 20:13:55 +02:00
|
|
|
Self::new(
|
|
|
|
utility::random_rng(min, max),
|
|
|
|
utility::random_rng(min, max),
|
|
|
|
utility::random_rng(min, max),
|
|
|
|
)
|
2022-05-18 17:49:46 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn random_in_unit_sphere() -> Self {
|
|
|
|
loop {
|
|
|
|
let p = Vec3::random_rng(-1.0, 1.0);
|
2022-06-01 20:13:55 +02:00
|
|
|
if p.length_squared() >= 1.0 {
|
|
|
|
continue;
|
|
|
|
};
|
2022-05-18 17:49:46 +02:00
|
|
|
return p;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-06-01 17:01:16 +02:00
|
|
|
pub fn random_unit_vector() -> Self {
|
|
|
|
Self::unit_vector(Self::random_in_unit_sphere())
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn random_in_hemisphere(&self) -> Self {
|
|
|
|
let in_unit_sphere = Self::random_in_unit_sphere();
|
|
|
|
if Self::dot(in_unit_sphere, *self) > 0.0 {
|
|
|
|
return in_unit_sphere;
|
|
|
|
} else {
|
2022-06-01 20:13:55 +02:00
|
|
|
return -1.0 * in_unit_sphere;
|
2022-06-01 17:01:16 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-04-20 18:59:29 +02:00
|
|
|
pub fn x(&self) -> f64 {
|
|
|
|
self.e[0]
|
|
|
|
}
|
|
|
|
pub fn y(&self) -> f64 {
|
|
|
|
self.e[1]
|
|
|
|
}
|
|
|
|
pub fn z(&self) -> f64 {
|
|
|
|
self.e[2]
|
|
|
|
}
|
2022-04-07 23:04:50 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
impl Add for Vec3 {
|
|
|
|
type Output = Vec3;
|
|
|
|
|
|
|
|
fn add(self, rhs: Self) -> Vec3 {
|
2022-04-20 18:59:29 +02:00
|
|
|
Vec3::new(self.x() + rhs.x(), self.y() + rhs.y(), self.z() + rhs.z())
|
2022-04-07 23:04:50 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl AddAssign for Vec3 {
|
|
|
|
fn add_assign(&mut self, rhs: Self) {
|
|
|
|
self.e[0] += rhs.x();
|
|
|
|
self.e[1] += rhs.y();
|
|
|
|
self.e[2] += rhs.z();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Sub for Vec3 {
|
|
|
|
type Output = Vec3;
|
|
|
|
|
|
|
|
fn sub(self, rhs: Self) -> Vec3 {
|
2022-04-20 18:59:29 +02:00
|
|
|
Vec3::new(self.x() - rhs.x(), self.y() - rhs.y(), self.z() - rhs.z())
|
2022-04-07 23:04:50 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-04-12 19:14:11 +02:00
|
|
|
impl SubAssign for Vec3 {
|
|
|
|
fn sub_assign(&mut self, rhs: Self) {
|
|
|
|
self.e[0] -= rhs.x();
|
|
|
|
self.e[1] -= rhs.y();
|
|
|
|
self.e[2] -= rhs.z();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-04-07 23:04:50 +02:00
|
|
|
impl Mul<Vec3> for f64 {
|
|
|
|
type Output = Vec3;
|
|
|
|
|
|
|
|
fn mul(self, rhs: Vec3) -> Vec3 {
|
2022-04-20 18:59:29 +02:00
|
|
|
Vec3::new(self * rhs.x(), self * rhs.y(), self * rhs.z())
|
2022-04-07 23:04:50 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-06-08 18:28:45 +02:00
|
|
|
impl Mul<Self> for Vec3 {
|
|
|
|
type Output = Self;
|
|
|
|
|
|
|
|
fn mul(self, rhs: Self) -> Self {
|
|
|
|
Self::new(self.x()*rhs.x(), self.y()*rhs.y(), self.z()*rhs.z())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-04-07 23:04:50 +02:00
|
|
|
impl MulAssign<f64> for Vec3 {
|
|
|
|
fn mul_assign(&mut self, rhs: f64) {
|
|
|
|
self.e[0] *= rhs;
|
|
|
|
self.e[1] *= rhs;
|
|
|
|
self.e[2] *= rhs;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl DivAssign<f64> for Vec3 {
|
2022-04-12 19:14:11 +02:00
|
|
|
fn div_assign(&mut self, rhs: f64) {
|
2022-04-07 23:04:50 +02:00
|
|
|
self.e[0] /= rhs;
|
|
|
|
self.e[1] /= rhs;
|
|
|
|
self.e[2] /= rhs;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-04-12 19:14:11 +02:00
|
|
|
impl Div<f64> for Vec3 {
|
|
|
|
type Output = Vec3;
|
|
|
|
|
|
|
|
fn div(self, rhs: f64) -> Vec3 {
|
2022-04-20 18:59:29 +02:00
|
|
|
Vec3::new(self.x() / rhs, self.y() / rhs, self.z() / rhs)
|
2022-04-12 19:14:11 +02:00
|
|
|
}
|
2022-04-20 18:59:29 +02:00
|
|
|
}
|