SurfacePoint.h

Go to the documentation of this file.
00001 /**<!-------------------------------------------------------------------->
00002    @class  SurfacePoint
00003    @author Travis Fischer (fisch0920@gmail.com)
00004    @date   Fall 2008
00005    
00006    @brief
00007       Core class representing a single point on the surface of a Shape, 
00008    which was likely generated by either an intersection with a Ray or random 
00009    sampling on the surface of the shape.  SurfacePoint encapsulates all of the 
00010    different information about a surface point and is used for shading 
00011    evaluation (BSDF), emittance evaluation (Emitter), and so-called importance 
00012    evaluation (Sensor).
00013    
00014       Milton supports the useful distinction between geometric and shading 
00015    normals defined at a point, where the geometric normal 
00016    (SurfacePoint::normalG) is the actual normal of the underlying surface at a 
00017    point, and the shading normal (SurfacePoint::normalS) is a (possibly) 
00018    perturbed version of the geometric normal.  Shading normals attempt to 
00019    simulate more complex underlying geometry by varying the apparent normal 
00020    across the surface of a simpler surface such as a plane. It is important to 
00021    note that shading normals have no physical basic whatsoever -- they are 
00022    merely a useful (and very common) method for faking higher resolution (ie. 
00023    more expensive) geometry. See the bump mapping implementation in Material 
00024    for an example use of shading normals.
00025    
00026    @note
00027       When finding the closest intersection point between a Ray and a set of 
00028    objects in the scene, SurfacePoint is used to hold the 'current' closest 
00029    object and any metadata that shape may need to <b>lazily</b> fill in the 
00030    rest of the SurfacePoint structure later on (see Shape::initSurfacePoint).
00031    <!-------------------------------------------------------------------->**/
00032 
00033 #ifndef SURFACE_POINT_H_
00034 #define SURFACE_POINT_H_
00035 
00036 #include <shapes/Triangle.h>
00037 #include <materials/IndexOfRefraction.h>
00038 
00039 #include <boost/shared_ptr.hpp>
00040 #include <ostream>
00041 
00042 class  BSDF;
00043 class  Emitter;
00044 class  Sensor;
00045 class  Shape;
00046 struct Ray;
00047 
00048 struct SurfacePoint : public SSEAligned {
00049    ///@name Surface data lazily filled in by Shape::initSurfacePoint
00050    //@{-----------------------------------------------------------------
00051    
00052    /// intersected shape
00053    Shape   *shape;
00054    
00055    /// world-space position
00056    Point3   position;
00057    
00058    /// geometric normal
00059    Vector3  normalG;
00060    
00061    /// shading normal (possibly a perturbed version of the geometric normal, 
00062    /// normalG)
00063    Vector3  normalS;
00064    
00065    /// UV coordinates
00066    UV       uv;
00067    
00068    
00069    //@}-----------------------------------------------------------------
00070    ///@name Material data evaluated lazily by Material::initSurfacePoint
00071    //@{-----------------------------------------------------------------
00072    
00073    /// reflectance
00074    BSDF    *bsdf;
00075    
00076    /// emittance
00077    Emitter *emitter;
00078    
00079    /// importance aka sensor response (for cameras)
00080    Sensor  *sensor;
00081    
00082    /// incident index of refraction
00083    real_t   ior1;
00084    
00085    /// exitent  index of refraction
00086    real_t   ior2;
00087    
00088    
00089    //@}-----------------------------------------------------------------
00090    ///@name Shape-specific, lazy-helper data
00091    //@{-----------------------------------------------------------------
00092    
00093    unsigned index;
00094    unsigned normalCase;
00095    
00096    
00097    //@}-----------------------------------------------------------------
00098    ///@name Constructors
00099    //@{-----------------------------------------------------------------
00100    
00101    inline SurfacePoint() 
00102       : shape(NULL), bsdf(NULL), emitter(NULL), sensor(NULL), 
00103         ior1(IndexOfRefraction::AIR), ior2(IndexOfRefraction::AIR), 
00104         normal(normalS)
00105    { }
00106    
00107    inline SurfacePoint(Shape *shape_, const Point3 &p0, const Point3 &p1)
00108       : shape(shape_), position(p1), normalG((p0 - p1).getNormalized()), 
00109         bsdf(NULL), emitter(NULL), sensor(NULL), 
00110         ior1(IndexOfRefraction::AIR), ior2(IndexOfRefraction::AIR), 
00111         normal(normalS)
00112    { }
00113    
00114    ~SurfacePoint();
00115    
00116    
00117    //@}-----------------------------------------------------------------
00118    ///@name Utility normal accessor
00119    //@{-----------------------------------------------------------------
00120    
00121    /**
00122     * @brief
00123     *    Convenience stand-in normal which plays nicely with shapes that 
00124     * don't support the concept of a normal (ex. point lights)
00125     */
00126    struct SurfacePointNormal {
00127       inline SurfacePointNormal(const Vector3 &normal)
00128          : hasNormal(true), m_normal(normal)
00129       { }
00130       
00131       /**
00132        * @brief
00133        *    If the associated SurfacePoint is defined at a point with a normal, 
00134        * will return the standard dot product of the given Vector3 @p v with 
00135        * its shading normal, normalS.  If the point does not have a normal 
00136        * (ex. point lights), this function will return 1.
00137        */
00138       inline real_t dot(const Vector3 &v) const {
00139          return (hasNormal ? m_normal.dot(v) : 1);
00140       }
00141       
00142       /// whether or not the underlying SurfacePoint has a surface normal
00143       bool hasNormal;
00144       
00145       private:
00146          const Vector3 &m_normal;
00147    } normal;
00148    
00149    
00150    //@}-----------------------------------------------------------------
00151    ///@name Initialization
00152    //@{-----------------------------------------------------------------
00153    
00154    /**
00155     * @brief 
00156     *    Initializes this point, assuming shape has already been 
00157     * filled in, in addition to any optional shape or material-specific 
00158     * utility data (index, normalCase)
00159     * 
00160     * @returns false if this point is invalid and can't be initialized
00161     *    (in the case of an invalid t-value)
00162     */
00163    bool init(const Ray &ray, real_t t);
00164    
00165    /**
00166     * @brief 
00167     *    Initializes this point, assuming shape/position have already been 
00168     * filled in, in addition to any optional shape or material-specific 
00169     * utility data (UV, index, normalCase)
00170     */
00171    void init();
00172    
00173    
00174    //@}-----------------------------------------------------------------
00175 };
00176 
00177 typedef boost::shared_ptr<SurfacePoint> SurfacePointPtr;
00178 
00179 /// Prints a SurfacePoint to an output stream for debugging purposes
00180 std::ostream &operator<<(std::ostream &os, const SurfacePoint &pt);
00181 
00182 #endif // SURFACE_POINT_H_
00183 

Generated on 28 Feb 2009 for Milton by doxygen 1.5.6