52 prim_type(prim_type_),
53 prim_index(prim_index_),
54 prim_object(prim_object_),
55 prim_time(prim_time_),
58 progress_start_time(0.0),
59 unaligned_heuristic(objects_)
77 for (
uint j = 0; j < num_triangles; j++) {
80 if (attr_mP ==
NULL) {
95 const size_t num_verts =
mesh->verts.
size();
96 const size_t num_steps =
mesh->motion_steps;
100 for (
size_t step = 0; step < num_steps - 1; step++) {
101 t.bounds_grow(vert_steps + step * num_verts,
bounds);
115 const float num_bvh_steps_inv_1 = 1.0f / (num_bvh_steps - 1);
116 const size_t num_verts =
mesh->verts.
size();
117 const size_t num_steps =
mesh->motion_steps;
124 t.motion_verts(
verts, vert_steps, num_verts, num_steps, 0.0f, prev_verts);
126 prev_bounds.
grow(prev_verts[0]);
127 prev_bounds.
grow(prev_verts[1]);
128 prev_bounds.
grow(prev_verts[2]);
130 for (
int bvh_step = 1; bvh_step < num_bvh_steps; ++bvh_step) {
131 const float curr_time = (
float)(bvh_step)*num_bvh_steps_inv_1;
133 t.motion_verts(
verts, vert_steps, num_verts, num_steps, curr_time, curr_verts);
135 curr_bounds.
grow(curr_verts[0]);
136 curr_bounds.
grow(curr_verts[1]);
137 curr_bounds.
grow(curr_verts[2]);
141 const float prev_time = (
float)(bvh_step - 1) * num_bvh_steps_inv_1;
150 prev_bounds = curr_bounds;
164 (curve_attr_mP !=
NULL) ?
170 for (
uint j = 0; j < num_curves; j++) {
172 const float *curve_radius = &hair->get_curve_radius()[0];
173 for (
int k = 0; k <
curve.num_keys - 1; k++) {
174 if (curve_attr_mP ==
NULL) {
177 curve.bounds_grow(k, &hair->get_curve_keys()[0], curve_radius,
bounds);
192 curve.bounds_grow(k, &hair->get_curve_keys()[0], curve_radius,
bounds);
193 const size_t num_keys = hair->get_curve_keys().size();
194 const size_t num_steps = hair->get_motion_steps();
196 for (
size_t step = 0; step < num_steps - 1; step++) {
197 curve.bounds_grow(k, key_steps + step * num_keys, curve_radius,
bounds);
212 const float num_bvh_steps_inv_1 = 1.0f / (num_bvh_steps - 1);
213 const size_t num_steps = hair->get_motion_steps();
214 const float3 *curve_keys = &hair->get_curve_keys()[0];
216 const size_t num_keys = hair->get_curve_keys().size();
222 curve.cardinal_motion_keys(curve_keys,
234 curve.bounds_grow(prev_keys, prev_bounds);
236 for (
int bvh_step = 1; bvh_step < num_bvh_steps; ++bvh_step) {
237 const float curr_time = (
float)(bvh_step)*num_bvh_steps_inv_1;
239 curve.cardinal_motion_keys(curve_keys,
251 curve.bounds_grow(curr_keys, curr_bounds);
255 const float prev_time = (
float)(bvh_step - 1) * num_bvh_steps_inv_1;
264 prev_bounds = curr_bounds;
278 Hair *hair =
static_cast<Hair *
>(geom);
292 size_t num = 0, num_curves = hair->
num_curves();
294 for (
size_t i = 0; i < num_curves; i++)
307 Hair *hair =
static_cast<Hair *
>(geom);
317 size_t num_alloc_references = 0;
324 if (!ob->get_geometry()->is_instanced()) {
328 num_alloc_references++;
347 if (!ob->get_geometry()->is_instanced())
396 double build_start_time;
436 VLOG(1) <<
"BVH build cancelled.";
443 if (rootnode !=
NULL) {
444 VLOG(1) <<
"BVH build statistics:\n"
445 <<
" Build time: " <<
time_dt() - build_start_time <<
"\n"
446 <<
" Total number of nodes: "
449 <<
" Number of inner nodes: "
452 <<
" Number of leaf nodes: "
455 <<
" Number of unaligned nodes: "
458 <<
" Allocation slop factor: "
462 <<
" Maximum depth: "
479 "Building BVH %.0f%%, duplicates %.0f%%", progress_start * 100.0, duplicates * 100.0);
536 if (
size > max_leaf_size)
539 size_t num_triangles = 0;
540 size_t num_motion_triangles = 0;
541 size_t num_curves = 0;
542 size_t num_motion_curves = 0;
544 for (
int i = 0; i <
size; i++) {
557 num_motion_triangles++;
591 float unalignedSplitSAH = FLT_MAX;
592 float unalignedLeafSAH = FLT_MAX;
594 bool do_unalinged_split =
false;
603 if (unalignedLeafSAH < unalignedSplitSAH && unalignedSplitSAH < splitSAH &&
609 if (unalignedSplitSAH < splitSAH) {
610 do_unalinged_split =
true;
616 if (do_unalinged_split) {
624 if (do_unalinged_split) {
648 if (do_unalinged_split) {
684 if (
split.no_split) {
694 float unalignedSplitSAH = FLT_MAX;
697 bool do_unalinged_split =
false;
707 if (unalignedSplitSAH < splitSAH) {
708 do_unalinged_split =
true;
714 if (do_unalinged_split) {
724 if (do_unalinged_split) {
760 task_pool.
push([=, refs = std::move(left_references)]()
mutable {
763 task_pool.
push([=, refs = std::move(right_references)]()
mutable {
768 if (do_unalinged_split) {
831 typedef StackAllocator<256, int> LeafStackAllocator;
832 typedef StackAllocator<256, float2> LeafTimeStackAllocator;
833 typedef StackAllocator<256, BVHReference> LeafReferenceStackAllocator;
849 int num_new_prims = 0;
851 for (
int i = 0; i < range.
size(); i++) {
855 p_ref[type_index].push_back(ref);
856 p_type[type_index].push_back(ref.
prim_type());
857 p_index[type_index].push_back(ref.
prim_index());
866 object_references.push_back(ref);
882 size_t start_index = 0;
885 local_prim_type.resize(num_new_prims);
886 local_prim_index.resize(num_new_prims);
887 local_prim_object.resize(num_new_prims);
889 local_prim_time.resize(num_new_prims);
892 int num = (int)p_type[i].
size();
894 assert(p_type[i].
size() == p_index[i].
size());
895 assert(p_type[i].
size() == p_object[i].
size());
897 bool alignment_found =
false;
898 for (
int j = 0; j < num; ++j) {
899 const int index = start_index + j;
900 local_prim_type[index] = p_type[i][j];
901 local_prim_index[index] = p_index[i][j];
902 local_prim_object[index] = p_object[i][j];
904 local_prim_time[index] = p_time[i][j];
912 float time_from = 1.0f, time_to = 0.0f;
913 for (
int j = 0; j < num; ++j) {
921 if (alignment_found) {
924 for (
int j = 0; j < num; ++j) {
933 leaves[num_leaves++] = leaf_node;
938 const int num_new_leaf_data = start_index;
939 const size_t new_leaf_data_size =
sizeof(int) * num_new_leaf_data;
952 const size_t range_end = start_index + range.
size();
960 const size_t reserve = (size_t)(range_end + (
float)range_end * factor);
977 if (new_leaf_data_size > 0) {
978 memcpy(&
prim_type[start_index], &local_prim_type[0], new_leaf_data_size);
979 memcpy(&
prim_index[start_index], &local_prim_index[0], new_leaf_data_size);
980 memcpy(&
prim_object[start_index], &local_prim_object[0], new_leaf_data_size);
982 memcpy(&
prim_time[start_index], &local_prim_time[0],
sizeof(
float2) * num_new_leaf_data);
992 start_index = range.
start();
993 if (new_leaf_data_size > 0) {
994 memcpy(&
prim_type[start_index], &local_prim_type[0], new_leaf_data_size);
995 memcpy(&
prim_index[start_index], &local_prim_index[0], new_leaf_data_size);
996 memcpy(&
prim_object[start_index], &local_prim_object[0], new_leaf_data_size);
998 memcpy(&
prim_time[start_index], &local_prim_time[0],
sizeof(
float2) * num_new_leaf_data);
1007 for (
int i = 0; i < num_leaves; ++i) {
1009 leaf->
lo += start_index;
1010 leaf->
hi += start_index;
1014 if (num_leaves == 0 || ob_num) {
1026 if (num_leaves == 1) {
1033 else if (num_leaves == 2) {
1036 else if (num_leaves == 3) {
1043 assert(num_leaves <= 5);
1050 if (num_leaves == 5) {
1056 #undef MAX_ITEMS_PER_LEAF
1066 for (
int i = 0; i < iterations; i++)
1073 if (
node->is_leaf() || max_depth < 0)
1079 for (
size_t c = 0;
c < 2;
c++)
1088 float4 child_area =
make_float4(area0, area1, 0.0f, 0.0f);
1092 float best_cost = FLT_MAX;
1093 int best_child = -1, best_target = -1, best_other = -1;
1095 for (
size_t c = 0;
c < 2;
c++) {
1101 BoundBox &other = (
c == 0) ? bounds1 : bounds0;
1111 if (
min(cost0, cost1) < best_cost) {
1112 best_child = (int)
c;
1113 best_other = (int)(1 -
c);
1115 if (cost0 < cost1) {
1130 assert(best_child == 0 || best_child == 1);
1131 assert(best_target != -1);
typedef float(TangentPoint)[2]
typedef double(DMatrix)[4][4]
NSNotificationCenter * center
_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
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
static btDbvtVolume bounds(btDbvtNode **leaves, int count)
static size_t count_primitives(Geometry *geom)
static size_t count_curve_segments(Hair *hair)
@ BVH_STAT_UNALIGNED_COUNT
Attribute * find(ustring name) const
BVHNode * create_object_leaf_nodes(const BVHReference *ref, int start, int num)
BVHNode * create_leaf_node(const BVHRange &range, const vector< BVHReference > &references)
void thread_build_spatial_split_node(InnerNode *node, int child, const BVHRange &range, vector< BVHReference > &references, int level)
BVHBuild(const vector< Object * > &objects, array< int > &prim_type, array< int > &prim_index, array< int > &prim_object, array< float2 > &prim_time, const BVHParams ¶ms, Progress &progress)
bool range_within_max_leaf_size(const BVHRange &range, const vector< BVHReference > &references) const
thread_spin_lock spatial_spin_lock
void add_references(BVHRange &root)
void add_reference_object(BoundBox &root, BoundBox ¢er, Object *ob, int i)
BVHNode * build_node(const BVHRange &range, vector< BVHReference > &references, int level, BVHSpatialStorage *storage)
void add_reference_curves(BoundBox &root, BoundBox ¢er, Hair *hair, int i)
size_t spatial_free_index
BVHUnaligned unaligned_heuristic
void add_reference_geometry(BoundBox &root, BoundBox ¢er, Geometry *geom, int i)
friend class BVHObjectBinning
array< float2 > & prim_time
vector< Object * > objects
array< int > & prim_index
void rotate(BVHNode *node, int max_depth)
enumerable_thread_specific< BVHSpatialStorage > spatial_storage
size_t progress_original_total
void thread_build_node(InnerNode *node, int child, const BVHObjectBinning &range, int level)
float spatial_min_overlap
double progress_start_time
array< int > & prim_object
friend class BVHMixedSplit
vector< BVHReference > references
void add_reference_triangles(BoundBox &root, BoundBox ¢er, Mesh *mesh, int i)
__forceinline void split(BVHBuild *builder, BVHRange &left, BVHRange &right, const BVHRange &range)
void split(BVHReference *prims, BVHObjectBinning &left_o, BVHObjectBinning &right_o) const
__forceinline const BoundBox & unaligned_bounds()
int max_triangle_leaf_size
int num_motion_triangle_steps
float spatial_split_alpha
__forceinline bool small_enough_for_leaf(int size, int level)
int max_motion_curve_leaf_size
int max_motion_triangle_leaf_size
float unaligned_split_threshold
int num_motion_curve_steps
__forceinline int size() const
__forceinline int start() const
__forceinline const BoundBox & bounds() const
__forceinline int prim_type() const
__forceinline int prim_object() const
__forceinline const BoundBox & bounds() const
__forceinline float time_from() const
__forceinline float time_to() const
__forceinline int prim_index() const
Transform compute_aligned_space(const BVHObjectBinning &range, const BVHReference *references) const
BoundBox compute_aligned_boundbox(const BVHObjectBinning &range, const BVHReference *references, const Transform &aligned_space, BoundBox *cent_bounds=NULL) const
BoundBox compute_aligned_prim_boundbox(const BVHReference &prim, const Transform &aligned_space) const
bool has_motion_blur() const
BVHNode * children[kNumMaxChildren]
void set_substatus(const string &substatus_)
T * resize(size_t newsize)
void reserve(size_t newcapacity)
#define CCL_NAMESPACE_END
#define make_float2(x, y)
#define make_float4(x, y, z, w)
#define PRIMITIVE_PACK_SEGMENT(type, segment)
@ PRIMITIVE_MOTION_CURVE_RIBBON
@ PRIMITIVE_MOTION_TRIANGLE
@ PRIMITIVE_MOTION_CURVE_THICK
@ ATTR_STD_MOTION_VERTEX_POSITION
void split(const std::string &s, const char delim, std::vector< std::string > &tokens)
int getSubtreeSize(BVH_STAT stat=BVH_STAT_NODE_COUNT) const
virtual bool is_leaf() const =0
void set_aligned_space(const Transform &aligned_space)
__forceinline float half_area() const
__forceinline float safe_area() const
__forceinline void grow(const float3 &pt)
__forceinline float3 center2() const
Curve get_curve(size_t i) const
size_t num_curves() const
CurveShapeType curve_shape
Triangle get_triangle(size_t i) const
size_t num_triangles() const
NODE_DECLARE BoundBox bounds
bool is_traceable() const
void push(TaskRunFunction &&task)
void wait_work(Summary *stats=NULL)
__forceinline BoundBox merge(const BoundBox &bbox, const float3 &pt)
ccl_device_inline float3 zero_float3()
__forceinline uint32_t bitscan(uint32_t value)
string string_human_readable_number(size_t num)
CCL_NAMESPACE_BEGIN string string_printf(const char *format,...)
std::unique_lock< std::mutex > thread_scoped_lock
CCL_NAMESPACE_BEGIN double time_dt()