diff --git a/Cargo.lock b/Cargo.lock index d571a0f..308032f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -11,9 +11,9 @@ dependencies = [ [[package]] name = "approx" -version = "0.3.2" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0e60b75072ecd4168020818c0107f2857bb6c4e64252d8d3983f6263b40a5c3" +checksum = "3f2a05fd1bd10b2527e20a2cd32d8873d115b8b39fe219ee25f42a8aca6ba278" dependencies = [ "num-traits", ] @@ -186,11 +186,9 @@ dependencies = [ [[package]] name = "glam" -version = "0.7.1" -source = "git+https://github.com/bitshifter/glam-rs.git?rev=0f314f99#0f314f990710ff9357e5896de2b55ec82fe88e0d" -dependencies = [ - "approx", -] +version = "0.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "411e0584defa447c328f25c756ba3d0685727ecc126b46c3c1176001141cd4b6" [[package]] name = "half" diff --git a/Cargo.toml b/Cargo.toml index 61592a7..79fd0db 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -35,7 +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"]} +glam = "0.15" fastapprox = "0.3" # Local crate dependencies diff --git a/src/accel/bvh4.rs b/src/accel/bvh4.rs index 211f476..3b78077 100644 --- a/src/accel/bvh4.rs +++ b/src/accel/bvh4.rs @@ -6,7 +6,7 @@ use std::mem::{transmute, MaybeUninit}; -use glam::Vec4Mask; +use glam::BVec4A; use kioku::Arena; @@ -123,12 +123,12 @@ impl<'a> BVH4<'a> { traversal_code, } => { node_tests += ray_stack.ray_count_in_next_task() as u64; - let mut all_hits = Vec4Mask::default(); + let mut all_hits = BVec4A::default(); // Ray testing ray_stack.pop_do_next_task_and_push_rays(children.len(), |ray_idx| { if rays.is_done(ray_idx) { - Vec4Mask::default() + BVec4A::default() } else { let hits = if bounds.len() == 1 { bounds[0].intersect_ray( diff --git a/src/bbox.rs b/src/bbox.rs index b7706f2..12e3212 100644 --- a/src/bbox.rs +++ b/src/bbox.rs @@ -41,8 +41,8 @@ impl BBox { // Returns whether the given ray intersects with the bbox. pub fn intersect_ray(&self, orig: Point, dir_inv: Vector, max_t: f32) -> bool { // Calculate slab intersections - let t1 = (self.min.co - orig.co).truncate() * dir_inv.co; - let t2 = (self.max.co - orig.co).truncate() * dir_inv.co; + let t1 = (self.min.co - orig.co) * dir_inv.co; + let t2 = (self.max.co - orig.co) * dir_inv.co; // Find the far and near intersection let far_t = t1.max(t2).extend(std::f32::INFINITY); diff --git a/src/bbox4.rs b/src/bbox4.rs index 7f80023..9464388 100644 --- a/src/bbox4.rs +++ b/src/bbox4.rs @@ -9,7 +9,7 @@ use crate::{ math::{Point, Vector}, }; -use glam::{Vec4, Vec4Mask}; +use glam::{BVec4A, Vec4}; const BBOX_MAXT_ADJUST: f32 = 1.000_000_24; @@ -60,14 +60,14 @@ impl BBox4 { } // Returns whether the given ray intersects with the bboxes. - pub fn intersect_ray(&self, orig: Point, dir_inv: Vector, max_t: f32) -> Vec4Mask { + pub fn intersect_ray(&self, orig: Point, dir_inv: Vector, max_t: f32) -> BVec4A { // Get the ray data into SIMD format. - let ro_x = Vec4::splat(orig.co.x()); - 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 ro_x = Vec4::splat(orig.co[0]); + let ro_y = Vec4::splat(orig.co[1]); + let ro_z = Vec4::splat(orig.co[2]); + let rdi_x = Vec4::splat(dir_inv.co[0]); + let rdi_y = Vec4::splat(dir_inv.co[1]); + let rdi_z = Vec4::splat(dir_inv.co[2]); let max_t = Vec4::splat(max_t); // Slab tests diff --git a/src/color.rs b/src/color.rs index b190e1d..3b1ec50 100644 --- a/src/color.rs +++ b/src/color.rs @@ -95,10 +95,10 @@ impl Color { SpectralSample::from_parts( // TODO: make this SIMD Vec4::new( - plancks_law(temperature, wls.x()) * factor, - plancks_law(temperature, wls.y()) * factor, - plancks_law(temperature, wls.z()) * factor, - plancks_law(temperature, wls.w()) * factor, + plancks_law(temperature, wls[0]) * factor, + plancks_law(temperature, wls[1]) * factor, + plancks_law(temperature, wls[2]) * factor, + plancks_law(temperature, wls[3]) * factor, ), hero_wavelength, ) @@ -110,10 +110,10 @@ impl Color { SpectralSample::from_parts( // TODO: make this SIMD Vec4::new( - plancks_law_normalized(temperature, wls.x()) * factor, - plancks_law_normalized(temperature, wls.y()) * factor, - plancks_law_normalized(temperature, wls.z()) * factor, - plancks_law_normalized(temperature, wls.w()) * factor, + plancks_law_normalized(temperature, wls[0]) * factor, + plancks_law_normalized(temperature, wls[1]) * factor, + plancks_law_normalized(temperature, wls[2]) * factor, + plancks_law_normalized(temperature, wls[3]) * factor, ), hero_wavelength, ) @@ -518,10 +518,10 @@ impl XYZ { } pub fn from_spectral_sample(ss: &SpectralSample) -> XYZ { - let xyz0 = XYZ::from_wavelength(ss.wl_n(0), ss.e.x()); - let xyz1 = XYZ::from_wavelength(ss.wl_n(1), ss.e.y()); - let xyz2 = XYZ::from_wavelength(ss.wl_n(2), ss.e.z()); - let xyz3 = XYZ::from_wavelength(ss.wl_n(3), ss.e.w()); + let xyz0 = XYZ::from_wavelength(ss.wl_n(0), ss.e[0]); + let xyz1 = XYZ::from_wavelength(ss.wl_n(1), ss.e[1]); + let xyz2 = XYZ::from_wavelength(ss.wl_n(2), ss.e[2]); + let xyz3 = XYZ::from_wavelength(ss.wl_n(3), ss.e[3]); (xyz0 + xyz1 + xyz2 + xyz3) * 0.75 } diff --git a/src/lerp.rs b/src/lerp.rs index 9078b5c..6abe117 100644 --- a/src/lerp.rs +++ b/src/lerp.rs @@ -120,8 +120,8 @@ impl Lerp for Normal { impl Lerp for Point { fn lerp(self, other: Point, alpha: f32) -> Point { - let s = self.norm(); - let o = other.norm(); + let s = self; + let o = other; Point { co: (s.co * (1.0 - alpha)) + (o.co * alpha), } diff --git a/src/ray.rs b/src/ray.rs index 2ad37b8..166056a 100644 --- a/src/ray.rs +++ b/src/ray.rs @@ -1,6 +1,6 @@ #![allow(dead_code)] -use glam::Vec4Mask; +use glam::BVec4A; 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) { self.hot[idx].orig_local = ray.orig; self.hot[idx].dir_inv_local = Vector { - co: ray.dir.co.reciprocal(), + co: ray.dir.co.recip(), }; self.hot[idx].max_t = ray.max_t; self.hot[idx].time = ray.time; @@ -122,7 +122,7 @@ impl RayBatch { pub fn update_local(&mut self, idx: usize, xform: &Matrix4x4) { self.hot[idx].orig_local = self.cold[idx].orig * *xform; self.hot[idx].dir_inv_local = Vector { - co: (self.cold[idx].dir * *xform).co.reciprocal(), + co: (self.cold[idx].dir * *xform).co.recip(), }; } @@ -349,7 +349,7 @@ impl RayStack { /// indicated lanes. pub fn pop_do_next_task_and_push_rays(&mut self, output_lane_count: usize, mut handle_ray: F) where - F: FnMut(usize) -> Vec4Mask, + F: FnMut(usize) -> BVec4A, { // Pop the task and do necessary bookkeeping. let task = self.tasks.pop().unwrap(); diff --git a/src/shading/surface_closure.rs b/src/shading/surface_closure.rs index 10713eb..b1f3741 100644 --- a/src/shading/surface_closure.rs +++ b/src/shading/surface_closure.rs @@ -492,23 +492,23 @@ mod ggx_closure { let spectrum_sample = col.to_spectral_sample(wavelength); let rev_fresnel = 1.0 - fresnel; let c0 = lerp( - schlick_fresnel_from_fac(spectrum_sample.e.x(), hb), - spectrum_sample.e.x(), + schlick_fresnel_from_fac(spectrum_sample.e[0], hb), + spectrum_sample.e[0], rev_fresnel, ); let c1 = lerp( - schlick_fresnel_from_fac(spectrum_sample.e.y(), hb), - spectrum_sample.e.y(), + schlick_fresnel_from_fac(spectrum_sample.e[1], hb), + spectrum_sample.e[1], rev_fresnel, ); let c2 = lerp( - schlick_fresnel_from_fac(spectrum_sample.e.z(), hb), - spectrum_sample.e.z(), + schlick_fresnel_from_fac(spectrum_sample.e[2], hb), + spectrum_sample.e[2], rev_fresnel, ); let c3 = lerp( - schlick_fresnel_from_fac(spectrum_sample.e.w(), hb), - spectrum_sample.e.w(), + schlick_fresnel_from_fac(spectrum_sample.e[3], hb), + spectrum_sample.e[3], rev_fresnel, ); diff --git a/sub_crates/math3d/Cargo.toml b/sub_crates/math3d/Cargo.toml index 0f69425..dba6e93 100644 --- a/sub_crates/math3d/Cargo.toml +++ b/sub_crates/math3d/Cargo.toml @@ -11,5 +11,5 @@ path = "src/lib.rs" # Local crate dependencies [dependencies] -glam = {git="https://github.com/bitshifter/glam-rs.git", rev="0f314f99", default-features=false, features=["approx"]} -approx = "0.3" +glam = "0.15" +approx = "0.4" diff --git a/sub_crates/math3d/src/matrix.rs b/sub_crates/math3d/src/matrix.rs index e804064..583c2b1 100644 --- a/sub_crates/math3d/src/matrix.rs +++ b/sub_crates/math3d/src/matrix.rs @@ -2,7 +2,7 @@ use std::ops::{Add, Mul}; -use approx::RelativeEq; +use approx::relative_eq; use glam::{Mat4, Vec4}; use super::Point; @@ -15,7 +15,7 @@ impl Matrix4x4 { /// Creates a new identity matrix #[inline] pub fn new() -> Matrix4x4 { - Matrix4x4(Mat4::identity()) + Matrix4x4(Mat4::IDENTITY) } /// Creates a new matrix with the specified values: @@ -44,7 +44,7 @@ impl Matrix4x4 { o: f32, p: f32, ) -> Matrix4x4 { - Matrix4x4(Mat4::new( + Matrix4x4(Mat4::from_cols( Vec4::new(a, e, i, m), Vec4::new(b, f, j, n), Vec4::new(c, g, k, o), @@ -54,7 +54,7 @@ impl Matrix4x4 { #[inline] pub fn from_location(loc: Point) -> Matrix4x4 { - Matrix4x4(Mat4::from_translation(loc.co.truncate())) + Matrix4x4(Mat4::from_translation(loc.co.into())) } /// Returns whether the matrices are approximately equal to each other. @@ -62,7 +62,15 @@ impl Matrix4x4 { /// error exceeding epsilon. #[inline] pub fn aprx_eq(&self, other: Matrix4x4, epsilon: f32) -> bool { - self.0.relative_eq(&other.0, std::f32::EPSILON, epsilon) + let mut eq = true; + for c in 0..4 { + for r in 0..4 { + let a = self.0.col(c)[r]; + let b = other.0.col(c)[r]; + eq &= relative_eq!(a, b, epsilon = epsilon); + } + } + eq } /// Returns the transpose of the matrix diff --git a/sub_crates/math3d/src/normal.rs b/sub_crates/math3d/src/normal.rs index c02bac9..2b79dd3 100644 --- a/sub_crates/math3d/src/normal.rs +++ b/sub_crates/math3d/src/normal.rs @@ -5,21 +5,21 @@ use std::{ ops::{Add, Div, Mul, Neg, Sub}, }; -use glam::Vec3; +use glam::Vec3A; use super::{CrossProduct, DotProduct, Matrix4x4, Vector}; /// A surface normal in 3d homogeneous space. #[derive(Debug, Copy, Clone)] pub struct Normal { - pub co: Vec3, + pub co: Vec3A, } impl Normal { #[inline(always)] pub fn new(x: f32, y: f32, z: f32) -> Normal { Normal { - co: Vec3::new(x, y, z), + co: Vec3A::new(x, y, z), } } @@ -57,32 +57,32 @@ impl Normal { #[inline(always)] pub fn x(&self) -> f32 { - self.co.x() + self.co[0] } #[inline(always)] pub fn y(&self) -> f32 { - self.co.y() + self.co[1] } #[inline(always)] pub fn z(&self) -> f32 { - self.co.z() + self.co[2] } #[inline(always)] pub fn set_x(&mut self, x: f32) { - self.co.set_x(x); + self.co[0] = x; } #[inline(always)] pub fn set_y(&mut self, y: f32) { - self.co.set_y(y); + self.co[1] = y; } #[inline(always)] pub fn set_z(&mut self, z: f32) { - self.co.set_z(z); + self.co[2] = z; } } @@ -133,7 +133,7 @@ impl Mul for Normal { fn mul(self, other: Matrix4x4) -> Normal { let mat = other.0.inverse().transpose(); Normal { - co: mat.transform_vector3(self.co), + co: mat.transform_vector3a(self.co), } } } diff --git a/sub_crates/math3d/src/point.rs b/sub_crates/math3d/src/point.rs index 33d993c..b6cbb5e 100644 --- a/sub_crates/math3d/src/point.rs +++ b/sub_crates/math3d/src/point.rs @@ -5,37 +5,37 @@ use std::{ ops::{Add, Mul, Sub}, }; -use glam::Vec4; +use glam::Vec3A; use super::{Matrix4x4, Vector}; /// A position in 3d homogeneous space. #[derive(Debug, Copy, Clone)] pub struct Point { - pub co: Vec4, + pub co: Vec3A, } impl Point { #[inline(always)] pub fn new(x: f32, y: f32, z: f32) -> Point { Point { - co: Vec4::new(x, y, z, 1.0), + co: Vec3A::new(x, y, z), } } - /// Returns the point in standardized coordinates, where the - /// fourth homogeneous component has been normalized to 1.0. - #[inline(always)] - pub fn norm(&self) -> Point { - Point { - co: self.co / self.co.w(), - } - } + // /// Returns the point in standardized coordinates, where the + // /// fourth homogeneous component has been normalized to 1.0. + // #[inline(always)] + // pub fn norm(&self) -> Point { + // Point { + // co: self.co / self.co[3], + // } + // } #[inline(always)] pub fn min(&self, other: Point) -> Point { - let n1 = self.norm(); - let n2 = other.norm(); + let n1 = self; + let n2 = other; Point { co: n1.co.min(n2.co), @@ -44,8 +44,8 @@ impl Point { #[inline(always)] pub fn max(&self, other: Point) -> Point { - let n1 = self.norm(); - let n2 = other.norm(); + let n1 = self; + let n2 = other; Point { co: n1.co.max(n2.co), @@ -54,9 +54,7 @@ impl Point { #[inline(always)] pub fn into_vector(self) -> Vector { - Vector { - co: self.co.truncate(), - } + Vector { co: self.co } } #[inline(always)] @@ -71,32 +69,32 @@ impl Point { #[inline(always)] pub fn x(&self) -> f32 { - self.co.x() + self.co[0] } #[inline(always)] pub fn y(&self) -> f32 { - self.co.y() + self.co[1] } #[inline(always)] pub fn z(&self) -> f32 { - self.co.z() + self.co[2] } #[inline(always)] pub fn set_x(&mut self, x: f32) { - self.co.set_x(x); + self.co[0] = x; } #[inline(always)] pub fn set_y(&mut self, y: f32) { - self.co.set_y(y); + self.co[1] = y; } #[inline(always)] pub fn set_z(&mut self, z: f32) { - self.co.set_z(z); + self.co[2] = z; } } @@ -113,7 +111,7 @@ impl Add for Point { #[inline(always)] fn add(self, other: Vector) -> Point { Point { - co: self.co + other.co.extend(0.0), + co: self.co + other.co, } } } @@ -124,7 +122,7 @@ impl Sub for Point { #[inline(always)] fn sub(self, other: Point) -> Vector { Vector { - co: (self.norm().co - other.norm().co).truncate(), + co: self.co - other.co, } } } @@ -135,7 +133,7 @@ impl Sub for Point { #[inline(always)] fn sub(self, other: Vector) -> Point { Point { - co: self.co - other.co.extend(0.0), + co: self.co - other.co, } } } @@ -146,7 +144,7 @@ impl Mul for Point { #[inline] fn mul(self, other: Matrix4x4) -> Point { Point { - co: other.0.mul_vec4(self.co), + co: other.0.transform_point3a(self.co), } } } diff --git a/sub_crates/math3d/src/vector.rs b/sub_crates/math3d/src/vector.rs index 3e409f0..633f6f3 100644 --- a/sub_crates/math3d/src/vector.rs +++ b/sub_crates/math3d/src/vector.rs @@ -5,21 +5,21 @@ use std::{ ops::{Add, Div, Mul, Neg, Sub}, }; -use glam::Vec3; +use glam::Vec3A; use super::{CrossProduct, DotProduct, Matrix4x4, Normal, Point}; /// A direction vector in 3d homogeneous space. #[derive(Debug, Copy, Clone)] pub struct Vector { - pub co: Vec3, + pub co: Vec3A, } impl Vector { #[inline(always)] pub fn new(x: f32, y: f32, z: f32) -> Vector { Vector { - co: Vec3::new(x, y, z), + co: Vec3A::new(x, y, z), } } @@ -43,15 +43,13 @@ impl Vector { #[inline(always)] pub fn abs(&self) -> Vector { Vector { - co: self.co * self.co.sign(), + co: self.co * self.co.signum(), } } #[inline(always)] pub fn into_point(self) -> Point { - Point { - co: self.co.extend(1.0), - } + Point { co: self.co } } #[inline(always)] @@ -71,32 +69,32 @@ impl Vector { #[inline(always)] pub fn x(&self) -> f32 { - self.co.x() + self.co[0] } #[inline(always)] pub fn y(&self) -> f32 { - self.co.y() + self.co[1] } #[inline(always)] pub fn z(&self) -> f32 { - self.co.z() + self.co[2] } #[inline(always)] pub fn set_x(&mut self, x: f32) { - self.co.set_x(x); + self.co[0] = x; } #[inline(always)] pub fn set_y(&mut self, y: f32) { - self.co.set_y(y); + self.co[1] = y; } #[inline(always)] pub fn set_z(&mut self, z: f32) { - self.co.set_z(z); + self.co[2] = z; } } @@ -146,7 +144,7 @@ impl Mul for Vector { #[inline] fn mul(self, other: Matrix4x4) -> Vector { Vector { - co: other.0.transform_vector3(self.co), + co: other.0.transform_vector3a(self.co), } } } diff --git a/sub_crates/spectral_upsampling/Cargo.toml b/sub_crates/spectral_upsampling/Cargo.toml index 7d22204..88be212 100644 --- a/sub_crates/spectral_upsampling/Cargo.toml +++ b/sub_crates/spectral_upsampling/Cargo.toml @@ -10,4 +10,4 @@ name = "spectral_upsampling" path = "src/lib.rs" [dependencies] -glam = {git="https://github.com/bitshifter/glam-rs.git", rev="0f314f99", default-features=false, features=["approx"]} \ No newline at end of file +glam = "0.15" \ No newline at end of file diff --git a/sub_crates/spectral_upsampling/src/jakob.rs b/sub_crates/spectral_upsampling/src/jakob.rs index b33f619..9a8e07c 100644 --- a/sub_crates/spectral_upsampling/src/jakob.rs +++ b/sub_crates/spectral_upsampling/src/jakob.rs @@ -118,14 +118,14 @@ fn small_rgb_to_spectrum_p4( // Evaluate the spectral function and return the result. if max_val <= table_mid_value { - rgb2spec_eval_4([c[0].x(), c[0].y(), c[0].z()], lambdas) * (1.0 / table_mid_value) * max_val + rgb2spec_eval_4([c[0][0], c[0][1], c[0][2]], lambdas) * (1.0 / table_mid_value) * max_val } else if max_val < 1.0 { let n = (max_val - table_mid_value) / (1.0 - table_mid_value); - let s0 = rgb2spec_eval_4([c[0].x(), c[0].y(), c[0].z()], lambdas); - let s1 = rgb2spec_eval_4([c[1].x(), c[1].y(), c[1].z()], lambdas); + let s0 = rgb2spec_eval_4([c[0][0], c[0][1], c[0][2]], lambdas); + let s1 = rgb2spec_eval_4([c[1][0], c[1][1], c[1][2]], lambdas); (s0 * (1.0 - n)) + (s1 * n) } else { - rgb2spec_eval_4([c[1].x(), c[1].y(), c[1].z()], lambdas) * max_val + rgb2spec_eval_4([c[1][0], c[1][1], c[1][2]], lambdas) * max_val } } @@ -147,7 +147,7 @@ fn rgb2spec_eval_4(coeff: [f32; RGB2SPEC_N_COEFFS], lambda: Vec4) -> Vec4 { let y = { // TODO: replace this with a SIMD sqrt op. let (x, y, z, w) = rgb2spec_fma_4(x, x, Vec4::splat(1.0)).into(); - Vec4::new(x.sqrt(), y.sqrt(), z.sqrt(), w.sqrt()).reciprocal() + Vec4::new(x.sqrt(), y.sqrt(), z.sqrt(), w.sqrt()).recip() }; rgb2spec_fma_4(Vec4::splat(0.5) * x, y, Vec4::splat(0.5)) diff --git a/sub_crates/spectral_upsampling/src/meng.rs b/sub_crates/spectral_upsampling/src/meng.rs index 953940e..f3ad3e7 100644 --- a/sub_crates/spectral_upsampling/src/meng.rs +++ b/sub_crates/spectral_upsampling/src/meng.rs @@ -227,13 +227,13 @@ pub fn spectrum_xyz_to_p_4(lambdas: Vec4, xyz: (f32, f32, f32)) -> Vec4 { // Get the spectral values for the vertices of the grid cell. // TODO: use integer SIMD intrinsics to make this part faster. let mut p = [Vec4::splat(0.0); 6]; - let sb0: [i32; 4] = [sb.x() as i32, sb.y() as i32, sb.z() as i32, sb.w() as i32]; + let sb0: [i32; 4] = [sb[0] as i32, sb[1] as i32, sb[2] as i32, sb[3] as i32]; assert!(sb0[0].max(sb0[1]).max(sb0[2].max(sb0[3])) < SPECTRUM_NUM_SAMPLES); let sb1: [i32; 4] = [ - (sb.x() as i32 + 1).min(SPECTRUM_NUM_SAMPLES - 1), - (sb.y() as i32 + 1).min(SPECTRUM_NUM_SAMPLES - 1), - (sb.z() as i32 + 1).min(SPECTRUM_NUM_SAMPLES - 1), - (sb.w() as i32 + 1).min(SPECTRUM_NUM_SAMPLES - 1), + (sb[0] as i32 + 1).min(SPECTRUM_NUM_SAMPLES - 1), + (sb[1] as i32 + 1).min(SPECTRUM_NUM_SAMPLES - 1), + (sb[2] as i32 + 1).min(SPECTRUM_NUM_SAMPLES - 1), + (sb[3] as i32 + 1).min(SPECTRUM_NUM_SAMPLES - 1), ]; let sbf = sb - Vec4::new(sb0[0] as f32, sb0[1] as f32, sb0[2] as f32, sb0[3] as f32); for i in 0..(num as usize) {