1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
//! The geometry module defines the Geometry trait implemented by
//! the various geometry in the ray tracer and provides some standard
//! geometry for rendering
//!
//! # Scene Usage Example
//! All geometry will appear within an object specification and requires the type
//! of geometry being specified along with any parameters for that geometry.
//!
//! An instance has a geometry along with additional information like a material
//! and transformation to place it in the world, see the instance module for more.
//!
//! ```json
//! "objects": [
//!     {
//!          "type": "The_Instance_Type",
//!          ...
//!          "geometry": {
//!              "type": "The_Geometry_Type",
//!              ...
//!          }
//!     },
//!     ...
//! ]
//! ```

use linalg::{Point, Vector, Ray, Normal};

pub use self::differential_geometry::DifferentialGeometry;
pub use self::intersection::Intersection;
pub use self::instance::Instance;
pub use self::sphere::Sphere;
pub use self::disk::Disk;
pub use self::rectangle::Rectangle;
pub use self::bbox::BBox;
pub use self::bvh::BVH;
pub use self::mesh::Mesh;
pub use self::animated_mesh::AnimatedMesh;
pub use self::receiver::Receiver;
pub use self::emitter::Emitter;

pub mod differential_geometry;
pub mod intersection;
pub mod instance;
pub mod sphere;
pub mod disk;
pub mod rectangle;
pub mod bbox;
pub mod bvh;
pub mod mesh;
pub mod animated_mesh;
pub mod receiver;
pub mod emitter;

/// Trait implemented by geometric primitives
pub trait Geometry {
    /// Test a ray for intersection with the geometry.
    /// The ray should have been previously transformed into the geometry's
    /// object space otherwise the test will be incorrect.
    /// Returns the differential geometry containing the hit information if the
    /// ray hit the object and set's the ray's `max_t` member accordingly
    fn intersect(&self, ray: &mut Ray) -> Option<DifferentialGeometry>;
}

/// Trait implemented by scene objects that can report an AABB describing their bounds
pub trait Boundable {
    /// Get an AABB reporting the object's bounds over the time period
    /// The default implementation assumes the object isn't animated and
    /// simply returns its bounds. This is kind of a hack to use
    /// the BVH for animated geomtry (instances) and non-animated geometry (triangles).
    fn bounds(&self, start: f32, end: f32) -> BBox;
    /// Have the object recompute its bounds for the time range. In the case
    /// of deforming geometry this can rebuild acceleration structures for example.
    fn update_deformation(&mut self, start: f32, end: f32) {}
}

/// Trait implemented by geometry that can sample a point on its surface
pub trait Sampleable {
    /// Uniformly sample a position and normal on the surface using the samples passed
    fn sample_uniform(&self, samples: &(f32, f32)) -> (Point, Normal);
    /// Sample the object using the probability density of the solid angle
    /// from `p` to the sampled point on the surface.
    /// Returns the sampled point and the surface normal at that point
    fn sample(&self, p: &Point, samples: &(f32, f32)) -> (Point, Normal);
    /// Return the surface area of the shape
    fn surface_area(&self) -> f32;
    /// Compute the PDF that the ray from `p` with direction `w_i` intersects
    /// the shape
    fn pdf(&self, p: &Point, w_i: &Vector) -> f32;
}

pub trait BoundableGeom: Geometry + Boundable {}
impl<T: ?Sized> BoundableGeom for T where T: Geometry + Boundable {}

pub trait SampleableGeom: Geometry + Boundable + Sampleable {}
impl<T: ?Sized> SampleableGeom for T where T: Geometry + Boundable + Sampleable {}