Code cleanup: deduplicate primitive refit code.

This commit is contained in:
Brecht Van Lommel 2017-10-13 18:36:10 +01:00
parent 383df45af9
commit 811dbf5525
4 changed files with 74 additions and 122 deletions

@ -108,6 +108,73 @@ void BVH::refit(Progress& progress)
refit_nodes(); refit_nodes();
} }
void BVH::refit_primitives(int start, int end, BoundBox& bbox, uint& visibility)
{
/* Refit range of primitives. */
for(int prim = start; prim < end; prim++) {
int pidx = pack.prim_index[prim];
int tob = pack.prim_object[prim];
Object *ob = objects[tob];
if(pidx == -1) {
/* Object instance. */
bbox.grow(ob->bounds);
}
else {
/* Primitives. */
const Mesh *mesh = ob->mesh;
if(pack.prim_type[prim] & PRIMITIVE_ALL_CURVE) {
/* Curves. */
int str_offset = (params.top_level)? mesh->curve_offset: 0;
Mesh::Curve curve = mesh->get_curve(pidx - str_offset);
int k = PRIMITIVE_UNPACK_SEGMENT(pack.prim_type[prim]);
curve.bounds_grow(k, &mesh->curve_keys[0], &mesh->curve_radius[0], bbox);
visibility |= PATH_RAY_CURVE;
/* Motion curves. */
if(mesh->use_motion_blur) {
Attribute *attr = mesh->curve_attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
if(attr) {
size_t mesh_size = mesh->curve_keys.size();
size_t steps = mesh->motion_steps - 1;
float3 *key_steps = attr->data_float3();
for(size_t i = 0; i < steps; i++)
curve.bounds_grow(k, key_steps + i*mesh_size, &mesh->curve_radius[0], bbox);
}
}
}
else {
/* Triangles. */
int tri_offset = (params.top_level)? mesh->tri_offset: 0;
Mesh::Triangle triangle = mesh->get_triangle(pidx - tri_offset);
const float3 *vpos = &mesh->verts[0];
triangle.bounds_grow(vpos, bbox);
/* Motion triangles. */
if(mesh->use_motion_blur) {
Attribute *attr = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
if(attr) {
size_t mesh_size = mesh->verts.size();
size_t steps = mesh->motion_steps - 1;
float3 *vert_steps = attr->data_float3();
for(size_t i = 0; i < steps; i++)
triangle.bounds_grow(vert_steps + i*mesh_size, bbox);
}
}
}
}
visibility |= ob->visibility_for_tracing();
}
}
/* Triangles */ /* Triangles */
void BVH::pack_triangle(int idx, float4 tri_verts[3]) void BVH::pack_triangle(int idx, float4 tri_verts[3])

@ -91,6 +91,9 @@ public:
protected: protected:
BVH(const BVHParams& params, const vector<Object*>& objects); BVH(const BVHParams& params, const vector<Object*>& objects);
/* Refit range of primitives. */
void refit_primitives(int start, int end, BoundBox& bbox, uint& visibility);
/* triangles and strands */ /* triangles and strands */
void pack_primitives(); void pack_primitives();
void pack_triangle(int idx, float4 storage[3]); void pack_triangle(int idx, float4 storage[3]);

@ -247,73 +247,14 @@ void BVH2::refit_nodes()
void BVH2::refit_node(int idx, bool leaf, BoundBox& bbox, uint& visibility) void BVH2::refit_node(int idx, bool leaf, BoundBox& bbox, uint& visibility)
{ {
if(leaf) { if(leaf) {
/* refit leaf node */
assert(idx + BVH_NODE_LEAF_SIZE <= pack.leaf_nodes.size()); assert(idx + BVH_NODE_LEAF_SIZE <= pack.leaf_nodes.size());
const int4 *data = &pack.leaf_nodes[idx]; const int4 *data = &pack.leaf_nodes[idx];
const int c0 = data[0].x; const int c0 = data[0].x;
const int c1 = data[0].y; const int c1 = data[0].y;
/* refit leaf node */
for(int prim = c0; prim < c1; prim++) {
int pidx = pack.prim_index[prim];
int tob = pack.prim_object[prim];
Object *ob = objects[tob];
if(pidx == -1) { BVH::refit_primitives(c0, c1, bbox, visibility);
/* object instance */
bbox.grow(ob->bounds);
}
else {
/* primitives */
const Mesh *mesh = ob->mesh;
if(pack.prim_type[prim] & PRIMITIVE_ALL_CURVE) {
/* curves */
int str_offset = (params.top_level)? mesh->curve_offset: 0;
Mesh::Curve curve = mesh->get_curve(pidx - str_offset);
int k = PRIMITIVE_UNPACK_SEGMENT(pack.prim_type[prim]);
curve.bounds_grow(k, &mesh->curve_keys[0], &mesh->curve_radius[0], bbox);
visibility |= PATH_RAY_CURVE;
/* motion curves */
if(mesh->use_motion_blur) {
Attribute *attr = mesh->curve_attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
if(attr) {
size_t mesh_size = mesh->curve_keys.size();
size_t steps = mesh->motion_steps - 1;
float3 *key_steps = attr->data_float3();
for(size_t i = 0; i < steps; i++)
curve.bounds_grow(k, key_steps + i*mesh_size, &mesh->curve_radius[0], bbox);
}
}
}
else {
/* triangles */
int tri_offset = (params.top_level)? mesh->tri_offset: 0;
Mesh::Triangle triangle = mesh->get_triangle(pidx - tri_offset);
const float3 *vpos = &mesh->verts[0];
triangle.bounds_grow(vpos, bbox);
/* motion triangles */
if(mesh->use_motion_blur) {
Attribute *attr = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
if(attr) {
size_t mesh_size = mesh->verts.size();
size_t steps = mesh->motion_steps - 1;
float3 *vert_steps = attr->data_float3();
for(size_t i = 0; i < steps; i++)
triangle.bounds_grow(vert_steps + i*mesh_size, bbox);
}
}
}
}
visibility |= ob->visibility_for_tracing();
}
/* TODO(sergey): De-duplicate with pack_leaf(). */ /* TODO(sergey): De-duplicate with pack_leaf(). */
float4 leaf_data[BVH_NODE_LEAF_SIZE]; float4 leaf_data[BVH_NODE_LEAF_SIZE];
leaf_data[0].x = __int_as_float(c0); leaf_data[0].x = __int_as_float(c0);

@ -375,71 +375,12 @@ void BVH4::refit_nodes()
void BVH4::refit_node(int idx, bool leaf, BoundBox& bbox, uint& visibility) void BVH4::refit_node(int idx, bool leaf, BoundBox& bbox, uint& visibility)
{ {
if(leaf) { if(leaf) {
/* Refit leaf node. */
int4 *data = &pack.leaf_nodes[idx]; int4 *data = &pack.leaf_nodes[idx];
int4 c = data[0]; int4 c = data[0];
/* Refit leaf node. */
for(int prim = c.x; prim < c.y; prim++) {
int pidx = pack.prim_index[prim];
int tob = pack.prim_object[prim];
Object *ob = objects[tob];
if(pidx == -1) { BVH::refit_primitives(c.x, c.y, bbox, visibility);
/* Object instance. */
bbox.grow(ob->bounds);
}
else {
/* Primitives. */
const Mesh *mesh = ob->mesh;
if(pack.prim_type[prim] & PRIMITIVE_ALL_CURVE) {
/* Curves. */
int str_offset = (params.top_level)? mesh->curve_offset: 0;
Mesh::Curve curve = mesh->get_curve(pidx - str_offset);
int k = PRIMITIVE_UNPACK_SEGMENT(pack.prim_type[prim]);
curve.bounds_grow(k, &mesh->curve_keys[0], &mesh->curve_radius[0], bbox);
visibility |= PATH_RAY_CURVE;
/* Motion curves. */
if(mesh->use_motion_blur) {
Attribute *attr = mesh->curve_attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
if(attr) {
size_t mesh_size = mesh->curve_keys.size();
size_t steps = mesh->motion_steps - 1;
float3 *key_steps = attr->data_float3();
for(size_t i = 0; i < steps; i++)
curve.bounds_grow(k, key_steps + i*mesh_size, &mesh->curve_radius[0], bbox);
}
}
}
else {
/* Triangles. */
int tri_offset = (params.top_level)? mesh->tri_offset: 0;
Mesh::Triangle triangle = mesh->get_triangle(pidx - tri_offset);
const float3 *vpos = &mesh->verts[0];
triangle.bounds_grow(vpos, bbox);
/* Motion triangles. */
if(mesh->use_motion_blur) {
Attribute *attr = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
if(attr) {
size_t mesh_size = mesh->verts.size();
size_t steps = mesh->motion_steps - 1;
float3 *vert_steps = attr->data_float3();
for(size_t i = 0; i < steps; i++)
triangle.bounds_grow(vert_steps + i*mesh_size, bbox);
}
}
}
}
visibility |= ob->visibility_for_tracing();
}
/* TODO(sergey): This is actually a copy of pack_leaf(), /* TODO(sergey): This is actually a copy of pack_leaf(),
* but this chunk of code only knows actual data and has * but this chunk of code only knows actual data and has
* no idea about BVHNode. * no idea about BVHNode.