60 for (
int i = range.
size() - 1;
i > 0;
i--) {
69 for (
int i = 1;
i < range.
size();
i++) {
114 effective_left_bounds.
grow(prim_boundbox);
116 for (
int i = 0;
i < num_right; ++
i) {
118 effective_right_bounds.
grow(prim_boundbox);
124 right =
BVHRange(effective_right_bounds,
left.end(), num_right);
146 if (aligned_space ==
nullptr) {
147 range_bounds = range.
bounds();
169 for (
unsigned int refIdx = range.
start(); refIdx < range.
end(); refIdx++) {
172 const float3 firstBinf = (prim_bounds.
min - origin) * invBinSize;
173 const float3 lastBinf = (prim_bounds.
max - origin) * invBinSize;
174 int3 firstBin =
make_int3((
int)firstBinf.
x, (
int)firstBinf.
y, (
int)firstBinf.
z);
175 int3 lastBin =
make_int3((
int)lastBinf.
x, (
int)lastBinf.
y, (
int)lastBinf.
z);
184 for (
int i = firstBin[
dim];
i < lastBin[
dim];
i++) {
189 builder, leftRef, rightRef, currRef,
dim, origin[
dim] + binSize[
dim] * (
float)(
i + 1));
207 storage_->right_bounds[
i - 1] = right_bounds;
213 int rightNum = range.
size();
220 const float sah = nodeSAH +
222 storage_->right_bounds[
i - 1].safe_area() *
246 const int left_start = range.
start();
247 int left_end = left_start;
248 int right_start = range.
end();
249 int right_end = range.
end();
253 for (
int i = left_end;
i < right_start;
i++) {
255 if (prim_bounds.
max[this->dim] <= this->pos) {
257 left_bounds.
grow(prim_bounds);
258 swap(refs[
i], refs[left_end++]);
260 else if (prim_bounds.
min[this->dim] >= this->pos) {
262 right_bounds.
grow(prim_bounds);
263 swap(refs[
i--], refs[--right_start]);
274 new_refs.reserve(right_start - left_end);
275 while (left_end < right_start) {
278 refs[left_end].prim_index(),
279 refs[left_end].prim_object(),
280 refs[left_end].prim_type());
304 const float minSAH =
min(
min(unsplitLeftSAH, unsplitRightSAH), duplicateSAH);
306 if (minSAH == unsplitLeftSAH) {
311 else if (minSAH == unsplitRightSAH) {
314 swap(refs[left_end], refs[--right_start]);
320 refs[left_end++] = lref;
321 new_refs.push_back(rref);
326 if (!new_refs.empty()) {
327 refs.insert(refs.begin() + (right_end - new_refs.size()), new_refs.begin(), new_refs.end());
331 for (
int i = left_start;
i < left_end - left_start; ++
i) {
333 left_bounds.
grow(prim_boundbox);
335 for (
int i = right_start;
i < right_end - right_start; ++
i) {
337 right_bounds.
grow(prim_boundbox);
340 left =
BVHRange(left_bounds, left_start, left_end - left_start);
341 right =
BVHRange(right_bounds, right_start, right_end - right_start);
346 const int prim_index,
357 for (
int i = 0;
i < 3;
i++) {
359 const int vindex = t.
v[
i];
362 const float v0p = v0[
dim];
363 const float v1p = v1[
dim];
367 left_bounds.
grow(v0);
371 right_bounds.
grow(v0);
375 if ((v0p < pos && v1p >
pos) || (v0p >
pos && v1p <
pos)) {
378 right_bounds.
grow(t);
385 const int prim_index,
386 const int segment_index,
394 const int k0 = curve.
first_key + segment_index;
395 const int k1 = k0 + 1;
396 float3 v0 = hair->get_curve_keys()[k0];
397 float3 v1 = hair->get_curve_keys()[k1];
399 if (tfm !=
nullptr) {
406 const float v0p = v0[
dim];
407 const float v1p = v1[
dim];
411 left_bounds.
grow(v0);
415 right_bounds.
grow(v0);
419 left_bounds.
grow(v1);
423 right_bounds.
grow(v1);
427 if ((v0p < pos && v1p >
pos) || (v0p >
pos && v1p <
pos)) {
430 right_bounds.
grow(t);
436 const int prim_index,
444 float3 point = pointcloud->get_points()[prim_index];
445 const float radius = pointcloud->get_radius()[prim_index];
447 if (tfm !=
nullptr) {
452 if (point[
dim] - radius <=
pos) {
453 left_bounds.
grow(point, radius);
456 if (point[
dim] + radius >=
pos) {
457 right_bounds.
grow(point, radius);
496 pointcloud,
nullptr, ref.
prim_index(),
dim,
pos, left_bounds, right_bounds);
505 Geometry *geom =
object->get_geometry();
508 Mesh *mesh =
static_cast<Mesh *
>(geom);
509 for (
int tri_idx = 0; tri_idx < mesh->
num_triangles(); ++tri_idx) {
511 mesh, &object->get_tfm(), tri_idx,
dim,
pos, left_bounds, right_bounds);
515 Hair *hair =
static_cast<Hair *
>(geom);
516 for (
int curve_idx = 0; curve_idx < hair->
num_curves(); ++curve_idx) {
518 for (
int segment_idx = 0; segment_idx < curve.
num_keys - 1; ++segment_idx) {
520 hair, &object->get_tfm(), curve_idx, segment_idx,
dim,
pos, left_bounds, right_bounds);
526 for (
int point_idx = 0; point_idx < pointcloud->
num_points(); ++point_idx) {
528 pointcloud, &object->get_tfm(), point_idx,
dim,
pos, left_bounds, right_bounds);
548 Mesh *mesh =
static_cast<Mesh *
>(ob->get_geometry());
552 Hair *hair =
static_cast<Hair *
>(ob->get_geometry());
MINLINE float safe_divide(float a, float b)
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(const 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
const BVHUnaligned * unaligned_heuristic_
void split_curve_reference(const BVHReference &ref, const Hair *hair, const int dim, const 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
void split_reference(const BVHBuild &builder, BVHReference &left, BVHReference &right, const BVHReference &ref, const int dim, float pos)
void split_triangle_reference(const BVHReference &ref, const Mesh *mesh, const int dim, const float pos, BoundBox &left_bounds, BoundBox &right_bounds)
BVHSpatialStorage * storage_
const Transform * aligned_space_
vector< BVHReference > * references_
void split_curve_primitive(const Hair *hair, const Transform *tfm, const int prim_index, const int segment_index, const int dim, const float pos, BoundBox &left_bounds, BoundBox &right_bounds)
void split_point_primitive(const PointCloud *pointcloud, const Transform *tfm, const int prim_index, const int dim, const float pos, BoundBox &left_bounds, BoundBox &right_bounds)
void split_triangle_primitive(const Mesh *mesh, const Transform *tfm, const int prim_index, const int dim, const float pos, BoundBox &left_bounds, BoundBox &right_bounds)
void split_object_reference(const Object *object, const int dim, const float pos, BoundBox &left_bounds, BoundBox &right_bounds)
void split(BVHBuild *builder, BVHRange &left, BVHRange &right, const BVHRange &range)
void split_point_reference(const BVHReference &ref, const PointCloud *pointcloud, const int dim, const float pos, BoundBox &left_bounds, BoundBox &right_bounds)
BoundBox compute_aligned_boundbox(const BVHObjectBinning &range, const BVHReference *references, const Transform &aligned_space, BoundBox *cent_bounds=nullptr) const
bool is_pointcloud() const
Curve get_curve(const size_t i) const
size_t num_curves() const
#define PRIMITIVE_UNPACK_SEGMENT(type)
#define CCL_NAMESPACE_END
#define assert(assertion)
constexpr T clamp(T, U, U) RET
void bvh_reference_sort(const int start, const int end, BVHReference *data, const 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)
size_t num_triangles() const
Triangle get_triangle(const size_t i) const
size_t num_points() const