Add a bunch of documentation to the raycasting module
This commit is contained in:
parent
c1d8044eb8
commit
8ee1f3a004
|
|
@ -7,6 +7,7 @@ pub mod image;
|
||||||
pub mod integrators;
|
pub mod integrators;
|
||||||
pub mod materials;
|
pub mod materials;
|
||||||
pub mod mesh;
|
pub mod mesh;
|
||||||
|
/// Core raycasting and geometry primitives
|
||||||
pub mod raycasting;
|
pub mod raycasting;
|
||||||
pub mod realtype;
|
pub mod realtype;
|
||||||
pub mod sampler;
|
pub mod sampler;
|
||||||
|
|
|
||||||
|
|
@ -20,13 +20,23 @@ pub use axis_aligned_bounding_box::BoundingBox;
|
||||||
pub mod bounding_volume_hierarchy;
|
pub mod bounding_volume_hierarchy;
|
||||||
pub use bounding_volume_hierarchy::BoundingVolumeHierarchy;
|
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)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct Ray<T: Real> {
|
pub struct Ray<T: Real> {
|
||||||
|
/// The start point of the ray
|
||||||
pub origin: Point3<T>,
|
pub origin: Point3<T>,
|
||||||
|
|
||||||
|
/// The direction the ray goes in.
|
||||||
|
///
|
||||||
|
/// This vector should always be kept normalized
|
||||||
pub direction: Vector3<T>,
|
pub direction: Vector3<T>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Real> Ray<T> {
|
impl<T: Real> Ray<T> {
|
||||||
|
/// Create a new ray
|
||||||
pub fn new(origin: Point3<T>, direction: Vector3<T>) -> Ray<T> {
|
pub fn new(origin: Point3<T>, direction: Vector3<T>) -> Ray<T> {
|
||||||
Ray {
|
Ray {
|
||||||
origin,
|
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> {
|
pub fn point_at(&self, t: T) -> Point3<T> {
|
||||||
self.origin + self.direction * 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> {
|
pub fn bias(&self, amount: T) -> Ray<T> {
|
||||||
Ray::new(self.origin + self.direction * amount, self.direction)
|
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)]
|
#[derive(Debug)]
|
||||||
pub struct IntersectionInfo<T: Real> {
|
pub struct IntersectionInfo<T: Real> {
|
||||||
|
/// The distance between the ray origin and the intersection point
|
||||||
pub distance: T,
|
pub distance: T,
|
||||||
|
|
||||||
|
/// The intersection point
|
||||||
pub location: Point3<T>,
|
pub location: Point3<T>,
|
||||||
|
|
||||||
|
/// The surface normal at the intersection point
|
||||||
pub normal: Vector3<T>,
|
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>,
|
pub tangent: Vector3<T>,
|
||||||
|
|
||||||
|
/// Another surface tangent, perpendicular to `tangent`
|
||||||
|
///
|
||||||
|
/// The cross product or `normal` and `tangent`
|
||||||
pub cotangent: Vector3<T>,
|
pub cotangent: Vector3<T>,
|
||||||
|
|
||||||
|
/// The direction from the intersection point back towards the ray
|
||||||
|
///
|
||||||
|
/// Equal to `-ray.direction`
|
||||||
pub retro: Vector3<T>,
|
pub retro: Vector3<T>,
|
||||||
|
|
||||||
|
/// The [Material](crate::materials::Material) which describes the optical
|
||||||
|
/// properties of the intersected surface
|
||||||
pub material: Arc<dyn Material<T>>,
|
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 {
|
pub trait Intersect<T: Real>: Send + Sync {
|
||||||
/// Test if the ray intersects the object, and return information about the object and intersection.
|
/// 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>>;
|
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 {
|
pub trait IntersectP<T: Real>: Send + Sync {
|
||||||
/// Test if the ray intersects the object, without calculating any extra information.
|
/// Test if the ray intersects the object, without calculating any extra information.
|
||||||
fn intersect(&self, ray: &Ray<T>) -> bool;
|
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 {
|
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>;
|
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 {
|
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;
|
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> {}
|
pub trait Primitive<T: Real>: Intersect<T> + HasBoundingBox<T> {}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue