Make better use of the types in the glam crate.

Appears to give a tiny performance boost.
This commit is contained in:
Nathan Vegdahl 2019-07-25 11:36:52 +09:00
parent e3179d5b2e
commit f42eedfd08
5 changed files with 35 additions and 37 deletions

View File

@ -41,14 +41,12 @@ impl BBox {
// Returns whether the given ray intersects with the bbox. // Returns whether the given ray intersects with the bbox.
pub fn intersect_ray(&self, orig: Point, dir_inv: Vector, max_t: f32) -> bool { pub fn intersect_ray(&self, orig: Point, dir_inv: Vector, max_t: f32) -> bool {
// Calculate slab intersections // Calculate slab intersections
let t1 = (self.min.co - orig.co) * dir_inv.co; let t1 = (self.min.co - orig.co).truncate() * dir_inv.co;
let t2 = (self.max.co - orig.co) * dir_inv.co; let t2 = (self.max.co - orig.co).truncate() * dir_inv.co;
// Find the far and near intersection // Find the far and near intersection
let mut far_t = t1.max(t2); let far_t = t1.max(t2).extend(std::f32::INFINITY);
let mut near_t = t1.min(t2); let near_t = t1.min(t2).extend(0.0);
far_t.set_w(std::f32::INFINITY);
near_t.set_w(0.0);
let far_hit_t = fast_minf32(far_t.min_element() * BBOX_MAXT_ADJUST, max_t); let far_hit_t = fast_minf32(far_t.min_element() * BBOX_MAXT_ADJUST, max_t);
let near_hit_t = near_t.max_element(); let near_hit_t = near_t.max_element();

View File

@ -1,6 +1,6 @@
#![allow(dead_code)] #![allow(dead_code)]
use glam::{Vec4, Vec4Mask}; use glam::Vec4Mask;
use crate::math::{Matrix4x4, Point, Vector}; use crate::math::{Matrix4x4, Point, Vector};
@ -86,7 +86,7 @@ impl RayBatch {
pub fn set_from_ray(&mut self, ray: &Ray, is_occlusion: bool, idx: usize) { pub fn set_from_ray(&mut self, ray: &Ray, is_occlusion: bool, idx: usize) {
self.hot[idx].orig_local = ray.orig; self.hot[idx].orig_local = ray.orig;
self.hot[idx].dir_inv_local = Vector { self.hot[idx].dir_inv_local = Vector {
co: Vec4::splat(1.0) / ray.dir.co, co: ray.dir.co.reciprocal(),
}; };
self.hot[idx].max_t = ray.max_t; self.hot[idx].max_t = ray.max_t;
self.hot[idx].time = ray.time; self.hot[idx].time = ray.time;
@ -122,7 +122,7 @@ impl RayBatch {
pub fn update_local(&mut self, idx: usize, xform: &Matrix4x4) { pub fn update_local(&mut self, idx: usize, xform: &Matrix4x4) {
self.hot[idx].orig_local = self.cold[idx].orig * *xform; self.hot[idx].orig_local = self.cold[idx].orig * *xform;
self.hot[idx].dir_inv_local = Vector { self.hot[idx].dir_inv_local = Vector {
co: Vec4::splat(1.0) / (self.cold[idx].dir * *xform).co, co: (self.cold[idx].dir * *xform).co.reciprocal(),
}; };
} }

View File

@ -5,21 +5,21 @@ use std::{
ops::{Add, Div, Mul, Neg, Sub}, ops::{Add, Div, Mul, Neg, Sub},
}; };
use glam::Vec4; use glam::Vec3;
use super::{CrossProduct, DotProduct, Matrix4x4, Vector}; use super::{CrossProduct, DotProduct, Matrix4x4, Vector};
/// A surface normal in 3d homogeneous space. /// A surface normal in 3d homogeneous space.
#[derive(Debug, Copy, Clone)] #[derive(Debug, Copy, Clone)]
pub struct Normal { pub struct Normal {
pub co: Vec4, pub co: Vec3,
} }
impl Normal { impl Normal {
#[inline(always)] #[inline(always)]
pub fn new(x: f32, y: f32, z: f32) -> Normal { pub fn new(x: f32, y: f32, z: f32) -> Normal {
Normal { Normal {
co: Vec4::new(x, y, z, 0.0), co: Vec3::new(x, y, z),
} }
} }
@ -132,9 +132,9 @@ impl Mul<Matrix4x4> for Normal {
#[inline] #[inline]
fn mul(self, other: Matrix4x4) -> Normal { fn mul(self, other: Matrix4x4) -> Normal {
let mat = other.0.inverse().transpose(); let mat = other.0.inverse().transpose();
let mut co = mat.mul_vec4(self.co); Normal {
co.set_w(0.0); co: mat.transform_vector3(self.co),
Normal { co: co } }
} }
} }
@ -169,7 +169,7 @@ impl CrossProduct for Normal {
#[inline] #[inline]
fn cross(self, other: Normal) -> Normal { fn cross(self, other: Normal) -> Normal {
Normal { Normal {
co: self.co.truncate().cross(other.co.truncate()).extend(0.0), co: self.co.cross(other.co),
} }
} }
} }
@ -213,8 +213,7 @@ mod tests {
let m = Matrix4x4::new_from_values( let m = Matrix4x4::new_from_values(
1.0, 2.0, 2.0, 1.5, 3.0, 6.0, 7.0, 8.0, 9.0, 2.0, 11.0, 12.0, 13.0, 7.0, 15.0, 3.0, 1.0, 2.0, 2.0, 1.5, 3.0, 6.0, 7.0, 8.0, 9.0, 2.0, 11.0, 12.0, 13.0, 7.0, 15.0, 3.0,
); );
let mut nm = n * m; let nm = n * m;
nm.co.set_w(0.0);
let nm2 = Normal::new(-19.258825, 5.717648, -1.770588); let nm2 = Normal::new(-19.258825, 5.717648, -1.770588);
assert!(nm.co.ulps_eq(&nm2.co, 0.0, 4)); assert!(nm.co.ulps_eq(&nm2.co, 0.0, 4));
} }

View File

@ -54,9 +54,9 @@ impl Point {
#[inline(always)] #[inline(always)]
pub fn into_vector(self) -> Vector { pub fn into_vector(self) -> Vector {
let mut v = Vector { co: self.co }; Vector {
v.co.set_w(0.0); co: self.co.truncate(),
v }
} }
#[inline(always)] #[inline(always)]
@ -113,7 +113,7 @@ impl Add<Vector> for Point {
#[inline(always)] #[inline(always)]
fn add(self, other: Vector) -> Point { fn add(self, other: Vector) -> Point {
Point { Point {
co: self.co + other.co, co: self.co + other.co.extend(0.0),
} }
} }
} }
@ -124,7 +124,7 @@ impl Sub for Point {
#[inline(always)] #[inline(always)]
fn sub(self, other: Point) -> Vector { fn sub(self, other: Point) -> Vector {
Vector { Vector {
co: self.norm().co - other.norm().co, co: (self.norm().co - other.norm().co).truncate(),
} }
} }
} }
@ -135,7 +135,7 @@ impl Sub<Vector> for Point {
#[inline(always)] #[inline(always)]
fn sub(self, other: Vector) -> Point { fn sub(self, other: Vector) -> Point {
Point { Point {
co: self.co - other.co, co: self.co - other.co.extend(0.0),
} }
} }
} }

View File

@ -5,21 +5,21 @@ use std::{
ops::{Add, Div, Mul, Neg, Sub}, ops::{Add, Div, Mul, Neg, Sub},
}; };
use glam::Vec4; use glam::Vec3;
use super::{CrossProduct, DotProduct, Matrix4x4, Normal, Point}; use super::{CrossProduct, DotProduct, Matrix4x4, Normal, Point};
/// A direction vector in 3d homogeneous space. /// A direction vector in 3d homogeneous space.
#[derive(Debug, Copy, Clone)] #[derive(Debug, Copy, Clone)]
pub struct Vector { pub struct Vector {
pub co: Vec4, pub co: Vec3,
} }
impl Vector { impl Vector {
#[inline(always)] #[inline(always)]
pub fn new(x: f32, y: f32, z: f32) -> Vector { pub fn new(x: f32, y: f32, z: f32) -> Vector {
Vector { Vector {
co: Vec4::new(x, y, z, 0.0), co: Vec3::new(x, y, z),
} }
} }
@ -42,17 +42,21 @@ impl Vector {
#[inline(always)] #[inline(always)]
pub fn abs(&self) -> Vector { pub fn abs(&self) -> Vector {
Vector::new(self.x().abs(), self.y().abs(), self.z().abs()) Vector {
co: self.co * self.co.sign(),
}
} }
#[inline(always)] #[inline(always)]
pub fn into_point(self) -> Point { pub fn into_point(self) -> Point {
Point::new(self.x(), self.y(), self.z()) Point {
co: self.co.extend(1.0),
}
} }
#[inline(always)] #[inline(always)]
pub fn into_normal(self) -> Normal { pub fn into_normal(self) -> Normal {
Normal::new(self.x(), self.y(), self.z()) Normal { co: self.co }
} }
#[inline(always)] #[inline(always)]
@ -142,7 +146,7 @@ impl Mul<Matrix4x4> for Vector {
#[inline] #[inline]
fn mul(self, other: Matrix4x4) -> Vector { fn mul(self, other: Matrix4x4) -> Vector {
Vector { Vector {
co: other.0.mul_vec4(self.co), co: other.0.transform_vector3(self.co),
} }
} }
} }
@ -178,7 +182,7 @@ impl CrossProduct for Vector {
#[inline] #[inline]
fn cross(self, other: Vector) -> Vector { fn cross(self, other: Vector) -> Vector {
Vector { Vector {
co: self.co.truncate().cross(other.co.truncate()).extend(0.0), co: self.co.cross(other.co),
} }
} }
} }
@ -221,9 +225,7 @@ mod tests {
let m = Matrix4x4::new_from_values( let m = Matrix4x4::new_from_values(
1.0, 2.0, 2.0, 1.5, 3.0, 6.0, 7.0, 8.0, 9.0, 2.0, 11.0, 12.0, 13.0, 7.0, 15.0, 3.0, 1.0, 2.0, 2.0, 1.5, 3.0, 6.0, 7.0, 8.0, 9.0, 2.0, 11.0, 12.0, 13.0, 7.0, 15.0, 3.0,
); );
let mut vm = Vector::new(14.0, 46.0, 58.0); assert_eq!(v * m, Vector::new(14.0, 46.0, 58.0));
vm.co.set_w(90.5);
assert_eq!(v * m, vm);
} }
#[test] #[test]
@ -232,8 +234,7 @@ mod tests {
let m = Matrix4x4::new_from_values( let m = Matrix4x4::new_from_values(
1.0, 2.0, 2.0, 1.5, 3.0, 6.0, 7.0, 8.0, 9.0, 2.0, 11.0, 12.0, 0.0, 0.0, 0.0, 1.0, 1.0, 2.0, 2.0, 1.5, 3.0, 6.0, 7.0, 8.0, 9.0, 2.0, 11.0, 12.0, 0.0, 0.0, 0.0, 1.0,
); );
let vm = Vector::new(14.0, 46.0, 58.0); assert_eq!(v * m, Vector::new(14.0, 46.0, 58.0));
assert_eq!(v * m, vm);
} }
#[test] #[test]