Add a bunch of documentation to the raycasting module

This commit is contained in:
Matthew Gordon 2020-04-23 23:58:35 -04:00
parent c1d8044eb8
commit 8ee1f3a004
2 changed files with 58 additions and 0 deletions

View File

@ -7,6 +7,7 @@ pub mod image;
pub mod integrators;
pub mod materials;
pub mod mesh;
/// Core raycasting and geometry primitives
pub mod raycasting;
pub mod realtype;
pub mod sampler;

View File

@ -20,13 +20,23 @@ pub use axis_aligned_bounding_box::BoundingBox;
pub mod bounding_volume_hierarchy;
pub use bounding_volume_hierarchy::BoundingVolumeHierarchy;
/// A ray, consisting or a start point and direction
///
/// This is the basic ray struct used to define things like a line-of-sight
/// going out from the camera of a reflection from a surface.
#[derive(Clone, Debug)]
pub struct Ray<T: Real> {
/// The start point of the ray
pub origin: Point3<T>,
/// The direction the ray goes in.
///
/// This vector should always be kept normalized
pub direction: Vector3<T>,
}
impl<T: Real> Ray<T> {
/// Create a new ray
pub fn new(origin: Point3<T>, direction: Vector3<T>) -> Ray<T> {
Ray {
origin,
@ -34,44 +44,91 @@ impl<T: Real> Ray<T> {
}
}
/// Return the point on the ray that is `t` units from the start
pub fn point_at(&self, t: T) -> Point3<T> {
self.origin + self.direction * t
}
/// Create a new ray by moving the original ray along it's direction by `amount`
///
/// `amount` is normally a very small number. This function is useful for ensuring
/// that rounding-errors don;t cause a reflection ray doesn't intersect with the point
/// it's reflected from.
pub fn bias(&self, amount: T) -> Ray<T> {
Ray::new(self.origin + self.direction * amount, self.direction)
}
}
/// Information about a ray-primitive intersection.
///
/// This struct is returned by [intersect()](Intersect::intersect) and contatins all the
/// information needed to evaluate the rendering function for that intersection.
#[derive(Debug)]
pub struct IntersectionInfo<T: Real> {
/// The distance between the ray origin and the intersection point
pub distance: T,
/// The intersection point
pub location: Point3<T>,
/// The surface normal at the intersection point
pub normal: Vector3<T>,
/// The surface tangent at the intersection point
///
/// Which surface tangent direction returned is dependent on the [Primitive](Primitive)
/// but should generally be smooth over any given surface
pub tangent: Vector3<T>,
/// Another surface tangent, perpendicular to `tangent`
///
/// The cross product or `normal` and `tangent`
pub cotangent: Vector3<T>,
/// The direction from the intersection point back towards the ray
///
/// Equal to `-ray.direction`
pub retro: Vector3<T>,
/// The [Material](crate::materials::Material) which describes the optical
/// properties of the intersected surface
pub material: Arc<dyn Material<T>>,
}
/// A geometric object that has a [Material](crate::materials::Material) and can be
/// intersected with a [Ray](Ray)
pub trait Intersect<T: Real>: Send + Sync {
/// Test if the ray intersects the object, and return information about the object and intersection.
fn intersect<'a>(&'a self, ray: &Ray<T>) -> Option<IntersectionInfo<T>>;
}
/// A geometric object that can be intersected with a ray
///
/// This is useful for objects that don't have materials (such as [BoundingBox](BoundingBox))
/// and as a (possibly) faster alternative to [Intersect](Intersect) when only a simple
/// intersection test is needed.
pub trait IntersectP<T: Real>: Send + Sync {
/// Test if the ray intersects the object, without calculating any extra information.
fn intersect(&self, ray: &Ray<T>) -> bool;
}
/// Any geometric object for which a [BoundingBox](BoundingBox) can be calculated
pub trait HasBoundingBox<T: Real>: Send + Sync {
/// The axis-aligned bounding box of the object
///
/// The object must fit entirely inside this box.
fn bounding_box(&self) -> BoundingBox<T>;
}
/// Any geometric object which can have an affine transformation applied to it
///
/// Used for moving, rotating or scaling primitives
pub trait Transform<T: Real>: Send + Sync {
/// Create a new object by applying the transformation to this object.
fn transform(&mut self, transformation: &Affine3<T>) -> &Self;
}
/// A basic geometric primitive such as a sphere or a triangle
pub trait Primitive<T: Real>: Intersect<T> + HasBoundingBox<T> {}
#[cfg(test)]