Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'intern/cycles/bvh/bvh_build.cpp')
-rw-r--r--intern/cycles/bvh/bvh_build.cpp428
1 files changed, 322 insertions, 106 deletions
diff --git a/intern/cycles/bvh/bvh_build.cpp b/intern/cycles/bvh/bvh_build.cpp
index 14f66aca70f..649ce52da05 100644
--- a/intern/cycles/bvh/bvh_build.cpp
+++ b/intern/cycles/bvh/bvh_build.cpp
@@ -15,25 +15,27 @@
* limitations under the License.
*/
-#include "bvh_binning.h"
-#include "bvh_build.h"
-#include "bvh_node.h"
-#include "bvh_params.h"
-#include "bvh_split.h"
+#include "bvh/bvh_build.h"
-#include "mesh.h"
-#include "object.h"
-#include "scene.h"
-#include "curves.h"
+#include "bvh/bvh_binning.h"
+#include "bvh/bvh_node.h"
+#include "bvh/bvh_params.h"
+#include "bvh_split.h"
-#include "util_debug.h"
-#include "util_foreach.h"
-#include "util_logging.h"
-#include "util_progress.h"
-#include "util_stack_allocator.h"
-#include "util_simd.h"
-#include "util_time.h"
-#include "util_queue.h"
+#include "render/mesh.h"
+#include "render/object.h"
+#include "render/scene.h"
+#include "render/curves.h"
+
+#include "util/util_algorithm.h"
+#include "util/util_debug.h"
+#include "util/util_foreach.h"
+#include "util/util_logging.h"
+#include "util/util_progress.h"
+#include "util/util_stack_allocator.h"
+#include "util/util_simd.h"
+#include "util/util_time.h"
+#include "util/util_queue.h"
CCL_NAMESPACE_BEGIN
@@ -92,12 +94,14 @@ BVHBuild::BVHBuild(const vector<Object*>& objects_,
array<int>& prim_type_,
array<int>& prim_index_,
array<int>& prim_object_,
+ array<float2>& prim_time_,
const BVHParams& params_,
Progress& progress_)
: objects(objects_),
prim_type(prim_type_),
prim_index(prim_index_),
prim_object(prim_object_),
+ prim_time(prim_time_),
params(params_),
progress(progress_),
progress_start_time(0.0),
@@ -112,81 +116,237 @@ BVHBuild::~BVHBuild()
/* Adding References */
-void BVHBuild::add_reference_mesh(BoundBox& root, BoundBox& center, Mesh *mesh, int i)
+void BVHBuild::add_reference_triangles(BoundBox& root, BoundBox& center, Mesh *mesh, int i)
{
- if(params.primitive_mask & PRIMITIVE_ALL_TRIANGLE) {
- Attribute *attr_mP = NULL;
-
- if(mesh->has_motion_blur())
- attr_mP = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
-
- size_t num_triangles = mesh->num_triangles();
- for(uint j = 0; j < num_triangles; j++) {
- Mesh::Triangle t = mesh->get_triangle(j);
+ const Attribute *attr_mP = NULL;
+ if(mesh->has_motion_blur()) {
+ attr_mP = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
+ }
+ const size_t num_triangles = mesh->num_triangles();
+ for(uint j = 0; j < num_triangles; j++) {
+ Mesh::Triangle t = mesh->get_triangle(j);
+ const float3 *verts = &mesh->verts[0];
+ if(attr_mP == NULL) {
BoundBox bounds = BoundBox::empty;
- PrimitiveType type = PRIMITIVE_TRIANGLE;
-
- t.bounds_grow(&mesh->verts[0], bounds);
-
- /* motion triangles */
- if(attr_mP) {
- size_t mesh_size = mesh->verts.size();
- size_t steps = mesh->motion_steps - 1;
- float3 *vert_steps = attr_mP->data_float3();
-
- for(size_t i = 0; i < steps; i++)
- t.bounds_grow(vert_steps + i*mesh_size, bounds);
-
- type = PRIMITIVE_MOTION_TRIANGLE;
+ t.bounds_grow(verts, bounds);
+ if(bounds.valid()) {
+ references.push_back(BVHReference(bounds,
+ j,
+ i,
+ PRIMITIVE_TRIANGLE));
+ root.grow(bounds);
+ center.grow(bounds.center2());
+ }
+ }
+ else if(params.num_motion_triangle_steps == 0 || params.use_spatial_split) {
+ /* Motion triangles, simple case: single node for the whole
+ * primitive. Lowest memory footprint and faster BVH build but
+ * least optimal ray-tracing.
+ */
+ /* TODO(sergey): Support motion steps for spatially split BVH. */
+ const size_t num_verts = mesh->verts.size();
+ const size_t num_steps = mesh->motion_steps;
+ const float3 *vert_steps = attr_mP->data_float3();
+ BoundBox bounds = BoundBox::empty;
+ t.bounds_grow(verts, bounds);
+ for(size_t step = 0; step < num_steps - 1; step++) {
+ t.bounds_grow(vert_steps + step*num_verts, bounds);
}
-
if(bounds.valid()) {
- references.push_back(BVHReference(bounds, j, i, type));
+ references.push_back(
+ BVHReference(bounds,
+ j,
+ i,
+ PRIMITIVE_MOTION_TRIANGLE));
root.grow(bounds);
center.grow(bounds.center2());
}
}
+ else {
+ /* Motion triangles, trace optimized case: we split triangle
+ * primitives into separate nodes for each of the time steps.
+ * This way we minimize overlap of neighbor curve primitives.
+ */
+ const int num_bvh_steps = params.num_motion_curve_steps * 2 + 1;
+ const float num_bvh_steps_inv_1 = 1.0f / (num_bvh_steps - 1);
+ const size_t num_verts = mesh->verts.size();
+ const size_t num_steps = mesh->motion_steps;
+ const float3 *vert_steps = attr_mP->data_float3();
+ /* Calculate bounding box of the previous time step.
+ * Will be reused later to avoid duplicated work on
+ * calculating BVH time step boundbox.
+ */
+ float3 prev_verts[3];
+ t.motion_verts(verts,
+ vert_steps,
+ num_verts,
+ num_steps,
+ 0.0f,
+ prev_verts);
+ BoundBox prev_bounds = BoundBox::empty;
+ prev_bounds.grow(prev_verts[0]);
+ prev_bounds.grow(prev_verts[1]);
+ prev_bounds.grow(prev_verts[2]);
+ /* Create all primitive time steps, */
+ for(int bvh_step = 1; bvh_step < num_bvh_steps; ++bvh_step) {
+ const float curr_time = (float)(bvh_step) * num_bvh_steps_inv_1;
+ float3 curr_verts[3];
+ t.motion_verts(verts,
+ vert_steps,
+ num_verts,
+ num_steps,
+ curr_time,
+ curr_verts);
+ BoundBox curr_bounds = BoundBox::empty;
+ curr_bounds.grow(curr_verts[0]);
+ curr_bounds.grow(curr_verts[1]);
+ curr_bounds.grow(curr_verts[2]);
+ BoundBox bounds = prev_bounds;
+ bounds.grow(curr_bounds);
+ if(bounds.valid()) {
+ const float prev_time = (float)(bvh_step - 1) * num_bvh_steps_inv_1;
+ references.push_back(
+ BVHReference(bounds,
+ j,
+ i,
+ PRIMITIVE_MOTION_TRIANGLE,
+ prev_time,
+ curr_time));
+ root.grow(bounds);
+ center.grow(bounds.center2());
+ }
+ /* Current time boundbox becomes previous one for the
+ * next time step.
+ */
+ prev_bounds = curr_bounds;
+ }
+ }
}
+}
- if(params.primitive_mask & PRIMITIVE_ALL_CURVE) {
- Attribute *curve_attr_mP = NULL;
-
- if(mesh->has_motion_blur())
- curve_attr_mP = mesh->curve_attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
-
- size_t num_curves = mesh->num_curves();
- for(uint j = 0; j < num_curves; j++) {
- Mesh::Curve curve = mesh->get_curve(j);
- PrimitiveType type = PRIMITIVE_CURVE;
-
- for(int k = 0; k < curve.num_keys - 1; k++) {
+void BVHBuild::add_reference_curves(BoundBox& root, BoundBox& center, Mesh *mesh, int i)
+{
+ const Attribute *curve_attr_mP = NULL;
+ if(mesh->has_motion_blur()) {
+ curve_attr_mP = mesh->curve_attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
+ }
+ const size_t num_curves = mesh->num_curves();
+ for(uint j = 0; j < num_curves; j++) {
+ const Mesh::Curve curve = mesh->get_curve(j);
+ const float *curve_radius = &mesh->curve_radius[0];
+ for(int k = 0; k < curve.num_keys - 1; k++) {
+ if(curve_attr_mP == NULL) {
+ /* Really simple logic for static hair. */
BoundBox bounds = BoundBox::empty;
- curve.bounds_grow(k, &mesh->curve_keys[0], &mesh->curve_radius[0], bounds);
-
- /* motion curve */
- if(curve_attr_mP) {
- size_t mesh_size = mesh->curve_keys.size();
- size_t steps = mesh->motion_steps - 1;
- float3 *key_steps = curve_attr_mP->data_float3();
-
- for(size_t i = 0; i < steps; i++)
- curve.bounds_grow(k, key_steps + i*mesh_size, &mesh->curve_radius[0], bounds);
-
- type = PRIMITIVE_MOTION_CURVE;
- }
-
+ curve.bounds_grow(k, &mesh->curve_keys[0], curve_radius, bounds);
if(bounds.valid()) {
- int packed_type = PRIMITIVE_PACK_SEGMENT(type, k);
-
+ int packed_type = PRIMITIVE_PACK_SEGMENT(PRIMITIVE_CURVE, k);
references.push_back(BVHReference(bounds, j, i, packed_type));
root.grow(bounds);
center.grow(bounds.center2());
}
}
+ else if(params.num_motion_curve_steps == 0 || params.use_spatial_split) {
+ /* Simple case of motion curves: single node for the while
+ * shutter time. Lowest memory usage but less optimal
+ * rendering.
+ */
+ /* TODO(sergey): Support motion steps for spatially split BVH. */
+ BoundBox bounds = BoundBox::empty;
+ curve.bounds_grow(k, &mesh->curve_keys[0], curve_radius, bounds);
+ const size_t num_keys = mesh->curve_keys.size();
+ const size_t num_steps = mesh->motion_steps;
+ const float3 *key_steps = curve_attr_mP->data_float3();
+ for(size_t step = 0; step < num_steps - 1; step++) {
+ curve.bounds_grow(k,
+ key_steps + step*num_keys,
+ curve_radius,
+ bounds);
+ }
+ if(bounds.valid()) {
+ int packed_type = PRIMITIVE_PACK_SEGMENT(PRIMITIVE_MOTION_CURVE, k);
+ references.push_back(BVHReference(bounds,
+ j,
+ i,
+ packed_type));
+ root.grow(bounds);
+ center.grow(bounds.center2());
+ }
+ }
+ else {
+ /* Motion curves, trace optimized case: we split curve keys
+ * primitives into separate nodes for each of the time steps.
+ * This way we minimize overlap of neighbor curve primitives.
+ */
+ const int num_bvh_steps = params.num_motion_curve_steps * 2 + 1;
+ const float num_bvh_steps_inv_1 = 1.0f / (num_bvh_steps - 1);
+ const size_t num_steps = mesh->motion_steps;
+ const float3 *curve_keys = &mesh->curve_keys[0];
+ const float3 *key_steps = curve_attr_mP->data_float3();
+ const size_t num_keys = mesh->curve_keys.size();
+ /* Calculate bounding box of the previous time step.
+ * Will be reused later to avoid duplicated work on
+ * calculating BVH time step boundbox.
+ */
+ float4 prev_keys[4];
+ curve.cardinal_motion_keys(curve_keys,
+ curve_radius,
+ key_steps,
+ num_keys,
+ num_steps,
+ 0.0f,
+ k - 1, k, k + 1, k + 2,
+ prev_keys);
+ BoundBox prev_bounds = BoundBox::empty;
+ curve.bounds_grow(prev_keys, prev_bounds);
+ /* Create all primitive time steps, */
+ for(int bvh_step = 1; bvh_step < num_bvh_steps; ++bvh_step) {
+ const float curr_time = (float)(bvh_step) * num_bvh_steps_inv_1;
+ float4 curr_keys[4];
+ curve.cardinal_motion_keys(curve_keys,
+ curve_radius,
+ key_steps,
+ num_keys,
+ num_steps,
+ curr_time,
+ k - 1, k, k + 1, k + 2,
+ curr_keys);
+ BoundBox curr_bounds = BoundBox::empty;
+ curve.bounds_grow(curr_keys, curr_bounds);
+ BoundBox bounds = prev_bounds;
+ bounds.grow(curr_bounds);
+ if(bounds.valid()) {
+ const float prev_time = (float)(bvh_step - 1) * num_bvh_steps_inv_1;
+ int packed_type = PRIMITIVE_PACK_SEGMENT(PRIMITIVE_MOTION_CURVE, k);
+ references.push_back(BVHReference(bounds,
+ j,
+ i,
+ packed_type,
+ prev_time,
+ curr_time));
+ root.grow(bounds);
+ center.grow(bounds.center2());
+ }
+ /* Current time boundbox becomes previous one for the
+ * next time step.
+ */
+ prev_bounds = curr_bounds;
+ }
+ }
}
}
}
+void BVHBuild::add_reference_mesh(BoundBox& root, BoundBox& center, Mesh *mesh, int i)
+{
+ if(params.primitive_mask & PRIMITIVE_ALL_TRIANGLE) {
+ add_reference_triangles(root, center, mesh, i);
+ }
+ if(params.primitive_mask & PRIMITIVE_ALL_CURVE) {
+ add_reference_curves(root, center, mesh, i);
+ }
+}
+
void BVHBuild::add_reference_object(BoundBox& root, BoundBox& center, Object *ob, int i)
{
references.push_back(BVHReference(ob->bounds, -1, i, 0));
@@ -200,7 +360,7 @@ static size_t count_curve_segments(Mesh *mesh)
for(size_t i = 0; i < num_curves; i++)
num += mesh->get_curve(i).num_keys - 1;
-
+
return num;
}
@@ -308,6 +468,9 @@ BVHNode* BVHBuild::run()
}
spatial_free_index = 0;
+ need_prim_time = params.num_motion_curve_steps > 0 ||
+ params.num_motion_triangle_steps > 0;
+
/* init progress updates */
double build_start_time;
build_start_time = progress_start_time = time_dt();
@@ -318,6 +481,12 @@ BVHNode* BVHBuild::run()
prim_type.resize(references.size());
prim_index.resize(references.size());
prim_object.resize(references.size());
+ if(need_prim_time) {
+ prim_time.resize(references.size());
+ }
+ else {
+ prim_time.resize(0);
+ }
/* build recursively */
BVHNode *rootnode;
@@ -344,6 +513,7 @@ BVHNode* BVHBuild::run()
else {
/*rotate(rootnode, 4, 5);*/
rootnode->update_visibility();
+ rootnode->update_time();
}
if(rootnode != NULL) {
VLOG(1) << "BVH build statistics:\n"
@@ -359,7 +529,9 @@ BVHNode* BVHBuild::run()
<< " Allocation slop factor: "
<< ((prim_type.capacity() != 0)
? (float)prim_type.size() / prim_type.capacity()
- : 1.0f) << "\n";
+ : 1.0f) << "\n"
+ << " Maximum depth: "
+ << string_human_readable_number(rootnode->getSubtreeSize(BVH_STAT_DEPTH)) << "\n";
}
}
@@ -371,7 +543,7 @@ void BVHBuild::progress_update()
{
if(time_dt() - progress_start_time < 0.25)
return;
-
+
double progress_start = (double)progress_count/(double)progress_total;
double duplicates = (double)(progress_total - progress_original_total)/(double)progress_total;
@@ -379,7 +551,7 @@ void BVHBuild::progress_update()
progress_start * 100.0, duplicates * 100.0);
progress.set_substatus(msg);
- progress_start_time = time_dt();
+ progress_start_time = time_dt();
}
void BVHBuild::thread_build_node(InnerNode *inner,
@@ -435,6 +607,7 @@ bool BVHBuild::range_within_max_leaf_size(const BVHRange& range,
return false;
size_t num_triangles = 0;
+ size_t num_motion_triangles = 0;
size_t num_curves = 0;
size_t num_motion_curves = 0;
@@ -445,13 +618,16 @@ bool BVHBuild::range_within_max_leaf_size(const BVHRange& range,
num_curves++;
if(ref.prim_type() & PRIMITIVE_MOTION_CURVE)
num_motion_curves++;
- else if(ref.prim_type() & PRIMITIVE_ALL_TRIANGLE)
+ else if(ref.prim_type() & PRIMITIVE_TRIANGLE)
num_triangles++;
+ else if(ref.prim_type() & PRIMITIVE_MOTION_TRIANGLE)
+ num_motion_triangles++;
}
- return (num_triangles < params.max_triangle_leaf_size) &&
- (num_curves < params.max_curve_leaf_size) &&
- (num_motion_curves < params.max_curve_leaf_size);
+ return (num_triangles <= params.max_triangle_leaf_size) &&
+ (num_motion_triangles <= params.max_motion_triangle_leaf_size) &&
+ (num_curves <= params.max_curve_leaf_size) &&
+ (num_motion_curves <= params.max_motion_curve_leaf_size);
}
/* multithreaded binning builder */
@@ -497,7 +673,7 @@ BVHNode* BVHBuild::build_node(const BVHObjectBinning& range, int level)
return create_leaf_node(range, references);
}
}
- /* Check whether unaligned split is better than the regulat one. */
+ /* Check whether unaligned split is better than the regular one. */
if(unalignedSplitSAH < splitSAH) {
do_unalinged_split = true;
}
@@ -687,20 +863,29 @@ BVHNode *BVHBuild::create_object_leaf_nodes(const BVHReference *ref, int start,
prim_type[start] = ref->prim_type();
prim_index[start] = ref->prim_index();
prim_object[start] = ref->prim_object();
+ if(need_prim_time) {
+ prim_time[start] = make_float2(ref->time_from(), ref->time_to());
+ }
- uint visibility = objects[ref->prim_object()]->visibility;
- return new LeafNode(ref->bounds(), visibility, start, start+1);
+ const uint visibility = objects[ref->prim_object()]->visibility_for_tracing();
+ BVHNode *leaf_node = new LeafNode(ref->bounds(), visibility, start, start+1);
+ leaf_node->time_from = ref->time_from();
+ leaf_node->time_to = ref->time_to();
+ return leaf_node;
}
else {
int mid = num/2;
- BVHNode *leaf0 = create_object_leaf_nodes(ref, start, mid);
- BVHNode *leaf1 = create_object_leaf_nodes(ref+mid, start+mid, num-mid);
+ BVHNode *leaf0 = create_object_leaf_nodes(ref, start, mid);
+ BVHNode *leaf1 = create_object_leaf_nodes(ref+mid, start+mid, num-mid);
BoundBox bounds = BoundBox::empty;
- bounds.grow(leaf0->m_bounds);
- bounds.grow(leaf1->m_bounds);
+ bounds.grow(leaf0->bounds);
+ bounds.grow(leaf1->bounds);
- return new InnerNode(bounds, leaf0, leaf1);
+ BVHNode *inner_node = new InnerNode(bounds, leaf0, leaf1);
+ inner_node->time_from = min(leaf0->time_from, leaf1->time_from);
+ inner_node->time_to = max(leaf0->time_to, leaf1->time_to);
+ return inner_node;
}
}
@@ -723,11 +908,13 @@ BVHNode* BVHBuild::create_leaf_node(const BVHRange& range,
* can not control.
*/
typedef StackAllocator<256, int> LeafStackAllocator;
+ typedef StackAllocator<256, float2> LeafTimeStackAllocator;
typedef StackAllocator<256, BVHReference> LeafReferenceStackAllocator;
vector<int, LeafStackAllocator> p_type[PRIMITIVE_NUM_TOTAL];
vector<int, LeafStackAllocator> p_index[PRIMITIVE_NUM_TOTAL];
vector<int, LeafStackAllocator> p_object[PRIMITIVE_NUM_TOTAL];
+ vector<float2, LeafTimeStackAllocator> p_time[PRIMITIVE_NUM_TOTAL];
vector<BVHReference, LeafReferenceStackAllocator> p_ref[PRIMITIVE_NUM_TOTAL];
/* TODO(sergey): In theory we should be able to store references. */
@@ -750,9 +937,11 @@ BVHNode* BVHBuild::create_leaf_node(const BVHRange& range,
p_type[type_index].push_back(ref.prim_type());
p_index[type_index].push_back(ref.prim_index());
p_object[type_index].push_back(ref.prim_object());
+ p_time[type_index].push_back(make_float2(ref.time_from(),
+ ref.time_to()));
bounds[type_index].grow(ref.bounds());
- visibility[type_index] |= objects[ref.prim_object()]->visibility;
+ visibility[type_index] |= objects[ref.prim_object()]->visibility_for_tracing();
if(ref.prim_type() & PRIMITIVE_ALL_CURVE) {
visibility[type_index] |= PATH_RAY_CURVE;
}
@@ -779,9 +968,13 @@ BVHNode* BVHBuild::create_leaf_node(const BVHRange& range,
vector<int, LeafStackAllocator> local_prim_type,
local_prim_index,
local_prim_object;
+ vector<float2, LeafTimeStackAllocator> local_prim_time;
local_prim_type.resize(num_new_prims);
local_prim_index.resize(num_new_prims);
local_prim_object.resize(num_new_prims);
+ if(need_prim_time) {
+ local_prim_time.resize(num_new_prims);
+ }
for(int i = 0; i < PRIMITIVE_NUM_TOTAL; ++i) {
int num = (int)p_type[i].size();
if(num != 0) {
@@ -794,6 +987,9 @@ BVHNode* BVHBuild::create_leaf_node(const BVHRange& range,
local_prim_type[index] = p_type[i][j];
local_prim_index[index] = p_index[i][j];
local_prim_object[index] = p_object[i][j];
+ if(need_prim_time) {
+ local_prim_time[index] = p_time[i][j];
+ }
if(params.use_unaligned_nodes && !alignment_found) {
alignment_found =
unaligned_heuristic.compute_aligned_space(p_ref[i][j],
@@ -804,16 +1000,26 @@ BVHNode* BVHBuild::create_leaf_node(const BVHRange& range,
visibility[i],
start_index,
start_index + num);
+ if(true) {
+ float time_from = 1.0f, time_to = 0.0f;
+ for(int j = 0; j < num; ++j) {
+ const BVHReference &ref = p_ref[i][j];
+ time_from = min(time_from, ref.time_from());
+ time_to = max(time_to, ref.time_to());
+ }
+ leaf_node->time_from = time_from;
+ leaf_node->time_to = time_to;
+ }
if(alignment_found) {
/* Need to recalculate leaf bounds with new alignment. */
- leaf_node->m_bounds = BoundBox::empty;
+ leaf_node->bounds = BoundBox::empty;
for(int j = 0; j < num; ++j) {
const BVHReference &ref = p_ref[i][j];
BoundBox ref_bounds =
unaligned_heuristic.compute_aligned_prim_boundbox(
ref,
aligned_space);
- leaf_node->m_bounds.grow(ref_bounds);
+ leaf_node->bounds.grow(ref_bounds);
}
/* Set alignment space. */
leaf_node->set_aligned_space(aligned_space);
@@ -836,7 +1042,6 @@ BVHNode* BVHBuild::create_leaf_node(const BVHRange& range,
*/
start_index = spatial_free_index;
spatial_free_index += range.size();
-
/* Extend an array when needed. */
const size_t range_end = start_index + range.size();
if(prim_type.size() < range_end) {
@@ -850,20 +1055,28 @@ BVHNode* BVHBuild::create_leaf_node(const BVHRange& range,
prim_type.reserve(reserve);
prim_index.reserve(reserve);
prim_object.reserve(reserve);
+ if(need_prim_time) {
+ prim_time.reserve(reserve);
+ }
}
prim_type.resize(range_end);
prim_index.resize(range_end);
prim_object.resize(range_end);
+ if(need_prim_time) {
+ prim_time.resize(range_end);
+ }
}
- spatial_spin_lock.unlock();
-
/* Perform actual data copy. */
if(new_leaf_data_size > 0) {
memcpy(&prim_type[start_index], &local_prim_type[0], new_leaf_data_size);
memcpy(&prim_index[start_index], &local_prim_index[0], new_leaf_data_size);
memcpy(&prim_object[start_index], &local_prim_object[0], new_leaf_data_size);
+ if(need_prim_time) {
+ memcpy(&prim_time[start_index], &local_prim_time[0], sizeof(float2)*num_new_leaf_data);
+ }
}
+ spatial_spin_lock.unlock();
}
else {
/* For the regular BVH builder we simply copy new data starting at the
@@ -875,6 +1088,9 @@ BVHNode* BVHBuild::create_leaf_node(const BVHRange& range,
memcpy(&prim_type[start_index], &local_prim_type[0], new_leaf_data_size);
memcpy(&prim_index[start_index], &local_prim_index[0], new_leaf_data_size);
memcpy(&prim_object[start_index], &local_prim_object[0], new_leaf_data_size);
+ if(need_prim_time) {
+ memcpy(&prim_time[start_index], &local_prim_time[0], sizeof(float2)*num_new_leaf_data);
+ }
}
}
@@ -884,8 +1100,8 @@ BVHNode* BVHBuild::create_leaf_node(const BVHRange& range,
*/
for(int i = 0; i < num_leaves; ++i) {
LeafNode *leaf = (LeafNode *)leaves[i];
- leaf->m_lo += start_index;
- leaf->m_hi += start_index;
+ leaf->lo += start_index;
+ leaf->hi += start_index;
}
/* Create leaf node for object. */
@@ -914,17 +1130,17 @@ BVHNode* BVHBuild::create_leaf_node(const BVHRange& range,
return new InnerNode(range.bounds(), leaves[0], leaves[1]);
}
else if(num_leaves == 3) {
- BoundBox inner_bounds = merge(leaves[1]->m_bounds, leaves[2]->m_bounds);
+ BoundBox inner_bounds = merge(leaves[1]->bounds, leaves[2]->bounds);
BVHNode *inner = new InnerNode(inner_bounds, leaves[1], leaves[2]);
return new InnerNode(range.bounds(), leaves[0], inner);
} else {
- /* Shpuld be doing more branches if more primitive types added. */
+ /* Should be doing more branches if more primitive types added. */
assert(num_leaves <= 5);
- BoundBox inner_bounds_a = merge(leaves[0]->m_bounds, leaves[1]->m_bounds);
- BoundBox inner_bounds_b = merge(leaves[2]->m_bounds, leaves[3]->m_bounds);
+ BoundBox inner_bounds_a = merge(leaves[0]->bounds, leaves[1]->bounds);
+ BoundBox inner_bounds_b = merge(leaves[2]->bounds, leaves[3]->bounds);
BVHNode *inner_a = new InnerNode(inner_bounds_a, leaves[0], leaves[1]);
BVHNode *inner_b = new InnerNode(inner_bounds_b, leaves[2], leaves[3]);
- BoundBox inner_bounds_c = merge(inner_a->m_bounds, inner_b->m_bounds);
+ BoundBox inner_bounds_c = merge(inner_a->bounds, inner_b->bounds);
BVHNode *inner_c = new InnerNode(inner_bounds_c, inner_a, inner_b);
if(num_leaves == 5) {
return new InnerNode(range.bounds(), inner_c, leaves[4]);
@@ -951,7 +1167,7 @@ void BVHBuild::rotate(BVHNode *node, int max_depth)
/* nothing to rotate if we reached a leaf node. */
if(node->is_leaf() || max_depth < 0)
return;
-
+
InnerNode *parent = (InnerNode*)node;
/* rotate all children first */
@@ -959,8 +1175,8 @@ void BVHBuild::rotate(BVHNode *node, int max_depth)
rotate(parent->children[c], max_depth-1);
/* compute current area of all children */
- BoundBox bounds0 = parent->children[0]->m_bounds;
- BoundBox bounds1 = parent->children[1]->m_bounds;
+ BoundBox bounds0 = parent->children[0]->bounds;
+ BoundBox bounds1 = parent->children[1]->bounds;
float area0 = bounds0.half_area();
float area1 = bounds1.half_area();
@@ -980,8 +1196,8 @@ void BVHBuild::rotate(BVHNode *node, int max_depth)
BoundBox& other = (c == 0)? bounds1: bounds0;
/* transpose child bounds */
- BoundBox target0 = child->children[0]->m_bounds;
- BoundBox target1 = child->children[1]->m_bounds;
+ BoundBox target0 = child->children[0]->bounds;
+ BoundBox target1 = child->children[1]->bounds;
/* compute cost for both possible swaps */
float cost0 = merge(other, target1).half_area() - child_area[c];
@@ -1013,7 +1229,7 @@ void BVHBuild::rotate(BVHNode *node, int max_depth)
InnerNode *child = (InnerNode*)parent->children[best_child];
swap(parent->children[best_other], child->children[best_target]);
- child->m_bounds = merge(child->children[0]->m_bounds, child->children[1]->m_bounds);
+ child->bounds = merge(child->children[0]->bounds, child->children[1]->bounds);
}
CCL_NAMESPACE_END