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
//! Defines the `DifferentialGeometry` type which is used to pass information
//! about the hit piece of geometry back from the intersection to the shading

use linalg::{self, Point, Normal, Vector};
use geometry::Geometry;

/// Stores information about a hit piece of geometry of some object in the scene
#[derive(Clone, Copy)]
pub struct DifferentialGeometry<'a> {
    /// The hit point
    pub p: Point,
    /// The shading normal
    pub n: Normal,
    /// The geometry normal
    pub ng: Normal,
    /// Surface parameterization u, v for texture mapping
    pub u: f32,
    pub v: f32,
    /// The intersection time
    pub time: f32,
    /// Derivative of the point with respect to the u parameterization coord of the surface
    pub dp_du: Vector,
    /// Derivative of the point with respect to the v parameterization coord of the surface
    pub dp_dv: Vector,
    /// The geometry that was hit
    pub geom: &'a (Geometry + 'a),
}

impl<'a> DifferentialGeometry<'a> {
    /// Setup the differential geometry. Note that the normal will be computed
    /// using cross(dp_du, dp_dv)
    pub fn new(p: &Point, ng: &Normal, u: f32, v: f32, time: f32,
               dp_du: &Vector, dp_dv: &Vector, geom: &'a (Geometry + 'a)) -> DifferentialGeometry<'a>
    {
        let n = linalg::cross(dp_du, dp_dv).normalized();
        DifferentialGeometry {
            p: *p,
            n: Normal::new(n.x, n.y, n.z),
            ng: ng.normalized(),
            u: u,
            v: v,
            time: time,
            dp_du: *dp_du,
            dp_dv: *dp_dv,
            geom: geom
        }
    }
    /// Setup the differential geometry using the normal passed for the surface normal
    pub fn with_normal(p: &Point, n: &Normal, u: f32, v: f32, time: f32,
               dp_du: &Vector, dp_dv: &Vector, geom: &'a (Geometry + 'a)) -> DifferentialGeometry<'a>
    {
        let nn = n.normalized();
        DifferentialGeometry {
            p: *p,
            n: nn,
            ng: nn,
            u: u,
            v: v,
            time: time,
            dp_du: *dp_du,
            dp_dv: *dp_dv,
            geom: geom
        }
    }
}