Blender  V2.93
bvh_split.cpp
Go to the documentation of this file.
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 #include "bvh/bvh_split.h"
19 
20 #include "bvh/bvh_build.h"
21 #include "bvh/bvh_sort.h"
22 
23 #include "render/hair.h"
24 #include "render/mesh.h"
25 #include "render/object.h"
26 
27 #include "util/util_algorithm.h"
28 
30 
31 /* Object Split */
32 
34  BVHSpatialStorage *storage,
35  const BVHRange &range,
36  vector<BVHReference> &references,
37  float nodeSAH,
38  const BVHUnaligned *unaligned_heuristic,
39  const Transform *aligned_space)
40  : sah(FLT_MAX),
41  dim(0),
42  num_left(0),
43  left_bounds(BoundBox::empty),
44  right_bounds(BoundBox::empty),
45  storage_(storage),
46  references_(&references),
47  unaligned_heuristic_(unaligned_heuristic),
48  aligned_space_(aligned_space)
49 {
50  const BVHReference *ref_ptr = &references_->at(range.start());
51  float min_sah = FLT_MAX;
52 
53  storage_->right_bounds.resize(range.size());
54 
55  for (int dim = 0; dim < 3; dim++) {
56  /* Sort references. */
57  bvh_reference_sort(range.start(),
58  range.end(),
59  &references_->at(0),
60  dim,
63 
64  /* sweep right to left and determine bounds. */
66  for (int i = range.size() - 1; i > 0; i--) {
67  BoundBox prim_bounds = get_prim_bounds(ref_ptr[i]);
68  right_bounds.grow(prim_bounds);
70  }
71 
72  /* sweep left to right and select lowest SAH. */
74 
75  for (int i = 1; i < range.size(); i++) {
76  BoundBox prim_bounds = get_prim_bounds(ref_ptr[i - 1]);
77  left_bounds.grow(prim_bounds);
79 
80  float sah = nodeSAH + left_bounds.safe_area() * builder->params.primitive_cost(i) +
81  right_bounds.safe_area() * builder->params.primitive_cost(range.size() - i);
82 
83  if (sah < min_sah) {
84  min_sah = sah;
85 
86  this->sah = sah;
87  this->dim = dim;
88  this->num_left = i;
89  this->left_bounds = left_bounds;
90  this->right_bounds = right_bounds;
91  }
92  }
93  }
94 }
95 
97 {
98  assert(references_->size() > 0);
99  /* sort references according to split */
100  bvh_reference_sort(range.start(),
101  range.end(),
102  &references_->at(0),
103  this->dim,
106 
107  BoundBox effective_left_bounds, effective_right_bounds;
108  const int num_right = range.size() - this->num_left;
109  if (aligned_space_ == NULL) {
110  effective_left_bounds = left_bounds;
111  effective_right_bounds = right_bounds;
112  }
113  else {
114  effective_left_bounds = BoundBox::empty;
115  effective_right_bounds = BoundBox::empty;
116  for (int i = 0; i < this->num_left; ++i) {
117  BoundBox prim_boundbox = references_->at(range.start() + i).bounds();
118  effective_left_bounds.grow(prim_boundbox);
119  }
120  for (int i = 0; i < num_right; ++i) {
121  BoundBox prim_boundbox = references_->at(range.start() + this->num_left + i).bounds();
122  effective_right_bounds.grow(prim_boundbox);
123  }
124  }
125 
126  /* split node ranges */
127  left = BVHRange(effective_left_bounds, range.start(), this->num_left);
128  right = BVHRange(effective_right_bounds, left.end(), num_right);
129 }
130 
131 /* Spatial Split */
132 
134  BVHSpatialStorage *storage,
135  const BVHRange &range,
136  vector<BVHReference> &references,
137  float nodeSAH,
138  const BVHUnaligned *unaligned_heuristic,
139  const Transform *aligned_space)
140  : sah(FLT_MAX),
141  dim(0),
142  pos(0.0f),
143  storage_(storage),
144  references_(&references),
145  unaligned_heuristic_(unaligned_heuristic),
146  aligned_space_(aligned_space)
147 {
148  /* initialize bins. */
149  BoundBox range_bounds;
150  if (aligned_space == NULL) {
151  range_bounds = range.bounds();
152  }
153  else {
154  range_bounds = unaligned_heuristic->compute_aligned_boundbox(
155  range, &references_->at(0), *aligned_space);
156  }
157 
158  float3 origin = range_bounds.min;
159  float3 binSize = (range_bounds.max - origin) * (1.0f / (float)BVHParams::NUM_SPATIAL_BINS);
160  float3 invBinSize = 1.0f / binSize;
161 
162  for (int dim = 0; dim < 3; dim++) {
163  for (int i = 0; i < BVHParams::NUM_SPATIAL_BINS; i++) {
164  BVHSpatialBin &bin = storage_->bins[dim][i];
165 
166  bin.bounds = BoundBox::empty;
167  bin.enter = 0;
168  bin.exit = 0;
169  }
170  }
171 
172  /* chop references into bins. */
173  for (unsigned int refIdx = range.start(); refIdx < range.end(); refIdx++) {
174  const BVHReference &ref = references_->at(refIdx);
175  BoundBox prim_bounds = get_prim_bounds(ref);
176  float3 firstBinf = (prim_bounds.min - origin) * invBinSize;
177  float3 lastBinf = (prim_bounds.max - origin) * invBinSize;
178  int3 firstBin = make_int3((int)firstBinf.x, (int)firstBinf.y, (int)firstBinf.z);
179  int3 lastBin = make_int3((int)lastBinf.x, (int)lastBinf.y, (int)lastBinf.z);
180 
181  firstBin = clamp(firstBin, 0, BVHParams::NUM_SPATIAL_BINS - 1);
182  lastBin = clamp(lastBin, firstBin, BVHParams::NUM_SPATIAL_BINS - 1);
183 
184  for (int dim = 0; dim < 3; dim++) {
185  BVHReference currRef(
186  get_prim_bounds(ref), ref.prim_index(), ref.prim_object(), ref.prim_type());
187 
188  for (int i = firstBin[dim]; i < lastBin[dim]; i++) {
189  BVHReference leftRef, rightRef;
190 
192  builder, leftRef, rightRef, currRef, dim, origin[dim] + binSize[dim] * (float)(i + 1));
193  storage_->bins[dim][i].bounds.grow(leftRef.bounds());
194  currRef = rightRef;
195  }
196 
197  storage_->bins[dim][lastBin[dim]].bounds.grow(currRef.bounds());
198  storage_->bins[dim][firstBin[dim]].enter++;
199  storage_->bins[dim][lastBin[dim]].exit++;
200  }
201  }
202 
203  /* select best split plane. */
205  for (int dim = 0; dim < 3; dim++) {
206  /* sweep right to left and determine bounds. */
207  BoundBox right_bounds = BoundBox::empty;
208  for (int i = BVHParams::NUM_SPATIAL_BINS - 1; i > 0; i--) {
209  right_bounds.grow(storage_->bins[dim][i].bounds);
210  storage_->right_bounds[i - 1] = right_bounds;
211  }
212 
213  /* sweep left to right and select lowest SAH. */
214  BoundBox left_bounds = BoundBox::empty;
215  int leftNum = 0;
216  int rightNum = range.size();
217 
218  for (int i = 1; i < BVHParams::NUM_SPATIAL_BINS; i++) {
219  left_bounds.grow(storage_->bins[dim][i - 1].bounds);
220  leftNum += storage_->bins[dim][i - 1].enter;
221  rightNum -= storage_->bins[dim][i - 1].exit;
222 
223  float sah = nodeSAH + left_bounds.safe_area() * builder.params.primitive_cost(leftNum) +
224  storage_->right_bounds[i - 1].safe_area() *
225  builder.params.primitive_cost(rightNum);
226 
227  if (sah < this->sah) {
228  this->sah = sah;
229  this->dim = dim;
230  this->pos = origin[dim] + binSize[dim] * (float)i;
231  }
232  }
233  }
234 }
235 
237  BVHRange &left,
238  BVHRange &right,
239  const BVHRange &range)
240 {
241  /* Categorize references and compute bounds.
242  *
243  * Left-hand side: [left_start, left_end[
244  * Uncategorized/split: [left_end, right_start[
245  * Right-hand side: [right_start, refs.size()[ */
246 
248  int left_start = range.start();
249  int left_end = left_start;
250  int right_start = range.end();
251  int right_end = range.end();
252  BoundBox left_bounds = BoundBox::empty;
253  BoundBox right_bounds = BoundBox::empty;
254 
255  for (int i = left_end; i < right_start; i++) {
256  BoundBox prim_bounds = get_prim_bounds(refs[i]);
257  if (prim_bounds.max[this->dim] <= this->pos) {
258  /* entirely on the left-hand side */
259  left_bounds.grow(prim_bounds);
260  swap(refs[i], refs[left_end++]);
261  }
262  else if (prim_bounds.min[this->dim] >= this->pos) {
263  /* entirely on the right-hand side */
264  right_bounds.grow(prim_bounds);
265  swap(refs[i--], refs[--right_start]);
266  }
267  }
268 
269  /* Duplicate or unsplit references intersecting both sides.
270  *
271  * Duplication happens into a temporary pre-allocated vector in order to
272  * reduce number of memmove() calls happening in vector.insert().
273  */
275  new_refs.clear();
276  new_refs.reserve(right_start - left_end);
277  while (left_end < right_start) {
278  /* split reference. */
279  BVHReference curr_ref(get_prim_bounds(refs[left_end]),
280  refs[left_end].prim_index(),
281  refs[left_end].prim_object(),
282  refs[left_end].prim_type());
283  BVHReference lref, rref;
284  split_reference(*builder, lref, rref, curr_ref, this->dim, this->pos);
285 
286  /* compute SAH for duplicate/unsplit candidates. */
287  BoundBox lub = left_bounds; // Unsplit to left: new left-hand bounds.
288  BoundBox rub = right_bounds; // Unsplit to right: new right-hand bounds.
289  BoundBox ldb = left_bounds; // Duplicate: new left-hand bounds.
290  BoundBox rdb = right_bounds; // Duplicate: new right-hand bounds.
291 
292  lub.grow(curr_ref.bounds());
293  rub.grow(curr_ref.bounds());
294  ldb.grow(lref.bounds());
295  rdb.grow(rref.bounds());
296 
297  float lac = builder->params.primitive_cost(left_end - left_start);
298  float rac = builder->params.primitive_cost(right_end - right_start);
299  float lbc = builder->params.primitive_cost(left_end - left_start + 1);
300  float rbc = builder->params.primitive_cost(right_end - right_start + 1);
301 
302  float unsplitLeftSAH = lub.safe_area() * lbc + right_bounds.safe_area() * rac;
303  float unsplitRightSAH = left_bounds.safe_area() * lac + rub.safe_area() * rbc;
304  float duplicateSAH = ldb.safe_area() * lbc + rdb.safe_area() * rbc;
305  float minSAH = min(min(unsplitLeftSAH, unsplitRightSAH), duplicateSAH);
306 
307  if (minSAH == unsplitLeftSAH) {
308  /* unsplit to left */
309  left_bounds = lub;
310  left_end++;
311  }
312  else if (minSAH == unsplitRightSAH) {
313  /* unsplit to right */
314  right_bounds = rub;
315  swap(refs[left_end], refs[--right_start]);
316  }
317  else {
318  /* duplicate */
319  left_bounds = ldb;
320  right_bounds = rdb;
321  refs[left_end++] = lref;
322  new_refs.push_back(rref);
323  right_end++;
324  }
325  }
326  /* Insert duplicated references into actual array in one go. */
327  if (new_refs.size() != 0) {
328  refs.insert(refs.begin() + (right_end - new_refs.size()), new_refs.begin(), new_refs.end());
329  }
330  if (aligned_space_ != NULL) {
331  left_bounds = right_bounds = BoundBox::empty;
332  for (int i = left_start; i < left_end - left_start; ++i) {
333  BoundBox prim_boundbox = references_->at(i).bounds();
334  left_bounds.grow(prim_boundbox);
335  }
336  for (int i = right_start; i < right_end - right_start; ++i) {
337  BoundBox prim_boundbox = references_->at(i).bounds();
338  right_bounds.grow(prim_boundbox);
339  }
340  }
341  left = BVHRange(left_bounds, left_start, left_end - left_start);
342  right = BVHRange(right_bounds, right_start, right_end - right_start);
343 }
344 
346  const Transform *tfm,
347  int prim_index,
348  int dim,
349  float pos,
350  BoundBox &left_bounds,
351  BoundBox &right_bounds)
352 {
353  Mesh::Triangle t = mesh->get_triangle(prim_index);
354  const float3 *verts = &mesh->verts[0];
355  float3 v1 = tfm ? transform_point(tfm, verts[t.v[2]]) : verts[t.v[2]];
357 
358  for (int i = 0; i < 3; i++) {
359  float3 v0 = v1;
360  int vindex = t.v[i];
361  v1 = tfm ? transform_point(tfm, verts[vindex]) : verts[vindex];
363  float v0p = v0[dim];
364  float v1p = v1[dim];
365 
366  /* insert vertex to the boxes it belongs to. */
367  if (v0p <= pos)
368  left_bounds.grow(v0);
369 
370  if (v0p >= pos)
371  right_bounds.grow(v0);
372 
373  /* edge intersects the plane => insert intersection to both boxes. */
374  if ((v0p < pos && v1p > pos) || (v0p > pos && v1p < pos)) {
375  float3 t = lerp(v0, v1, clamp((pos - v0p) / (v1p - v0p), 0.0f, 1.0f));
376  left_bounds.grow(t);
377  right_bounds.grow(t);
378  }
379  }
380 }
381 
383  const Transform *tfm,
384  int prim_index,
385  int segment_index,
386  int dim,
387  float pos,
388  BoundBox &left_bounds,
389  BoundBox &right_bounds)
390 {
391  /* curve split: NOTE - Currently ignores curve width and needs to be fixed.*/
392  Hair::Curve curve = hair->get_curve(prim_index);
393  const int k0 = curve.first_key + segment_index;
394  const int k1 = k0 + 1;
395  float3 v0 = hair->get_curve_keys()[k0];
396  float3 v1 = hair->get_curve_keys()[k1];
397 
398  if (tfm != NULL) {
399  v0 = transform_point(tfm, v0);
400  v1 = transform_point(tfm, v1);
401  }
402  v0 = get_unaligned_point(v0);
404 
405  float v0p = v0[dim];
406  float v1p = v1[dim];
407 
408  /* insert vertex to the boxes it belongs to. */
409  if (v0p <= pos)
410  left_bounds.grow(v0);
411 
412  if (v0p >= pos)
413  right_bounds.grow(v0);
414 
415  if (v1p <= pos)
416  left_bounds.grow(v1);
417 
418  if (v1p >= pos)
419  right_bounds.grow(v1);
420 
421  /* edge intersects the plane => insert intersection to both boxes. */
422  if ((v0p < pos && v1p > pos) || (v0p > pos && v1p < pos)) {
423  float3 t = lerp(v0, v1, clamp((pos - v0p) / (v1p - v0p), 0.0f, 1.0f));
424  left_bounds.grow(t);
425  right_bounds.grow(t);
426  }
427 }
428 
430  const Mesh *mesh,
431  int dim,
432  float pos,
433  BoundBox &left_bounds,
434  BoundBox &right_bounds)
435 {
436  split_triangle_primitive(mesh, NULL, ref.prim_index(), dim, pos, left_bounds, right_bounds);
437 }
438 
440  const Hair *hair,
441  int dim,
442  float pos,
443  BoundBox &left_bounds,
444  BoundBox &right_bounds)
445 {
447  NULL,
448  ref.prim_index(),
450  dim,
451  pos,
452  left_bounds,
453  right_bounds);
454 }
455 
457  const Object *object, int dim, float pos, BoundBox &left_bounds, BoundBox &right_bounds)
458 {
459  Geometry *geom = object->get_geometry();
460 
461  if (geom->geometry_type == Geometry::MESH || geom->geometry_type == Geometry::VOLUME) {
462  Mesh *mesh = static_cast<Mesh *>(geom);
463  for (int tri_idx = 0; tri_idx < mesh->num_triangles(); ++tri_idx) {
465  mesh, &object->get_tfm(), tri_idx, dim, pos, left_bounds, right_bounds);
466  }
467  }
468  else if (geom->geometry_type == Geometry::HAIR) {
469  Hair *hair = static_cast<Hair *>(geom);
470  for (int curve_idx = 0; curve_idx < hair->num_curves(); ++curve_idx) {
471  Hair::Curve curve = hair->get_curve(curve_idx);
472  for (int segment_idx = 0; segment_idx < curve.num_keys - 1; ++segment_idx) {
474  hair, &object->get_tfm(), curve_idx, segment_idx, dim, pos, left_bounds, right_bounds);
475  }
476  }
477  }
478 }
479 
483  const BVHReference &ref,
484  int dim,
485  float pos)
486 {
487  /* initialize boundboxes */
488  BoundBox left_bounds = BoundBox::empty;
489  BoundBox right_bounds = BoundBox::empty;
490 
491  /* loop over vertices/edges. */
492  const Object *ob = builder.objects[ref.prim_object()];
493 
494  if (ref.prim_type() & PRIMITIVE_ALL_TRIANGLE) {
495  Mesh *mesh = static_cast<Mesh *>(ob->get_geometry());
496  split_triangle_reference(ref, mesh, dim, pos, left_bounds, right_bounds);
497  }
498  else if (ref.prim_type() & PRIMITIVE_ALL_CURVE) {
499  Hair *hair = static_cast<Hair *>(ob->get_geometry());
500  split_curve_reference(ref, hair, dim, pos, left_bounds, right_bounds);
501  }
502  else {
503  split_object_reference(ob, dim, pos, left_bounds, right_bounds);
504  }
505 
506  /* intersect with original bounds. */
507  left_bounds.max[dim] = pos;
508  right_bounds.min[dim] = pos;
509 
510  left_bounds.intersect(ref.bounds());
511  right_bounds.intersect(ref.bounds());
512 
513  /* set references */
514  left = BVHReference(left_bounds, ref.prim_index(), ref.prim_object(), ref.prim_type());
515  right = BVHReference(right_bounds, ref.prim_index(), ref.prim_object(), ref.prim_type());
516 }
517 
typedef float(TangentPoint)[2]
void swap(T &a, T &b)
Definition: Common.h:33
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble right
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble w _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat w _GL_VOID_RET _GL_VOID GLint GLint GLint w _GL_VOID_RET _GL_VOID GLshort GLshort GLshort w _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble y2 _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat y2 _GL_VOID_RET _GL_VOID GLint GLint GLint y2 _GL_VOID_RET _GL_VOID GLshort GLshort GLshort y2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLuint *buffer _GL_VOID_RET _GL_VOID GLdouble t _GL_VOID_RET _GL_VOID GLfloat t _GL_VOID_RET _GL_VOID GLint t _GL_VOID_RET _GL_VOID GLshort t _GL_VOID_RET _GL_VOID GLdouble t
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble v1
void bvh_reference_sort(int start, int end, BVHReference *data, int dim, const BVHUnaligned *unaligned_heuristic, const Transform *aligned_space)
Definition: bvh_sort.cpp:164
vector< Object * > objects
Definition: bvh_build.h:105
BVHParams params
Definition: bvh_build.h:118
BVHSpatialStorage * storage_
Definition: bvh_split.h:55
vector< BVHReference > * references_
Definition: bvh_split.h:56
BoundBox left_bounds
Definition: bvh_split.h:38
BoundBox right_bounds
Definition: bvh_split.h:39
__forceinline BoundBox get_prim_bounds(const BVHReference &prim) const
Definition: bvh_split.h:60
void split(BVHRange &left, BVHRange &right, const BVHRange &range)
Definition: bvh_split.cpp:96
const Transform * aligned_space_
Definition: bvh_split.h:58
const BVHUnaligned * unaligned_heuristic_
Definition: bvh_split.h:57
@ NUM_SPATIAL_BINS
Definition: bvh_params.h:95
__forceinline float primitive_cost(int n) const
Definition: bvh_params.h:133
__forceinline int size() const
Definition: bvh_params.h:266
__forceinline int start() const
Definition: bvh_params.h:262
__forceinline const BoundBox & bounds() const
Definition: bvh_params.h:254
__forceinline int end() const
Definition: bvh_params.h:270
__forceinline int prim_type() const
Definition: bvh_params.h:192
__forceinline int prim_object() const
Definition: bvh_params.h:188
__forceinline const BoundBox & bounds() const
Definition: bvh_params.h:180
__forceinline int prim_index() const
Definition: bvh_params.h:184
void split_curve_primitive(const Hair *hair, const Transform *tfm, int prim_index, int segment_index, int dim, float pos, BoundBox &left_bounds, BoundBox &right_bounds)
Definition: bvh_split.cpp:382
void split_curve_reference(const BVHReference &ref, const Hair *hair, int dim, float pos, BoundBox &left_bounds, BoundBox &right_bounds)
Definition: bvh_split.cpp:439
void split_triangle_primitive(const Mesh *mesh, const Transform *tfm, int prim_index, int dim, float pos, BoundBox &left_bounds, BoundBox &right_bounds)
Definition: bvh_split.cpp:345
__forceinline float3 get_unaligned_point(const float3 &point) const
Definition: bvh_split.h:157
__forceinline BoundBox get_prim_bounds(const BVHReference &prim) const
Definition: bvh_split.h:147
BVHSpatialStorage * storage_
Definition: bvh_split.h:100
void split_object_reference(const Object *object, int dim, float pos, BoundBox &left_bounds, BoundBox &right_bounds)
Definition: bvh_split.cpp:456
const Transform * aligned_space_
Definition: bvh_split.h:103
vector< BVHReference > * references_
Definition: bvh_split.h:101
void split_triangle_reference(const BVHReference &ref, const Mesh *mesh, int dim, float pos, BoundBox &left_bounds, BoundBox &right_bounds)
Definition: bvh_split.cpp:429
void split_reference(const BVHBuild &builder, BVHReference &left, BVHReference &right, const BVHReference &ref, int dim, float pos)
Definition: bvh_split.cpp:480
void split(BVHBuild *builder, BVHRange &left, BVHRange &right, const BVHRange &range)
Definition: bvh_split.cpp:236
BoundBox compute_aligned_boundbox(const BVHObjectBinning &range, const BVHReference *references, const Transform &aligned_space, BoundBox *cent_bounds=NULL) const
Type geometry_type
Definition: geometry.h:78
@ MESH
Definition: geometry.h:73
@ VOLUME
Definition: geometry.h:75
@ HAIR
Definition: geometry.h:74
Curve curve
static float verts[][3]
uint pos
#define CCL_NAMESPACE_END
#define make_int3(x, y, z)
@ PRIMITIVE_ALL_TRIANGLE
Definition: kernel_types.h:697
@ PRIMITIVE_ALL_CURVE
Definition: kernel_types.h:698
#define PRIMITIVE_UNPACK_SEGMENT(type)
Definition: kernel_types.h:711
static int left
static float lerp(float t, float a, float b)
#define min(a, b)
Definition: sort.c:51
BoundBox bounds
Definition: bvh_params.h:283
vector< BVHReference > new_references
Definition: bvh_params.h:309
vector< BoundBox > right_bounds
Definition: bvh_params.h:301
BVHSpatialBin bins[3][BVHParams::NUM_SPATIAL_BINS]
Definition: bvh_params.h:304
float3 max
Definition: util_boundbox.h:34
__forceinline void intersect(const BoundBox &bbox)
__forceinline float safe_area() const
__forceinline void grow(const float3 &pt)
Definition: util_boundbox.h:55
float3 min
Definition: util_boundbox.h:34
Curve get_curve(size_t i) const
Definition: hair.h:119
size_t num_curves() const
Definition: hair.h:133
Triangle get_triangle(size_t i) const
Definition: mesh.h:86
size_t num_triangles() const
Definition: mesh.h:92
float z
Definition: sky_float3.h:35
float y
Definition: sky_float3.h:35
float x
Definition: sky_float3.h:35
ccl_device_inline int clamp(int a, int mn, int mx)
Definition: util_math.h:283
ccl_device_inline float3 transform_point(const Transform *t, const float3 a)