Cycles: Make all #include statements relative to cycles source directory
[blender.git] / intern / cycles / bvh / bvh_params.h
1 /*
2  * Adapted from code copyright 2009-2010 NVIDIA Corporation
3  * Modifications Copyright 2011, Blender Foundation.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17
18 #ifndef __BVH_PARAMS_H__
19 #define __BVH_PARAMS_H__
20
21 #include "util/util_boundbox.h"
22
23 #include "kernel/kernel_types.h"
24
25 CCL_NAMESPACE_BEGIN
26
27 /* BVH Parameters */
28
29 class BVHParams
30 {
31 public:
32         /* spatial split area threshold */
33         bool use_spatial_split;
34         float spatial_split_alpha;
35
36         /* Unaligned nodes creation threshold */
37         float unaligned_split_threshold;
38
39         /* SAH costs */
40         float sah_node_cost;
41         float sah_primitive_cost;
42
43         /* number of primitives in leaf */
44         int min_leaf_size;
45         int max_triangle_leaf_size;
46         int max_motion_triangle_leaf_size;
47         int max_curve_leaf_size;
48         int max_motion_curve_leaf_size;
49
50         /* object or mesh level bvh */
51         bool top_level;
52
53         /* QBVH */
54         bool use_qbvh;
55
56         /* Mask of primitives to be included into the BVH. */
57         int primitive_mask;
58
59         /* Use unaligned bounding boxes.
60          * Only used for curves BVH.
61          */
62         bool use_unaligned_nodes;
63
64         /* Split time range to this number of steps and create leaf node for each
65          * of this time steps.
66          *
67          * Speeds up rendering of motion curve primitives in the cost of higher
68          * memory usage.
69          */
70         int num_motion_curve_steps;
71
72         /* Same as above, but for triangle primitives. */
73         int num_motion_triangle_steps;
74
75         /* fixed parameters */
76         enum {
77                 MAX_DEPTH = 64,
78                 MAX_SPATIAL_DEPTH = 48,
79                 NUM_SPATIAL_BINS = 32
80         };
81
82         BVHParams()
83         {
84                 use_spatial_split = true;
85                 spatial_split_alpha = 1e-5f;
86
87                 unaligned_split_threshold = 0.7f;
88
89                 /* todo: see if splitting up primitive cost to be separate for triangles
90                  * and curves can help. so far in tests it doesn't help, but why? */
91                 sah_node_cost = 1.0f;
92                 sah_primitive_cost = 1.0f;
93
94                 min_leaf_size = 1;
95                 max_triangle_leaf_size = 8;
96                 max_motion_triangle_leaf_size = 8;
97                 max_curve_leaf_size = 1;
98                 max_motion_curve_leaf_size = 4;
99
100                 top_level = false;
101                 use_qbvh = false;
102                 use_unaligned_nodes = false;
103
104                 primitive_mask = PRIMITIVE_ALL;
105
106                 num_motion_curve_steps = 0;
107                 num_motion_triangle_steps = 0;
108         }
109
110         /* SAH costs */
111         __forceinline float cost(int num_nodes, int num_primitives) const
112         { return node_cost(num_nodes) + primitive_cost(num_primitives); }
113
114         __forceinline float primitive_cost(int n) const
115         { return n*sah_primitive_cost; }
116
117         __forceinline float node_cost(int n) const
118         { return n*sah_node_cost; }
119
120         __forceinline bool small_enough_for_leaf(int size, int level)
121         { return (size <= min_leaf_size || level >= MAX_DEPTH); }
122 };
123
124 /* BVH Reference
125  *
126  * Reference to a primitive. Primitive index and object are sneakily packed
127  * into BoundBox to reduce memory usage and align nicely */
128
129 class BVHReference
130 {
131 public:
132         __forceinline BVHReference() {}
133
134         __forceinline BVHReference(const BoundBox& bounds_,
135                                    int prim_index_,
136                                    int prim_object_,
137                                    int prim_type,
138                                    float time_from = 0.0f,
139                                    float time_to = 1.0f)
140                 : rbounds(bounds_),
141                   time_from_(time_from),
142                   time_to_(time_to)
143         {
144                 rbounds.min.w = __int_as_float(prim_index_);
145                 rbounds.max.w = __int_as_float(prim_object_);
146                 type = prim_type;
147         }
148
149         __forceinline const BoundBox& bounds() const { return rbounds; }
150         __forceinline int prim_index() const { return __float_as_int(rbounds.min.w); }
151         __forceinline int prim_object() const { return __float_as_int(rbounds.max.w); }
152         __forceinline int prim_type() const { return type; }
153         __forceinline float time_from() const { return time_from_; }
154         __forceinline float time_to() const { return time_to_; }
155
156
157         BVHReference& operator=(const BVHReference &arg) {
158                 if(&arg != this) {
159                         memcpy(this, &arg, sizeof(BVHReference));
160                 }
161                 return *this;
162         }
163
164
165 protected:
166         BoundBox rbounds;
167         uint type;
168         float time_from_, time_to_;
169 };
170
171 /* BVH Range
172  *
173  * Build range used during construction, to indicate the bounds and place in
174  * the reference array of a subset of primitives Again uses trickery to pack
175  * integers into BoundBox for alignment purposes. */
176
177 class BVHRange
178 {
179 public:
180         __forceinline BVHRange()
181         {
182                 rbounds.min.w = __int_as_float(0);
183                 rbounds.max.w = __int_as_float(0);
184         }
185
186         __forceinline BVHRange(const BoundBox& bounds_, int start_, int size_)
187         : rbounds(bounds_)
188         {
189                 rbounds.min.w = __int_as_float(start_);
190                 rbounds.max.w = __int_as_float(size_);
191         }
192
193         __forceinline BVHRange(const BoundBox& bounds_, const BoundBox& cbounds_, int start_, int size_)
194         : rbounds(bounds_), cbounds(cbounds_)
195         {
196                 rbounds.min.w = __int_as_float(start_);
197                 rbounds.max.w = __int_as_float(size_);
198         }
199
200         __forceinline void set_start(int start_) { rbounds.min.w = __int_as_float(start_); }
201
202         __forceinline const BoundBox& bounds() const { return rbounds; }
203         __forceinline const BoundBox& cent_bounds() const { return cbounds; }
204         __forceinline int start() const { return __float_as_int(rbounds.min.w); }
205         __forceinline int size() const { return __float_as_int(rbounds.max.w); }
206         __forceinline int end() const { return start() + size(); }
207
208 protected:
209         BoundBox rbounds;
210         BoundBox cbounds;
211 };
212
213 /* BVH Spatial Bin */
214
215 struct BVHSpatialBin
216 {
217         BoundBox bounds;
218         int enter;
219         int exit;
220
221         __forceinline BVHSpatialBin()
222         {
223         }
224 };
225
226 /* BVH Spatial Storage
227  *
228  * The idea of this storage is have thread-specific storage for the spatial
229  * splitters. We can pre-allocate this storage in advance and avoid heavy memory
230  * operations during split process.
231  */
232
233 struct BVHSpatialStorage {
234         /* Accumulated bounds when sweeping from right to left.  */
235         vector<BoundBox> right_bounds;
236
237         /* Bins used for histogram when selecting best split plane. */
238         BVHSpatialBin bins[3][BVHParams::NUM_SPATIAL_BINS];
239
240         /* Temporary storage for the new references. Used by spatial split to store
241          * new references in before they're getting inserted into actual array,
242          */
243         vector<BVHReference> new_references;
244 };
245
246 CCL_NAMESPACE_END
247
248 #endif /* __BVH_PARAMS_H__ */
249