Nori
|
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 */