diff options
author | Andre Susano Pinto <andresusanopinto@gmail.com> | 2009-07-08 14:40:26 +0400 |
---|---|---|
committer | Andre Susano Pinto <andresusanopinto@gmail.com> | 2009-07-08 14:40:26 +0400 |
commit | f90a0b838321cfa11cda2fd65d820a6f39a06e5c (patch) | |
tree | cdda4251713439f053ab34d71e3153f6a91f8475 /source/blender/render/intern | |
parent | 5b75ea38ff034d40a67b331b161d0ce870848ebb (diff) |
Added local stack during bvh transversal
Diffstat (limited to 'source/blender/render/intern')
-rw-r--r-- | source/blender/render/intern/source/rayobject_bvh.c | 55 |
1 files changed, 55 insertions, 0 deletions
diff --git a/source/blender/render/intern/source/rayobject_bvh.c b/source/blender/render/intern/source/rayobject_bvh.c index 62adcb75b7c..33821db0905 100644 --- a/source/blender/render/intern/source/rayobject_bvh.c +++ b/source/blender/render/intern/source/rayobject_bvh.c @@ -37,6 +37,7 @@ #include "rayobject_rtbuild.h" #include "rayobject.h" +#define DFS_STACK_SIZE 64 #define DYNAMIC_ALLOC //#define SPLIT_OVERLAP_MEAN_LONGEST_AXIS /* objects mean split on the longest axis, childs BB are allowed to overlap */ @@ -47,6 +48,7 @@ typedef struct BVHTree BVHTree; static int bvh_intersect(BVHTree *obj, Isect *isec); +static int bvh_intersect_stack(BVHTree *obj, Isect *isec); static void bvh_add(BVHTree *o, RayObject *ob); static void bvh_done(BVHTree *o); static void bvh_free(BVHTree *o); @@ -54,7 +56,11 @@ static void bvh_bb(BVHTree *o, float *min, float *max); static RayObjectAPI bvh_api = { +#ifdef DFS_STACK_SIZE + (RE_rayobject_raycast_callback) bvh_intersect_stack, +#else (RE_rayobject_raycast_callback) bvh_intersect, +#endif (RE_rayobject_add_callback) bvh_add, (RE_rayobject_done_callback) bvh_done, (RE_rayobject_free_callback) bvh_free, @@ -150,6 +156,55 @@ static void bvh_bb(BVHTree *obj, float *min, float *max) /* * Tree transverse */ +static int dfs_raycast_stack(BVHNode *root, Isect *isec) +{ + BVHNode *stack[DFS_STACK_SIZE]; + int hit = 0, stack_pos = 0; + + stack[stack_pos++] = root; + + while(stack_pos) + { + BVHNode *node = stack[--stack_pos]; + if(RayObject_isAligned(node)) + { + if(RE_rayobject_bb_intersect(isec, (const float*)node->bb) != FLT_MAX) + { + //push nodes in reverse visit order + if(isec->idot_axis[node->split_axis] < 0.0f) + { + int i; + for(i=0; i<BVH_NCHILDS; i++) + if(node->child[i] == 0) break; + else stack[stack_pos++] = node->child[i]; + } + else + { + int i; + for(i=0; i<BVH_NCHILDS; i++) + if(node->child[i] != 0) stack[stack_pos++] = node->child[i]; + else break; + } + assert(stack_pos <= DFS_STACK_SIZE); + } + } + else + { + hit |= RE_rayobject_intersect( (RayObject*)node, isec); + if(hit && isec->mode == RE_RAY_SHADOW) return hit; + } + } + return hit; +} + +static int bvh_intersect_stack(BVHTree *obj, Isect *isec) +{ + if(RayObject_isAligned(obj->root)) + return dfs_raycast_stack(obj->root, isec); + else + return RE_rayobject_intersect( (RayObject*)obj->root, isec); +} + static int dfs_raycast(BVHNode *node, Isect *isec) { int hit = 0; |