57 for (
int i = range.
size() - 1; i > 0; i--) {
66 for (
int i = 1; i < range.
size(); i++) {
98 BoundBox effective_left_bounds, effective_right_bounds;
107 for (
int i = 0; i < this->
num_left; ++i) {
109 effective_left_bounds.
grow(prim_boundbox);
111 for (
int i = 0; i < num_right; ++i) {
113 effective_right_bounds.
grow(prim_boundbox);
119 right =
BVHRange(effective_right_bounds,
left.end(), num_right);
141 if (aligned_space ==
NULL) {
142 range_bounds = range.
bounds();
151 float3 invBinSize = 1.0f / binSize;
164 for (
unsigned int refIdx = range.
start(); refIdx < range.
end(); refIdx++) {
165 const BVHReference &ref = references_->at(refIdx);
166 BoundBox prim_bounds = get_prim_bounds(ref);
167 float3 firstBinf = (prim_bounds.min - origin) * invBinSize;
168 float3 lastBinf = (prim_bounds.max - origin) * invBinSize;
169 int3 firstBin = make_int3((int)firstBinf.x, (int)firstBinf.y, (int)firstBinf.z);
170 int3 lastBin = make_int3((int)lastBinf.x, (int)lastBinf.y, (int)lastBinf.z);
172 firstBin = clamp(firstBin, 0, BVHParams::NUM_SPATIAL_BINS - 1);
173 lastBin = clamp(lastBin, firstBin, BVHParams::NUM_SPATIAL_BINS - 1);
175 for (int dim = 0; dim < 3; dim++) {
176 BVHReference currRef(
177 get_prim_bounds(ref), ref.prim_index(), ref.prim_object(), ref.prim_type());
179 for (int i = firstBin[dim]; i < lastBin[dim]; i++) {
180 BVHReference leftRef, rightRef;
183 builder, leftRef, rightRef, currRef, dim, origin[dim] + binSize[dim] * (float)(i + 1));
184 storage_->bins[dim][i].bounds.grow(leftRef.bounds());
188 storage_->bins[dim][lastBin[dim]].bounds.grow(currRef.bounds());
189 storage_->bins[dim][firstBin[dim]].enter++;
190 storage_->bins[dim][lastBin[dim]].exit++;
196 for (
int dim = 0; dim < 3; dim++) {
200 right_bounds.
grow(storage_->bins[dim][i].bounds);
201 storage_->right_bounds[i - 1] = right_bounds;
207 int rightNum = range.size();
210 left_bounds.
grow(storage_->bins[dim][i - 1].bounds);
211 leftNum += storage_->bins[dim][i - 1].enter;
212 rightNum -= storage_->bins[dim][i - 1].exit;
214 float sah = nodeSAH + left_bounds.
safe_area() * builder.params.primitive_cost(leftNum) +
215 storage_->right_bounds[i - 1].safe_area() *
216 builder.params.primitive_cost(rightNum);
218 if (sah < this->sah) {
221 this->
pos = origin[dim] + binSize[dim] * (
float)i;
239 int left_start = range.
start();
240 int left_end = left_start;
241 int right_start = range.
end();
242 int right_end = range.
end();
246 for (
int i = left_end; i < right_start; i++) {
248 if (prim_bounds.
max[this->dim] <= this->pos) {
250 left_bounds.
grow(prim_bounds);
251 swap(refs[i], refs[left_end++]);
253 else if (prim_bounds.
min[this->dim] >= this->pos) {
255 right_bounds.
grow(prim_bounds);
256 swap(refs[i--], refs[--right_start]);
267 new_refs.reserve(right_start - left_end);
268 while (left_end < right_start) {
271 refs[left_end].prim_index(),
272 refs[left_end].prim_object(),
273 refs[left_end].prim_type());
296 float minSAH =
min(
min(unsplitLeftSAH, unsplitRightSAH), duplicateSAH);
298 if (minSAH == unsplitLeftSAH) {
303 else if (minSAH == unsplitRightSAH) {
306 swap(refs[left_end], refs[--right_start]);
312 refs[left_end++] = lref;
313 new_refs.push_back(rref);
318 if (new_refs.size() != 0) {
319 refs.insert(refs.begin() + (right_end - new_refs.size()), new_refs.begin(), new_refs.end());
323 for (
int i = left_start; i < left_end - left_start; ++i) {
325 left_bounds.
grow(prim_boundbox);
327 for (
int i = right_start; i < right_end - right_start; ++i) {
329 right_bounds.
grow(prim_boundbox);
332 left =
BVHRange(left_bounds, left_start, left_end - left_start);
333 right =
BVHRange(right_bounds, right_start, right_end - right_start);
349 for (
int i = 0; i < 3; i++) {
359 left_bounds.
grow(v0);
363 right_bounds.
grow(v0);
367 if ((v0p < pos && v1p >
pos) || (v0p >
pos && v1p <
pos)) {
370 right_bounds.
grow(t);
386 const int k0 = curve.
first_key + segment_index;
387 const int k1 = k0 + 1;
388 float3 v0 = hair->get_curve_keys()[k0];
389 float3 v1 = hair->get_curve_keys()[k1];
403 left_bounds.
grow(v0);
407 right_bounds.
grow(v0);
411 left_bounds.
grow(v1);
415 right_bounds.
grow(v1);
419 if ((v0p < pos && v1p >
pos) || (v0p >
pos && v1p <
pos)) {
422 right_bounds.
grow(t);
436 float3 point = pointcloud->get_points()[prim_index];
437 float radius = pointcloud->get_radius()[prim_index];
493 Geometry *geom =
object->get_geometry();
496 Mesh *mesh =
static_cast<Mesh *
>(geom);
497 for (
int tri_idx = 0; tri_idx < mesh->
num_triangles(); ++tri_idx) {
499 mesh, &object->get_tfm(), tri_idx,
dim,
pos, left_bounds, right_bounds);
503 Hair *hair =
static_cast<Hair *
>(geom);
504 for (
int curve_idx = 0; curve_idx < hair->
num_curves(); ++curve_idx) {
506 for (
int segment_idx = 0; segment_idx < curve.
num_keys - 1; ++segment_idx) {
508 hair, &object->get_tfm(), curve_idx, segment_idx,
dim,
pos, left_bounds, right_bounds);
514 for (
int point_idx = 0; point_idx < pointcloud->
num_points(); ++point_idx) {
516 pointcloud, &object->get_tfm(), point_idx,
dim,
pos, left_bounds, right_bounds);
536 Mesh *mesh =
static_cast<Mesh *
>(ob->get_geometry());
540 Hair *hair =
static_cast<Hair *
>(ob->get_geometry());
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 Gabor Generate Gabor noise Gradient Generate interpolated color and intensity values based on the input vector Magic Generate a psychedelic color texture 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
vector< Object * > objects
BVHSpatialStorage * storage_
vector< BVHReference > * references_
__forceinline BoundBox get_prim_bounds(const BVHReference &prim) const
void split(BVHRange &left, BVHRange &right, const BVHRange &range)
const Transform * aligned_space_
const BVHUnaligned * unaligned_heuristic_
__forceinline float primitive_cost(int n) const
__forceinline int size() const
__forceinline int start() const
__forceinline const BoundBox & bounds() const
__forceinline int end() const
__forceinline int prim_type() const
__forceinline int prim_object() const
__forceinline const BoundBox & bounds() const
__forceinline int prim_index() const
void split_point_primitive(const PointCloud *pointcloud, const Transform *tfm, int prim_index, int dim, float pos, BoundBox &left_bounds, BoundBox &right_bounds)
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)
const BVHUnaligned * unaligned_heuristic_
void split_curve_reference(const BVHReference &ref, const Hair *hair, int dim, float pos, BoundBox &left_bounds, BoundBox &right_bounds)
void split_triangle_primitive(const Mesh *mesh, const Transform *tfm, int prim_index, int dim, float pos, BoundBox &left_bounds, BoundBox &right_bounds)
__forceinline float3 get_unaligned_point(const float3 &point) const
__forceinline BoundBox get_prim_bounds(const BVHReference &prim) const
BVHSpatialStorage * storage_
void split_object_reference(const Object *object, int dim, float pos, BoundBox &left_bounds, BoundBox &right_bounds)
const Transform * aligned_space_
vector< BVHReference > * references_
void split_triangle_reference(const BVHReference &ref, const Mesh *mesh, int dim, float pos, BoundBox &left_bounds, BoundBox &right_bounds)
void split_point_reference(const BVHReference &ref, const PointCloud *pointcloud, int dim, float pos, BoundBox &left_bounds, BoundBox &right_bounds)
void split_reference(const BVHBuild &builder, BVHReference &left, BVHReference &right, const BVHReference &ref, int dim, float pos)
void split(BVHBuild *builder, BVHRange &left, BVHRange &right, const BVHRange &range)
BoundBox compute_aligned_boundbox(const BVHObjectBinning &range, const BVHReference *references, const Transform &aligned_space, BoundBox *cent_bounds=NULL) const
Curve get_curve(size_t i) const
size_t num_curves() const
#define CCL_NAMESPACE_END
draw_view in_light_buf[] float
#define PRIMITIVE_UNPACK_SEGMENT(type)
void bvh_reference_sort(int start, int end, BVHReference *data, int dim, const BVHUnaligned *unaligned_heuristic, const Transform *aligned_space)
__forceinline void intersect(const BoundBox &bbox)
__forceinline float safe_area() const
__forceinline void grow(const float3 &pt)
Triangle get_triangle(size_t i) const
size_t num_triangles() const
size_t num_points() const
ccl_device_inline int clamp(int a, int mn, int mx)