Blender  V3.3
bvh/split.cpp
Go to the documentation of this file.
1 /* SPDX-License-Identifier: Apache-2.0
2  * Adapted from code copyright 2009-2010 NVIDIA Corporation
3  * Modifications Copyright 2011-2022 Blender Foundation. */
4 
5 #include "bvh/split.h"
6 
7 #include "bvh/build.h"
8 #include "bvh/sort.h"
9 
10 #include "scene/hair.h"
11 #include "scene/mesh.h"
12 #include "scene/object.h"
13 #include "scene/pointcloud.h"
14 
15 #include "util/algorithm.h"
16 
18 
19 /* Object Split */
20 
22  BVHSpatialStorage *storage,
23  const BVHRange &range,
24  vector<BVHReference> &references,
25  float nodeSAH,
26  const BVHUnaligned *unaligned_heuristic,
27  const Transform *aligned_space)
28  : sah(FLT_MAX),
29  dim(0),
30  num_left(0),
31  left_bounds(BoundBox::empty),
32  right_bounds(BoundBox::empty),
33  storage_(storage),
34  references_(&references),
35  unaligned_heuristic_(unaligned_heuristic),
36  aligned_space_(aligned_space)
37 {
38  const BVHReference *ref_ptr = &references_->at(range.start());
39  float min_sah = FLT_MAX;
40 
41  storage_->right_bounds.resize(range.size());
42 
43  for (int dim = 0; dim < 3; dim++) {
44  /* Sort references. */
45  bvh_reference_sort(range.start(),
46  range.end(),
47  &references_->at(0),
48  dim,
51 
52  /* sweep right to left and determine bounds. */
54  for (int i = range.size() - 1; i > 0; i--) {
55  BoundBox prim_bounds = get_prim_bounds(ref_ptr[i]);
56  right_bounds.grow(prim_bounds);
58  }
59 
60  /* sweep left to right and select lowest SAH. */
62 
63  for (int i = 1; i < range.size(); i++) {
64  BoundBox prim_bounds = get_prim_bounds(ref_ptr[i - 1]);
65  left_bounds.grow(prim_bounds);
67 
68  float sah = nodeSAH + left_bounds.safe_area() * builder->params.primitive_cost(i) +
69  right_bounds.safe_area() * builder->params.primitive_cost(range.size() - i);
70 
71  if (sah < min_sah) {
72  min_sah = sah;
73 
74  this->sah = sah;
75  this->dim = dim;
76  this->num_left = i;
77  this->left_bounds = left_bounds;
78  this->right_bounds = right_bounds;
79  }
80  }
81  }
82 }
83 
85 {
86  assert(references_->size() > 0);
87  /* sort references according to split */
88  bvh_reference_sort(range.start(),
89  range.end(),
90  &references_->at(0),
91  this->dim,
94 
95  BoundBox effective_left_bounds, effective_right_bounds;
96  const int num_right = range.size() - this->num_left;
97  if (aligned_space_ == NULL) {
98  effective_left_bounds = left_bounds;
99  effective_right_bounds = right_bounds;
100  }
101  else {
102  effective_left_bounds = BoundBox::empty;
103  effective_right_bounds = BoundBox::empty;
104  for (int i = 0; i < this->num_left; ++i) {
105  BoundBox prim_boundbox = references_->at(range.start() + i).bounds();
106  effective_left_bounds.grow(prim_boundbox);
107  }
108  for (int i = 0; i < num_right; ++i) {
109  BoundBox prim_boundbox = references_->at(range.start() + this->num_left + i).bounds();
110  effective_right_bounds.grow(prim_boundbox);
111  }
112  }
113 
114  /* split node ranges */
115  left = BVHRange(effective_left_bounds, range.start(), this->num_left);
116  right = BVHRange(effective_right_bounds, left.end(), num_right);
117 }
118 
119 /* Spatial Split */
120 
122  BVHSpatialStorage *storage,
123  const BVHRange &range,
124  vector<BVHReference> &references,
125  float nodeSAH,
126  const BVHUnaligned *unaligned_heuristic,
127  const Transform *aligned_space)
128  : sah(FLT_MAX),
129  dim(0),
130  pos(0.0f),
131  storage_(storage),
132  references_(&references),
133  unaligned_heuristic_(unaligned_heuristic),
134  aligned_space_(aligned_space)
135 {
136  /* initialize bins. */
137  BoundBox range_bounds;
138  if (aligned_space == NULL) {
139  range_bounds = range.bounds();
140  }
141  else {
142  range_bounds = unaligned_heuristic->compute_aligned_boundbox(
143  range, &references_->at(0), *aligned_space);
144  }
145 
146  float3 origin = range_bounds.min;
147  float3 binSize = (range_bounds.max - origin) * (1.0f / (float)BVHParams::NUM_SPATIAL_BINS);
148  float3 invBinSize = 1.0f / binSize;
149 
150  for (int dim = 0; dim < 3; dim++) {
151  for (int i = 0; i < BVHParams::NUM_SPATIAL_BINS; i++) {
152  BVHSpatialBin &bin = storage_->bins[dim][i];
153 
154  bin.bounds = BoundBox::empty;
155  bin.enter = 0;
156  bin.exit = 0;
157  }
158  }
159 
160  /* chop references into bins. */
161  for (unsigned int refIdx = range.start(); refIdx < range.end(); refIdx++) {
162  const BVHReference &ref = references_->at(refIdx);
163  BoundBox prim_bounds = get_prim_bounds(ref);
164  float3 firstBinf = (prim_bounds.min - origin) * invBinSize;
165  float3 lastBinf = (prim_bounds.max - origin) * invBinSize;
166  int3 firstBin = make_int3((int)firstBinf.x, (int)firstBinf.y, (int)firstBinf.z);
167  int3 lastBin = make_int3((int)lastBinf.x, (int)lastBinf.y, (int)lastBinf.z);
168 
169  firstBin = clamp(firstBin, 0, BVHParams::NUM_SPATIAL_BINS - 1);
170  lastBin = clamp(lastBin, firstBin, BVHParams::NUM_SPATIAL_BINS - 1);
171 
172  for (int dim = 0; dim < 3; dim++) {
173  BVHReference currRef(
174  get_prim_bounds(ref), ref.prim_index(), ref.prim_object(), ref.prim_type());
175 
176  for (int i = firstBin[dim]; i < lastBin[dim]; i++) {
177  BVHReference leftRef, rightRef;
178 
180  builder, leftRef, rightRef, currRef, dim, origin[dim] + binSize[dim] * (float)(i + 1));
181  storage_->bins[dim][i].bounds.grow(leftRef.bounds());
182  currRef = rightRef;
183  }
184 
185  storage_->bins[dim][lastBin[dim]].bounds.grow(currRef.bounds());
186  storage_->bins[dim][firstBin[dim]].enter++;
187  storage_->bins[dim][lastBin[dim]].exit++;
188  }
189  }
190 
191  /* select best split plane. */
193  for (int dim = 0; dim < 3; dim++) {
194  /* sweep right to left and determine bounds. */
195  BoundBox right_bounds = BoundBox::empty;
196  for (int i = BVHParams::NUM_SPATIAL_BINS - 1; i > 0; i--) {
197  right_bounds.grow(storage_->bins[dim][i].bounds);
198  storage_->right_bounds[i - 1] = right_bounds;
199  }
200 
201  /* sweep left to right and select lowest SAH. */
202  BoundBox left_bounds = BoundBox::empty;
203  int leftNum = 0;
204  int rightNum = range.size();
205 
206  for (int i = 1; i < BVHParams::NUM_SPATIAL_BINS; i++) {
207  left_bounds.grow(storage_->bins[dim][i - 1].bounds);
208  leftNum += storage_->bins[dim][i - 1].enter;
209  rightNum -= storage_->bins[dim][i - 1].exit;
210 
211  float sah = nodeSAH + left_bounds.safe_area() * builder.params.primitive_cost(leftNum) +
212  storage_->right_bounds[i - 1].safe_area() *
213  builder.params.primitive_cost(rightNum);
214 
215  if (sah < this->sah) {
216  this->sah = sah;
217  this->dim = dim;
218  this->pos = origin[dim] + binSize[dim] * (float)i;
219  }
220  }
221  }
222 }
223 
225  BVHRange &left,
226  BVHRange &right,
227  const BVHRange &range)
228 {
229  /* Categorize references and compute bounds.
230  *
231  * Left-hand side: [left_start, left_end[
232  * Uncategorized/split: [left_end, right_start[
233  * Right-hand side: [right_start, refs.size()[ */
234 
236  int left_start = range.start();
237  int left_end = left_start;
238  int right_start = range.end();
239  int right_end = range.end();
240  BoundBox left_bounds = BoundBox::empty;
241  BoundBox right_bounds = BoundBox::empty;
242 
243  for (int i = left_end; i < right_start; i++) {
244  BoundBox prim_bounds = get_prim_bounds(refs[i]);
245  if (prim_bounds.max[this->dim] <= this->pos) {
246  /* entirely on the left-hand side */
247  left_bounds.grow(prim_bounds);
248  swap(refs[i], refs[left_end++]);
249  }
250  else if (prim_bounds.min[this->dim] >= this->pos) {
251  /* entirely on the right-hand side */
252  right_bounds.grow(prim_bounds);
253  swap(refs[i--], refs[--right_start]);
254  }
255  }
256 
257  /* Duplicate or unsplit references intersecting both sides.
258  *
259  * Duplication happens into a temporary pre-allocated vector in order to
260  * reduce number of memmove() calls happening in vector.insert().
261  */
263  new_refs.clear();
264  new_refs.reserve(right_start - left_end);
265  while (left_end < right_start) {
266  /* split reference. */
267  BVHReference curr_ref(get_prim_bounds(refs[left_end]),
268  refs[left_end].prim_index(),
269  refs[left_end].prim_object(),
270  refs[left_end].prim_type());
271  BVHReference lref, rref;
272  split_reference(*builder, lref, rref, curr_ref, this->dim, this->pos);
273 
274  /* compute SAH for duplicate/unsplit candidates. */
275  BoundBox lub = left_bounds; // Unsplit to left: new left-hand bounds.
276  BoundBox rub = right_bounds; // Unsplit to right: new right-hand bounds.
277  BoundBox ldb = left_bounds; // Duplicate: new left-hand bounds.
278  BoundBox rdb = right_bounds; // Duplicate: new right-hand bounds.
279 
280  lub.grow(curr_ref.bounds());
281  rub.grow(curr_ref.bounds());
282  ldb.grow(lref.bounds());
283  rdb.grow(rref.bounds());
284 
285  float lac = builder->params.primitive_cost(left_end - left_start);
286  float rac = builder->params.primitive_cost(right_end - right_start);
287  float lbc = builder->params.primitive_cost(left_end - left_start + 1);
288  float rbc = builder->params.primitive_cost(right_end - right_start + 1);
289 
290  float unsplitLeftSAH = lub.safe_area() * lbc + right_bounds.safe_area() * rac;
291  float unsplitRightSAH = left_bounds.safe_area() * lac + rub.safe_area() * rbc;
292  float duplicateSAH = ldb.safe_area() * lbc + rdb.safe_area() * rbc;
293  float minSAH = min(min(unsplitLeftSAH, unsplitRightSAH), duplicateSAH);
294 
295  if (minSAH == unsplitLeftSAH) {
296  /* unsplit to left */
297  left_bounds = lub;
298  left_end++;
299  }
300  else if (minSAH == unsplitRightSAH) {
301  /* unsplit to right */
302  right_bounds = rub;
303  swap(refs[left_end], refs[--right_start]);
304  }
305  else {
306  /* duplicate */
307  left_bounds = ldb;
308  right_bounds = rdb;
309  refs[left_end++] = lref;
310  new_refs.push_back(rref);
311  right_end++;
312  }
313  }
314  /* Insert duplicated references into actual array in one go. */
315  if (new_refs.size() != 0) {
316  refs.insert(refs.begin() + (right_end - new_refs.size()), new_refs.begin(), new_refs.end());
317  }
318  if (aligned_space_ != NULL) {
319  left_bounds = right_bounds = BoundBox::empty;
320  for (int i = left_start; i < left_end - left_start; ++i) {
321  BoundBox prim_boundbox = references_->at(i).bounds();
322  left_bounds.grow(prim_boundbox);
323  }
324  for (int i = right_start; i < right_end - right_start; ++i) {
325  BoundBox prim_boundbox = references_->at(i).bounds();
326  right_bounds.grow(prim_boundbox);
327  }
328  }
329  left = BVHRange(left_bounds, left_start, left_end - left_start);
330  right = BVHRange(right_bounds, right_start, right_end - right_start);
331 }
332 
334  const Transform *tfm,
335  int prim_index,
336  int dim,
337  float pos,
338  BoundBox &left_bounds,
339  BoundBox &right_bounds)
340 {
341  Mesh::Triangle t = mesh->get_triangle(prim_index);
342  const float3 *verts = &mesh->verts[0];
343  float3 v1 = tfm ? transform_point(tfm, verts[t.v[2]]) : verts[t.v[2]];
345 
346  for (int i = 0; i < 3; i++) {
347  float3 v0 = v1;
348  int vindex = t.v[i];
349  v1 = tfm ? transform_point(tfm, verts[vindex]) : verts[vindex];
351  float v0p = v0[dim];
352  float v1p = v1[dim];
353 
354  /* insert vertex to the boxes it belongs to. */
355  if (v0p <= pos)
356  left_bounds.grow(v0);
357 
358  if (v0p >= pos)
359  right_bounds.grow(v0);
360 
361  /* edge intersects the plane => insert intersection to both boxes. */
362  if ((v0p < pos && v1p > pos) || (v0p > pos && v1p < pos)) {
363  float3 t = lerp(v0, v1, clamp((pos - v0p) / (v1p - v0p), 0.0f, 1.0f));
364  left_bounds.grow(t);
365  right_bounds.grow(t);
366  }
367  }
368 }
369 
371  const Transform *tfm,
372  int prim_index,
373  int segment_index,
374  int dim,
375  float pos,
376  BoundBox &left_bounds,
377  BoundBox &right_bounds)
378 {
379  /* curve split: NOTE - Currently ignores curve width and needs to be fixed. */
380  Hair::Curve curve = hair->get_curve(prim_index);
381  const int k0 = curve.first_key + segment_index;
382  const int k1 = k0 + 1;
383  float3 v0 = hair->get_curve_keys()[k0];
384  float3 v1 = hair->get_curve_keys()[k1];
385 
386  if (tfm != NULL) {
387  v0 = transform_point(tfm, v0);
388  v1 = transform_point(tfm, v1);
389  }
390  v0 = get_unaligned_point(v0);
392 
393  float v0p = v0[dim];
394  float v1p = v1[dim];
395 
396  /* insert vertex to the boxes it belongs to. */
397  if (v0p <= pos)
398  left_bounds.grow(v0);
399 
400  if (v0p >= pos)
401  right_bounds.grow(v0);
402 
403  if (v1p <= pos)
404  left_bounds.grow(v1);
405 
406  if (v1p >= pos)
407  right_bounds.grow(v1);
408 
409  /* edge intersects the plane => insert intersection to both boxes. */
410  if ((v0p < pos && v1p > pos) || (v0p > pos && v1p < pos)) {
411  float3 t = lerp(v0, v1, clamp((pos - v0p) / (v1p - v0p), 0.0f, 1.0f));
412  left_bounds.grow(t);
413  right_bounds.grow(t);
414  }
415 }
416 
418  const Transform *tfm,
419  int prim_index,
420  int dim,
421  float pos,
422  BoundBox &left_bounds,
423  BoundBox &right_bounds)
424 {
425  /* No real splitting support for points, assume they are small enough for it
426  * not to matter. */
427  float3 point = pointcloud->get_points()[prim_index];
428 
429  if (tfm != NULL) {
430  point = transform_point(tfm, point);
431  }
433 
434  if (point[dim] <= pos) {
435  left_bounds.grow(point);
436  }
437 
438  if (point[dim] >= pos) {
439  right_bounds.grow(point);
440  }
441 }
442 
444  const Mesh *mesh,
445  int dim,
446  float pos,
447  BoundBox &left_bounds,
448  BoundBox &right_bounds)
449 {
450  split_triangle_primitive(mesh, NULL, ref.prim_index(), dim, pos, left_bounds, right_bounds);
451 }
452 
454  const Hair *hair,
455  int dim,
456  float pos,
457  BoundBox &left_bounds,
458  BoundBox &right_bounds)
459 {
461  NULL,
462  ref.prim_index(),
464  dim,
465  pos,
466  left_bounds,
467  right_bounds);
468 }
469 
471  const PointCloud *pointcloud,
472  int dim,
473  float pos,
474  BoundBox &left_bounds,
475  BoundBox &right_bounds)
476 {
477  split_point_primitive(pointcloud, NULL, ref.prim_index(), dim, pos, left_bounds, right_bounds);
478 }
479 
481  const Object *object, int dim, float pos, BoundBox &left_bounds, BoundBox &right_bounds)
482 {
483  Geometry *geom = object->get_geometry();
484 
485  if (geom->geometry_type == Geometry::MESH || geom->geometry_type == Geometry::VOLUME) {
486  Mesh *mesh = static_cast<Mesh *>(geom);
487  for (int tri_idx = 0; tri_idx < mesh->num_triangles(); ++tri_idx) {
489  mesh, &object->get_tfm(), tri_idx, dim, pos, left_bounds, right_bounds);
490  }
491  }
492  else if (geom->geometry_type == Geometry::HAIR) {
493  Hair *hair = static_cast<Hair *>(geom);
494  for (int curve_idx = 0; curve_idx < hair->num_curves(); ++curve_idx) {
495  Hair::Curve curve = hair->get_curve(curve_idx);
496  for (int segment_idx = 0; segment_idx < curve.num_keys - 1; ++segment_idx) {
498  hair, &object->get_tfm(), curve_idx, segment_idx, dim, pos, left_bounds, right_bounds);
499  }
500  }
501  }
502  else if (geom->geometry_type == Geometry::POINTCLOUD) {
503  PointCloud *pointcloud = static_cast<PointCloud *>(geom);
504  for (int point_idx = 0; point_idx < pointcloud->num_points(); ++point_idx) {
506  pointcloud, &object->get_tfm(), point_idx, dim, pos, left_bounds, right_bounds);
507  }
508  }
509 }
510 
514  const BVHReference &ref,
515  int dim,
516  float pos)
517 {
518  /* initialize boundboxes */
519  BoundBox left_bounds = BoundBox::empty;
520  BoundBox right_bounds = BoundBox::empty;
521 
522  /* loop over vertices/edges. */
523  const Object *ob = builder.objects[ref.prim_object()];
524 
525  if (ref.prim_type() & PRIMITIVE_TRIANGLE) {
526  Mesh *mesh = static_cast<Mesh *>(ob->get_geometry());
527  split_triangle_reference(ref, mesh, dim, pos, left_bounds, right_bounds);
528  }
529  else if (ref.prim_type() & PRIMITIVE_CURVE) {
530  Hair *hair = static_cast<Hair *>(ob->get_geometry());
531  split_curve_reference(ref, hair, dim, pos, left_bounds, right_bounds);
532  }
533  else if (ref.prim_type() & PRIMITIVE_POINT) {
534  PointCloud *pointcloud = static_cast<PointCloud *>(ob->get_geometry());
535  split_point_reference(ref, pointcloud, dim, pos, left_bounds, right_bounds);
536  }
537  else {
538  split_object_reference(ob, dim, pos, left_bounds, right_bounds);
539  }
540 
541  /* intersect with original bounds. */
542  left_bounds.max[dim] = pos;
543  right_bounds.min[dim] = pos;
544 
545  left_bounds.intersect(ref.bounds());
546  right_bounds.intersect(ref.bounds());
547 
548  /* set references */
549  left = BVHReference(left_bounds, ref.prim_index(), ref.prim_object(), ref.prim_type());
550  right = BVHReference(right_bounds, ref.prim_index(), ref.prim_object(), ref.prim_type());
551 }
552 
typedef float(TangentPoint)[2]
void swap(T &a, T &b)
Definition: Common.h:19
_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
in reality light always falls off quadratically Particle Retrieve the data of the particle that spawned the object for example to give variation to multiple instances of an object Point Retrieve information about points in a point cloud Retrieve the edges of an object as it appears to Cycles topology will always appear triangulated Convert a blackbody temperature to an RGB value Normal Generate a perturbed normal from an RGB normal map image Typically used for faking highly detailed surfaces Generate an OSL shader from a file or text data block Image Sample an image file as a texture Sky Generate a procedural sky texture Noise Generate fractal Perlin noise Wave Generate procedural bands or rings with noise Voronoi Generate Worley noise based on the distance to random points Typically used to generate textures such as or biological cells Brick Generate a procedural texture producing bricks Texture Retrieve multiple types of texture coordinates nTypically used as inputs for texture nodes Vector Convert a point
Definition: build.h:34
vector< Object * > objects
Definition: build.h:94
BVHParams params
Definition: build.h:107
BVHSpatialStorage * storage_
Definition: bvh/split.h:43
vector< BVHReference > * references_
Definition: bvh/split.h:44
BoundBox left_bounds
Definition: bvh/split.h:26
BoundBox right_bounds
Definition: bvh/split.h:27
__forceinline BoundBox get_prim_bounds(const BVHReference &prim) const
Definition: bvh/split.h:48
void split(BVHRange &left, BVHRange &right, const BVHRange &range)
Definition: bvh/split.cpp:84
const Transform * aligned_space_
Definition: bvh/split.h:46
const BVHUnaligned * unaligned_heuristic_
Definition: bvh/split.h:45
@ NUM_SPATIAL_BINS
Definition: params.h:108
__forceinline float primitive_cost(int n) const
Definition: params.h:150
__forceinline int size() const
Definition: params.h:289
__forceinline int start() const
Definition: params.h:285
__forceinline const BoundBox & bounds() const
Definition: params.h:277
__forceinline int end() const
Definition: params.h:293
__forceinline int prim_type() const
Definition: params.h:215
__forceinline int prim_object() const
Definition: params.h:211
__forceinline const BoundBox & bounds() const
Definition: params.h:203
__forceinline int prim_index() const
Definition: params.h:207
void split_point_primitive(const PointCloud *pointcloud, const Transform *tfm, int prim_index, int dim, float pos, BoundBox &left_bounds, BoundBox &right_bounds)
Definition: bvh/split.cpp:417
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:370
void split_curve_reference(const BVHReference &ref, const Hair *hair, int dim, float pos, BoundBox &left_bounds, BoundBox &right_bounds)
Definition: bvh/split.cpp:453
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:333
__forceinline float3 get_unaligned_point(const float3 &point) const
Definition: bvh/split.h:158
__forceinline BoundBox get_prim_bounds(const BVHReference &prim) const
Definition: bvh/split.h:148
BVHSpatialStorage * storage_
Definition: bvh/split.h:88
void split_object_reference(const Object *object, int dim, float pos, BoundBox &left_bounds, BoundBox &right_bounds)
Definition: bvh/split.cpp:480
const Transform * aligned_space_
Definition: bvh/split.h:91
vector< BVHReference > * references_
Definition: bvh/split.h:89
void split_triangle_reference(const BVHReference &ref, const Mesh *mesh, int dim, float pos, BoundBox &left_bounds, BoundBox &right_bounds)
Definition: bvh/split.cpp:443
void split_point_reference(const BVHReference &ref, const PointCloud *pointcloud, int dim, float pos, BoundBox &left_bounds, BoundBox &right_bounds)
Definition: bvh/split.cpp:470
void split_reference(const BVHBuild &builder, BVHReference &left, BVHReference &right, const BVHReference &ref, int dim, float pos)
Definition: bvh/split.cpp:511
void split(BVHBuild *builder, BVHRange &left, BVHRange &right, const BVHRange &range)
Definition: bvh/split.cpp:224
BoundBox compute_aligned_boundbox(const BVHObjectBinning &range, const BVHReference *references, const Transform &aligned_space, BoundBox *cent_bounds=NULL) const
Definition: unaligned.cpp:99
Type geometry_type
Definition: hair.h:13
Curve get_curve(size_t i) const
Definition: hair.h:109
size_t num_curves() const
Definition: hair.h:123
#define CCL_NAMESPACE_END
Definition: cuda/compat.h:9
Curve curve
static float verts[][3]
uint pos
CCL_NAMESPACE_END CCL_NAMESPACE_BEGIN ccl_device_inline float3 transform_point(ccl_private const Transform *t, const float3 a)
@ PRIMITIVE_CURVE
Definition: kernel/types.h:564
@ PRIMITIVE_TRIANGLE
Definition: kernel/types.h:551
@ PRIMITIVE_POINT
Definition: kernel/types.h:554
#define PRIMITIVE_UNPACK_SEGMENT(type)
Definition: kernel/types.h:579
static int left
#define make_int3(x, y, z)
Definition: metal/compat.h:207
static float lerp(float t, float a, float b)
T clamp(const T &a, const T &min, const T &max)
#define min(a, b)
Definition: sort.c:35
void bvh_reference_sort(int start, int end, BVHReference *data, int dim, const BVHUnaligned *unaligned_heuristic, const Transform *aligned_space)
Definition: sort.cpp:151
BoundBox bounds
Definition: params.h:306
vector< BVHReference > new_references
Definition: params.h:332
vector< BoundBox > right_bounds
Definition: params.h:324
BVHSpatialBin bins[3][BVHParams::NUM_SPATIAL_BINS]
Definition: params.h:327
@ empty
Definition: boundbox.h:35
float3 max
Definition: boundbox.h:21
__forceinline void intersect(const BoundBox &bbox)
Definition: boundbox.h:88
__forceinline float safe_area() const
Definition: boundbox.h:95
__forceinline void grow(const float3 &pt)
Definition: boundbox.h:42
float3 min
Definition: boundbox.h:21
Triangle get_triangle(size_t i) const
Definition: scene/mesh.h:73
size_t num_triangles() const
Definition: scene/mesh.h:79
size_t num_points() const
float z
float y
float x