pub mod alloc; pub mod atomic; pub mod complex; pub mod containers; pub mod hash; pub mod interval; pub mod math; pub mod noise; pub mod options; pub mod ptr; pub mod quaternion; pub mod rng; pub mod sampling; pub mod soa; pub mod sobol; pub mod splines; pub mod transform; pub use atomic::{AtomicFloat, AtomicU32}; pub use containers::Array2D; pub use options::{BasicPBRTOptions, PBRTOptions}; pub use ptr::Ptr; pub use transform::{AnimatedTransform, Transform, TransformGeneric}; use crate::Float; #[inline] pub fn find_interval(sz: u32, pred: F) -> u32 where F: Fn(u32) -> bool, { let mut first = 0; let mut len = sz; while len > 0 { let half = len >> 1; let middle = first + half; if pred(middle) { first = middle + 1; len -= half + 1; } else { len = half; } } let ret = (first as i32 - 1).max(0) as u32; ret.min(sz.saturating_sub(2)) } #[inline] pub fn partition_slice(data: &mut [T], predicate: F) -> usize where F: Fn(&T) -> bool, { let mut i = 0; for j in 0..data.len() { if predicate(&data[j]) { data.swap(i, j); i += 1; } } i } #[inline(always)] pub fn gpu_array_from_fn(mut f: impl FnMut(usize) -> T) -> [T; N] { unsafe { let mut arr: core::mem::MaybeUninit<[T; N]> = core::mem::MaybeUninit::uninit(); let ptr = arr.as_mut_ptr() as *mut T; let mut i = 0; while i < N { ptr.add(i).write(f(i)); i += 1; } arr.assume_init() } }