1
2 //
3 // This source file is part of appleseed.
4 // Visit https://appleseedhq.net/ for additional information and resources.
5 //
6 // This software is released under the MIT license.
7 //
8 // Copyright (c) 2010-2013 Francois Beaune, Jupiter Jazz Limited
9 // Copyright (c) 2014-2018 Francois Beaune, The appleseedhq Organization
10 //
11 // Permission is hereby granted, free of charge, to any person obtaining a copy
12 // of this software and associated documentation files (the "Software"), to deal
13 // in the Software without restriction, including without limitation the rights
14 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15 // copies of the Software, and to permit persons to whom the Software is
16 // furnished to do so, subject to the following conditions:
17 //
18 // The above copyright notice and this permission notice shall be included in
19 // all copies or substantial portions of the Software.
20 //
21 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
27 // THE SOFTWARE.
28 //
29
30 #pragma once
31
32 // appleseed.renderer headers.
33 #include "renderer/global/globaltypes.h"
34 #include "renderer/kernel/intersection/intersectionsettings.h"
35 #include "renderer/kernel/intersection/probevisitorbase.h"
36 #include "renderer/kernel/intersection/trianglekey.h"
37 #include "renderer/kernel/intersection/trianglevertexinfo.h"
38 #include "renderer/modeling/scene/visibilityflags.h"
39
40 // appleseed.foundation headers.
41 #include "foundation/core/concepts/noncopyable.h"
42 #include "foundation/math/aabb.h"
43 #include "foundation/math/bvh.h"
44 #include "foundation/math/ray.h"
45 #include "foundation/platform/types.h"
46 #include "foundation/utility/alignedvector.h"
47 #include "foundation/utility/lazy.h"
48 #include "foundation/utility/poolallocator.h"
49 #include "foundation/utility/uid.h"
50
51 // Standard headers.
52 #include <cstddef>
53 #include <map>
54 #include <memory>
55 #include <vector>
56
57 // Forward declarations.
58 namespace foundation { class Statistics; }
59 namespace renderer { class Assembly; }
60 namespace renderer { class IntersectionFilter; }
61 namespace renderer { class ParamArray; }
62 namespace renderer { class Scene; }
63 namespace renderer { class ShadingPoint; }
64
65 namespace renderer
66 {
67
68 typedef std::map<foundation::uint64, IntersectionFilter*> IntersectionFilterRepository;
69
70
71 //
72 // Triangle tree.
73 //
74
75 class TriangleTree
76 : public foundation::bvh::Tree<
77 foundation::AlignedVector<
78 foundation::bvh::Node<foundation::AABB3d>
79 >
80 >
81 {
82 public:
83 // Construction arguments.
84 struct Arguments
85 {
86 const Scene& m_scene;
87 const foundation::UniqueID m_triangle_tree_uid;
88 const GAABB3 m_bbox;
89 const Assembly& m_assembly;
90
91 // Constructor.
92 Arguments(
93 const Scene& scene,
94 const foundation::UniqueID triangle_tree_uid,
95 const GAABB3& bbox,
96 const Assembly& assembly);
97 };
98
99 // Constructor, builds the tree for a given assembly.
100 explicit TriangleTree(const Arguments& arguments);
101
102 // Destructor.
103 ~TriangleTree();
104
105 // Update the non-geometry aspects of the tree.
106 void update_non_geometry(const bool enable_intersection_filters);
107
108 // Return the number of static and moving triangles.
109 size_t get_static_triangle_count() const;
110 size_t get_moving_triangle_count() const;
111
112 // Return the size (in bytes) of this object in memory.
113 size_t get_memory_size() const;
114
115 private:
116 friend class TriangleLeafVisitor;
117 friend class TriangleLeafProbeVisitor;
118
119 const Arguments m_arguments;
120
121 size_t m_static_triangle_count;
122 size_t m_moving_triangle_count;
123
124 std::vector<TriangleKey> m_triangle_keys;
125 std::vector<foundation::uint8> m_leaf_data;
126
127 IntersectionFilterRepository m_intersection_filters_repository;
128 std::vector<const IntersectionFilter*> m_intersection_filters;
129
130 void build_bvh(
131 const ParamArray& params,
132 const double time,
133 const bool save_memory,
134 foundation::Statistics& statistics);
135
136 void build_sbvh(
137 const ParamArray& params,
138 const double time,
139 const bool save_memory,
140 foundation::Statistics& statistics);
141
142 std::vector<GAABB3> compute_motion_bboxes(
143 const std::vector<size_t>& triangle_indices,
144 const std::vector<TriangleVertexInfo>& triangle_vertex_infos,
145 const std::vector<GVector3>& triangle_vertices,
146 const size_t node_index);
147
148 void store_triangles(
149 const std::vector<size_t>& triangle_indices,
150 const std::vector<TriangleVertexInfo>& triangle_vertex_infos,
151 const std::vector<GVector3>& triangle_vertices,
152 const std::vector<TriangleKey>& triangle_keys,
153 foundation::Statistics& statistics);
154
155 void update_intersection_filters();
156 void delete_intersection_filters();
157 };
158
159
160 //
161 // Triangle tree factory.
162 //
163
164 class TriangleTreeFactory
165 : public foundation::ILazyFactory<TriangleTree>
166 {
167 public:
168 // Constructor.
169 explicit TriangleTreeFactory(
170 const TriangleTree::Arguments& arguments);
171
172 // Create the triangle tree.
173 std::unique_ptr<TriangleTree> create() override;
174
175 private:
176 TriangleTree::Arguments m_arguments;
177 };
178
179
180 //
181 // Some additional types.
182 //
183
184 // Triangle tree container and iterator types.
185 typedef std::map<
186 foundation::UniqueID,
187 foundation::Lazy<TriangleTree>*
188 > TriangleTreeContainer;
189 typedef TriangleTreeContainer::iterator TriangleTreeIterator;
190 typedef TriangleTreeContainer::const_iterator TriangleTreeConstIterator;
191
192 // Triangle tree access cache type.
193 typedef foundation::AccessCacheMap<
194 TriangleTreeContainer,
195 TriangleTreeAccessCacheLines,
196 TriangleTreeAccessCacheWays,
197 foundation::PoolAllocator<void, TriangleTreeAccessCacheLines * TriangleTreeAccessCacheWays>
198 > TriangleTreeAccessCache;
199
200
201 //
202 // Triangle leaf visitor, used during tree intersection.
203 //
204
205 class TriangleLeafVisitor
206 : public foundation::NonCopyable
207 {
208 public:
209 // Constructor.
210 TriangleLeafVisitor(
211 const TriangleTree& tree,
212 ShadingPoint& shading_point);
213
214 // Visit a leaf.
215 bool visit(
216 const TriangleTree::NodeType& node,
217 const foundation::Ray3d& ray,
218 const foundation::RayInfo3d& ray_info,
219 double& distance
220 #ifdef FOUNDATION_BVH_ENABLE_TRAVERSAL_STATS
221 , foundation::bvh::TraversalStatistics& stats
222 #endif
223 );
224
225 // Read additional data about the triangle that was hit, if any.
226 void read_hit_triangle_data() const;
227
228 private:
229 const TriangleTree& m_tree;
230 const bool m_has_intersection_filters;
231 ShadingPoint& m_shading_point;
232 GTriangleType m_interpolated_triangle;
233 const GTriangleType* m_hit_triangle;
234 size_t m_hit_triangle_index;
235 };
236
237
238 //
239 // Triangle leaf visitor for probe rays, only return boolean answers
240 // (whether an intersection was found or not).
241 //
242
243 class TriangleLeafProbeVisitor
244 : public ProbeVisitorBase
245 {
246 public:
247 // Constructor.
248 TriangleLeafProbeVisitor(
249 const TriangleTree& tree,
250 const double ray_time,
251 const VisibilityFlags::Type ray_flags);
252
253 // Visit a leaf.
254 bool visit(
255 const TriangleTree::NodeType& node,
256 const foundation::Ray3d& ray,
257 const foundation::RayInfo3d& ray_info,
258 double& distance
259 #ifdef FOUNDATION_BVH_ENABLE_TRAVERSAL_STATS
260 , foundation::bvh::TraversalStatistics& stats
261 #endif
262 );
263
264 private:
265 const TriangleTree& m_tree;
266 const double m_ray_time;
267 const VisibilityFlags::Type m_ray_flags;
268 const bool m_has_intersection_filters;
269 };
270
271
272 //
273 // Triangle tree intersectors.
274 //
275
276 typedef foundation::bvh::Intersector<
277 TriangleTree,
278 TriangleLeafVisitor,
279 foundation::Ray3d, // make sure we pick the SSE2-optimized version of foundation::bvh::Intersector
280 TriangleTreeStackSize
281 > TriangleTreeIntersector;
282
283 typedef foundation::bvh::Intersector<
284 TriangleTree,
285 TriangleLeafProbeVisitor,
286 foundation::Ray3d, // make sure we pick the SSE2-optimized version of foundation::bvh::Intersector
287 TriangleTreeStackSize
288 > TriangleTreeProbeIntersector;
289
290
291 //
292 // TriangleTree class implementation.
293 //
294
get_static_triangle_count()295 inline size_t TriangleTree::get_static_triangle_count() const
296 {
297 return m_static_triangle_count;
298 }
299
get_moving_triangle_count()300 inline size_t TriangleTree::get_moving_triangle_count() const
301 {
302 return m_moving_triangle_count;
303 }
304
305
306 //
307 // TriangleLeafVisitor class implementation.
308 //
309
TriangleLeafVisitor(const TriangleTree & tree,ShadingPoint & shading_point)310 inline TriangleLeafVisitor::TriangleLeafVisitor(
311 const TriangleTree& tree,
312 ShadingPoint& shading_point)
313 : m_tree(tree)
314 , m_has_intersection_filters(!tree.m_intersection_filters.empty())
315 , m_shading_point(shading_point)
316 , m_hit_triangle(nullptr)
317 {
318 }
319
320
321 //
322 // TriangleLeafProbeVisitor class implementation.
323 //
324
TriangleLeafProbeVisitor(const TriangleTree & tree,const double ray_time,const VisibilityFlags::Type ray_flags)325 inline TriangleLeafProbeVisitor::TriangleLeafProbeVisitor(
326 const TriangleTree& tree,
327 const double ray_time,
328 const VisibilityFlags::Type ray_flags)
329 : m_tree(tree)
330 , m_ray_time(ray_time)
331 , m_ray_flags(ray_flags)
332 , m_has_intersection_filters(!tree.m_intersection_filters.empty())
333 {
334 }
335
336 } // namespace renderer
337