Skip to content

Commit

Permalink
Switched from in-tree float4 lib to glam.
Browse files Browse the repository at this point in the history
  • Loading branch information
cessen committed Jul 22, 2019
1 parent 5c5a01e commit 88e7365
Show file tree
Hide file tree
Showing 21 changed files with 297 additions and 2,029 deletions.
29 changes: 22 additions & 7 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 1 addition & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
members = [
"sub_crates/bvh_order",
"sub_crates/color",
"sub_crates/float4",
"sub_crates/halton",
"sub_crates/math3d",
"sub_crates/mem_arena",
Expand Down Expand Up @@ -36,6 +35,7 @@ png_encode_mini = "0.1.2"
rustc-serialize = "0.3"
scoped_threadpool = "0.1"
time = "0.1"
glam = {git="https://github.com/bitshifter/glam-rs.git", rev="0f314f99", default-features=false, features=["approx"]}

# Local crate dependencies
[dependencies.bvh_order]
Expand All @@ -44,9 +44,6 @@ path = "sub_crates/bvh_order"
[dependencies.color]
path = "sub_crates/color"

[dependencies.float4]
path = "sub_crates/float4"

[dependencies.halton]
path = "sub_crates/halton"

Expand Down
9 changes: 5 additions & 4 deletions src/accel/bvh4.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@

use std::mem::{transmute, MaybeUninit};

use glam::Vec4Mask;

use mem_arena::MemArena;

use crate::{
Expand All @@ -23,7 +25,6 @@ use super::{
};

use bvh_order::{calc_traversal_code, SplitAxes, TRAVERSAL_TABLE};
use float4::Bool4;

pub fn ray_code(dir: Vector) -> usize {
let ray_sign_is_neg = [dir.x() < 0.0, dir.y() < 0.0, dir.z() < 0.0];
Expand Down Expand Up @@ -122,12 +123,12 @@ impl<'a> BVH4<'a> {
traversal_code,
} => {
node_tests += ray_stack.ray_count_in_next_task() as u64;
let mut all_hits = Bool4::new_false();
let mut all_hits = Vec4Mask::default();

// Ray testing
ray_stack.pop_do_next_task_and_push_rays(children.len(), |ray_idx| {
if rays.is_done(ray_idx) {
Bool4::new_false()
Vec4Mask::default()
} else {
let hits = if bounds.len() == 1 {
bounds[0].intersect_ray(
Expand All @@ -148,7 +149,7 @@ impl<'a> BVH4<'a> {
});

// If there were any intersections, create tasks.
if !all_hits.is_all_false() {
if all_hits.any() {
let order_code = traversal_table[traversal_code as usize];
let mut lane_count = 0;
let mut i = children.len() as u8;
Expand Down
20 changes: 10 additions & 10 deletions src/bbox.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,12 @@ impl BBox {
let t2 = (self.max.co - orig.co) * dir_inv.co;

// Find the far and near intersection
let mut far_t = t1.v_max(t2);
let mut near_t = t1.v_min(t2);
far_t.set_3(std::f32::INFINITY);
near_t.set_3(0.0);
let far_hit_t = fast_minf32(far_t.h_min() * BBOX_MAXT_ADJUST, max_t);
let near_hit_t = near_t.h_max();
let mut far_t = t1.max(t2);
let mut near_t = t1.min(t2);
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 near_hit_t = near_t.max_element();

// Did we hit?
near_hit_t <= far_hit_t
Expand Down Expand Up @@ -106,10 +106,10 @@ impl BitOr for BBox {
fn bitor(self, rhs: BBox) -> BBox {
BBox::from_points(
Point {
co: self.min.co.v_min(rhs.min.co),
co: self.min.co.min(rhs.min.co),
},
Point {
co: self.max.co.v_max(rhs.max.co),
co: self.max.co.max(rhs.max.co),
},
)
}
Expand All @@ -128,10 +128,10 @@ impl BitOr<Point> for BBox {
fn bitor(self, rhs: Point) -> BBox {
BBox::from_points(
Point {
co: self.min.co.v_min(rhs.co),
co: self.min.co.min(rhs.co),
},
Point {
co: self.max.co.v_max(rhs.co),
co: self.max.co.max(rhs.co),
},
)
}
Expand Down
75 changes: 36 additions & 39 deletions src/bbox4.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,33 +9,33 @@ use crate::{
math::{Point, Vector},
};

use float4::{Bool4, Float4};
use glam::{Vec4, Vec4Mask};

const BBOX_MAXT_ADJUST: f32 = 1.00000024;

/// A SIMD set of 4 3D axis-aligned bounding boxes.
#[derive(Debug, Copy, Clone)]
pub struct BBox4 {
pub x: (Float4, Float4), // (min, max)
pub y: (Float4, Float4), // (min, max)
pub z: (Float4, Float4), // (min, max)
pub x: (Vec4, Vec4), // (min, max)
pub y: (Vec4, Vec4), // (min, max)
pub z: (Vec4, Vec4), // (min, max)
}

impl BBox4 {
/// Creates a degenerate BBox with +infinity min and -infinity max.
pub fn new() -> BBox4 {
BBox4 {
x: (
Float4::splat(std::f32::INFINITY),
Float4::splat(std::f32::NEG_INFINITY),
Vec4::splat(std::f32::INFINITY),
Vec4::splat(std::f32::NEG_INFINITY),
),
y: (
Float4::splat(std::f32::INFINITY),
Float4::splat(std::f32::NEG_INFINITY),
Vec4::splat(std::f32::INFINITY),
Vec4::splat(std::f32::NEG_INFINITY),
),
z: (
Float4::splat(std::f32::INFINITY),
Float4::splat(std::f32::NEG_INFINITY),
Vec4::splat(std::f32::INFINITY),
Vec4::splat(std::f32::NEG_INFINITY),
),
}
}
Expand All @@ -45,30 +45,30 @@ impl BBox4 {
pub fn from_bboxes(b1: BBox, b2: BBox, b3: BBox, b4: BBox) -> BBox4 {
BBox4 {
x: (
Float4::new(b1.min.x(), b2.min.x(), b3.min.x(), b4.min.x()),
Float4::new(b1.max.x(), b2.max.x(), b3.max.x(), b4.max.x()),
Vec4::new(b1.min.x(), b2.min.x(), b3.min.x(), b4.min.x()),
Vec4::new(b1.max.x(), b2.max.x(), b3.max.x(), b4.max.x()),
),
y: (
Float4::new(b1.min.y(), b2.min.y(), b3.min.y(), b4.min.y()),
Float4::new(b1.max.y(), b2.max.y(), b3.max.y(), b4.max.y()),
Vec4::new(b1.min.y(), b2.min.y(), b3.min.y(), b4.min.y()),
Vec4::new(b1.max.y(), b2.max.y(), b3.max.y(), b4.max.y()),
),
z: (
Float4::new(b1.min.z(), b2.min.z(), b3.min.z(), b4.min.z()),
Float4::new(b1.max.z(), b2.max.z(), b3.max.z(), b4.max.z()),
Vec4::new(b1.min.z(), b2.min.z(), b3.min.z(), b4.min.z()),
Vec4::new(b1.max.z(), b2.max.z(), b3.max.z(), b4.max.z()),
),
}
}

// Returns whether the given ray intersects with the bboxes.
pub fn intersect_ray(&self, orig: Point, dir_inv: Vector, max_t: f32) -> Bool4 {
pub fn intersect_ray(&self, orig: Point, dir_inv: Vector, max_t: f32) -> Vec4Mask {
// Get the ray data into SIMD format.
let ro_x = orig.co.all_0();
let ro_y = orig.co.all_1();
let ro_z = orig.co.all_2();
let rdi_x = dir_inv.co.all_0();
let rdi_y = dir_inv.co.all_1();
let rdi_z = dir_inv.co.all_2();
let max_t = Float4::splat(max_t);
let ro_x = Vec4::splat(orig.co.x());

This comment has been minimized.

Copy link
@bitshifter

bitshifter Jul 22, 2019

I hope you don't mind me commenting, you're one of the first people to use glam so I'm interested in how you are using it. I do have dup_x etc methods for doing what your all_0 method did but I haven't made them public because while glam uses them internally I wasn't sure how useful they would be to other users. Anyway, it looks like they would be useful so I'm make them public. I was also wanting to write a shuffle macro which could also do this, but that would be more verbose and this operation seems common enough that it warrants it's own method. I made an issue so I don't forget here bitshifter/glam-rs#14.

This comment has been minimized.

Copy link
@cessen

cessen Jul 23, 2019

Author Owner

Oh, that's awesome! Thanks! I'll give those a whirl.

And yeah, I think they are generally useful for a lot of SIMD type stuff. I was going to ask about making them public at some point as well, but didn't want to overwhelm you with too much stuff, ha ha. :-)

let ro_y = Vec4::splat(orig.co.y());
let ro_z = Vec4::splat(orig.co.z());
let rdi_x = Vec4::splat(dir_inv.co.x());
let rdi_y = Vec4::splat(dir_inv.co.y());
let rdi_z = Vec4::splat(dir_inv.co.z());
let max_t = Vec4::splat(max_t);

// Slab tests
let t1_x = (self.x.0 - ro_x) * rdi_x;
Expand All @@ -79,24 +79,21 @@ impl BBox4 {
let t2_z = (self.z.1 - ro_z) * rdi_z;

// Get the far and near t hits for each axis.
let t_far_x = t1_x.v_max(t2_x);
let t_far_y = t1_y.v_max(t2_y);
let t_far_z = t1_z.v_max(t2_z);
let t_near_x = t1_x.v_min(t2_x);
let t_near_y = t1_y.v_min(t2_y);
let t_near_z = t1_z.v_min(t2_z);
let t_far_x = t1_x.max(t2_x);
let t_far_y = t1_y.max(t2_y);
let t_far_z = t1_z.max(t2_z);
let t_near_x = t1_x.min(t2_x);
let t_near_y = t1_y.min(t2_y);
let t_near_z = t1_z.min(t2_z);

// Calculate over-all far t hit.
let far_t =
(t_far_x.v_min(t_far_y.v_min(t_far_z)) * Float4::splat(BBOX_MAXT_ADJUST)).v_min(max_t);
let far_t = (t_far_x.min(t_far_y.min(t_far_z)) * Vec4::splat(BBOX_MAXT_ADJUST)).min(max_t);

// Calculate over-all near t hit.
let near_t = t_near_x
.v_max(t_near_y)
.v_max(t_near_z.v_max(Float4::splat(0.0)));
let near_t = t_near_x.max(t_near_y).max(t_near_z.max(Vec4::splat(0.0)));

// Hit results
near_t.lt(far_t)
near_t.cmplt(far_t)
}
}

Expand All @@ -106,9 +103,9 @@ impl BitOr for BBox4 {

fn bitor(self, rhs: BBox4) -> BBox4 {
BBox4 {
x: (self.x.0.v_min(rhs.x.0), self.x.1.v_max(rhs.x.1)),
y: (self.y.0.v_min(rhs.y.0), self.y.1.v_max(rhs.y.1)),
z: (self.z.0.v_min(rhs.z.0), self.z.1.v_max(rhs.z.1)),
x: (self.x.0.min(rhs.x.0), self.x.1.max(rhs.x.1)),
y: (self.y.0.min(rhs.y.0), self.y.1.max(rhs.y.1)),
z: (self.z.0.min(rhs.z.0), self.z.1.max(rhs.z.1)),
}
}
}
Expand Down
Loading

0 comments on commit 88e7365

Please sign in to comment.