Added local stack during bvh transversal
This commit is contained in:
@@ -37,6 +37,7 @@
|
|||||||
#include "rayobject_rtbuild.h"
|
#include "rayobject_rtbuild.h"
|
||||||
#include "rayobject.h"
|
#include "rayobject.h"
|
||||||
|
|
||||||
|
#define DFS_STACK_SIZE 64
|
||||||
#define DYNAMIC_ALLOC
|
#define DYNAMIC_ALLOC
|
||||||
|
|
||||||
//#define SPLIT_OVERLAP_MEAN_LONGEST_AXIS /* objects mean split on the longest axis, childs BB are allowed to overlap */
|
//#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;
|
typedef struct BVHTree BVHTree;
|
||||||
|
|
||||||
static int bvh_intersect(BVHTree *obj, Isect *isec);
|
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_add(BVHTree *o, RayObject *ob);
|
||||||
static void bvh_done(BVHTree *o);
|
static void bvh_done(BVHTree *o);
|
||||||
static void bvh_free(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 =
|
static RayObjectAPI bvh_api =
|
||||||
{
|
{
|
||||||
|
#ifdef DFS_STACK_SIZE
|
||||||
|
(RE_rayobject_raycast_callback) bvh_intersect_stack,
|
||||||
|
#else
|
||||||
(RE_rayobject_raycast_callback) bvh_intersect,
|
(RE_rayobject_raycast_callback) bvh_intersect,
|
||||||
|
#endif
|
||||||
(RE_rayobject_add_callback) bvh_add,
|
(RE_rayobject_add_callback) bvh_add,
|
||||||
(RE_rayobject_done_callback) bvh_done,
|
(RE_rayobject_done_callback) bvh_done,
|
||||||
(RE_rayobject_free_callback) bvh_free,
|
(RE_rayobject_free_callback) bvh_free,
|
||||||
@@ -150,6 +156,55 @@ static void bvh_bb(BVHTree *obj, float *min, float *max)
|
|||||||
/*
|
/*
|
||||||
* Tree transverse
|
* 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)
|
static int dfs_raycast(BVHNode *node, Isect *isec)
|
||||||
{
|
{
|
||||||
int hit = 0;
|
int hit = 0;
|
||||||
|
|||||||
Reference in New Issue
Block a user