performance wins!
[carveJwlIkooP6JGAAIwe30JlM.git] / bvh.h
diff --git a/bvh.h b/bvh.h
index 945d3cbbe1c6f8d4963e28bac9fc93f61056fa62..b04c3de2b95f38342259a85d54386854ce295488 100644 (file)
--- a/bvh.h
+++ b/bvh.h
@@ -55,6 +55,7 @@ struct bh_tree{
 };
 
 struct bh_system{
+   u32 system_type;
    void  (*expand_bound)( void *user, boxf bound, u32 item_index );
    float (*item_centroid)( void *user, u32 item_index, int axis );
    void  (*item_closest)( void *user, u32 item_index, v3f point, v3f closest );
@@ -71,13 +72,20 @@ struct bh_system{
    int   (*cast_ray)( void *user, u32 index, v3f co, v3f dir, ray_hit *hit );
 };
 
+static float scene_bh_centroid( void *user, u32 item_index, int axis );
+static void scene_bh_swap( void *user, u32 ia, u32 ib );
+static void scene_bh_expand_bound( void *user, boxf bound, u32 item_index );
+
 static void bh_update_bounds( bh_tree *bh, u32 inode ){
    bh_node *node = &bh->nodes[ inode ];
 
    box_init_inf( node->bbx );
    for( u32 i=0; i<node->count; i++ ){
       u32 idx = node->start+i;
-      bh->system->expand_bound( bh->user, node->bbx, idx );
+      if( bh->system->system_type == 0x1 )
+         scene_bh_expand_bound( bh->user, node->bbx, idx );
+      else
+         bh->system->expand_bound( bh->user, node->bbx, idx );
    }
 }
 
@@ -96,10 +104,13 @@ static void bh_subdivide( bh_tree *bh, u32 inode ){
 
    float split = node->bbx[0][axis] + extent[axis]*0.5f;
    float avg = 0.0;
-   for( u32 t=0; t<node->count; t++ )
-   {
+   for( u32 t=0; t<node->count; t++ ){
       u32 idx = node->start+t;
-      avg += bh->system->item_centroid( bh->user, idx, axis );
+
+      if( bh->system->system_type == 0x1 )
+         avg += scene_bh_centroid( bh->user, idx, axis );
+      else 
+         avg += bh->system->item_centroid( bh->user, idx, axis );
    }
    avg /= (float)node->count;
    split = avg;
@@ -109,10 +120,20 @@ static void bh_subdivide( bh_tree *bh, u32 inode ){
        j = i + node->count-1;
    
    while( i <= j ){
-      if( bh->system->item_centroid( bh->user, i, axis ) < split )
+      f32 centroid;
+      
+      if( bh->system->system_type == 0x1 )
+         centroid = scene_bh_centroid( bh->user, i, axis );
+      else
+         centroid = bh->system->item_centroid( bh->user, i, axis );
+
+      if( centroid < split )
          i ++;
       else{
-         bh->system->item_swap( bh->user, i, j );
+         if( bh->system->system_type == 0x1 )
+            scene_bh_swap( bh->user, i, j );
+         else
+            bh->system->item_swap( bh->user, i, j );
          j --;
       }
    }