diff options
Diffstat (limited to 'source/blender/render/intern/raytrace/svbvh.h')
-rw-r--r-- | source/blender/render/intern/raytrace/svbvh.h | 89 |
1 files changed, 50 insertions, 39 deletions
diff --git a/source/blender/render/intern/raytrace/svbvh.h b/source/blender/render/intern/raytrace/svbvh.h index a4044db8208..e0e96781f36 100644 --- a/source/blender/render/intern/raytrace/svbvh.h +++ b/source/blender/render/intern/raytrace/svbvh.h @@ -94,9 +94,9 @@ static int svbvh_bb_intersect_test(const Isect *isec, const float *_bb) RE_RC_COUNT(isec->raycounter->bb.test); - if (t1x > t2y || t2x < t1y || t1x > t2z || t2x < t1z || t1y > t2z || t2y < t1z) return 0; - if (t2x < 0.0 || t2y < 0.0 || t2z < 0.0) return 0; - if (t1x > isec->dist || t1y > isec->dist || t1z > isec->dist) return 0; + if(t1x > t2y || t2x < t1y || t1x > t2z || t2x < t1z || t1y > t2z || t2y < t1z) return 0; + if(t2x < 0.0 || t2y < 0.0 || t2z < 0.0) return 0; + if(t1x > isec->dist || t1y > isec->dist || t1z > isec->dist) return 0; RE_RC_COUNT(isec->raycounter->bb.hit); @@ -116,39 +116,40 @@ static int svbvh_node_stack_raycast(SVBVHNode *root, Isect *isec) stack[stack_pos++] = root; - while (stack_pos) { + while(stack_pos) + { node = stack[--stack_pos]; - if (!svbvh_node_is_leaf(node)) { + if(!svbvh_node_is_leaf(node)) + { int nchilds= node->nchilds; - if (nchilds == 4) { + if(nchilds == 4) { float *child_bb= node->child_bb; int res = svbvh_bb_intersect_test_simd4(isec, ((__m128*) (child_bb))); SVBVHNode **child= node->child; RE_RC_COUNT(isec->raycounter->simd_bb.test); - if (res & 1) { stack[stack_pos++] = child[0]; RE_RC_COUNT(isec->raycounter->simd_bb.hit); } - if (res & 2) { stack[stack_pos++] = child[1]; RE_RC_COUNT(isec->raycounter->simd_bb.hit); } - if (res & 4) { stack[stack_pos++] = child[2]; RE_RC_COUNT(isec->raycounter->simd_bb.hit); } - if (res & 8) { stack[stack_pos++] = child[3]; RE_RC_COUNT(isec->raycounter->simd_bb.hit); } + if(res & 1) { stack[stack_pos++] = child[0]; RE_RC_COUNT(isec->raycounter->simd_bb.hit); } + if(res & 2) { stack[stack_pos++] = child[1]; RE_RC_COUNT(isec->raycounter->simd_bb.hit); } + if(res & 4) { stack[stack_pos++] = child[2]; RE_RC_COUNT(isec->raycounter->simd_bb.hit); } + if(res & 8) { stack[stack_pos++] = child[3]; RE_RC_COUNT(isec->raycounter->simd_bb.hit); } } else { float *child_bb= node->child_bb; SVBVHNode **child= node->child; int i; - for (i = 0; i < nchilds; i++) { - if (svbvh_bb_intersect_test(isec, (float *)child_bb + 6 * i)) { + for(i=0; i<nchilds; i++) + if(svbvh_bb_intersect_test(isec, (float*)child_bb+6*i)) stack[stack_pos++] = child[i]; - } - } } } - else { + else + { hit |= RE_rayobject_intersect((RayObject*)node, isec); - if (SHADOW && hit) break; + if(SHADOW && hit) break; } } @@ -159,20 +160,25 @@ static int svbvh_node_stack_raycast(SVBVHNode *root, Isect *isec) template<> inline void bvh_node_merge_bb<SVBVHNode>(SVBVHNode *node, float *min, float *max) { - if (is_leaf(node)) { + if(is_leaf(node)) + { RE_rayobject_merge_bb((RayObject*)node, min, max); } - else { + else + { int i=0; - while (i+4 <= node->nchilds) { + while(i+4 <= node->nchilds) + { float *res = node->child_bb + 6*i; - for (int j = 0; j < 3; j++) { + for(int j=0; j<3; j++) + { min[j] = MIN2(min[j], res[4*j+0]); min[j] = MIN2(min[j], res[4*j+1]); min[j] = MIN2(min[j], res[4*j+2]); min[j] = MIN2(min[j], res[4*j+3]); } - for (int j = 0; j < 3; j++) { + for(int j=0; j<3; j++) + { max[j] = MAX2(max[j], res[4*(j+3)+0]); max[j] = MAX2(max[j], res[4*(j+3)+1]); max[j] = MAX2(max[j], res[4*(j+3)+2]); @@ -182,9 +188,10 @@ inline void bvh_node_merge_bb<SVBVHNode>(SVBVHNode *node, float *min, float *max i += 4; } - for ( ; i < node->nchilds; i++) { - DO_MIN(node->child_bb + 6 * i, min); - DO_MAX(node->child_bb + 3 + 6 * i, max); + for(; i<node->nchilds; i++) + { + DO_MIN(node->child_bb+6*i , min); + DO_MAX(node->child_bb+3+6*i, max); } } } @@ -211,19 +218,17 @@ struct Reorganize_SVBVH childs_per_node = 0; useless_bb = 0; - for (int i = 0; i < 16; i++) { + for(int i=0; i<16; i++) nodes_with_childs[i] = 0; - } } ~Reorganize_SVBVH() { - if (G.debug & G_DEBUG) { + if(G.debug & G_DEBUG) { printf("%f childs per node\n", childs_per_node / nodes); printf("%d childs BB are useless\n", useless_bb); - for (int i = 0; i < 16; i++) { + for(int i=0; i<16; i++) printf("%i childs per node: %d/%d = %f\n", i, nodes_with_childs[i], nodes, nodes_with_childs[i]/float(nodes)); - } } } @@ -243,12 +248,14 @@ struct Reorganize_SVBVH void prepare_for_simd(SVBVHNode *node) { int i=0; - while (i + 4 <= node->nchilds) { + while(i+4 <= node->nchilds) + { float vec_tmp[4*6]; float *res = node->child_bb+6*i; std::copy(res, res+6*4, vec_tmp); - for (int j=0; j<6; j++) { + for(int j=0; j<6; j++) + { res[4*j+0] = vec_tmp[6*0+j]; res[4*j+1] = vec_tmp[6*1+j]; res[4*j+2] = vec_tmp[6*2+j]; @@ -267,25 +274,26 @@ struct Reorganize_SVBVH SVBVHNode *transform(OldNode *old) { - if (is_leaf(old)) + if(is_leaf(old)) return (SVBVHNode*)old; - if (is_leaf(old->child)) + if(is_leaf(old->child)) return (SVBVHNode*)old->child; int nchilds = count_childs(old); int alloc_childs = nchilds; - if (nchilds % 4 > 2) + if(nchilds % 4 > 2) alloc_childs = padup(nchilds, 4); SVBVHNode *node = create_node(alloc_childs); childs_per_node += nchilds; nodes++; - if (nchilds < 16) + if(nchilds < 16) nodes_with_childs[nchilds]++; useless_bb += alloc_childs-nchilds; - while (alloc_childs > nchilds) { + while(alloc_childs > nchilds) + { const static float def_bb[6] = { FLT_MAX, FLT_MAX, FLT_MAX, FLT_MIN, FLT_MIN, FLT_MIN }; alloc_childs--; node->child[alloc_childs] = NULL; @@ -293,17 +301,20 @@ struct Reorganize_SVBVH } int i=nchilds; - for (OldNode *o_child = old->child; o_child; o_child = o_child->sibling) { + for(OldNode *o_child = old->child; o_child; o_child = o_child->sibling) + { i--; node->child[i] = transform(o_child); - if (is_leaf(o_child)) { + if(is_leaf(o_child)) + { float bb[6]; INIT_MINMAX(bb, bb+3); RE_rayobject_merge_bb((RayObject*)o_child, bb, bb+3); copy_bb(node->child_bb+i*6, bb); break; } - else { + else + { copy_bb(node->child_bb+i*6, o_child->bb); } } |