Created a RayBatch type, which stores multiple rays is SoA layout.
This commit is contained in:
parent
cd50e0dd11
commit
3d4ac7f57b
99
src/ray.rs
99
src/ray.rs
|
@ -4,8 +4,99 @@ use float4::Float4;
|
|||
|
||||
use crate::math::{Matrix4x4, Point, Vector};
|
||||
|
||||
const OCCLUSION_FLAG: u32 = 1;
|
||||
const DONE_FLAG: u32 = 1 << 1;
|
||||
type FlagType = u8;
|
||||
const OCCLUSION_FLAG: FlagType = 1;
|
||||
const DONE_FLAG: FlagType = 1 << 1;
|
||||
|
||||
/// A batch of rays, stored in SoA layout.
|
||||
#[derive(Debug)]
|
||||
pub struct RayBatch {
|
||||
pub orig_world: Vec<Point>,
|
||||
pub dir_world: Vec<Vector>,
|
||||
pub orig_accel: Vec<Point>,
|
||||
pub dir_inv_accel: Vec<Vector>,
|
||||
pub max_t: Vec<f32>,
|
||||
pub time: Vec<f32>,
|
||||
pub wavelength: Vec<f32>,
|
||||
pub flags: Vec<FlagType>,
|
||||
}
|
||||
|
||||
impl RayBatch {
|
||||
/// Creates a new empty ray batch.
|
||||
pub fn new() -> RayBatch {
|
||||
RayBatch {
|
||||
orig_world: Vec::new(),
|
||||
dir_world: Vec::new(),
|
||||
orig_accel: Vec::new(),
|
||||
dir_inv_accel: Vec::new(),
|
||||
max_t: Vec::new(),
|
||||
time: Vec::new(),
|
||||
wavelength: Vec::new(),
|
||||
flags: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates a new empty ray batch, with pre-allocated capacity for
|
||||
/// `n` rays.
|
||||
pub fn with_capacity(n: usize) -> RayBatch {
|
||||
RayBatch {
|
||||
orig_world: Vec::with_capacity(n),
|
||||
dir_world: Vec::with_capacity(n),
|
||||
orig_accel: Vec::with_capacity(n),
|
||||
dir_inv_accel: Vec::with_capacity(n),
|
||||
max_t: Vec::with_capacity(n),
|
||||
time: Vec::with_capacity(n),
|
||||
wavelength: Vec::with_capacity(n),
|
||||
flags: Vec::with_capacity(n),
|
||||
}
|
||||
}
|
||||
|
||||
/// Clear all rays, settings the size of the batch back to zero.
|
||||
///
|
||||
/// Capacity is maintained.
|
||||
pub fn clear(&mut self) {
|
||||
self.orig_world.clear();
|
||||
self.dir_world.clear();
|
||||
self.orig_accel.clear();
|
||||
self.dir_inv_accel.clear();
|
||||
self.max_t.clear();
|
||||
self.time.clear();
|
||||
self.wavelength.clear();
|
||||
self.flags.clear();
|
||||
}
|
||||
|
||||
/// Returns whether the given ray (at index `idx`) is an occlusion ray.
|
||||
pub fn is_occlusion(&self, idx: usize) -> bool {
|
||||
(self.flags[idx] & OCCLUSION_FLAG) != 0
|
||||
}
|
||||
|
||||
/// Returns whether the given ray (at index `idx`) has finished traversal.
|
||||
pub fn is_done(&self, idx: usize) -> bool {
|
||||
(self.flags[idx] & DONE_FLAG) != 0
|
||||
}
|
||||
|
||||
/// Marks the given ray (at index `idx`) as an occlusion ray.
|
||||
pub fn mark_occlusion(&mut self, idx: usize) {
|
||||
self.flags[idx] |= OCCLUSION_FLAG
|
||||
}
|
||||
|
||||
/// Marks the given ray (at index `idx`) as having finished traversal.
|
||||
pub fn mark_done(&mut self, idx: usize) {
|
||||
self.flags[idx] |= DONE_FLAG
|
||||
}
|
||||
|
||||
/// Updates the accel data of the given ray (at index `idx`) with the
|
||||
/// given world-to-local-space transform matrix.
|
||||
///
|
||||
/// This should be called when entering (and exiting) traversal of a
|
||||
/// new transform space.
|
||||
pub fn update_accel(&mut self, idx: usize, xform: &Matrix4x4) {
|
||||
self.orig_accel[idx] = self.orig_world[idx] * *xform;
|
||||
self.dir_inv_accel[idx] = Vector {
|
||||
co: Float4::splat(1.0) / (self.dir_world[idx] * *xform).co,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct Ray {
|
||||
|
@ -14,7 +105,7 @@ pub struct Ray {
|
|||
pub max_t: f32,
|
||||
pub time: f32,
|
||||
pub wavelength: f32,
|
||||
pub flags: u32,
|
||||
pub flags: FlagType,
|
||||
}
|
||||
|
||||
impl Ray {
|
||||
|
@ -56,7 +147,7 @@ pub struct AccelRay {
|
|||
pub dir_inv: Vector,
|
||||
pub max_t: f32,
|
||||
pub time: f32,
|
||||
pub flags: u32,
|
||||
pub flags: FlagType,
|
||||
pub id: u32,
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user