chore: Unit convertor by value, clean stale code

The Vec3::as_unit() function accepts input by reference. It passes back
out a copy, however, and some inputs are even temporaries. I bet the
optimizer can see through this game and will do the right thing if I
give it a value instead. It should perform copy elision as appropriate,
even if I'm missing out on Rust's move semantics here.

Remove some old, unused, and unuseable functions.
This commit is contained in:
2023-06-06 17:43:29 -05:00
parent 4ea2208208
commit 0822096a3a
3 changed files with 65 additions and 36 deletions

View File

@@ -125,7 +125,7 @@ fn ray_color(r: Ray, world: &dyn Hittable, depth: u32, srng: &mut SmallRng, dist
}
}
let unitdir = Vec3::as_unit(&r.dir);
let unitdir = Vec3::as_unit(r.dir);
let t = 0.5 * (unitdir.y + 1.0);
return Vec3::ones() * (1.0 - t) + Vec3::new(0.5, 0.7, 1.0) * t
}
@@ -134,17 +134,3 @@ fn degrees_to_radians(degrees: f32) -> f32 {
degrees * std::f32::consts::PI / 180.0
}
fn hit_sphere(center: Vec3, radius: f32, ray: &Ray) -> f32{
let oc = ray.orig - center;
let a = ray.dir.length_squared();
let half_b = Vec3::dot(oc, ray.dir);
let c = oc.length_squared() - radius*radius;
let discriminant = half_b*half_b - a*c;
if discriminant < 0.0 {
return -1.0;
} else {
return (-half_b - discriminant.sqrt()) / a;
}
}

View File

@@ -1,9 +1,9 @@
use crate::ray::Ray;
use crate::hittable::HitRecord;
use crate::Vec3;
use crate::vec3;
use crate::vec3::Vec3;
use rand::Rng;
use rand::rngs::SmallRng;
use rand::distributions::Uniform;
@@ -49,7 +49,7 @@ impl Material {
},
Material::Metal { albedo, fuzz } => {
let reflected = Vec3::reflect(
Vec3::as_unit(&ray_in.dir),
Vec3::as_unit(ray_in.dir),
rec.normal
);
*scattered = Ray{
@@ -63,7 +63,7 @@ impl Material {
*attenuation = Vec3::ones();
let refraction_ratio = if rec.front_face { 1.0 / index_refraction } else { *index_refraction };
let unit_direction = Vec3::as_unit(&ray_in.dir);
let unit_direction = Vec3::as_unit(ray_in.dir);
let refracted = Vec3::refract(unit_direction, rec.normal, refraction_ratio);
*scattered = Ray {

View File

@@ -17,11 +17,7 @@ use rand::Rng;
use rand::rngs::SmallRng;
use rand::distributions::Uniform;
#[derive(Copy)]
#[derive(Clone)]
#[derive(PartialEq)]
#[derive(PartialOrd)]
#[derive(Debug)]
#[derive(Copy, Clone, PartialEq, PartialOrd, Debug)]
pub struct Vec3{
pub x: f32,
pub y: f32,
@@ -66,7 +62,7 @@ impl Vec3{
}
pub fn rand_unit_vector(srng: &mut SmallRng, distrib: Uniform<f32>) -> Vec3 {
return Vec3::as_unit(&Vec3::rand_in_unit_sphere(srng, distrib));
return Vec3::as_unit(Vec3::rand_in_unit_sphere(srng, distrib));
}
pub fn length(&self) -> f32 {
@@ -126,9 +122,9 @@ impl Vec3{
}
}
pub fn as_unit(v: &Vec3) -> Vec3 {
pub fn as_unit(v: Vec3) -> Vec3 {
let len = v.length();
*v / len
v / len
}
}
@@ -194,7 +190,6 @@ impl Mul<f32> for Vec3{
z: self.z * other,
}
}
}
impl MulAssign<Vec3> for Vec3 {
@@ -232,9 +227,9 @@ impl Div<f32> for Vec3 {
type Output = Vec3;
fn div(self, other: f32) -> Vec3 {
Vec3 {
x: self.x / other,
y: self.y / other,
z: self.z / other,
x: 1.0/other * self.x,
y: 1.0/other * self.y,
z: 1.0/other * self.z,
}
}
}
@@ -449,6 +444,20 @@ mod test{
assert_eq!(Vec3::dot(v1, v2), 1.0);
}
#[test]
fn test_dot_acute(){
let v1 = Vec3::new(1.0, 1.0, 0.0);
let v2 = Vec3::new(0.5, 1.0, 0.0);
assert_eq!(Vec3::dot(v1, v2), 1.5);
}
#[test]
fn test_dot_obtuse(){
let v1 = Vec3::new(1.0, 1.0, 0.0);
let v2 = Vec3::new(0.5, -1.0, 0.0);
assert_eq!(Vec3::dot(v1, v2), -0.5);
}
#[test]
fn test_cross_perpendicular(){
let v1 = Vec3::new(1.0, 0.0, 0.0);
@@ -483,7 +492,7 @@ mod test{
let v = Vec3::new(2.0, 0.0, 0.0);
let expected = Vec3::new(1.0, 0.0, 0.0);
assert_eq!(Vec3::as_unit(&v), expected);
assert_eq!(Vec3::as_unit(v), expected);
}
#[test]
@@ -491,7 +500,7 @@ mod test{
let v = Vec3::new(0.5, 0.0, 0.0);
let expected = Vec3::new(1.0, 0.0, 0.0);
assert_eq!(Vec3::as_unit(&v), expected);
assert_eq!(Vec3::as_unit(v), expected);
}
#[test]
@@ -499,8 +508,42 @@ mod test{
let v = Vec3::new(1.0, 1.0, 1.0);
let expected = Vec3::new(0.577350269,0.577350269,0.577350269);
assert!(Vec3::as_unit(&v) <= expected * 1.001); // within very small under-estimate
assert!(Vec3::as_unit(&v) >= expected * 0.999); // within very small over-estimate
assert!(Vec3::as_unit(v) <= expected * 1.001); // within very small under-estimate
assert!(Vec3::as_unit(v) >= expected * 0.999); // within very small over-estimate
}
#[test]
fn test_reflect_flat(){
let ray = Vec3::new(1.0, 0.0, 0.0);
let normal = Vec3::new(-1.0, 0.0, 0.0);
let refl = Vec3::reflect(ray, normal);
let expected = Vec3::new(-1.0, 0.0, 0.0);
assert!(refl == expected);
}
#[test]
fn test_reflect_flat_back(){
let ray = Vec3::new(1.0, 0.0, 0.0);
let normal = Vec3::new(1.0, 0.0, 0.0);
let refl = Vec3::reflect(ray, normal);
let expected = Vec3::new(-1.0, 0.0, 0.0);
assert!(refl == expected);
}
#[test]
fn test_reflect_45(){
let ray = Vec3::new(1.0, 0.0, 0.0);
let normal = Vec3::as_unit(Vec3::new(-1.0, 1.0, 0.0));
let refl = Vec3::reflect(ray, normal);
let expected = Vec3::new(0.0, 1.0, 0.0);
let diff = refl - expected;
eprintln!("Diff: {}", diff);
assert!(Vec3::near_zero(&diff));
}
}