Nori

include/nori/mesh.h

Go to the documentation of this file.
00001 /*
00002     This file is part of Nori, a simple educational ray tracer
00003 
00004     Copyright (c) 2012 by Wenzel Jakob and Steve Marschner.
00005 
00006     Nori is free software; you can redistribute it and/or modify
00007     it under the terms of the GNU General Public License Version 3
00008     as published by the Free Software Foundation.
00009 
00010     Nori is distributed in the hope that it will be useful,
00011     but WITHOUT ANY WARRANTY; without even the implied warranty of
00012     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00013     GNU General Public License for more details.
00014 
00015     You should have received a copy of the GNU General Public License
00016     along with this program. If not, see <http://www.gnu.org/licenses/>.
00017 */
00018 
00019 #if !defined(__MESH_H)
00020 #define __MESH_H
00021 
00022 #include <nori/object.h>
00023 #include <nori/dpdf.h>
00024 #include <nori/frame.h>
00025 
00026 NORI_NAMESPACE_BEGIN
00027 
00028 /**
00029  * \brief Intersection data structure
00030  *
00031  * This data structure records local information about a ray-triangle intersection.
00032  * This includes the position, traveled ray distance, uv coordinates, as well
00033  * as well as two local coordinate frames (one that corresponds to the true
00034  * geometry, and one that is used for shading computations).
00035  */
00036 struct Intersection {
00037         /// Position of the surface intersection
00038         Point3f p;
00039         /// Unoccluded distance along the ray
00040         float t;
00041         /// UV coordinates, if any
00042         Point2f uv;
00043         /// Shading frame (based on the shading normal)
00044         Frame shFrame;
00045         /// Geometric frame (based on the true geometry)
00046         Frame geoFrame;
00047         /// Pointer to the associated mesh
00048         const Mesh *mesh;
00049 
00050         /// Create an uninitialized intersection record
00051         inline Intersection() : mesh(NULL) { }
00052 
00053         /// Transform a direction vector into the local shading frame
00054         inline Vector3f toLocal(const Vector3f &d) const {
00055                 return shFrame.toLocal(d);
00056         }
00057 
00058         /// Transform a direction vector from local to world coordinates
00059         inline Vector3f toWorld(const Vector3f &d) const {
00060                 return shFrame.toWorld(d);
00061         }
00062 
00063         /// Return a human-readable summary of the intersection record
00064         QString toString() const;
00065 };
00066 
00067 /**
00068  * \brief Triangle mesh
00069  *
00070  * This class stores a triangle mesh object and provides numerous functions
00071  * for querying the individual triangles. Subclasses of \c Mesh implement 
00072  * the specifics of how to create its contents (e.g. by loading from an 
00073  * external file)
00074  */
00075 class Mesh : public NoriObject {
00076 public:
00077         /// Release all memory
00078         virtual ~Mesh();
00079         
00080         /// Initialize internal data structures (called once by the XML parser)
00081         virtual void activate();
00082 
00083         /// Return the total number of triangles in this hsape
00084         inline uint32_t getTriangleCount() const { return m_triangleCount; }
00085         
00086         /// Return the total number of vertices in this hsape
00087         inline uint32_t getVertexCount() const { return m_vertexCount; }
00088 
00089         /**
00090          * \brief Uniformly sample a position on the mesh with 
00091          * respect to surface area. Returns both position and normal
00092          */
00093         void samplePosition(const Point2f &sample, Point3f &p, Normal3f &n) const;
00094 
00095         /// Return the surface area of the given triangle
00096         float surfaceArea(uint32_t index) const;
00097 
00098         //// Return an axis-aligned bounding box containing the given triangle
00099         BoundingBox3f getBoundingBox(uint32_t index) const;
00100 
00101         /**
00102          * \brief Returns the axis-aligned bounding box of a triangle after it has 
00103          * clipped to the extents of another given bounding box.
00104          *
00105          * This function uses the Sutherland-Hodgman algorithm to calculate the 
00106          * convex polygon that is created when applying all 6 BoundingBox3f splitting 
00107          * planes to the triangle. Afterwards, the BoundingBox3f of the newly created 
00108          * convex polygon is returned. This function is an important component 
00109          * for efficiently creating 'Perfect Split' KD-trees. For more detail, 
00110          * see "On building fast kd-Trees for Ray Tracing, and on doing 
00111          * that in O(N log N)" by Ingo Wald and Vlastimil Havran
00112          */
00113         BoundingBox3f getClippedBoundingBox(uint32_t index, const BoundingBox3f &clip) const;
00114 
00115         /** \brief Ray-triangle intersection test
00116          * 
00117          * Uses the algorithm by Moeller and Trumbore discussed at
00118          * <tt>http://www.acm.org/jgt/papers/MollerTrumbore97/code.html</tt>.
00119          *
00120          * \param index
00121          *    Index of the triangle that should be intersected
00122          * \param ray
00123          *    The ray segment to be used for the intersection query
00124          * \param t
00125          *    Upon success, \a t contains the distance from the ray origin to the
00126          *    intersection point,
00127          * \param u
00128          *   Upon success, \c u will contain the 'U' component of the intersection
00129          *   in barycentric coordinates
00130          * \param v
00131          *   Upon success, \c v will contain the 'V' component of the intersection
00132          *   in barycentric coordinates
00133          * \return
00134          *   \c true if an intersection has been detected
00135          */
00136         bool rayIntersect(uint32_t index, const Ray3f &ray, float &u, float &v, float &t) const;
00137 
00138         /// Return the surface area of the entire mesh
00139         inline float surfaceArea() const { return m_distr.getSum(); }
00140 
00141         /// Return a pointer to the vertex positions
00142         inline const Point3f *getVertexPositions() const { return m_vertexPositions; }
00143 
00144         /// Return a pointer to the vertex normals (or \c NULL if there are none)
00145         inline const Normal3f *getVertexNormals() const { return m_vertexNormals; }
00146 
00147         /// Return a pointer to the texture coordinates (or \c NULL if there are none)
00148         inline const Point2f *getVertexTexCoords() const { return m_vertexTexCoords; }
00149 
00150         /// Return a pointer to the triangle vertex index list
00151         inline const uint32_t *getIndices() const { return m_indices; }
00152 
00153         /// Return a pointer to the BSDF associated with this mesh
00154         inline const BSDF *getBSDF() const { return m_bsdf; }
00155 
00156         /// Register a child object (e.g. a BSDF) with the mesh
00157         virtual void addChild(NoriObject *child);
00158 
00159         /// Return the name of this mesh
00160         inline const QString &getName() const { return m_name; }
00161 
00162         /// Return a human-readable summary of this instance
00163         QString toString() const;
00164 
00165         /**
00166          * \brief Return the type of object (i.e. Mesh/BSDF/etc.) 
00167          * provided by this instance
00168          * */
00169         EClassType getClassType() const { return EMesh; }
00170 protected:
00171         /// Create an empty mesh
00172         Mesh();
00173 protected:
00174         Point3f  *m_vertexPositions;
00175         Normal3f *m_vertexNormals;
00176         Point2f  *m_vertexTexCoords;
00177         uint32_t *m_indices;
00178         uint32_t m_vertexCount;
00179         uint32_t m_triangleCount;
00180         DiscretePDF m_distr;
00181         BSDF    *m_bsdf;
00182         QString m_name;
00183 };
00184 
00185 NORI_NAMESPACE_END
00186 
00187 #endif /* __MESH_H */
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Defines