Mitsuba Renderer  0.5.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
triaccel.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_RENDER_TRIACCEL_H_)
21 #define __MITSUBA_RENDER_TRIACCEL_H_
22 
23 #include <mitsuba/render/trimesh.h>
24 
26 
27 // Used when a fake triangle is used to reference a non-triangle shape instance
28 static const uint32_t KNoTriangleFlag = 0xFFFFFFFF;
29 
30 /**
31  * \brief Pre-computed triangle representation based on Ingo Wald's TriAccel layout.
32  *
33  * Fits into three 16-byte cache lines if single precision floats are used.
34  * The k parameter is also used for classification during kd-tree construction.
35  * \ingroup librender
36  */
37 struct TriAccel {
42 
47 
52 
53  /// Construct from vertex data. Returns '1' if there was a failure
54  inline int load(const Point &A, const Point &B, const Point &C);
55 
56  /// Fast ray-triangle intersection test
57  FINLINE bool rayIntersect(const Ray &ray, Float mint, Float maxt,
58  Float &u, Float &v, Float &t) const;
59 };
60 
61 inline int TriAccel::load(const Point &A, const Point &B, const Point &C) {
62  static const int waldModulo[4] = { 1, 2, 0, 1 };
63 
64  Vector b = C-A, c = B-A, N = cross(c, b);
65 
66  k = 0;
67  /* Determine the largest projection axis */
68  for (int j=0; j<3; j++) {
69  if (std::abs(N[j]) > std::abs(N[k]))
70  k = j;
71  }
72 
73  uint32_t u = waldModulo[k],
74  v = waldModulo[k+1];
75  const Float n_k = N[k],
76  denom = b[u]*c[v] - b[v]*c[u];
77 
78  if (denom == 0) {
79  k = 3;
80  return 1;
81  }
82 
83  /* Pre-compute intersection calculation constants */
84  n_u = N[u] / n_k;
85  n_v = N[v] / n_k;
86  n_d = dot(Vector(A), N) / n_k;
87  b_nu = b[u] / denom;
88  b_nv = -b[v] / denom;
89  a_u = A[u];
90  a_v = A[v];
91  c_nu = c[v] / denom;
92  c_nv = -c[u] / denom;
93  return 0;
94 }
95 
96 FINLINE bool TriAccel::rayIntersect(const Ray &ray, Float mint, Float maxt,
97  Float &u, Float &v, Float &t) const {
98 
99 #if 0
100  static const MM_ALIGN16 int waldModulo[4] = { 1, 2, 0, 1 };
101  const int ku = waldModulo[k], kv = waldModulo[k+1];
102  /* Get the u and v components */
103  const Float o_u = ray.o[ku], o_v = ray.o[kv], o_k = ray.o[k],
104  d_u = ray.d[ku], d_v = ray.d[kv], d_k = ray.d[k];
105 #else
106  Float o_u, o_v, o_k, d_u, d_v, d_k;
107  switch (k) {
108  case 0:
109  o_u = ray.o[1];
110  o_v = ray.o[2];
111  o_k = ray.o[0];
112  d_u = ray.d[1];
113  d_v = ray.d[2];
114  d_k = ray.d[0];
115  break;
116  case 1:
117  o_u = ray.o[2];
118  o_v = ray.o[0];
119  o_k = ray.o[1];
120  d_u = ray.d[2];
121  d_v = ray.d[0];
122  d_k = ray.d[1];
123  break;
124  case 2:
125  o_u = ray.o[0];
126  o_v = ray.o[1];
127  o_k = ray.o[2];
128  d_u = ray.d[0];
129  d_v = ray.d[1];
130  d_k = ray.d[2];
131  break;
132  default:
133  return false;
134  }
135 #endif
136 
137 
138 #if defined(MTS_DEBUG_FP)
139  if (d_u * n_u + d_v * n_v + d_k == 0)
140  return false;
141 #endif
142 
143  /* Calculate the plane intersection (Typo in the thesis?) */
144  t = (n_d - o_u*n_u - o_v*n_v - o_k) /
145  (d_u * n_u + d_v * n_v + d_k);
146 
147  if (t < mint || t > maxt)
148  return false;
149 
150  /* Calculate the projected plane intersection point */
151  const Float hu = o_u + t * d_u - a_u;
152  const Float hv = o_v + t * d_v - a_v;
153 
154  /* In barycentric coordinates */
155  u = hv * b_nu + hu * b_nv;
156  v = hu * c_nu + hv * c_nv;
157  return u >= 0 && v >= 0 && u+v <= 1.0f;
158 }
159 
161 
162 #endif /* __MITSUBA_RENDER_TRIACCEL_H_ */
Float n_v
Definition: triaccel.h:40
uint32_t shapeIndex
Definition: triaccel.h:50
Float n_u
Definition: triaccel.h:39
TVector3< Float > Vector
Definition: fwd.h:113
Float b_nv
Definition: triaccel.h:46
Float c_nv
Definition: triaccel.h:49
#define MTS_NAMESPACE_BEGIN
Definition: platform.h:137
Float a_u
Definition: triaccel.h:43
Float n_d
Definition: triaccel.h:41
Definition: fwd.h:65
Definition: fwd.h:96
uint32_t primIndex
Definition: triaccel.h:51
Float b_nu
Definition: triaccel.h:45
uint32_t k
Definition: triaccel.h:38
Pre-computed triangle representation based on Ingo Wald&#39;s TriAccel layout.
Definition: triaccel.h:37
Float c_nu
Definition: triaccel.h:48
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
Float a_v
Definition: triaccel.h:44
#define MTS_NAMESPACE_END
Definition: platform.h:138