psychopath/src/surface/mod.rs

93 lines
2.3 KiB
Rust

#![allow(dead_code)]
// pub mod micropoly_batch;
pub mod bilinear_patch;
pub mod micropoly_batch;
pub mod triangle;
pub mod triangle_mesh;
use std::fmt::Debug;
use crate::{
boundable::Boundable,
math::{Matrix4x4, Normal, Point, Vector},
ray::{RayBatch, RayStack},
shading::surface_closure::SurfaceClosure,
shading::SurfaceShader,
};
const MAX_EDGE_DICE: u32 = 128;
pub trait Surface: Boundable + Debug + Sync {
fn intersect_rays(
&self,
rays: &mut RayBatch,
ray_stack: &mut RayStack,
isects: &mut [SurfaceIntersection],
shader: &dyn SurfaceShader,
space: &[Matrix4x4],
);
}
pub trait Splitable: Copy {
/// Splits the surface into two pieces if necessary.
fn split<F>(&self, metric: F) -> Option<(Self, Self)>
where
F: Fn(Point, Point) -> f32;
}
#[derive(Debug, Copy, Clone)]
pub enum PointOrder {
AsIs,
Flip,
}
pub fn point_order(p1: Point, p2: Point) -> PointOrder {
let max_diff = {
let v = p2 - p1;
let v_abs = v.abs();
let mut diff = v.x();
let mut diff_abs = v_abs.x();
if v_abs.y() > diff_abs {
diff = v.y();
diff_abs = v_abs.y();
}
if v_abs.z() > diff_abs {
diff = v.z();
}
diff
};
if max_diff <= 0.0 {
PointOrder::AsIs
} else {
PointOrder::Flip
}
}
#[derive(Debug, Copy, Clone)]
#[allow(clippy::large_enum_variant)]
pub enum SurfaceIntersection {
Miss,
Occlude,
Hit {
intersection_data: SurfaceIntersectionData,
closure: SurfaceClosure,
},
}
#[derive(Debug, Copy, Clone)]
pub struct SurfaceIntersectionData {
pub incoming: Vector, // Direction of the incoming ray
pub pos: Point, // Position of the intersection
pub pos_err: f32, // Error magnitude of the intersection position. Imagine
// a cube centered around `pos` with dimensions of `2 * pos_err`.
pub nor: Normal, // Shading normal
pub nor_g: Normal, // True geometric normal
pub local_space: Matrix4x4, // Matrix from global space to local space
pub t: f32, // Ray t-value at the intersection point
pub sample_pdf: f32, // The PDF of getting this point by explicitly sampling the surface
}