Renderer/src/vec3.rs

204 lines
4.6 KiB
Rust
Raw Normal View History

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-08-02 18:30:39 +02:00
pub fn diff(a: &Self, b: &Self) -> f64 {
(a.x() - b.x()).abs() + (a.y() - b.y()).abs() + (a.z() - b.z()).abs()
}
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 {
2022-06-29 16:17:28 +02:00
*v - 2.0 * Self::dot(*v, *n) * *(n)
2022-06-08 18:28:45 +02:00
}
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-06-28 18:23:22 +02:00
}
return p;
}
}
pub fn random_in_unit_disk() -> Self {
loop {
2022-06-29 16:17:28 +02:00
let p = Vec3::new(
utility::random_rng(-1.0, 1.0),
utility::random_rng(-1.0, 1.0),
0.0,
);
2022-06-28 18:23:22 +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 {
2022-06-29 16:17:28 +02:00
Self::new(self.x() * rhs.x(), self.y() * rhs.y(), self.z() * rhs.z())
2022-06-08 18:28:45 +02:00
}
}
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
}