Fermat
path.h
1 /*
2  * Fermat
3  *
4  * Copyright (c) 2016-2019, NVIDIA CORPORATION. All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions are met:
8  * * Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  * * Redistributions in binary form must reproduce the above copyright
11  * notice, this list of conditions and the following disclaimer in the
12  * documentation and/or other materials provided with the distribution.
13  * * Neither the name of the NVIDIA CORPORATION nor the
14  * names of its contributors may be used to endorse or promote products
15  * derived from this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20  * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY
21  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28 
29 #pragma once
30 
31 // ------------------------------------------------------------------------- //
32 //
33 // Declaration of classes used to represent and manipulate paths.
34 //
35 // ------------------------------------------------------------------------- //
36 
37 #include <vertex.h>
38 #include <renderer.h>
39 
42 
51 
55 struct Path
56 {
57  VertexGeometryId* vertex_ids;
58  uint32 n_vertices;
59  uint32 stride;
60 
61  FERMAT_HOST_DEVICE
62  Path() {}
63 
64  FERMAT_HOST_DEVICE
65  Path(const uint32 _n_vertices, VertexGeometryId* _verts, const uint32 _stride) :
66  vertex_ids(_verts),
67  n_vertices(_n_vertices),
68  stride(_stride)
69  {}
70 
71  FERMAT_HOST_DEVICE
72  const VertexGeometryId& v_L(const uint32 i) const
73  {
74  FERMAT_ASSERT(i < n_vertices);
75  return vertex_ids[i * stride];
76  }
77 
78  FERMAT_HOST_DEVICE
79  const VertexGeometryId& v_E(const uint32 i) const
80  {
81  FERMAT_ASSERT(i < n_vertices);
82  return vertex_ids[(n_vertices - i - 1) * stride];
83  }
84 
85  FERMAT_HOST_DEVICE
86  VertexGeometryId& v_L(const uint32 i)
87  {
88  FERMAT_ASSERT(i < n_vertices);
89  return vertex_ids[i * stride];
90  }
91 
92  FERMAT_HOST_DEVICE
93  VertexGeometryId& v_E(const uint32 i)
94  {
95  FERMAT_ASSERT(i < n_vertices);
96  return vertex_ids[(n_vertices - i - 1) * stride];
97  }
98 
99  FERMAT_HOST_DEVICE
100  float G(const uint32 i, const RenderingContextView& renderer) const
101  {
102  VertexGeometry v;
103  VertexGeometry v_next;
104 
105  setup_differential_geometry(renderer.mesh, v_L(i), &v);
106  setup_differential_geometry(renderer.mesh, v_L(i+1), &v_next);
107 
108  cugar::Vector3f out = v_next.position - v.position;
109 
110  const float d2 = cugar::max( cugar::square_length(out), 1.0e-8f);
111 
112  out /= sqrtf( d2 );
113 
114  return fabsf(cugar::dot(v.normal_s, out) * cugar::dot(v_next.normal_s, out)) / d2;
115  }
116 
117  FERMAT_HOST_DEVICE
118  cugar::Vector3f edge_L(const uint32 i, const RenderingContextView& renderer) const
119  {
120  return
121  interpolate_position(renderer.mesh, v_L(i + 1)) -
122  interpolate_position(renderer.mesh, v_L(i));
123  }
124 
125  FERMAT_HOST_DEVICE
126  cugar::Vector3f edge_E(const uint32 i, const RenderingContextView& renderer) const
127  {
128  return
129  interpolate_position(renderer.mesh, v_E(i + 1)) -
130  interpolate_position(renderer.mesh, v_E(i));
131  }
132 };
133 
134 
138 struct BidirPath
139 {
140  VertexGeometryId* l_vertex_ids;
141  VertexGeometryId* e_vertex_ids;
142  uint32 l_vertices;
143  uint32 e_vertices;
144  uint32 n_vertices;
145  uint32 stride;
146 
147  FERMAT_HOST_DEVICE
148  BidirPath() {}
149 
150  FERMAT_HOST_DEVICE
151  BidirPath(const uint32 _l_vertices, const uint32 _e_vertices, VertexGeometryId* _l_verts, VertexGeometryId* _e_verts, const uint32 _stride) :
152  l_vertex_ids(_l_verts),
153  e_vertex_ids(_e_verts),
154  l_vertices(_l_vertices),
155  e_vertices(_e_vertices),
156  n_vertices(_l_vertices + _e_vertices),
157  stride(_stride)
158  {}
159 
160  FERMAT_HOST_DEVICE
161  const VertexGeometryId& v_L(const uint32 i) const
162  {
163  FERMAT_ASSERT(i < l_vertices + e_vertices);
164  return i < l_vertices ?
165  l_vertex_ids[i * stride] :
166  e_vertex_ids[(l_vertices + e_vertices - i - 1) * stride];
167  }
168 
169  FERMAT_HOST_DEVICE
170  const VertexGeometryId& v_E(const uint32 i) const
171  {
172  FERMAT_ASSERT(i < l_vertices + e_vertices);
173  return i < e_vertices ?
174  e_vertex_ids[i * stride] :
175  l_vertex_ids[(l_vertices + e_vertices - i - 1) * stride];
176  }
177 
178  FERMAT_HOST_DEVICE
179  VertexGeometryId& v_L(const uint32 i)
180  {
181  FERMAT_ASSERT(i < l_vertices + e_vertices);
182  return i < l_vertices ?
183  l_vertex_ids[i * stride] :
184  e_vertex_ids[(l_vertices + e_vertices - i - 1) * stride];
185  }
186 
187  FERMAT_HOST_DEVICE
188  VertexGeometryId& v_E(const uint32 i)
189  {
190  FERMAT_ASSERT(i < l_vertices + e_vertices);
191  return i < e_vertices ?
192  e_vertex_ids[i * stride] :
193  l_vertex_ids[(l_vertices + e_vertices - i - 1) * stride];
194  }
195 
196  FERMAT_HOST_DEVICE
197  float G(const uint32 i, const RenderingContextView& renderer) const
198  {
199  VertexGeometry v;
200  VertexGeometry v_next;
201 
202  setup_differential_geometry(renderer.mesh, v_L(i), &v);
203  setup_differential_geometry(renderer.mesh, v_L(i+1), &v_next);
204 
205  cugar::Vector3f out = v_next.position - v.position;
206 
207  const float d2 = cugar::max( cugar::square_length(out), 1.0e-8f);
208 
209  out /= sqrtf( d2 );
210 
211  return fabsf(cugar::dot(v.normal_s, out) * cugar::dot(v_next.normal_s, out)) / d2;
212  }
213 
214  FERMAT_HOST_DEVICE
215  cugar::Vector3f edge_L(const uint32 i, const RenderingContextView& renderer) const
216  {
217  return
218  interpolate_position(renderer.mesh, v_L(i + 1)) -
219  interpolate_position(renderer.mesh, v_L(i));
220  }
221 
222  FERMAT_HOST_DEVICE
223  cugar::Vector3f edge_E(const uint32 i, const RenderingContextView& renderer) const
224  {
225  return
226  interpolate_position(renderer.mesh, v_E(i + 1)) -
227  interpolate_position(renderer.mesh, v_E(i));
228  }
229 };
230 
231 
235 template <typename T>
236 struct PathCache
237 {
238  T* vertices;
239  uint32 n_vertices;
240  uint32 stride;
241 
242  FERMAT_HOST_DEVICE
243  PathCache() {}
244 
245  FERMAT_HOST_DEVICE
246  PathCache(const uint32 _n_vertices, T* _verts, const uint32 _stride) :
247  vertices(_verts),
248  n_vertices(_n_vertices),
249  stride(_stride)
250  {}
251 
252  FERMAT_HOST_DEVICE
253  const T& v_L(const uint32 i) const
254  {
255  FERMAT_ASSERT(i < n_vertices);
256  return vertices[i * stride];
257  }
258 
259  FERMAT_HOST_DEVICE
260  const T& v_E(const uint32 i) const
261  {
262  FERMAT_ASSERT(i < n_vertices);
263  return vertices[(n_vertices - i - 1) * stride];
264  }
265 
266  FERMAT_HOST_DEVICE
267  T& v_L(const uint32 i)
268  {
269  FERMAT_ASSERT(i < n_vertices);
270  return vertices[i * stride];
271  }
272 
273  FERMAT_HOST_DEVICE
274  T& v_E(const uint32 i)
275  {
276  FERMAT_ASSERT(i < n_vertices);
277  return vertices[(n_vertices - i - 1) * stride];
278  }
279 };
280 
Definition: path.h:138
Definition: vertex.h:105
Definition: vertex.h:92
FERMAT_HOST_DEVICE void setup_differential_geometry(const MeshView &mesh, const uint32 tri_id, const float u, const float v, VertexGeometry *geom, float *pdf=0)
Definition: mesh_utils.h:185
Definition: path.h:55
FERMAT_HOST_DEVICE cugar::Vector3f interpolate_position(const MeshView &mesh, const uint32 tri_id, const float u, const float v, float *pdf=0)
Definition: mesh_utils.h:323
Definition: renderer_view.h:80
Definition: path.h:236