diff --git a/src/core/camera.rs b/src/core/camera.rs index 69a1011..0c9b625 100644 --- a/src/core/camera.rs +++ b/src/core/camera.rs @@ -1,3 +1,5 @@ +//! Camera related logic + use super::film::Film; use crate::{Point, Vector}; use serde::{Deserialize, Deserializer}; @@ -12,6 +14,24 @@ pub struct Camera { } impl Camera { + /// Creates a new `Camera`. + /// + /// # Examples + /// + /// ``` + /// # use pathtracer::core::Camera; + /// use pathtracer::{Point, Vector}; + /// + /// let cam = Camera::new( + /// Point::new(-1., 0., 0.), + /// Vector::new(1., 0., 0.), + /// Vector::new(0., 1., 0.), + /// 2. * f32::atan(1.), /* 90° in radian */ + /// 1., + /// 1080, + /// 1080, + /// ); + /// ``` pub fn new( origin: Point, forward: Vector, @@ -28,15 +48,73 @@ impl Camera { Camera { origin, film } } + /// Get the `Camera`'s [`Film`]. + /// + /// [`Film`]: ../film/struct.Film.html + /// + /// # Examples + /// + /// ``` + /// # use pathtracer::core::{Camera, Film}; + /// # + /// let cam = Camera::default(); + /// let film: &Film = cam.film(); + /// ``` pub fn film(&self) -> &Film { &self.film } + /// Get the `Camera`'s `Point` of origin. + /// + /// # Examples + /// + /// ``` + /// # use pathtracer::core::Camera; + /// # use pathtracer::Point; + /// # + /// let cam = Camera::default(); + /// let origin: &Point = cam.origin(); + /// ``` pub fn origin(&self) -> &Point { &self.origin } } +impl Default for Camera { + /// Returns a `Camera` with a 1080x1080 `Film` + /// + /// # Examples + /// + /// ``` + /// # use pathtracer::core::Camera; + /// use pathtracer::{Point, Vector}; + /// + /// let default = Camera::default(); + /// let new = Camera::new( + /// Point::new(0., 0., 0.), + /// Vector::new(1., 0., 0.), + /// Vector::new(0., 1., 0.), + /// 2. * f32::atan(1.), /* 90° in radian */ + /// 1., + /// 1080, + /// 1080, + /// ); + /// + /// assert_eq!(default, new); + /// ``` + fn default() -> Self { + Self::new( + Point::origin(), + Vector::new(1., 0., 0.), + Vector::new(0., 1., 0.), + 2. * f32::atan(1.), /* 90° in radian */ + 1., + 1080, + 1080, + ) + } +} + #[derive(Debug, Deserialize)] struct SerializedCamera { origin: Point, diff --git a/src/core/color.rs b/src/core/color.rs index b1e9475..5a90730 100644 --- a/src/core/color.rs +++ b/src/core/color.rs @@ -1,3 +1,5 @@ +//! Color definition and operations + use derive_more::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Sub, SubAssign, Sum}; use serde::Deserialize; use std::ops::{Div, DivAssign, Mul, MulAssign}; @@ -19,12 +21,34 @@ use std::ops::{Div, DivAssign, Mul, MulAssign}; )] /// A structure to represent operations in the linear RGB colorspace. pub struct LinearColor { + /// The color's red component pub r: f32, + /// The color's green component pub g: f32, + /// The color's blue component pub b: f32, } impl LinearColor { + /// Creates the color black. + /// + /// All 3 components are set to 0. + /// + /// # Examples + /// + /// ``` + /// # use pathtracer::core::LinearColor; + /// # + /// let black = LinearColor::black(); + /// assert_eq!( + /// black, + /// LinearColor { + /// r: 0., + /// g: 0., + /// b: 0. + /// } + /// ); + /// ``` pub fn black() -> Self { LinearColor { r: 0., @@ -33,11 +57,30 @@ impl LinearColor { } } + /// Creates a new `Color`. + /// + /// # Examples + /// + /// ``` + /// # use pathtracer::core::LinearColor; + /// # + /// let color = LinearColor::new(1.0, 0.0, 0.0); // bright red! + /// ``` pub fn new(r: f32, g: f32, b: f32) -> Self { LinearColor { r, g, b } } #[must_use] + /// Clamps the color's RGB components between 0.0 and 1.0. + /// + /// # Examples + /// + /// ``` + /// # use pathtracer::core::LinearColor; + /// # + /// let color = LinearColor::new(1.5, -1.0, 0.5); + /// assert_eq!(color.clamp(), LinearColor::new(1.0, 0.0, 0.5)) + /// ``` pub fn clamp(self) -> Self { fn clamp(v: f32) -> f32 { if v > 1. { @@ -109,19 +152,6 @@ impl From for image::Rgb { mod test { use super::*; - #[test] - fn black_is_black() { - let black = LinearColor::black(); - assert_eq!( - black, - LinearColor { - r: 0., - g: 0., - b: 0. - } - ) - } - #[test] fn default_is_black() { assert_eq!(::default(), LinearColor::black()) @@ -304,12 +334,6 @@ mod test { ); } - #[test] - fn clamp_works() { - let color = LinearColor::new(1.5, -1., 0.5); - assert_eq!(color.clamp(), LinearColor::new(1., 0., 0.5)) - } - #[test] fn deserialization_works() { let yaml = "{r: 1.0, g: 0.5, b: 0.2}"; diff --git a/src/core/film.rs b/src/core/film.rs index 82659f0..d7fa7c7 100644 --- a/src/core/film.rs +++ b/src/core/film.rs @@ -1,3 +1,5 @@ +//! Camera film logic + use crate::{Point, Vector}; /// Represent an abstract camera film, to know where each pixel is in space. @@ -11,6 +13,23 @@ pub struct Film { } impl Film { + /// Creates a new `Film`. + /// + /// # Examples + /// + /// ``` + /// # use pathtracer::core::Film; + /// # use pathtracer::{Point, Vector}; + /// # + /// let film = Film::new( + /// 1080, + /// 1080, + /// 10.0, + /// Point::origin(), + /// Vector::new(0.0, 1.0, 0.0), + /// Vector::new(1.0, 0.0, 0.0) + /// ); + /// ``` pub fn new(x: u32, y: u32, screen_size: f32, center: Point, up: Vector, right: Vector) -> Self { let (x_size, y_size) = if x > y { (screen_size, screen_size * y as f32 / x as f32) @@ -26,30 +45,103 @@ impl Film { } } + /// Get the `Film`'s width. + /// + /// # Examples + /// + /// ``` + /// # use pathtracer::core::Film; + /// # + /// let film = Film::default(); + /// let width: u32 = film.width(); + /// ``` pub fn width(&self) -> u32 { self.x } + /// Get the `Film`'s height. + /// + /// # Examples + /// + /// ``` + /// # use pathtracer::core::Film; + /// # + /// let film = Film::default(); + /// let height: u32 = film.height(); + /// ``` pub fn height(&self) -> u32 { self.y } + /// Get a ratio of the pixel's position on the screen. + /// + /// # Examples + /// + /// ``` + /// # use pathtracer::core::Film; + /// # + /// let film = Film::default(); // 1080x1080 film, width of 1.0 + /// let (x, y) = film.pixel_ratio(108.0, 972.0); + /// assert_eq!(x, 0.1); + /// assert_eq!(y, 0.9); + /// ``` pub fn pixel_ratio(&self, x: f32, y: f32) -> (f32, f32) { (x / self.x as f32, y / self.y as f32) } + /// Get a pixel's absolute position from a relative screen ratio. + /// + /// # Examples + /// + /// ``` + /// # use pathtracer::core::Film; + /// use pathtracer::Point; + /// + /// let film = Film::default(); // 1080x1080 film, width of 1.0 + /// let (x, y) = film.pixel_ratio(108.0, 1080.0); + /// let pos: Point = film.pixel_at_ratio(x, y); + /// assert_eq!(pos, Point::new(-0.4, -0.5, 0.0)); + /// ``` pub fn pixel_at_ratio(&self, x: f32, y: f32) -> Point { let delt_x = x - 0.5; let delt_y = 0.5 - y; self.center + self.ratio_right * delt_x + self.ratio_up * delt_y } + /// Get a pixel's absolute position from screen coordinates. + /// + /// # Examples + /// + /// ``` + /// # use pathtracer::core::Film; + /// use pathtracer::Point; + /// + /// let film = Film::default(); // 1080x1080 film, width of 1.0 + /// let pos: Point = film.pixel_at_coord(108, 1080); + /// assert_eq!(pos, Point::new(-0.4, -0.5, 0.0)); + /// ``` pub fn pixel_at_coord(&self, x: u32, y: u32) -> Point { let (x, y) = self.pixel_ratio(x as f32, y as f32); self.pixel_at_ratio(x, y) } } +impl Default for Film { + /// Creates a simple 1080x1080 `Film`. + /// + /// The screen size is 1.0, and the screen is centered at the origin. + fn default() -> Self { + Film::new( + 1080, + 1080, + 1.0, + Point::origin(), + Vector::new(0.0, 1.0, 0.0), + Vector::new(1.0, 0.0, 0.0), + ) + } +} + #[cfg(test)] mod test { use super::*; diff --git a/src/core/light_properties.rs b/src/core/light_properties.rs index c76cab9..9cc6bcc 100644 --- a/src/core/light_properties.rs +++ b/src/core/light_properties.rs @@ -1,9 +1,13 @@ +//! Light property coefficients (diffuse, specular, transparency, reflectivity...) + use super::color::LinearColor; use serde::Deserialize; #[derive(Debug, PartialEq, Clone, Deserialize)] #[serde(untagged)] +/// This enum stores the reflectivity or transparency information. pub enum ReflTransEnum { + /// Transparence properties. Transparency { /// The transparency coefficient. #[serde(rename = "transparency")] @@ -11,6 +15,7 @@ pub enum ReflTransEnum { /// The diffraction index. index: f32, }, + /// Reflectivity properties. Reflectivity { /// The reflectivity coefficient. #[serde(rename = "reflectivity")] @@ -31,6 +36,20 @@ pub struct LightProperties { } impl LightProperties { + /// Creates a new `LightProperties` struct. + /// + /// # Examples + /// + /// ``` + /// # use pathtracer::core::light_properties::{LightProperties, ReflTransEnum}; + /// # use pathtracer::core::color::LinearColor; + /// # + /// let lp = LightProperties::new( + /// LinearColor::new(0.25, 0.5, 1.), + /// LinearColor::new(0.75, 0.375, 0.125), + /// Some(ReflTransEnum::Reflectivity { coef: 0.5 }), + /// ); + /// ``` pub fn new( diffuse: LinearColor, specular: LinearColor, diff --git a/src/core/mod.rs b/src/core/mod.rs index e516fb5..d609ac7 100644 --- a/src/core/mod.rs +++ b/src/core/mod.rs @@ -1,3 +1,5 @@ +//! Core pathtracing pipeline elements + pub mod camera; pub use camera::*; diff --git a/src/lib.rs b/src/lib.rs index 02d90a0..d3e939a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,7 +1,14 @@ +#![warn(missing_docs)] + +//! A pathtracing crate + use bvh::nalgebra::{Point2, Point3, Vector3}; +/// A 2D point coordinate pub type Point2D = Point2; +/// A 3D point coordinate pub type Point = Point3; +/// A 3D vector pub type Vector = Vector3; pub mod core; diff --git a/src/light/ambient_light.rs b/src/light/ambient_light.rs index a6668a7..6e8a75f 100644 --- a/src/light/ambient_light.rs +++ b/src/light/ambient_light.rs @@ -10,6 +10,16 @@ pub struct AmbientLight { } impl AmbientLight { + /// Creates a new `AmbientLight`. + /// + /// # Examples + /// + /// ``` + /// # use pathtracer::light::AmbientLight; + /// # use pathtracer::core::color::LinearColor; + /// # + /// let amb_light = AmbientLight::new(LinearColor::new(1.0, 0.0, 1.0)); + /// ``` pub fn new(color: LinearColor) -> Self { AmbientLight { color } } diff --git a/src/light/directional_light.rs b/src/light/directional_light.rs index 0168340..a3a44a0 100644 --- a/src/light/directional_light.rs +++ b/src/light/directional_light.rs @@ -12,6 +12,20 @@ pub struct DirectionalLight { } impl DirectionalLight { + /// Creates a new `DirectionalLight`. + /// + /// # Examples + /// + /// ``` + /// # use pathtracer::light::DirectionalLight; + /// # use pathtracer::core::color::LinearColor; + /// # use pathtracer::Vector; + /// # + /// let dir_light = DirectionalLight::new( + /// Vector::new(1.0, 0.0, 0.0), + /// LinearColor::new(1.0, 0.0, 1.0), + /// ); + /// ``` pub fn new(direction: Vector, color: LinearColor) -> Self { DirectionalLight { direction: direction.normalize(), diff --git a/src/light/mod.rs b/src/light/mod.rs index 2096101..10f6e55 100644 --- a/src/light/mod.rs +++ b/src/light/mod.rs @@ -1,3 +1,5 @@ +//! Various light implementations + use super::core::LinearColor; use super::{Point, Vector}; @@ -13,14 +15,14 @@ pub trait SpatialLight: Light { fn to_source(&self, origin: &Point) -> (Vector, f32); } -pub mod ambient_light; +mod ambient_light; pub use ambient_light::*; -pub mod directional_light; +mod directional_light; pub use directional_light::*; -pub mod point_light; +mod point_light; pub use point_light::*; -pub mod spot_light; +mod spot_light; pub use spot_light::*; diff --git a/src/light/point_light.rs b/src/light/point_light.rs index 281c99c..3fb00d5 100644 --- a/src/light/point_light.rs +++ b/src/light/point_light.rs @@ -11,6 +11,20 @@ pub struct PointLight { } impl PointLight { + /// Creates a new `PointLight`. + /// + /// # Examples + /// + /// ``` + /// # use pathtracer::light::PointLight; + /// # use pathtracer::core::color::LinearColor; + /// # use pathtracer::Point; + /// # + /// let dir_light = PointLight::new( + /// Point::origin(), + /// LinearColor::new(1.0, 0.0, 1.0), + /// ); + /// ``` pub fn new(position: Point, color: LinearColor) -> Self { PointLight { position, color } } diff --git a/src/light/spot_light.rs b/src/light/spot_light.rs index 9676ce7..9fa80ff 100644 --- a/src/light/spot_light.rs +++ b/src/light/spot_light.rs @@ -4,6 +4,7 @@ use crate::{Point, Vector}; use serde::{Deserialize, Deserializer}; /// Represent a light emanating from a directed light-source, outputting rays in a cone. +/// /// The illumination cone cannot have an FOV over 180°. #[derive(Debug, PartialEq)] pub struct SpotLight { diff --git a/src/material/mod.rs b/src/material/mod.rs index 8be6f84..699eac3 100644 --- a/src/material/mod.rs +++ b/src/material/mod.rs @@ -1,3 +1,5 @@ +//! Various material implementations + use super::core::LightProperties; use super::Point2D; use serde::Deserialize; @@ -5,6 +7,7 @@ use serde::Deserialize; /// All the existing `Material` implementation. #[serde(tag = "type")] #[serde(rename_all = "lowercase")] +#[allow(missing_docs)] #[enum_dispatch::enum_dispatch] #[derive(Debug, PartialEq, Deserialize)] pub enum MaterialEnum { @@ -19,5 +22,5 @@ pub trait Material: std::fmt::Debug { fn properties(&self, point: Point2D) -> LightProperties; } -pub mod uniform; +mod uniform; pub use uniform::*; diff --git a/src/material/uniform.rs b/src/material/uniform.rs index 73060b7..93fff05 100644 --- a/src/material/uniform.rs +++ b/src/material/uniform.rs @@ -11,6 +11,22 @@ pub struct UniformMaterial { } impl UniformMaterial { + /// Creates a new `UniformMaterial`. + /// + /// # Examples + /// + /// ``` + /// # use pathtracer::material::UniformMaterial; + /// # use pathtracer::core::{LightProperties, LinearColor}; + /// # + /// let uni_mat = UniformMaterial::new( + /// LightProperties::new( + /// LinearColor::new(1.0, 0.0, 0.0), // diffuse component + /// LinearColor::new(0.0, 0.0, 0.0), // specular component + /// None, + /// ), + /// ); + /// ``` pub fn new(properties: LightProperties) -> Self { UniformMaterial { properties } } diff --git a/src/render/light_aggregate.rs b/src/render/light_aggregate.rs index 03d3fbf..26af7cc 100644 --- a/src/render/light_aggregate.rs +++ b/src/render/light_aggregate.rs @@ -1,8 +1,11 @@ +//! Utility module to compute overall illumination + use crate::light::*; use serde::Deserialize; use std::iter::Iterator; #[derive(Debug, PartialEq, Deserialize)] +/// A struct centralizing the light computation logic. pub struct LightAggregate { #[serde(default)] ambients: Vec, @@ -15,10 +18,39 @@ pub struct LightAggregate { } impl LightAggregate { + /// Creates a new empty `LightAggregate`. + /// + /// # Examples + /// + /// ``` + /// # use pathtracer::render::LightAggregate; + /// # + /// let la = LightAggregate::empty(); + /// assert_eq!(la.ambient_lights_iter().count(), 0); + /// assert_eq!(la.spatial_lights_iter().count(), 0); + /// ``` pub fn empty() -> Self { LightAggregate::new(vec![], vec![], vec![], vec![]) } + /// Creates a new `LightAggregate` from `Vec`s of [`Light`]s. + /// + /// [`Light`]: ../../light/trait.Light.html + /// + /// # Examples + /// + /// ``` + /// # use pathtracer::render::LightAggregate; + /// # + /// let la = LightAggregate::new( + /// Vec::new(), + /// Vec::new(), + /// Vec::new(), + /// Vec::new(), + /// ); + /// assert_eq!(la.ambient_lights_iter().count(), 0); + /// assert_eq!(la.spatial_lights_iter().count(), 0); + /// ``` pub fn new( ambients: Vec, directionals: Vec, @@ -33,10 +65,21 @@ impl LightAggregate { } } + /// Returns an iterator over the aggregate's [`AmbientLight`]s. + /// + /// [`AmbientLight`]: ../../light/ambient_light/struct.AmbientLight.html pub fn ambient_lights_iter(&self) -> impl Iterator { self.ambients.iter().map(|l| l as &dyn Light) } + /// Returns an iterator over the aggregate's [`SpatialLight`]s. + /// + /// This simply merges iterators over [`DirectionalLight`], [`PointLight`] and [`SpotLight`]. + /// + /// [`SpatialLight`]: ../../light/trait.SpatialLight.html + /// [`DirectionalLight`]: ../../light/directional_light/struct.DirectionalLight.html + /// [`PointLight`]: ../../light/point_light/struct.PointLight.html + /// [`Spotight`]: ../../light/spot_light/struct.Spotight.html pub fn spatial_lights_iter(&self) -> impl Iterator { self.directionals .iter() diff --git a/src/render/mod.rs b/src/render/mod.rs index 257c216..769c70c 100644 --- a/src/render/mod.rs +++ b/src/render/mod.rs @@ -1,3 +1,5 @@ +//! Rendering logic + pub mod light_aggregate; pub use light_aggregate::*; diff --git a/src/render/object.rs b/src/render/object.rs index c208c0e..7f09fdc 100644 --- a/src/render/object.rs +++ b/src/render/object.rs @@ -1,3 +1,5 @@ +//! Logic for the scene objects + use crate::material::MaterialEnum; use crate::shape::{Shape, ShapeEnum}; use crate::texture::TextureEnum; @@ -8,14 +10,42 @@ use serde::Deserialize; /// An object being rendered in the scene. #[derive(Debug, PartialEq, Deserialize)] pub struct Object { + /// The `Object`'s physical shape pub shape: ShapeEnum, + /// The `Object`'s material pub material: MaterialEnum, + /// The `Object`'s texture pub texture: TextureEnum, #[serde(skip_deserializing)] + /// Index inside the `BVH` index: usize, } impl Object { + /// Creates a new `Object`. + /// + /// # Examples + /// + /// ``` + /// # use pathtracer::core::{LightProperties, LinearColor}; + /// # use pathtracer::material::UniformMaterial; + /// # use pathtracer::render::Object; + /// # use pathtracer::shape::Sphere; + /// # use pathtracer::texture::UniformTexture; + /// # use pathtracer::Point; + /// # + /// let obj = Object::new( + /// Sphere::new(Point::origin(), 1.0).into(), + /// UniformMaterial::new( + /// LightProperties::new( + /// LinearColor::new(1.0, 0.0, 0.0), // diffuse component + /// LinearColor::new(0.0, 0.0, 0.0), // specular component + /// None, + /// ), + /// ).into(), + /// UniformTexture::new(LinearColor::new(0.5, 0.5, 0.5)).into(), + /// ); + /// ``` pub fn new(shape: ShapeEnum, material: MaterialEnum, texture: TextureEnum) -> Self { Object { shape, diff --git a/src/render/scene.rs b/src/render/scene.rs index 399771e..d1a755f 100644 --- a/src/render/scene.rs +++ b/src/render/scene.rs @@ -1,3 +1,5 @@ +//! Scene rendering logic + use std::cmp::Ordering; use super::{light_aggregate::LightAggregate, object::Object}; @@ -26,6 +28,39 @@ pub struct Scene { } impl Scene { + /// Creates a new `Scene`. + /// + /// # Examples + /// + /// ``` + /// # use pathtracer::core::{Camera, LightProperties, LinearColor}; + /// # use pathtracer::material::UniformMaterial; + /// # use pathtracer::render::{LightAggregate, Object, Scene}; + /// # use pathtracer::shape::Sphere; + /// # use pathtracer::texture::UniformTexture; + /// # use pathtracer::Point; + /// # + /// let scene = Scene::new( + /// Camera::default(), + /// LightAggregate::empty(), + /// vec![ + /// Object::new( + /// Sphere::new(Point::origin(), 1.0).into(), + /// UniformMaterial::new( + /// LightProperties::new( + /// LinearColor::new(1.0, 0.0, 0.0), // diffuse component + /// LinearColor::new(0.0, 0.0, 0.0), // specular component + /// None, + /// ), + /// ).into(), + /// UniformTexture::new(LinearColor::new(0.5, 0.5, 0.5)).into(), + /// ), + /// ], + /// 5, // aliasing limit + /// 3, // reflection recursion limit + /// 0.0, // diffraction index + /// ); + /// ``` pub fn new( camera: Camera, lights: LightAggregate, @@ -34,6 +69,7 @@ impl Scene { reflection_limit: u32, diffraction_index: f32, ) -> Self { + // NOTE(Antoine): fun fact: BVH::build stack overflows when given an empty slice :) let bvh = BVH::build(&mut objects); Scene { camera, @@ -338,4 +374,20 @@ mod test { let _: Scene = serde_yaml::from_str(yaml).unwrap(); // FIXME: actually test the equality ? } + + #[test] + #[ignore] // stack overflow because of BVH :( + fn bvh_fails() { + use crate::core::Camera; + use crate::render::{LightAggregate, Scene}; + + let _scene = Scene::new( + Camera::default(), + LightAggregate::empty(), + Vec::new(), // Objects list + 5, // aliasing limit + 3, // reflection recursion limit + 0.0, // diffraction index + ); + } } diff --git a/src/serialize/coefficient.rs b/src/serialize/coefficient.rs index 1b37875..229871a 100644 --- a/src/serialize/coefficient.rs +++ b/src/serialize/coefficient.rs @@ -1,3 +1,6 @@ +//! Helper functions deserialize coefficients. + +/// Returns the identity for a f32, i.e. 1.0. pub fn default_identity() -> f32 { 1. } diff --git a/src/serialize/mod.rs b/src/serialize/mod.rs index 1b8a1b0..9b6b8e4 100644 --- a/src/serialize/mod.rs +++ b/src/serialize/mod.rs @@ -1,3 +1,5 @@ +//! Helper functions to help scene (de)serialization + pub mod vector; pub use vector::*; diff --git a/src/serialize/vector.rs b/src/serialize/vector.rs index 3a354bf..00d40ab 100644 --- a/src/serialize/vector.rs +++ b/src/serialize/vector.rs @@ -1,6 +1,11 @@ +//! Helper functions to deserialize `Vector` values. + use crate::Vector; use serde::de::{Deserialize, Deserializer}; +/// Deserialize a vector. +/// +/// Needs a custom implementation to make sur the vector is normalized when deserialized. pub fn vector_normalizer<'de, D>(deserializer: D) -> Result where D: Deserializer<'de>, diff --git a/src/shape/mod.rs b/src/shape/mod.rs index c8b79cd..c820dbd 100644 --- a/src/shape/mod.rs +++ b/src/shape/mod.rs @@ -1,3 +1,5 @@ +//! Various shape implementations + use super::{Point, Point2D, Vector}; use bvh::{ aabb::{Bounded, AABB}, @@ -8,6 +10,7 @@ use serde::Deserialize; /// All the existing `Shape` implementation. #[serde(tag = "type")] #[serde(rename_all = "lowercase")] +#[allow(missing_docs)] #[enum_dispatch::enum_dispatch] #[derive(Debug, PartialEq, Deserialize)] pub enum ShapeEnum { @@ -34,8 +37,8 @@ impl Bounded for dyn Shape { } } -pub mod sphere; +mod sphere; pub use sphere::*; -pub mod triangle; +mod triangle; pub use triangle::*; diff --git a/src/shape/triangle.rs b/src/shape/triangle.rs index a1a8fd5..a78af0e 100644 --- a/src/shape/triangle.rs +++ b/src/shape/triangle.rs @@ -13,6 +13,22 @@ pub struct Triangle { } impl Triangle { + /// Creates a new `Triangle` from 3 [`Point`]s. + /// + /// [`Point`]: ../../type.Point.html + /// + /// # Examples + /// + /// ``` + /// # use pathtracer::shape::Triangle; + /// # use pathtracer::Point; + /// # + /// let t = Triangle::new( + /// Point::new(1.0, 0.0, 0.0), + /// Point::new(0.0, 1.0, 0.0), + /// Point::new(0.0, 0.0, 1.0), + /// ); + /// ``` pub fn new(c0: Point, c1: Point, c2: Point) -> Self { Triangle { c0, diff --git a/src/texture/mod.rs b/src/texture/mod.rs index 64aa44d..ca99154 100644 --- a/src/texture/mod.rs +++ b/src/texture/mod.rs @@ -1,3 +1,5 @@ +//! Various texture implementations + use super::core::LinearColor; use super::Point2D; use serde::Deserialize; @@ -5,6 +7,7 @@ use serde::Deserialize; /// All the existing `Texture` implementation. #[serde(tag = "type")] #[serde(rename_all = "lowercase")] +#[allow(missing_docs)] #[enum_dispatch::enum_dispatch] #[derive(Debug, PartialEq, Deserialize)] pub enum TextureEnum { @@ -19,5 +22,5 @@ pub trait Texture: std::fmt::Debug { fn texel_color(&self, point: Point2D) -> LinearColor; } -pub mod uniform; +mod uniform; pub use uniform::*; diff --git a/src/texture/uniform.rs b/src/texture/uniform.rs index 2f1d587..ff986d3 100644 --- a/src/texture/uniform.rs +++ b/src/texture/uniform.rs @@ -10,6 +10,16 @@ pub struct UniformTexture { } impl UniformTexture { + /// Creates a new `UniformTexture`. + /// + /// # Examples + /// + /// ``` + /// # use pathtracer::texture::UniformTexture; + /// # use pathtracer::core::LinearColor; + /// # + /// let uni_text = UniformTexture::new(LinearColor::new(0.5, 0.5, 0.5)); + /// ``` pub fn new(color: LinearColor) -> Self { UniformTexture { color } }