Mitsuba Renderer  0.5.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
triangle.h
Go to the documentation of this file.
1 /*
2  This file is part of Mitsuba, a physically based rendering system.
3 
4  Copyright (c) 2007-2014 by Wenzel Jakob and others.
5 
6  Mitsuba is free software; you can redistribute it and/or modify
7  it under the terms of the GNU General Public License Version 3
8  as published by the Free Software Foundation.
9 
10  Mitsuba is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License
16  along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18 
19 #pragma once
20 #if !defined(__MITSUBA_CORE_TRIANGLE_H_)
21 #define __MITSUBA_CORE_TRIANGLE_H_
22 
23 #include <mitsuba/mitsuba.h>
24 #include <mitsuba/core/aabb.h>
25 
27 
28 /**
29  * \brief Simple triangle class including a collection of routines
30  * for analysis and transformation.
31  *
32  * Triangles are stored as indices into a vertex array
33  * \ingroup libcore
34  */
36  /// Indices into a vertex buffer
37  uint32_t idx[3];
38 
39  /// Construct an axis-aligned box, which contains the triangle
40  inline AABB getAABB(const Point *positions) const {
41  AABB result(positions[idx[0]]);
42  result.expandBy(positions[idx[1]]);
43  result.expandBy(positions[idx[2]]);
44  return result;
45  }
46 
47  /**
48  * \brief Returns the axis-aligned bounding box of a triangle after it has
49  * clipped to the extends of another given AABB.
50  *
51  * This function uses the Sutherland-Hodgman algorithm to calculate the
52  * convex polygon that is created when applying all 6 AABB splitting
53  * planes to the triangle. Afterwards, the AABB of the newly created
54  * convex polygon is returned. This function is an important component
55  * for efficiently creating 'Perfect Split' KD-trees. For more detail,
56  * see "On building fast kd-Trees for Ray Tracing, and on doing
57  * that in O(N log N)" by Ingo Wald and Vlastimil Havran
58  */
59  AABB getClippedAABB(const Point *positions, const AABB &aabb) const;
60 
61  // Returns the bounding sphere of the triangle
62  inline BSphere getBSphere(const Point *positions) const {
63  Vector a = (positions[idx[1]] - positions[idx[0]]);
64  Vector b = (positions[idx[2]] - positions[idx[0]]);
65  Float a2 = dot(a, a);
66  Float b2 = dot(b, b);
67  Float da = std::sqrt(a2);
68  Float db = std::sqrt(b2);
69  Vector axb = cross(a, b);
70  Float axb2 = dot(axb, axb);
71  Float daxb = std::sqrt(axb2);
72  return BSphere(positions[idx[0]] + cross(a2 * b - b2 * a, axb) / (2 * axb2),
73  da * db * (a - b).length() / (2 * daxb));
74  }
75 
76  /// Uniformly sample a point on the triangle and return its normal and UV coordinates
77  Point sample(const Point *positions, const Normal *normals,
78  const Point2 *texCoords, Normal &n, Point2 &uv,
79  const Point2 &seed) const;
80 
81  /// Calculate the surface area of this triangle
82  Float surfaceArea(const Point *positions) const;
83 
84  /** \brief Ray-triangle intersection test
85  *
86  * Uses the algorithm by Moeller and Trumbore discussed at
87  * <tt>http://www.acm.org/jgt/papers/MollerTrumbore97/code.html</tt>.
88  *
89  * \param p0
90  * Position of the first vertex
91  * \param p1
92  * Position of the second vertex
93  * \param p2
94  * Position of the third vertex
95  * \param ray
96  * The ray segment to be used for the intersection query
97  * \param t
98  * Upon success, \a t contains the distance from the ray origin to the
99  * intersection point,
100  * \param u
101  * Upon success, \c u will contain the 'U' component of the intersection
102  * in barycentric coordinates
103  * \param v
104  * Upon success, \c v will contain the 'V' component of the intersection
105  * in barycentric coordinates
106  * \return
107  * \c true if an intersection has been detected
108  */
109  FINLINE static bool rayIntersect(const Point &p0, const Point &p1, const Point &p2,
110  const Ray &ray, Float &u, Float &v, Float &t) {
111  /* Find vectors for two edges sharing */
112  Vector edge1 = p1 - p0, edge2 = p2 - p0;
113 
114  /* Begin calculating determinant - also used to calculate U parameter */
115  Vector pvec = cross(ray.d, edge2);
116 
117  Float det = dot(edge1, pvec);
118  if (det == 0)
119  return false;
120  Float inv_det = 1.0f / det;
121 
122  /* Calculate distance from v[0] to ray origin */
123  Vector tvec = ray.o - p0;
124 
125  /* Calculate U parameter and test bounds */
126  u = dot(tvec, pvec) * inv_det;
127  if (u < 0.0 || u > 1.0)
128  return false;
129 
130  /* Prepare to test V parameter */
131  Vector qvec = cross(tvec, edge1);
132 
133  /* Calculate V parameter and test bounds */
134  v = dot(ray.d, qvec) * inv_det;
135 
136  /* Inverted comparison (to catch NaNs) */
137  if (v >= 0.0 && u + v <= 1.0) {
138  /* ray intersects triangle -> compute t */
139  t = dot(edge2, qvec) * inv_det;
140 
141  return true;
142  }
143 
144  return false;
145  }
146 
147  /** \brief Ray-triangle intersection test
148  *
149  * Uses the algorithm by Moeller and Trumbore discussed at
150  * <tt>http://www.acm.org/jgt/papers/MollerTrumbore97/code.html</tt>.
151  *
152  * \param positions
153  * Pointer to the vertex positions of the underlying triangle mesh
154  * \param index
155  * Index of the triangle that should be intersected
156  * \param ray
157  * The ray segment to be used for the intersection query
158  * \param t
159  * Upon success, \a t contains the distance from the ray origin to the
160  * intersection point,
161  * \param u
162  * Upon success, \c u will contain the 'U' component of the intersection
163  * in barycentric coordinates
164  * \param v
165  * Upon success, \c v will contain the 'V' component of the intersection
166  * in barycentric coordinates
167  * \return
168  * \c true if an intersection has been detected
169  */
170  FINLINE bool rayIntersect(const Point *positions, const Ray &ray, Float &u,
171  Float &v, Float &t) const {
172  return rayIntersect(
173  positions[idx[0]], positions[idx[1]],
174  positions[idx[2]], ray, u, v, t);
175  }
176 };
177 
179 
180 #endif /* __MITSUBA_CORE_TRIANGLE_H_ */
Three-dimensional normal data structure.
Definition: normal.h:39
static FINLINE bool rayIntersect(const Point &p0, const Point &p1, const Point &p2, const Ray &ray, Float &u, Float &v, Float &t)
Ray-triangle intersection test.
Definition: triangle.h:109
Simple triangle class including a collection of routines for analysis and transformation.
Definition: triangle.h:35
void expandBy(const PointType &p)
Expand the bounding box to contain another point.
Definition: aabb.h:189
FINLINE bool rayIntersect(const Point *positions, const Ray &ray, Float &u, Float &v, Float &t) const
Ray-triangle intersection test.
Definition: triangle.h:170
Bounding sphere data structure in three dimensions.
Definition: bsphere.h:32
#define MTS_EXPORT_CORE
Definition: getopt.h:29
T det(const TVector2< T > &v1, const TVector2< T > &v2)
Definition: vector.h:411
#define MTS_NAMESPACE_BEGIN
Definition: platform.h:137
Axis-aligned bounding box data structure in three dimensions.
Definition: aabb.h:437
Definition: fwd.h:99
BSphere getBSphere(const Point *positions) const
Definition: triangle.h:62
Definition: fwd.h:65
AABB getAABB(const Point *positions) const
Construct an axis-aligned box, which contains the triangle.
Definition: triangle.h:40
Definition: fwd.h:96
Definition: fwd.h:100
TVector3< T > cross(const TVector3< T > &v1, const TVector3< T > &v2)
Definition: vector.h:617
T dot(const TQuaternion< T > &q1, const TQuaternion< T > &q2)
Definition: quat.h:348
#define MTS_NAMESPACE_END
Definition: platform.h:138