Update psychopath code to work with RMath changes.

This commit is contained in:
Nathan Vegdahl 2022-07-17 17:24:58 -07:00
parent 6dbdcba91a
commit d55ec9b025
9 changed files with 71 additions and 57 deletions

View File

@ -7,7 +7,7 @@ use std::{
use crate::{ use crate::{
lerp::{lerp, lerp_slice, Lerp}, lerp::{lerp, lerp_slice, Lerp},
math::{fast_minf32, Point, Vector, Xform, XformFull}, math::{fast_minf32, Point, Vector, Xform},
}; };
const BBOX_MAXT_ADJUST: f32 = 1.000_000_24; const BBOX_MAXT_ADJUST: f32 = 1.000_000_24;
@ -57,7 +57,7 @@ impl BBox {
// Creates a new BBox transformed from its local space to the // Creates a new BBox transformed from its local space to the
// given space. // given space.
#[must_use] #[must_use]
pub fn xform(&self, xform: &XformFull) -> BBox { pub fn xform(&self, xform: &Xform) -> BBox {
// BBox corners // BBox corners
let vs = [ let vs = [
Point::new(self.min.x(), self.min.y(), self.min.z()), Point::new(self.min.x(), self.min.y(), self.min.z()),
@ -73,7 +73,7 @@ impl BBox {
// Transform BBox corners and make new bbox // Transform BBox corners and make new bbox
let mut b = BBox::new(); let mut b = BBox::new();
for v in &vs { for v in &vs {
let v = v.xform(&xform); let v = v.xform(xform);
b.min = v.min(b.min); b.min = v.min(b.min);
b.max = v.max(b.max); b.max = v.max(b.max);
} }
@ -141,11 +141,7 @@ impl Lerp for BBox {
} }
} }
pub fn transform_bbox_slice_from( pub fn transform_bbox_slice_from(bbs_in: &[BBox], xforms: &[Xform], bbs_out: &mut Vec<BBox>) {
bbs_in: &[BBox],
xforms: &[Xform],
bbs_out: &mut Vec<BBox>,
) -> Result<(), ()> {
bbs_out.clear(); bbs_out.clear();
// Transform the bounding boxes // Transform the bounding boxes
@ -153,19 +149,17 @@ pub fn transform_bbox_slice_from(
bbs_out.extend_from_slice(bbs_in); bbs_out.extend_from_slice(bbs_in);
} else if bbs_in.len() == xforms.len() { } else if bbs_in.len() == xforms.len() {
for (bb, xf) in Iterator::zip(bbs_in.iter(), xforms.iter()) { for (bb, xf) in Iterator::zip(bbs_in.iter(), xforms.iter()) {
bbs_out.push(bb.xform(&xf.into_full().ok_or(())?)); bbs_out.push(bb.xform(&xf));
} }
} else if bbs_in.len() > xforms.len() { } else if bbs_in.len() > xforms.len() {
let s = (bbs_in.len() - 1) as f32; let s = (bbs_in.len() - 1) as f32;
for (i, bb) in bbs_in.iter().enumerate() { for (i, bb) in bbs_in.iter().enumerate() {
bbs_out.push(bb.xform(&lerp_slice(xforms, i as f32 / s).into_full().ok_or(())?)); bbs_out.push(bb.xform(&lerp_slice(xforms, i as f32 / s)));
} }
} else if bbs_in.len() < xforms.len() { } else if bbs_in.len() < xforms.len() {
let s = (xforms.len() - 1) as f32; let s = (xforms.len() - 1) as f32;
for (i, xf) in xforms.iter().enumerate() { for (i, xf) in xforms.iter().enumerate() {
bbs_out.push(lerp_slice(bbs_in, i as f32 / s).xform(&xf.into_full().ok_or(())?)); bbs_out.push(lerp_slice(bbs_in, i as f32 / s).xform(&xf));
} }
} }
Ok(())
} }

View File

@ -73,7 +73,7 @@ impl<'a> Camera<'a> {
pub fn generate_ray(&self, x: f32, y: f32, time: f32, wavelength: f32, u: f32, v: f32) -> Ray { pub fn generate_ray(&self, x: f32, y: f32, time: f32, wavelength: f32, u: f32, v: f32) -> Ray {
// Get time-interpolated camera settings // Get time-interpolated camera settings
let transform = lerp_slice(self.transforms, time).into_full_fast().unwrap(); let transform = lerp_slice(self.transforms, time).to_full_fast().unwrap();
let tfov = lerp_slice(self.tfovs, time); let tfov = lerp_slice(self.tfovs, time);
let aperture_radius = lerp_slice(self.aperture_radii, time); let aperture_radius = lerp_slice(self.aperture_radii, time);
let focus_distance = lerp_slice(self.focus_distances, time); let focus_distance = lerp_slice(self.focus_distances, time);

View File

@ -271,7 +271,7 @@ impl<'a> Surface for RectangleLight<'a> {
let dim = lerp_slice(self.dimensions, time); let dim = lerp_slice(self.dimensions, time);
let xform = lerp_slice(space, time); let xform = lerp_slice(space, time);
let space = if let Some(xform) = xform.into_full() { let space = if let Some(xform) = xform.to_full() {
xform xform
} else { } else {
return; return;

View File

@ -215,7 +215,7 @@ impl<'a> Surface for SphereLight<'a> {
let time = rays.time(ray_idx); let time = rays.time(ray_idx);
// Get the transform space // Get the transform space
let xform = if let Some(xform) = lerp_slice(space, time).into_full() { let xform = if let Some(xform) = lerp_slice(space, time).to_full() {
xform xform
} else { } else {
return; return;

View File

@ -3,8 +3,8 @@
use std::f32; use std::f32;
pub use rmath::{ pub use rmath::{
cross, cross_fast, dot, dot_fast, wide4::Float4, CrossProduct, DotProduct, Normal, Point, cross, cross_fast, dot, dot_fast, wide4::Float4, AsXform, CrossProduct, DotProduct, Normal,
Vector, Xform, XformFull, Point, Vector, Xform, XformFull,
}; };
/// Clamps a value between a min and max. /// Clamps a value between a min and max.

View File

@ -58,7 +58,7 @@ impl<'a> Assembly<'a> {
} = *intr } = *intr
{ {
let sel_xform = if !xform_stack.top().is_empty() { let sel_xform = if !xform_stack.top().is_empty() {
if let Some(xform) = lerp_slice(xform_stack.top(), time).into_full() { if let Some(xform) = lerp_slice(xform_stack.top(), time).to_full() {
xform xform
} else { } else {
return None; return None;
@ -98,7 +98,7 @@ impl<'a> Assembly<'a> {
Xform::identity() Xform::identity()
} }
} }
.into_full(); .to_full();
// Sample the light // Sample the light
if let Some(xform) = xform { if let Some(xform) = xform {
@ -390,7 +390,7 @@ impl<'a> AssemblyBuilder<'a> {
// Transform the bounding boxes, if necessary // Transform the bounding boxes, if necessary
if let Some((xstart, xend)) = inst.transform_indices { if let Some((xstart, xend)) = inst.transform_indices {
let xf = &self.xforms[xstart..xend]; let xf = &self.xforms[xstart..xend];
transform_bbox_slice_from(&bbs, xf, &mut bbs2).unwrap(); transform_bbox_slice_from(&bbs, xf, &mut bbs2);
} else { } else {
bbs2.clear(); bbs2.clear();
bbs2.extend(bbs); bbs2.extend(bbs);

View File

@ -9,7 +9,7 @@ use crate::{
bbox::BBox, bbox::BBox,
boundable::Boundable, boundable::Boundable,
lerp::lerp_slice, lerp::lerp_slice,
math::{cross, dot, Normal, Point, Xform, XformFull}, math::{cross, dot, Normal, Point, Xform},
ray::{RayBatch, RayStack}, ray::{RayBatch, RayStack},
shading::SurfaceClosure, shading::SurfaceClosure,
}; };
@ -154,13 +154,9 @@ impl<'a> MicropolyBatch<'a> {
) { ) {
// Precalculate transform for non-motion blur cases // Precalculate transform for non-motion blur cases
let static_mat_space = if space.len() == 1 { let static_mat_space = if space.len() == 1 {
if let Some(xform) = space[0].into_full() { space[0]
xform
} else {
return;
}
} else { } else {
XformFull::identity() Xform::identity()
}; };
self.accel self.accel
@ -209,11 +205,7 @@ impl<'a> MicropolyBatch<'a> {
// Calculate the ray space, if necessary. // Calculate the ray space, if necessary.
let mat_space = if space.len() > 1 { let mat_space = if space.len() > 1 {
// Per-ray transform, for motion blur // Per-ray transform, for motion blur
if let Some(xform) = lerp_slice(space, ray_time).into_full() { lerp_slice(space, ray_time)
xform
} else {
return;
}
} else { } else {
static_mat_space static_mat_space
}; };
@ -292,6 +284,13 @@ impl<'a> MicropolyBatch<'a> {
// Calculate intersection data if necessary. // Calculate intersection data if necessary.
if non_shadow_hit { if non_shadow_hit {
// Get the full space data.
let mat_space = if let Some(space) = mat_space.to_full() {
space
} else {
return;
};
let hit_tri = unsafe { hit_tri.assume_init() }; let hit_tri = unsafe { hit_tri.assume_init() };
let hit_tri_indices = unsafe { hit_tri_indices.assume_init() }; let hit_tri_indices = unsafe { hit_tri_indices.assume_init() };
let (t, b0, b1, b2) = unsafe { hit_tri_data.assume_init() }; let (t, b0, b1, b2) = unsafe { hit_tri_data.assume_init() };

View File

@ -7,7 +7,7 @@ use crate::{
bbox::BBox, bbox::BBox,
boundable::Boundable, boundable::Boundable,
lerp::lerp_slice, lerp::lerp_slice,
math::{cross, dot, Normal, Point, Xform, XformFull}, math::{cross, dot, Normal, Point, Xform},
ray::{RayBatch, RayStack}, ray::{RayBatch, RayStack},
shading::SurfaceShader, shading::SurfaceShader,
}; };
@ -132,13 +132,9 @@ impl<'a> Surface for TriangleMesh<'a> {
) { ) {
// Precalculate transform for non-motion blur cases // Precalculate transform for non-motion blur cases
let static_mat_space = if space.len() == 1 { let static_mat_space = if space.len() == 1 {
if let Some(xform) = lerp_slice(space, 0.0).into_full() { space[0]
xform
} else {
return;
}
} else { } else {
XformFull::identity() Xform::identity()
}; };
self.accel self.accel
@ -187,11 +183,7 @@ impl<'a> Surface for TriangleMesh<'a> {
// Calculate the ray space, if necessary. // Calculate the ray space, if necessary.
let mat_space = if space.len() > 1 { let mat_space = if space.len() > 1 {
// Per-ray transform, for motion blur // Per-ray transform, for motion blur
if let Some(xform) = lerp_slice(space, ray_time).into_full() { lerp_slice(space, ray_time)
xform
} else {
return;
}
} else { } else {
static_mat_space static_mat_space
}; };
@ -270,6 +262,13 @@ impl<'a> Surface for TriangleMesh<'a> {
// Calculate intersection data if necessary. // Calculate intersection data if necessary.
if non_shadow_hit { if non_shadow_hit {
// Get the full space data.
let mat_space = if let Some(space) = mat_space.to_full() {
space
} else {
return;
};
let hit_tri = unsafe { hit_tri.assume_init() }; let hit_tri = unsafe { hit_tri.assume_init() };
let (t, b0, b1, b2) = unsafe { hit_tri_data.assume_init() }; let (t, b0, b1, b2) = unsafe { hit_tri_data.assume_init() };

View File

@ -103,16 +103,27 @@ impl<'a> TracerInner<'a> {
// Do transforms // Do transforms
// TODO: re-divide rays based on direction (maybe?). // TODO: re-divide rays based on direction (maybe?).
let xforms = self.xform_stack.top(); let xforms = self.xform_stack.top();
let static_xform = if xforms.len() == 1 {
if let Some(xform) = xforms[0].to_full() {
Some(xform)
} else {
return;
}
} else if xforms.len() == 0 {
Some(XformFull::identity())
} else {
None
};
ray_stack.do_next_task(|ray_idx| { ray_stack.do_next_task(|ray_idx| {
let t = rays.time(ray_idx); let t = rays.time(ray_idx);
rays.update_local( rays.update_local(
ray_idx, ray_idx,
&if let Some(xform) = lerp_slice(xforms, t).into_full() { &static_xform.unwrap_or_else(|| {
xform lerp_slice(xforms, t).to_full().unwrap_or(
} else { // TODO: filter out ray instead.
// TODO: filter out ray instead. XformFull::identity(),
XformFull::identity() )
}, }),
); );
}); });
ray_stack.duplicate_next_task(); ray_stack.duplicate_next_task();
@ -142,17 +153,28 @@ impl<'a> TracerInner<'a> {
// Undo transforms // Undo transforms
let xforms = self.xform_stack.top(); let xforms = self.xform_stack.top();
let static_xform = if xforms.len() == 1 {
if let Some(xform) = xforms[0].to_full() {
Some(xform)
} else {
return;
}
} else if xforms.len() == 0 {
Some(XformFull::identity())
} else {
None
};
if !xforms.is_empty() { if !xforms.is_empty() {
ray_stack.pop_do_next_task(|ray_idx| { ray_stack.pop_do_next_task(|ray_idx| {
let t = rays.time(ray_idx); let t = rays.time(ray_idx);
rays.update_local( rays.update_local(
ray_idx, ray_idx,
&if let Some(xform) = lerp_slice(xforms, t).into_full() { &static_xform.unwrap_or_else(|| {
xform lerp_slice(xforms, t).to_full().unwrap_or(
} else { // TODO: filter out ray instead.
// TODO: filter out ray instead. XformFull::identity(),
XformFull::identity() )
}, }),
); );
}); });
} else { } else {